较深入的理解Pod下的"多个容器"定义

众所周知,k8s能调度的最小单元就是pod,但是pod里面是可以有多个docker容器的。但是pod和docker之间到底一种什么关系?还是需要实际的操作来更加直白的理解。

首先,先写了一个test.yaml用来启动Pod:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
apiVersion: v1	#这里注意版本号
kind: Pod #注意这里的大小写
metadata:
name: nginx-greenbook
labels:
app: test
spec:
volumes:
- name: test
emptyDir: {}
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: test #这里必须要跟Volumes的名称一致,都是test
mountPath: /usr/share/nginx/html
- name: debian1
image: debian
volumeMounts:
- name: test
mountPath: /html
command: ["/bin/sh","-c"]
args:
- while true; do
date >> /html/index.html;
sleep 1;
done
- name: debian2 #每一个容器的名称不能一样
image: debian
volumeMounts:
- name: test
mountPath: /html
command: ["/bin/sh","-c"]
args:
- while true; do
echo "woxcwy" >> /html/index.html;
sleep 2;
done
restartPolicy: Never #死了就死了

这个yaml主要是建立了一个存储卷叫html,它默认类型是emptyDir。这意味着当一个POD被分配到一个节点时,卷先被创建,并只要Pod在节点上运行时,这个卷仍存在(node重启的话,卷内容丢失,所以它只能做一个临时行的存储,如果想要持久化存储请使用hostPath)。第一容器运行nginx的服务器并将共享卷挂载到目录/usr/share/Nginx/html。第二容器使用Debian的镜像,并将共享卷挂载到目录/html,每一秒输入当前时间。第三个容器同理,每两秒输入一些字符串。

然后kubectl create -f test.yaml --record创建这个pod,然后使用docker ps -a就能看到生成了四个docker—分别是pod的三个容器和一个pause容器。使用kubectl exec -it pod名 -c 容器名 /bin/bash进入nginx的容器,会发现里面的/usr/share/nginx/html/index.html果然按照我们的要求在不断的输出日期和字符串。可见这三个容器已经挂载了同一个卷,如图:
akb48

可见挂载volume到Pod,本质上是将volume挂载到Pod中的每一个容器。如果在这三个容器ps -ef一下,会发现他们的pid=1的进程是各自的进程而不是pause容器的/pause进程,如图:
akb48
akb48

所以很多人说pod里每个容器的init进程其实是/pause,而pause容器的作用,可以担任init的角色(默认都docker run -ipc:container:pause),及时的清理僵尸进程。但是在我这里的实验结果看来并不是真的。不知道是不是我某个姿势不对…

话说回来,这个例子很明显的体现了“一个pod里可以有多个容器”这句话,每个pod是一个namespace,即这些容器都可以通过localhost来彼此访问,但是不能重复使用同一个端口而且所有的pod都是同时启动的。

k8s的容器编排这里有一个比较不错的例子:https://cloud.tencent.com/developer/ask/180938 ,个人觉得说的很形象。

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------