1、Pod基础概念
Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的,例如,用于管理Pod运行的StatefulSet和Deployment等控制器对象,用于暴露Pod应用的Service和Ingress对象,为Pod提供存储的PersistentVolume存储资源对象等。
Pod由一个或者多个容器组成。这里的容器通常指运行应用的业务容器。在Pod中,除业务容器外,通常还有基础容器、初始化容器和临时容器。
2、Pod容器分类
一个 Pod 能包含几个容器?
- 1个 pause容器(基础容器/父容器/根容器)
- 1个或多个应用容器(业务容器)通常一个Pod最好只包含一个应用容器,一个应用容器最好只运行一个业务进程同一个Pod里的容器,都是运行在同一个Node节点上的,并且共享 NET MNT UTS IPC PID 命名空
2.1 业务容器
业务容器是实际运行应用的容器。例如我们在编辑yml文件创建pod时,containers指定的容器为业务容器,这里配置我们实际运行的业务的容器镜像
2.2 基础容器(pause)
基础容器负责维护整个Pod的网络空间。这种类型的容器是透明的,用户不能操作这种容器。每个Pod都有一个特殊的被称为“基础容器”的Pause容器。Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或者多个紧密相关的用户应用容器。
pause容器使得Pod中的所有容器可以共享两种资源:网络和存储。
●网络:每个Pod都会被分配一个唯一的IP地址。Pod中的所有容器共享网络空间,包括IP地址和端口。Pod内部的容器可以使用localhost互相通信。Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)。
●存储:Pod可以指定多个共享的Volume。Pod中的所有容器都可以访问共享的Volume。Volume也可以用来持久化Pod中的存储资源,以防容器重启后文件丢失
pause容器的作用?【重要】
是作为共享 NET MNT UTS IPC PID 命名空间的基础
给Pod里的其它容器提供网络、存储资源的共享
作为PID=1的进程(init进程)管理整个Pod容器组的生命周期
如何查看pause容器
如下以first-pod的pod为例
1、通过命令kubectl get pod -o wide查看我们有个first-pod被分配到node2节点上
[root@master study-demo]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
first-pod 1/1 Running 7 (3m48s ago) 129m 10.244.2.2 node2 <none> <none>
2、在node2节点上docker ps | grep first-pod
这里我们看到有2个容器,其中一个是应用容器,还有一个就是pause容器。
[root@node2 ~]# docker ps | grep first-pod
d1b06d84a1c6 busybox "sh -c 'echo hello k…" 2 minutes ago Up 2 minutes k8s_busybox-container_first-pod_default_daad0216-e404-43fb-b952-094134c4cb29_7
a949b8801ddc registry.aliyuncs.com/google_containers/pause:3.6 "/pause" 2 hours ago Up 2 hours k8s_POD_first-pod_default_daad0216-e404-43fb-b952-094134c4cb29_0
当我们删除pod时,两个容器也会一起被删除。
2.3 初始化容器
初始化容器晚于基础容器运行,但先于业务容器运行。如果Pod的初始化容器运行失败,则默认情况下Kubernetes会不断尝试重启Pod,直到初始化容器运行成功。如果将Pod的配置参数“restartPolicy”设置为“Never”,则kubernetes不会执行重启动作。
如果要将Pod中的容器指定为初始化容器,则需要在“spec”中添加“initContainers”字段。一个Pod可以指定多个初始化容器,它们会按顺序逐个运行:一个初始化容器运行成功,下一个才能够运行。当所有的初始化容器运行完成后,Kubernetes才会执行业务容器从而运行应用。
下面是一个初始化容器的示例
(1)创建 initcontainer.yaml,并在其中输入一下内容
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh','-c', ' echo the app runing! && sleep 5']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', 'echo the init-myservice runing! && sleep 5']
- name: init-mydb
image: busybox:1.28
command: ['sh','-c', ' echo the init-mydb runing! && sleep 5']
(2)执行一下语句创建Pod
kubectl apply -f initcontainer.yaml
(3)在Pod创建后,使用“describe”命令查看输出信息
kubectl describe -f initcontainer.yaml
从输出信息可以看到,kubernetes先启动了两个初始化容器(init-myservice和init-mydb),之后启动业务容器(myapp-container)
初始化容器与业务容器使分离的,具有以下优势:
- 在初始化容器中可以提前安装在业务容器中要使用的工具,或者运行一些初始化的脚本
- 将应用依赖的工具和脚本分离到初始化容器中,可以避免这些工具降低应用镜像的安全性。
- 开发人员可以进行组件的独立创建和部署,而不需要将所有的组件构成一个大的应用镜像
- 初始化容器可以独立访问kubernetes中的一些敏感信息,如Secret
- 由于初始化容器必须在业务容器之前执行完成,因此,可以利用初始化容器来阻塞或延迟业务容器的启动,从而进行先决条件的检查
2.4 临时容器
临时容器是一种特殊的容器。它在现有的Pod中临时运行,以完成用户发起的操作(例如故障排查可性能诊断等)。由于临时容器没有端口要配置,且资源分配是不可变的,所以它不适合用来构建应用。
临时容器的最大用途是调试其它的容器。因为,当Pod中的容易异常退出,或者容器镜像不包含测试工具(例如没有shell时),会导致 kubecel exec 命令无法使用。这时临时容器对于交互式故障排查就很有用了。
参照一下格式便可启动:
kubectl debug -it <pod-name> --image=busybox --target=<container-name>