不会飞的章鱼

熟能生巧,勤能补拙;念念不忘,必有回响。

第一个Kubernetes应用

本文将以创建一个nginxdeployment为例体验Kubernetes的基础使用

KubernetesDocker等很多项目最大的不同是:它不推荐你使用命令行方式的方式直接运行容器,而是希望你用YAML文件的方式,即把容器的定义、参数、配置都记录在一个YAML文件中,然后用

1
# kubectl create -f test.yml

运行起来。

这么做最直接的好处就是,会有一个文件记录下Kubernetes到底运行了什么。

编写YAML文件

nginx-deployment.yaml文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: apps/v1
kind: Deployment # API对象的类型
metadata:
name: nginx-deployment
spec:
selector:
matchLabels: # 过滤规则的定义
app: nginx
replicas: 2 # 定义Pod副本个数为2
template:
metadata: labels: # 元数据
app: nginx # labels,一组键值对的标签
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
  • Deployment是一个定义多副本应用(多个副本Pod)的对象,此外,Deployment还负责在Pod定义发生变化时对每个副本进行滚动更新;
  • PodKubernetes世界里的”应用运行单元”,而一个应用运行单元可以由多个容器组成;
  • 使用一种API对象(Deployment)管理另一种API对象(Pod),在Kubernetes中叫作控制器模式(controller pattern
  • Labels作用:可以通过它从Kubernetes中过滤出它所关心的被控制对象;
  • 另外,在Metadata中,还有一个与Labels格式、层级完全相同的字段,叫做Annotations。它专门用来携带键值对格式的内部信息。所谓内部信息,指的是对这些信息感兴趣的是Kubernetes组件,而不是用户。所以大多数Annotations是在Kubernetes运行过程中被自动加在这个API对象上;
  • 一个KubernetesAPI对象定义,大多可以分为MetadataSpec两个部分,前者存放的是这个对象的元数据,而后者存放的是属于这个对象的定义,用来描述它所要表达的功能。

运行YAML文件

执行:

1
kubectl create -f nginx-default.yaml

然后,通过kubectl get命令检查这个YAML运行起来的状态

1
kubectl get pods -l app=nginx

此外,还可以使用kubectl describe命令查看一个API对象的细节,比如

1
kubectl describe pod nginx-deployment-67594d6bf6-4vkq9

  • Kubernetes执行的过程中,对API对象的所有重要操作都会被记录在这个对象的Events里,并且显示在kubectl describe指令返回的结果中。

升级

接下来,如果要升级这个Nginx服务,把它的镜像版本从1.7.9升级到1.8,只需要修改这个YAML文件即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: apps/v1
kind: Deployment # API对象的类型
metadata:
name: nginx-deployment
spec:
selector:
matchLabels: # 过滤规则的定义
app: nginx
replicas: 2 # 定义Pod副本个数为2
template:
metadata: labels: # 元数据
app: nginx # labels,一组键值对的标签
spec:
containers:
- name: nginx
image: nginx:1.8 # 这里从1.7.9修改为1.8
ports:
- containerPort: 80

然后执行

1
kubectl apply -f nginx-deployment.yaml

声明书API

kubectl apply -f的操作方法是``Kubernetes声明式API所推荐的用法。也就说,作为用户,你不必关心当前的操作是创建还是更新,你执行的命令始终是kubectl apply,这个YAML文件描述的就是你这个应用的期望状态,或者说最终状态。而当这个文件发生变化后,Kubernetes`会根据具体的变化内容自动进行处理,将整个系统的状态向你所定义的最终状态“逐步逼近”,最终重新“达成一致”。

这个流程的好处是有助于开发人员和运维人员围绕可以版本化管理的YAML文件,而不是“行踪不定”的命令式进行写作,从而大大降低沟通成本。这种面向最终状态的分布式系统设计原则就被称为“声明式API”。

小结

所以,如果通过容器镜像能够保证应用本身在开发环境与部署环境中的一致性的话,那么现在Kubernetes项目通过YAML文件就保证了应用的“部署配置”在开发环境与部署环境中的一致性。而当应用本身发生变化时,开发人员和运维人员可以依靠容器镜像来进行同步,当应用部署参数发生变化时,这些YAML文件就是他们相互沟通和信任的媒介。

在Deployment中声明Volume

Kubernetes中,Volume属于Pod对象的一部分,所以,我们需要修改这个YAML文件里的template.spec字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: apps/v1
kind: Deployment # API对象的类型
metadata:
name: nginx-deployment
spec:
selector:
matchLabels: # 过滤规则的定义
app: nginx
replicas: 2 # 定义Pod副本个数为2
template:
metadata: labels: # 元数据
app: nginx # labels,一组键值对的标签
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-vol
volumes:
- name: nginx-vol # Volume的名称
emptyDir: {} # Volume的类型
  • emptyDir类型等同于Docker的隐式Volume参数,即不显式声明宿主机目录的Volume。所以,Kubernetes也会在宿主机上创建一个临时目录,这个目录将会在被绑定挂载到容器所声明的Volume目录上。

执行

1
kubectl apply -f nginx-deployment.yaml

1
kubectl describe pod nginx-deployment-54d8dff7d7-r6z8t

最后,还可以使用kubectl exec指令进入这个Pod中(容器的Namespace中)查看这个Volume目录:

1
2
3
kubectl exec -it nginx-deployment-54d8dff7d7-r6z8t -- /bin/bash

ls /usr/share/nginx/html

删除

若要从Kubernetes集群中删除这个Nginx Deployment,直接执行以下命令:

1
kubectl delete -f nginx-deployment.yaml

总结

本文介绍了一个完整kubernetes应用从创建,更新到删除的全过程,以及目录挂载的命令使用。

------ 本文结束------
如果本篇文章对你有帮助,可以给作者加个鸡腿~(*^__^*),感谢鼓励与支持!