英文原作者:Ben Cane 翻译作者:Miazzy 翻译&转载:https://blog.codeship.com/getting-started-with-kubernetes/
Kubernetes入门
Kubernetes是一个非常受欢迎的开源容器管理系统。Kubernetes项目的目标是跨多个节点管理容器,就像管理单个系统上的容器一样简单。为此,它提供了许多独特的功能,例如流量负载平衡,自我修复(自动重启),调度,扩展和滚动更新。
在今天的文章中,我们将通过在多节点Kubernetes集群中部署简单的Web应用程序来了解Kubernetes。然而,在我们开始部署容器之前,我们首先需要设置一个集群。
搭建Kubernetes集群
官方入门指南将指导您在Google的Container Engine平台上部署Kubernetes集群。虽然这是一种快速简便的启动和运行方法,但对于本文,我们将使用替代提供程序部署Kubernetes,特别是通过Vagrant。我们使用Vagrant有几个原因,但主要是因为它显示了如何在通用平台而不是GCE上部署Kubernetes。
Kubernetes附带了几个适用于各种平台的安装脚本。这些脚本中的大多数使用Bash环境变量来更改Kubernetes的安装方式和方式。
对于此安装,我们将定义两个变量:
NUM_NODES
- 控制要部署的节点数KUBERNETES_PROVIDER
- 指定安装Kubernetes的平台
让我们定义安装脚本应该使用vagrant
平台并配置2节点集群。
$ export NUM_NODES=2
$ export KUBERNETES_PROVIDER=vagrant
例如,如果我们想在AWS上部署Kubernetes,我们可以通过将KUBERNETES_PROVIDER
环境变量更改为aws
。
使用Kubernetes安装脚本
虽然有很多关于如何安装Kubernetes的演练,但我发现最简单的方法是使用(https://get.k8s.io)上提供的Kubernetes安装脚本。
该脚本本质上是与Kubernetes一起分发的安装脚本的包装器,这使得该过程变得更加容易。关于这个脚本我最喜欢的一件事是它也会为你下载Kubernetes。
要开始使用此脚本,我们需要下载它; 我们可以通过快速curl
命令完成此操作。一旦我们下载了脚本,我们就可以通过运行bash
命令后跟脚本名来执行它。
$ curl https://get.k8s.io > kubernetes_install.sh
$ bash kubernetes_install.sh
Downloading kubernetes release v1.2.2 to /var/tmp/kubernetes.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 426M 100 426M 0 0 12.2M 0 0:00:34 0:00:34 --:--:-- 6007k
Unpacking kubernetes release v1.2.2
Creating a kubernetes on vagrant...
<output truncated>
Kubernetes master is running at https://10.245.1.2
Heapster is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/heapster
KubeDNS is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kube-dns
kubernetes-dashboard is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard
Grafana is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
InfluxDB is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb
Installation successful!
脚本完成执行后,我们有一个正在运行的Kubernetes集群。但是,在我们开始与这个Kubernetes集群交互之前,我们还有一个步骤; 我们需要kubectl
安装命令。
设置kubectl
该kubectl
命令存在两个的Linux和Mac OS X的。由于我从MacBook运行此安装,我将安装Mac OS X版本kubectl
。这意味着我将通过Vagrant运行集群,但是从我的MacBook与该集群进行交互。
要下载kubectl
命令,我们将再次使用curl
。
$ curl https://storage.googleapis.com/kubernetes-release/release/v1.2.0/bin/darwin/amd64/kubectl > kubectl
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 38.7M 100 38.7M 0 0 10.4M 0 0:00:03 0:00:03 --:--:-- 10.4M
$ chmod 750 kubectl
在之后kubectl
的二进制文件下载和权限更改为允许执行的kubectl
命令几乎准备就绪。在我们开始与Kubernetes集群进行交互之前,还需要一步。该步骤是配置kubectl
命令。
$ export KUBECONFIG=~/.kube/config
与大多数Kubernetes脚本一样,kubectl
命令的配置由环境变量驱动。当我们执行上面的集群安装脚本时,该脚本.kube
在我的用户主目录中创建了一个配置目录。在该目录中,它还创建了一个名为的文件config
。此文件用于存储有关已创建的Kubernetes群集的信息。
通过将KUBECONFIG
环境变量设置为~/.kube/config
,我们定义该kubectl
命令应该引用此配置文件。让我们快速浏览一下该文件,以便更好地了解正在设置的内容。
$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <SSLKEYDATA>
server: https://10.245.1.2
name: vagrant
contexts:
- context:
cluster: vagrant
user: vagrant
name: vagrant
current-context: vagrant
kind: Config
preferences: {}
users:
- name: vagrant
user:
client-certificate-data: <SSLKEYDATA>
client-key-data: <SSLKEYDATA>
token: sometoken
- name: vagrant-basic-auth
user:
password: somepassword
username: admin
该.kube/config
文件设置了两个主要信息:
- 集群的位置
- 用于与该群集通信的身份验证数据
在.kube/config
定义文件后,让我们尝试kubectl
对我们的Kubernetes集群执行命令以验证一切正常。
$ ./kubectl get nodes
NAME STATUS AGE
kubernetes-node-1 Ready 31m
kubernetes-node-2 Ready 24m
在输出./kubectl get nodes
命令向我们表明,我们能够连接到我们的Kubernetes集群,并显示我们的两个节点的状态kubernetes-node-1
和kubernetes-node-2
。有了这个,我们可以继续安装完成。
关于Kubernetes节点的更多信息
在上面的命令中,我们用于kubectl
显示此群集上可用的Kubernetes节点的状态。但是,我们确实没有探究节点是什么或它在群集中扮演什么角色。
Kubernetes 节点是用于托管应用程序容器的物理或虚拟(在我们的示例中为虚拟)机器。在传统的基于容器的环境中,您通常会定义在指定的物理或虚拟主机上运行的特定容器。但是,在Kubernetes集群中,您只需定义要运行的应用程序容器。Kubernetes主服务器确定应用程序容器将在哪个节点上运行。
此方法还使Kubernetes集群能够执行诸如容器或节点死亡时自动重启等任务。
部署我们的应用程序
随着我们的Kubernetes集群准备就绪,我们现在可以开始部署应用程序容器。我们今天要部署的应用程序容器将是Ghost的一个实例。Ghost是一个流行的基于JavaScript的博客平台,凭借其官方Docker镜像,它的部署非常简单。
由于我们将使用预构建的Docker容器,因此我们不需要首先构建Docker镜像。但是,重要的是要说明为了在Kubernetes集群上使用自定义构建的容器。您必须首先构建容器并将其推送到Docker Hub等Docker存储库。
要启动我们的Ghost容器,我们将使用./kubectl
带有该run
选项的命令。
$ ./kubectl run ghost --image=ghost --port=2368
deployment "ghost" created
在上面的命令中,我们ghost
使用映像创建了一个名为的部署,ghost
并指定ghost
容器需要端口2368
。在走得太远之前,让我们首先验证容器是否正在运行。我们可以通过kubectl
使用get pods
选项执行命令来验证这一点。
$ ./kubectl get pods
NAME READY STATUS RESTARTS AGE
ghost-3550706830-4c2n5 1/1 Running 0 20m
该get pods
选项将告诉kubectl
命令列出当前部署到群集的所有Kubernetes Pod。
什么是Pod和部署?
甲波德是一组可以如同它们是在同一系统内运行相互通信容器。对于那些熟悉Docker的人来说,这可能听起来像链接容器,但实际上还有更多的东西。Pod中的容器不仅能够通过连接相互localhost
连接,容器内运行的进程还能够与其他容器共享内存段。
Pod的目标是允许在Pod中运行的应用程序以与它们不在容器中运行但只是在同一物理主机上运行相同的方式进行交互。此功能可以轻松部署非专门设计为在容器内运行的应用程序。
一个部署或部署对象,类似于期望状态的概念。本质上,部署是围绕所需功能的高级配置。例如,在我们启动Ghost容器之前,我们不只是启动Ghost容器。我们实际上配置了Kubernetes以确保至少有一个Ghost容器副本正在运行。
为Ghost创建服务
虽然Pod中的容器可以连接到群集外部的系统,但外部系统甚至其他Pod都无法与它们通信。这是因为,默认情况下,为Ghost服务定义的端口不会在此群集之外公开。这是服务发挥作用的地方。
为了使我们的Ghost应用程序可以在集群外部访问,我们刚刚创建的部署需要作为Kubernetes 服务公开。要将Ghost部署设置为服务,我们将kubectl
再次使用该命令,这次使用该expose
选项。
$ ./kubectl expose deployment ghost --type="NodePort"
service "ghost" exposed
在上面的命令中,我们使用--type
带有参数的标志NodePort
。此标志定义要为此服务公开的服务类型,在本例中为NodePort
服务类型。该NodePort
服务类型将设置所有节点监听指定的端口上。如果我们kubectl
再次使用该命令,我们可以看到我们的更改生效,但这次使用该get services
选项。
$ ./kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ghost 10.247.63.140 nodes 2368/TCP 55s
kubernetes 10.247.0.1 <none> 443/TCP 19m
服务类型
目前,Kubernetes支持三种服务类型:
ClusterIP
NodePort
LoadBalancer
如果我们只希望将此服务公开给此集群中的其他Pod,我们可以使用ClusterIP
默认的服务类型。这将打开每个节点上用于Pod to Pod通信的端口。
该LoadBalancer
服务类型旨在提供一个外部IP作为该服务的负载均衡。由于我们的部署是在本地笔记本电脑上利用Vagrant,因此该选项在我们的环境中不起作用。它适用于部署在GCE或AWS等云环境中的Kubernetes集群。
测试我们的Ghost实例
由于我们在定义NodePort
服务时未指定要使用的端口,因此Kubernetes随机分配了一个端口。要查看它分配的端口,我们可以使用kubectl
带有该describe service
选项的命令。
$ ./kubectl describe service ghost
Name: ghost
Namespace: default
Labels: run=ghost
Selector: run=ghost
Type: NodePort
IP: 10.247.63.140
Port: <unset> 2368/TCP
NodePort: <unset> 32738/TCP
Endpoints: 10.246.3.3:2368
Session Affinity: None
No events.
我们可以看到分配的端口是32738
。使用此端口,我们可以使用该curl
命令对任何Kubernetes节点进行HTTP调用,并重定向到2368
应用程序容器中的端口。
$ curl -vk http://10.245.1.3:32738
* Rebuilt URL to: http://10.245.1.3:32738/
* Trying 10.245.1.3...
* Connected to 10.245.1.3 (10.245.1.3) port 32738 (#0)
> GET / HTTP/1.1
> Host: 10.245.1.3:32738
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
从curl
命令的输出中,我们可以看到连接200 OK
响应成功。有趣的是,请求是指未运行Ghost容器的节点。我们可以看到这一点,如果我们使用kubectl
到describe
的群。
$ ./kubectl describe pod ghost-3550706830-ss4se
Name: ghost-3550706830-ss4se
Namespace: default
Node: kubernetes-node-2/10.245.1.4
Start Time: Sat, 16 Apr 2016 21:13:20 -0700
Labels: pod-template-hash=3550706830,run=ghost
Status: Running
IP: 10.246.3.3
Controllers: ReplicaSet/ghost-3550706830
Containers:
ghost:
Container ID: docker://55ea497a166ff13a733d4ad3be3abe42a6d7f3d2c259f2653102fedda485e25d
Image: ghost
Image ID: docker://09849b7a78d3882afcd46f2310c8b972352bc36aaec9f7fe7771bbc86e5222b9
Port: 2368/TCP
QoS Tier:
memory: BestEffort
cpu: Burstable
Requests:
cpu: 100m
State: Running
Started: Sat, 16 Apr 2016 21:14:33 -0700
Ready: True
Restart Count: 0
Environment Variables:
Conditions:
Type Status
Ready True
Volumes:
default-token-imnyi:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-imnyi
No events.
在上面的描述中,我们可以看到Ghost Pod正在运行kubernetes-node-2
。但是,我们刚刚提出的HTTP请求是kubernetes-node-1
。这可以通过名为的Kubernetes服务实现kube-proxy
。使用kube-proxy
,每当流量到达服务端口时,Kubernetes节点将检查该服务是否在该节点本地运行。如果没有,它会将流量重定向到运行该服务的节点。
在上面的例子中,这意味着即使发出了HTTP请求kubernetes-node-1
,kube-proxy
服务也会将该流量重定向到kubernetes-node-2
容器运行的位置。
此功能允许用户运行服务,而无需担心服务的位置以及服务是否已从一个节点移动到另一个节点。一个非常有用的功能,可以减少相当多的维护和头痛。
扩展部署
既然我们的Ghost服务正在运行并且可以被外部访问,我们需要执行上一个任务,在多个实例中扩展我们的Ghost应用程序。要做到这一点,我们可以简单地kubectl
再次调用该命令,但这次使用该scale
选项。
$ ./kubectl scale deployment ghost --replicas=4
deployment "ghost" scaled
我们已经指定应该有4 replicas
个ghost部署。如果我们kubectl get pods
再次执行,我们应该看到3个额外的pod用于ghost部署。
./kubectl get pods
NAME READY STATUS RESTARTS AGE
ghost-3550706830-49r81 1/1 Running 0 7h
ghost-3550706830-4c2n5 1/1 Running 0 8h
ghost-3550706830-7o2fs 1/1 Running 0 7h
ghost-3550706830-f3dae 1/1 Running 0 7h
通过最后一步,我们现在让我们的Ghost服务跨多个节点和多个pod运行。在请求我们的Ghost服务时,这些请求将被负载平衡到我们的各种Ghost实例。
摘要
在本文中,我们学习了如何跨多个Vagrant管理的虚拟机部署多节点Kubernetes集群。我们还学习了如何将应用程序部署到集群,使该应用程序可以被外部系统访问,最后将应用程序扩展到四个实例。尽管我们完成了所有这些任务,但我们只是触及了Kubernetes的表面。