本文讲的是Kubernetes基本要素介绍,【编者的话】Rimas Mocevicius是云计算、 CoreOS 、 Kubernetes 、DEIS和应用程序容器解决方案架构师 。CoreOS Essentials一书作者。目前就职于DEIS。本文是其发表在DEIS上的官方博客,介绍Kubernetes的系列教程的第一篇。
Kubernetes是在群集中管理跨多台主机容器化应用的开源系统。
Kubernetes提供了应用部署、调度、更新、维护和扩缩的机制。Kubernetes的一个重要特点是,它可以主动管理的容器,以确保集群的状态持续匹配用户的意图。
Kubernetes使您可以通过扩缩或推出新功能快速响应客户的需求。它还允许你最大限度使用硬件资源。
Kubernetes是:
- 精益的:轻量级的,简单,操作方便
- 便携的:公开的,私有的,混合的多种云方式
- 可扩展的:模块化,可插拔,插件化,可组合并且可工具化
- 自愈性:自动部署,自动重启,自动复制
Kubernetes是建立在十五年来谷歌运行大规模生产系统的经验 ,并结合了来自社区的顶级创意和实践。
Kubernetes支持Docker和rkt容器,更多的容器类型将在未来予以支持。
在这篇短文里,我们会从基本要素介绍Kubernetes。
让我们先从基本的组成部分开始。
kubectl
kubectl实用程序可以与Kubernetes集群管理器交互。例如,您可以添加和删除节点,Pod,复制控制器和服务。你也可以检查它们的状态,等等。
欲了解更多信息,请参阅文档。
集群
群集是一组物理机或虚拟机(或两者)与使用Kubernetes运行应用程序等基础资源的总和。
在下图中,我们可以看到一组不同种类的用户指定的容器都整齐地并自动打包成Kubernetes可用节点。
我们可以使用cluster-info命令获取集群的基本信息。
下面是例子:
$ kubectl cluster-info Kubernetes master is running at http://172.19.17.99:8080 Kube-dns is running at http://172.19.17.99:8080/api/v1/proxy/namespaces/kube-system/services/kube-dns KubeUI is running at http://172.19.17.99:8080/api/v1/proxy/namespaces/kube-system/services/kube-ui
控制面板
Kubernetes控制面板被分成多个组件。这些组件协同工作以提供集群的统一视图。
ETCD
所有的持久状态数据存储在etcd集群中。它提供了一种分布式的方式来可靠地存储配置数据。
主服务
主服务是一套主要的Kubernetes控制服务,通常运行在一台服务器上。如果需要高可用性,可在负载均衡器之后运行多台服务器。
主服务包括以下几个部分:
- API服务器是整个群集的中央管理点,并允许管理员配置Kubernetes工作负载和组织单元。 API服务器还负责确保etcd并部署容器的服务细节是一致的。
换句话说,API服务器验证并配置(通过命令)pod,服务,和复制控制器的数据。它还分配pod到服务节点和同步pod的配置信息。 - controller manager服务处理由独立的复制任务定义的复制过程。这些操作的细节将写入etcd,其中controller manager监视写入过程。当发现配置更改,controller manager读取的信息,并实现了满足所需状态的复制过程,例如应用组的扩缩容。
换句话说,controller manager监视etcd中的复制任务并使用API来保证所需的状态。 - scheduler分配工作负载迁移到集群中的指定节点。它通过读取工作量操作要求,分析当前环境执行此过程(即,集群中的各个节点的健康情况和操作细节),然后放置工作量到一个合适节点,或一组节点上。
节点
一个节点(有时称为工作节点)是运行Kubernetes服务用以调度Pod的一个物理或虚拟机。
节点可以被控制面板管理。
Kubernetes在每个节点上运行的服务包括:
- kubelet守护进程是每个节点上运行的主要媒介。kubelet守护进程观察主API服务器,并确保适当的本地容器被启动,并保证其健康的持续运行。
- kube-proxy守护进程在每个节点上作为该节点上的简单网络代理和负载均衡器而提供服务。
你可以通过下面的命令获取节点运行情况列表:
$ kubectl get nodes NAME LABELS STATUS 172.19.17.99 kubernetes.io/hostname=172.19.17.99 Ready
配置文件
Kubernetes通过配置文件(称为manifests),它可以是YAML或JSON格式。
命名空间
命名空间就像一个资源名称的前缀。命名空间帮助不同的项目,环境(例如,开发和生产),团队或客户共享同一个集群。它能够阻止名称冲突。
命名空间可以通过配置文件创建。
创建一个命名为development-ns.yaml
的文件,并写入以下内容:
kind: "Namespace" apiVersion: "v1" metadata: name: "development" labels: name: "development"
然后可以运行下面的命令创建新的命名空间:
$ kubectl create -f development-ns.yaml namespaces/development
去查看已经存在的命名空间,运行:
$ kubectl get namespaces NAME LABELS STATUS default <none> Active development name=development Active
欲了解更多有关命名空间的内容,请参阅文档。
Pod
Pod是一组并置的应用容器,这些容器是共享磁盘卷的。
Pod是可以被创建,调度,并与Kubernetes管理最小部署单元。Pod可以单独创建。由于Pods没有受管的生命周期,如果他们进程死掉了,他们将不会重新创建。出于这个原因,建议您使用复制控制器(我们将在后面介绍),即使你创造了单独的Pod。
所有在Pod的应用使用相同的网络命名空间,IP地址及端口空间。他们可以找到并互相使用localhost
沟通。每个Pod有一个与跨网络的其他物理计算机和容器充分沟通的扁平网络共享命名空间中的IP地址。
让我们为一个nginx网络容器创建一个简单的Pod定义。
创建一个命名为nginx.yaml
的文件,并写入下列内容:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx-server image: nginx ports: - containerPort: 80
在这个文件中:
Name
是容器的名称image
是将要使用的Docker镜像的名称containerPort
对外暴露容器的端口,这样我们可以通过Pod的IP地址与nginx服务器通信
定义在镜像中的entrypoint默认会被运行。随着我们的nginx镜像,该命令运行nginx。
让我们通过运行下列命令来创建Pod
$ kubectl create -f nginx.yaml pods/nginx
就这么简单!
你可以通过下列命令检查创建是否生效:
$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 1m
哦了。这里,我们看见一分钟之前创建的nginx的Pod了。
我们可以继续检查将要运行的Pod的资源状况:
$ kubectl describe pod nginx Name: nginx Namespace: default Image(s): nginx Node: 172.19.17.99/172.19.17.99 Labels: <none> Status: Running Reason: Message: IP: 10.244.3.2 Replication Controllers: <none> Containers: nginx: Image: nginx State: Running Started: Sat, 29 Aug 2015 18:23:15 +0100 Ready: True Restart Count: 0 Conditions: Type Status Ready True
并且我们可以删除该Pod:
$ kubectl delete pod nginx pods/nginx
看见了吧,它生效了:
$ kubectl get pods NAME READY STATUS RESTARTS AGE
欲了解更多关于Pod的内容,请参阅文档。
复制控制器
复制控制器管理Pod的生命周期。它们保证指定数量的Pod在任何给定的时间都在运行。他们通过创建或删除Pod做到这一点。出于这个原因,建议您使用复制控制器,即使你创造了单独的Pod。
让我们为我们以前使用nginx的Pod创建复制控制器。
创建nginxrc.yaml
文件,并写入:
apiVersion: v1 kind: ReplicationController metadata: name: my-nginx spec: replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
现在创建该文件复制控制器:
$ kubectl create -f nginxrc.yaml replicationcontrollers/my-nginx
我们可以看到有多少副本:
$ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS my-nginx nginx nginx app=nginx 1
我们可以很容易地扩展Pod:
$ kubectl scale --replicas=3 rc my-nginx
并检查它是否生效:
$ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS my-nginx nginx nginx app=nginx 3
在这里,我们看到在复制控制器将Pod从一个副本扩展为三个副本。
复制控制器将保证特定数量的副本将在任何时候都可以运行。
下图展示了复制管理器如何工作的:
正如你所看到的,它知道有三个标签为nginx的Pod。并监视着这些Pod,准备在必要时创建一个。
欲了解更多关于复制控制器的内容,请参阅文档。
服务
服务为一组Pod提供单一稳定的名称和地址。他们作为基本负载均衡器而存在。
Pod大多数被设计为长期运行的,但一旦单个进程死亡,Pod也跟着退出。如果Pod退出,复制控制器使用新的Pod替换它。每个Pod都有自己专用的IP地址,这使得容器具有相同的端口,即使他们共享相同的主机。但每次Pod由复制控制器启动,Pod将获取一个新的IP地址。
这是服务真正其作用的地方。服务附加到一个复制控制器。每个服务被分配了虚拟IP地址,它保持恒定不变。只要我们知道服务IP地址,服务本身将跟踪由复制控制器创建的Pod,并将请求分发给它们。
现在让我们为my-nginx
复制控制器创建一个服务。
创一个nginxsvc.yaml
文件,并写入:
apiVersion: v1 kind: Service metadata: name: nginxsvc labels: app: nginx spec: ports: - port: 80 protocol: TCP selector: app: nginx
现在我们可以运行下列命令创建服务:
$ kubectl create -f nginxsvc.yaml
并检查其是否工作:
$ kubectl get svc nginxsvc NAME LABELS SELECTOR IP(S) PORT(S) nginxsvc app=nginx app=nginx 10.100.168.74 80/TCP
因为在Kubernetes群集中的每个节点都运行一个kube-proxy,它监视Kubernetes API服务器的添加和删除动作。对于每一个新的服务,kube-proxy打开本地节点上的(随机选择)端口。到该端口的任何连接被代理到对应后端一个Pod中。
下图展示了nginxsvc
如何工作的:
正如你所看到的,进入HTTP端口80的请求在到达nginxsvc
服务后被代理到三个nginx
的Pod中的一个上。
欲了解更多关于服务的内容,请参阅文档。
标签
标签用于组织和选择基于键值对的对象组。
它们被用于每一个Kubernetes组件。例如:复制控制器使用他们做服务发现。
让我们看看标签如何运用在链接复制控制器my-nginx和nginxsvc
服务。
my-nginx
复制控制器配置包括如下:
... metadata: labels: app: nginx ...
app
标签设置给nginx
。
这种标签用于我们的nginxsvc
服务配置:
... selector: app: nginx ...
此标签用于链接服务和复制控制器。
你可以运行下列命令查看服务正在使用那一个选择器:
$ kubectl get svc nginxsvc NAME LABELS SELECTOR IP(S) PORT(S) nginxsvc app=nginx app=nginx 10.100.168.74 80/TCP
欲了解更多关于标签的内容,请参阅文档。
总结
在Kubernetes的短片教程的第一部分,我们看了kubectl,集群,控制面板,命名空间,Pod,服务,复制控制器和标签。
在第二部分,我们将涉及卷,加密,滚动更新和Helm。
相关阅读
- Deis Workflow, Beta 3 by Jason Hansen ON 28 APR 2016
- Deis Workflow, now in Beta by Jason Hansen ON 24 MAR 2016
- KubeCon Trip Report by Michelle Noorali ON 15 MAR 2016
- Connecting Docker Containers, Part Two by Eddy Mavungu ON 4 MAR 2016
- Connecting Docker Containers, Part One by Eddy Mavungu ON 26 FEB 2016
- Internal Load Balancing on Google Container Engine by Rimantas Mocevicius ON 19 FEB 2016
原文链接:Kubernetes Overview, Part One (翻译:高洪涛)
===========================================
译者介绍
高洪涛,当当网架构师,开源数据库分库分表中间件Sharding-JDBC作者。目前从事Docker相关调研工作。
原文发布时间为:2016-05-02
本文作者:gaohongtao
本文来自合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:Kubernetes基本要素介绍