轻松了解Kubernetes部署功能
Kubernetes简称k8s,是谷歌于2014年开始主导的开源项目,提供了以容器为中心的部署、伸缩和运维平台。截止目前它的最新版本为1.2。搭建环境之前建议先了解一下kubernetes的相关知识,可以参考《如果有10000台机器,你想怎么玩?》系列文章。本文介绍kubernetes的基本部署功能。
准备工作
首先需要搭建kubernetes集群环境,可以参考《轻松搭建Kubernetes 1.2版运行环境》来安装自己的kubernetes集群。
结果应该是有三台虚拟机,一台叫做master,它的IP是192.168.33.17,运行着k8s的api server、controller manager和scheduler;另两台叫做node1和node2,它们的IP分别是192.168.33.18和192.168.33.19,运行着k8s的kubelet和kube-proxy,当做k8s的两个节点。
部署(deployment)
启动一个容器最简单的方法应该就是使用以下命令了:
如果一切工作正常,应该能看到一条消息deployment “my-nginx” created。Deployment是kubernetes 1.2的一个新引入的概念,它包含着对Pod和将要代替Replication Controller的Replica Set的描述。
为了简化命令,我们设置一个别名:
使用以下命令可以看到目前集群里的信息:
用kubectl describe po my-nginx
可以查看到这个pod被分配到哪台node上去。当kubectl get po
显示1/1 Running时,说明容器已经启动完成了。SSH到那台虚拟机上,docker ps
一下,能够看到有两个容器启动完成了,一个是nginx,另一个就是负责网络的pause。使用docker rm -f
将nginx容器删除,再用kubectl get po
查看,一会儿便会显示0/1 ContainerCreating,随即又变成1/1 Running,这是replica set的功劳。当它检测到容器挂掉的时候,便会重新启动一个容器来保证服务不中断。不仅是容器挂掉,停止虚拟机也能使容器被再分配到另一台node上,有兴趣的朋友可以自行尝试,虚拟机重启回来后记得再次运行flannel和kubelet哦。
使用以下命令可以删除my-nginx deployment,my-nginx replica set和my-nginx pod(抵消第一条run命令的作用):
可以使用kubectl get
命令来查看删除后的结果。一般我们会把部署信息写在一个yaml格式的文件里,这样比较容易查看,并且方便写入各种参数:
Deployment文件的详细说明可以看Extensions API定义,通用参数的详细信息可以看Kubernetes API定义。由于这次的replicas设置为2,kubernetes会帮我们启动并维持两个实例。如果我们想要更新部署的yaml,有两种方法。第一种是使用edit直接修改:
把nginx:1.7.9
修改为nginx:1.9.11
,保存退出。Kubernetes就会自动帮我们升级镜像。通过kubectl get deployment nginx
的Events里可以看到升级的事件。不管是哪一种方法,升级的过程都是这样的:
- 启动一个新容器
- 停止两个旧容器
- 启动一个新容器
启动一个新的容器,然后停止一个旧的,重复这个过程直到旧的容器全部停止为止。这样可以保证
第二种是修改yaml文件,然后apply:
细心的你可能已经发现我在上面的命令里把nginx:1.9.1
打成nginx:1.91
了。如果此时用kubectl describe po nginx
命令,就能看到Error syncing pod, skipping: failed to “StartContainer” for “nginx” with ErrImagePull: “Tag 1.91 not found in repository docker.io/library/nginx”的错误。现在我需要停止这次升级。我们可以用这条命令来查看升级历史:
由于kubectl create
的时候用了--record
的标志,我们能够直接看到命令,方便定位到上一次正确的升级2 kubectl -s 192.168.33.17:8080 edit deployment/nginx-deployment,查看详细的deployment内容:
有两种方法可以回退到这个版本:
服务
前面创建了nginx的部署对象,那么别人如何使用nginx这个服务呢?首先要确定的是,这个nginx服务,是给内部使用的,还是外部。如果是内部使用,那就可以不用设置服务的类型(默认为ClusterIP),否则,可以将服务类型设置为NodePort,通过node的端口暴露出来给外部使用;或者是LoadBalancer,由云服务商提供一个负载均衡直接挂在服务上。这里我们使用NodePort,暴露出30088端口给外部使用。如果不指定nodePort,那么kubernetes会随机生成一个。下面让我们来启动服务:
这样便可以通过http://192.168.33.18:30088或http://192.168.33.19:30088访问nginx服务了:
可以使用以下命令来删除服务及nginx的部署:
一次性任务(job)
Kubernetes 1.1版时将Job还是Beta版,1.2之后已经可用于生产环境。Job是包含着若干pod的一次性任务。它与Replication Controller和Replica Set最大的区别就是当容器正常停止后,不会再次重启以维持一定数量的pod提供服务。下面我们用busybox运行一个耗时30s的任务:
可以使用以下命令来取得目前的job:
可以看到,30s之后,SUCCESSFUL从0变为1了,说明这个job已经顺利完成了。可以使用以下命令来查看所有的pod,包含在busybox的job里正常结束的pod:
Job完成之后仍然会在那里。如果需要删除,运行以下两条命令之一:
相关的pod也会一并被删除。不过容器仍然会留在运行过这个pod的node上。这可以通过设置kubelet的--maximum-dead-containers
和--maximum-dead-containers-per-container
参数来解决。
Daemon Sets
有时候需要每个node上都运行一个pod,比如监控或是日志收集等。这时候使用Daemon Sets就非常方便。我们用一个tomcat容器来做例子:
运行完毕后,通过以下命令来取得运行结果:
这个yaml文件和一开始的deployment的yaml文件格式很像,虽然我们没有指定replicas,但还是起了两个pod(因为我们有两个node)。可以ssh到这两个node上看看是不是每一个node上都启动了一个tomcat容器。