文章目录
  1. 1. 准备工作
  2. 2. 部署(deployment)
  3. 3. 服务
  4. 4. 一次性任务(job)
  5. 5. Daemon Sets

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;另两台叫做node1node2,它们的IP分别是192.168.33.18192.168.33.19,运行着k8s的kubelet和kube-proxy,当做k8s的两个节点。

部署(deployment)

启动一个容器最简单的方法应该就是使用以下命令了:

master
1
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 run my-nginx --image=nginx:1.7.9

如果一切工作正常,应该能看到一条消息deployment “my-nginx” createdDeployment是kubernetes 1.2的一个新引入的概念,它包含着对Pod和将要代替Replication ControllerReplica Set的描述。

为了简化命令,我们设置一个别名:

master
1
alias kubectl="kubernetes/server/bin/kubectl -s 192.168.33.17:8080"

使用以下命令可以看到目前集群里的信息:

master
1
2
3
4
5
6
kubectl get po # 查看目前所有的pod
kubectl get rs # 查看目前所有的replica set
kubectl get deployment # 查看目前所有的deployment
kubectl describe po my-nginx # 查看my-nginx pod的详细状态
kubectl describe rs my-nginx # 查看my-nginx replica set的详细状态
kubectl describe deployment my-nginx # 查看my-nginx deployment的详细状态

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命令的作用):

master
1
kubectl delete deployment my-nginx

可以使用kubectl get命令来查看删除后的结果。一般我们会把部署信息写在一个yaml格式的文件里,这样比较容易查看,并且方便写入各种参数:

master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat << EOF >nginx.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
resources:
requests:
cpu: 400m
EOF
kubectl create -f nginx.yaml --record

Deployment文件的详细说明可以看Extensions API定义,通用参数的详细信息可以看Kubernetes API定义。由于这次的replicas设置为2,kubernetes会帮我们启动并维持两个实例。如果我们想要更新部署的yaml,有两种方法。第一种是使用edit直接修改:

master
1
kubectl edit deployment/nginx-deployment

nginx:1.7.9修改为nginx:1.9.11,保存退出。Kubernetes就会自动帮我们升级镜像。通过kubectl get deployment nginx的Events里可以看到升级的事件。不管是哪一种方法,升级的过程都是这样的:

  • 启动一个新容器
  • 停止两个旧容器
  • 启动一个新容器
    启动一个新的容器,然后停止一个旧的,重复这个过程直到旧的容器全部停止为止。这样可以保证

第二种是修改yaml文件,然后apply:

master
1
2
sed -i "s/nginx:1.7.9/nginx:1.91/g" nginx.yaml
kubectl apply -f nginx.yaml

细心的你可能已经发现我在上面的命令里把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”的错误。现在我需要停止这次升级。我们可以用这条命令来查看升级历史:

master
1
kubectl rollout history deployment/nginx-deployment

由于kubectl create的时候用了--record的标志,我们能够直接看到命令,方便定位到上一次正确的升级2 kubectl -s 192.168.33.17:8080 edit deployment/nginx-deployment,查看详细的deployment内容:

master
1
kubectl rollout history deployment/nginx-deployment --revision=2

有两种方法可以回退到这个版本:

master
1
2
kubectl rollout undo deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment --to-revision=2

服务

前面创建了nginx的部署对象,那么别人如何使用nginx这个服务呢?首先要确定的是,这个nginx服务,是给内部使用的,还是外部。如果是内部使用,那就可以不用设置服务的类型(默认为ClusterIP),否则,可以将服务类型设置为NodePort,通过node的端口暴露出来给外部使用;或者是LoadBalancer,由云服务商提供一个负载均衡直接挂在服务上。这里我们使用NodePort,暴露出30088端口给外部使用。如果不指定nodePort,那么kubernetes会随机生成一个。下面让我们来启动服务:

master master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat << EOF >nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30088
EOF
kubectl create -f nginx-svc.yaml

这样便可以通过http://192.168.33.18:30088http://192.168.33.19:30088访问nginx服务了:

可以使用以下命令来删除服务及nginx的部署:

master
1
2
kubectl delete -f nginx-svc.yaml
kubectl delete -f nginx.yaml

一次性任务(job)

Kubernetes 1.1版时将Job还是Beta版,1.2之后已经可用于生产环境。Job是包含着若干pod的一次性任务。它与Replication Controller和Replica Set最大的区别就是当容器正常停止后,不会再次重启以维持一定数量的pod提供服务。下面我们用busybox运行一个耗时30s的任务:

master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cat << EOF >busybox.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: busybox
spec:
template:
metadata:
name: busybox
spec:
containers:
- name: busybox
image: busybox:1.24.1
command:
- sleep
- "30"
restartPolicy: Never
EOF
kubectl create -f busybox.yaml

可以使用以下命令来取得目前的job:

master
1
kubectl get jobs

可以看到,30s之后,SUCCESSFUL从0变为1了,说明这个job已经顺利完成了。可以使用以下命令来查看所有的pod,包含在busybox的job里正常结束的pod:

master
1
kubectl get pods --show-all

Job完成之后仍然会在那里。如果需要删除,运行以下两条命令之一:

master
1
2
kubectl delete job busybox
kubectl delete -f busybox.yaml

相关的pod也会一并被删除。不过容器仍然会留在运行过这个pod的node上。这可以通过设置kubelet的--maximum-dead-containers--maximum-dead-containers-per-container参数来解决。

Daemon Sets

有时候需要每个node上都运行一个pod,比如监控或是日志收集等。这时候使用Daemon Sets就非常方便。我们用一个tomcat容器来做例子:

master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat << EOF >tomcat.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: tomcat-ds
spec:
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:8.0.30-jre8
ports:
- containerPort: 8080
EOF
kubectl create -f tomcat.yaml

运行完毕后,通过以下命令来取得运行结果:

master
1
2
kubectl get ds
kubectl get pods

这个yaml文件和一开始的deployment的yaml文件格式很像,虽然我们没有指定replicas,但还是起了两个pod(因为我们有两个node)。可以ssh到这两个node上看看是不是每一个node上都启动了一个tomcat容器。

文章目录
  1. 1. 准备工作
  2. 2. 部署(deployment)
  3. 3. 服务
  4. 4. 一次性任务(job)
  5. 5. Daemon Sets