文章目录
一、基本了解二、管理命令三、yaml文件参数大全四、创建pod的工作流程五、资源共享机制5.1 共享网络5.2 共享存储
六、生命周期+重启策略+健康检查七、环境变量八、Init Containe初始化容器九、静态Pod
一、基本了解
概念:
Pod是一个逻辑抽象概念,是K8s创建和管理的最小单元,一个Pod由一个容器或多个容器组成。可以把Pod看成一个箱子,箱子里装的就是容器,每个箱子都是互相隔离的。
特点:
一个Pod可以理解为是一个应用实例,提供服务。Pod中容器始终部署在一个Node上。Pod中容器共享网络、存储资源。
主要用法:
运行单个容器:最常见的用法,在这种情况下,可以将Pod看做是单个容器的抽象封装。运行多个容器:边车模式(Sidecar) ,通过在Pod中定义专门容器,来执行主业务容器需要的辅助工作,其好处是将辅助功能同主业务容器解耦,实现独立发布和能力重用。
应用场景:
日志收集应用监控
二、管理命令
注意事项:
和kubectl create deployment 命令相比,kubectl run 【Pod名称】命令更加单一,就相当于只运行了一个容器,前者可以生成多个副本等多项功能,后者没有,一般用于测试,正式环境还是用的前者。
功能命令创建Podkubectl apply -f pod.yaml 或者 kubectl run nginx --image=nginx查看Podkubectl get pods 或者 kubectl describe pod
三、yaml文件参数大全
参数释义是否必选version版本号,例如v1必选kind资源对象类型,例如pod、deployment、service必选metadata元数据必选metadata.name对象名称必选metadata.namespace对象所属的命名空间,默认值为 default必选metadata.labels自定义标签列表metadata.annotation自定义注解列表SpecPod 中容器的详细定义必选spec.containers容器列表必选spec.containers.name容器名称必选spec.containers.image镜像名称必选spec.containers.imagePullPolicy镜像拉取策略,可选值Always、Never、IfNotPresent,默认为Always。Always:表示每次都尝试重新拉取镜像。IfNotPresent:表示若本地有该镜像,则使用本地的镜像,若本地不存在则拉取镜像。Never:表示仅使用本地镜像。若存在以下设置,系统则将设置成默认设置imagePullPolicy=Always:1、不设置 imagePullPolicy,也未指定镜像的tag。2、不设置 imagePullPolicy,镜像tag为 latest。3、启用了名为 AlwaysPulllmages 的准入控制器Admission Controller )spec.containers.command容器的启动命令列表。若不指定,则使用镜像打包时使用的启动命令。spec.containers.args容器的启动命令参数列表。spec.containers.workingDir容器的工作目录spec.containers.volumeMounts挂载到容器内部的存储卷配置spec.containers.volumeMounts .name引用在volumes部分定义的共享存储卷名称spec.containers.volumeMounts.mountPath挂载到容器内的绝对路径spec.containers.volumeMounts.readOnly设置是否为只读模式,默认为读写模式spec.containers.ports容器需要暴露的端口号列表spec.containers.ports.name端口名称spec.containers.ports.containerPort容器内部端口spec.containers.ports.hostPort暴露在宿主机上的端口,默认与containerPort相同,需要保证唯一性。spec.containers.ports.protocol端口协议,默认为TCP,支持 TCP、UDP、SCTPspec.containers.env容器运行前需设置的环境变量列表。spec.containers.env.name变量名称spec.containers.env.value变量值spec.containersl.resources资源限制和资源请求的设置配置,用于资源配额和资源限制功能。spec.containers.resources.limits资源限制值,允许容器内程序最大的使用资源。spec.containers.resources.limits.cpuCPU 限制,可以写m也可以写浮点数,例如0.5=500m,1=1000mspec.containers.resources.limits.memory内存限制,单位可以为 MiB、GiB 等spec.containers.resources.requests容器资源请求值。告诉k8s最小分配的资源,分配的节点必须能够满足requests指定的值。spec.containers .resources.requests.cpuCPU请求,可以写m也可以写浮点数,例如0.5=500m,1=1000mspec.containers.resources.requests.memo内存请求,单位可以为MiB、GiB 等。spec.volumes共享存储卷列表spec.volumes.name共享存储卷的名称。可以定义多个 Volume,每个 Volume的 name 保持唯一。容器定义部分的containers.volumeMounts.name 将引用该共享存储卷的名称。类型有: emptyDir、hostPath、secret、nfs、iscsi等等。spec.volumes.emptyDir类型为emptyDir 的存储卷。表示与 Pod 同生命周期的-个临时目录,其值为一个空对象:emptyDir:{}spec.volumes .hostPath类型为 hostPath的存储卷。表示 Pod 容器挂载的宿主机目录,通过volumes.hostPath.path 指定spec.volumes.hostPath.pathPod 容器挂载的宿主机目录spec.volumes.secret类型为secret的存储卷,表示挂载集群预定义的secret对象到容器内部spec.volumes.configMap类型为 configMap 的存储卷,表示挂载集群预定义的configMap对象到容器内部spec.volumes.livenessProbe健康检查配置项。当探测无响应几次之后,系统将自动重启该容器。可设值有:exec、httpGet 和 tcpSocket。对一个容器仅需设置一种健康检查方法spec.volumes.livenessProbe.exec健康检查方式之一,exec 方式spec.volumes.livenessProbe.exec.commandexec 方式需要指定的命令或者脚本spec.volumes.livenessProbe.httpGet健康检查方式之一,httpGet方式。需指定 path、portspec.volumes.livenessProbe.tcpSocket健康检查方式之一,cpSocket 方式。spec.volumes.livenessProbe.initialDelaySeconds容器启动完成后首次探测的时间,单位为sspec.volumes .livenessProbe.timeoutSeconds健康检查的探测等待响应超时时间,单位为 s,默认值为 1s。若超过该超时时间设置,则将认为该容器不健康,会重启该容器。spec.volumes .livenessProbe.periodSeconds健康检查的定期探测时间,单位为 s,默认 10s 探测一次。spec.restartPolicy重启策略,可选值为Always、OnFailure,默认值为Always。Always:Pod 一旦终止运行,则无论容器是如何终止的,kubelet 都将重启它。OnFailure:只有 Pod 以非零退出码终止时kubelet 才会重启该容器。如果容器正常结束(退出码为 0),则 kubelet 将不会重启它。Never:Pod 终止后,kubelet 将退出码报告给Master,不会再重启该 Podspec.nodeSelector节点标签,以 key:value 格式指定,Pod将被调度到具有这些Label的节点上。spec.imagePullSecretspull 镜像时使用的 Secret 名称,以name:secretkey格式指定。spec.hostNetwork是否使用主机网络模式,默认值为 false。设置为true,表示容器使用宿主机网络,不再使用 Docker网桥。
四、创建pod的工作流程
基本了解:
Kubernetes基于list-watch机制的控制器架构,实现组件间交互的解耦。其他组件监控自己负责的资源,当这些资源发生变化时,kube-apiserver会通知这些组件,这个过程类似于发布与订阅。
流程图: 流程解析: 创建一个Pod命令为:kubectl run pod1 --image=nginx,命令执行过程步骤如下:
kubectl向apiserver发送一个创建pod的请求,apiserver会将数据写到etcd(实线),etcd将接受数据情况反馈给apiserver(虚线)。scheduler调度器订阅apiserver,当apiserver有新事件时scheduler会第一时间收到,此时会根据算法选择一个节点加入分配到k8s-node1节点,并将选择结果告诉给apiserver,apiserver会将数据写到etcd(实线),etcd将接受数据情况反馈给apiserver(虚线)。k8s-node1节点上的kubelet收到apiserver分配到我这个节点的pod,kubelet调用docker api创建容器,汇报容器的状态。
注意事项:
从以上的流程中来看,缺少两个组件的使用。
kube-controller-manager # 负责一些控制器工作的,例如deploymentkube-proxy # 负载pod网络,例如service
情景模拟流程:
把apiserver 看成 “小卖铺老板”,etcd 看成 “仓库”,scheduler看成“送货员”,其他组件 看成 “学生”。当老板接到货物时,会先把货物放进仓库,仓库返回给老板结果。送货员根据算法规则算出货物要配送到哪个节点,将结果告诉老板。老板根据每个组件学生的订阅要求,发布货物给各个订阅学生。学生接收到货物后找docker api获取生成任务,并把结果返回给老板。老板把情况记录到仓库里。
五、资源共享机制
5.1 共享网络
共享网络:将业务容器网络加入到“负责网络的容器”实现网络共享。
yaml文件示例:
apiVersion: v1
kind: Pod
metadata:
labels:
app: test
name: pod-net-test
namespace: default
spec:
containers:
- image: busybox
name: test
command: ["/bin/sh","-c","sleep 12h"]
- image: nginx
name: web
1.先尝试运行一个Pod,导出查看yaml文件。
[root@k8s-master bck]# kubectl run nginx --image=nginx --dry-run=client -o yaml > nginx.yaml
[root@k8s-master bck]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
2.尝试运行创建一个deployemnt,,导出查看yaml文件。
[root@k8s-master bck]# kubectl create deployment web --image=nginx --dry-run=client --replicas=3 -o yaml > deploymnet.yaml
[root@k8s-master bck]# cat deploymnet.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
labels:
app: web
spec:
containers:
- image: nginx
name: nginx
resources: {}
3.对比两个命令导出的yaml文件,Pod为对象的内容就是以deployment为对象的最后一部分内容。 4.修改nginx.yaml文件内容,新增辅助容器busybox使其后台运行24小时不退出。
[root@k8s-master bck]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx ##主容器。
name: nginx
- image: busybox ##辅助容器。
name: bs
command:
- sleep
- 24h
5.导入yaml文件,并查看Pod,其内部有两个容器就是nginx和busybox。
[root@k8s-master bck]# kubectl apply -f nginx.yaml
6.进入Pod验证。没有使用-c参数指定进入哪个容器,就会提示这行。当一个Pod中有多个容器时,不指定进入容器就默认进入主容器。
[root@k8s-master bck]# kubectl exec -it nginx -- bash
7.进入主容器验证。
8.进入辅助容器验证。可以监听到nginx的80端口,但是查看不到Nginx进程,是因为nginx和busybox容器是通过加入了Infra Container网络容器,该容器通过共用网络协议栈,使busybox容器和nginx容器里实现网络共享。而端口是属于协议栈中的一部分能看到,进程不属于协议栈内容就看不到。 9.查看Infra Container网络容器位置。
5.2 共享存储
共享存储:容器通过数据卷共享数据。
1.通过yaml文件定义数据卷。
[root@k8s-master bck]# cat nginx2.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx2
spec:
containers:
- image: nginx ##主容器。
name: nginx
volumeMounts: ## 数据卷挂载
- name: log ## 指定挂载的数据卷名称
mountPath: /data ## 数据卷挂载到容器中的路径
- image: busybox ##辅助容器。
name: bs
command:
- sleep
- 24h
volumeMounts: ## 数据卷挂载
- name: log ## 指定挂载的数据卷名称
mountPath: /data ## 数据卷挂载到容器中的路径
volumes: ##定义数据卷
- name: log ##数据卷名称
emptyDir: {} ##数据卷类型
2.导入yaml文件,查看pod。
[root@k8s-master bck]# kubectl apply -f nginx2.yaml
3.进入nginx容器创建123.txt文件,之后退出进入bs容器里可以看到123.txt文件;进入bs容器创建456.txt文件,之后退出进入bs容器里可以看到456.txt文件。
六、生命周期+重启策略+健康检查
pod状态释义Pending等待状态。API Server 已经创建该 Pod,但在 Pod 内还有一个或多个容器的像没有创建,包括正在下载镜像的过程。RunningPod内所有容器均已创建,且至少有一个容器处于运行状态、正在启动状态或正在重启状态SucceededPod内所有容器均成功执行后退出,且不会再重启FailedPod 内所有容器均已退出,但至少有一个容器为退出失败状态Unknown由于某种原因无法获取该 Pod 的状态,可能由于网络通信不畅导致
重启策略:
Always:当容器终止退出后,总是重启容器,默认策略。OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。Never:当容器终止退出,从不重启容器。
健康检查3种类型:
livenessProbe(存活检查):判断容器是否存活(Running状态)。若检查失败,则将杀死容器,再根据Pod的容器策略来操作。readinessProbe(就绪检查):判断容器服务是否可用(Ready状态),达到Ready状态的Pod才可以接收请求。如果在运行过程中Ready状态变为False,则系统自动将其从Service的后端Endpoint列表中隔离出去,后续再把恢复到Ready状态的Pod加回后端Endpoint列表,这样就能保证客户端在访问Service时不会被转发到服务不可用的Pod实例上。startupProbe(启动检查):检查成功才由存活检查接手,用于保护慢启动容器。适用于应用启动较慢的情况,就绪检查就不适用了,需要用启动检查。
健康检查支持的3种检查方法:
httpget:通过容器的IP地址、端口号及路径调用HTTP Get方法,返回200-400范围状态码为成功。exec:执行Shell命令返回状态码是0为成功。tcpSocket:通过容器的IP地址和端口号执行TCP检查,如果能够建立TCP连接,则表明容器健康。
1.创建deployment时,加入健康检查策略。
[root@k8s-master bck]# cat qingjun.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: qingjun
name: qingjun
spec:
replicas: 3
selector:
matchLabels:
app: qingjun
template:
metadata:
labels:
app: qingjun
spec:
containers:
- image: nginx
name: nginx
livenessProbe: # 存活检查,重启容器
httpGet:
path: /index.html #检查网页文件
port: 80
initialDelaySeconds: 10 #启动容器后多少秒后进行第一次健康检查
periodSeconds: 30 #以后每间隔多少秒检查一次
readinessProbe: # 就绪检查,从Service中剔除容器
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 10
periodSeconds: 30
2.导入yaml文件,并创建service。
[root@k8s-master bck]# kubectl apply -f qingjun.yaml
[root@k8s-master bck]# kubectl expose deployment qingjun --port=80 --target-port=80 --type=NodePort
3.此时查看svc的地址,集群内的三个副本都能监听到。 4.删除一个副本容器里的网页文件。 5.此时再查看service监听状态,被删除网页文件的副本容器IP地址监听消失,该容器日志也显示报错异常。这是就绪检查起作用。
6.过一段时间,该容器又重新生成,日志恢复,前端文件恢复。这是存活检查在起作用。
七、环境变量
为什么会有环境变量的用法?
创建 Pod 时,可以为其下的容器设置环境变量。官网地址
应用场景:
容器内应用程序获取Pod信息。容器内应用程序通过用户定义的变量改变默认行为。
变量值几种定义方式:
自定义变量值。变量值从Pod属性获取。变量值从Secret、ConfigMap挂载获取。
设置方式可设置的参数释义fieldRefmetadata.namePod名称fieldRefmetadata.namespacefieldRefmetadata.uidPod的UID,从Kubernetes 1.8.0-alpha.2版本开始支持。fieldRefmetadata.labels[‘< KEY >’]Pod某个Label的值,通过< KEY >进行引用,从Kubernetes 1.9版本开始支持。fieldRefmetadata.annotations[‘< KEY >’]Pod某个Annotation的值,通过< KEY >进行引用,从Kubernetes 1.9版本开始支持。resourceFieldRefContainer级别的CPU Limit容器的CPU限制值resourceFieldRefContainer级别的CPU Request。容器的CPU请求值resourceFieldRefContainer级别的Memory Limit。容器的内存限制值resourceFieldRefContainer级别的Memory Request。容器的内存请求值resourceFieldRefContainer级别的临时存储空间(ephemeral-storage)Limit,从K8s 1.8.0-beta.0版本开始支持。resourceFieldRefContainer级别的临时存储空间(ephemeral-storage)Request,从K8s 1.8.0-beta.0版本开始支持。fieldRef字段metadata.labelsPod的Label列表,每个Label都以key为文件名,value为文件内容,每个Label各占一行。fieldRef字段metadata.namannotationsPod的Annotation列表,每个Annotation都以key为文件名,value为文件内容,每个Annotation各占一行。Pod元数据信息status.podIPPod的IP地址Pod元数据信息spec.serviceAccountNamePod使用的ServiceAccount名称。Pod元数据信息spec.nodeNamePod所在Node的名称,从Kubernetes 1.4.0-alpha.3版本开始支持。Pod元数据信息status.hostIPPod所在Node的IP地址,从Kubernetes 1.7.0-alpha.1版本开始支持。
1.创建一个deployment,编辑yaml文件添加环境变量。
[root@k8s-master bck]# cat env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: env
name: env
spec:
replicas: 3
selector:
matchLabels:
app: qingjun
template:
metadata:
labels:
app: qingjun
spec:
containers:
- image: nginx
name: nginx
env:
- name: ABC
value: "123"
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName ##pod所在node节点的名称。
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name ##pod名称。
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace ##pod所在命名空间的名称。
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP ##pod的IP地址。
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName ##pod使用sa的名称。
2.导入yaml文件,进入容器,查看容器内环境变量。
八、Init Containe初始化容器
定义:
Init Container初始化容器用于初始化工作,执行完就结束,可以理解为一次性任务。初始化容器与应用容器本质上是一样的,但是仅运行一次就结束任务,并且必须在成功运行完成后,系统才能继续执行下一个容器。
特点:
支持大部分应用容器配置,但不支持健康检查。运行方式与应用容器不同,优先应用容器执行。当有多个init container时,会按顺序逐个运行,并且只有前一个init container运行成功后才能运行后一个init container。在所有init container都成功运行后,K8s才会初始化Pod的各种信息,并开始创建和运行应用容器。
应用场景:
环境检查:例如确保应用容器依赖的服务启动后再启动应用容器。初始化配置:例如给应用容器准备配置文件。
Pod内的容器类型:
Infrastructure Container:基础容器
维护整个Pod网络空间,镜像为pause。某节点上又多少个pause镜像容器,该节点上就有多少个pod。 InitContainers:初始化容器
先于业务容器开始执行 Containers:业务容器
并行启动
注意事项:
Pod重新启动时,init container将会重新运行。
情景一,init container的镜像被更新时,init container将会重新运行,导致Pod重启。仅更新应用容器的镜像只会使得应用容器被重启。情景二,Pod的infrastructure容器更新时,Pod将会重启。情景三,若Pod中的所有应用容器都终止了,并且RestartPolicy=Always,则Pod会重启。 也可以对init container设置资源限制、挂载卷和安全策略等。但资源限制的设置与应用容器略有不同。
若多个init container都定义了资源请求/资源限制,则取最大的值作为所有init container的资源请求值/资源限制值。Pod的有效(effective)资源请求值/资源限制值取以下二者中的较大值:
所有应用容器的资源请求值/资源限制值之和。initcontainer的有效资源请求值/资源限制值。 调度算法将基于Pod的有效资源请求值/资源限制值进行计算,也就是说init container可以为初始化操作预留系统资源,即使后续应用容器无须使用这些资源。Pod的有效QoS等级适用于init container和应用容器。资源配额和限制将根据Pod的有效资源请求值/资源限制值计算生效。Pod级别的cgroup将基于Pod的有效资源请求/限制,与调度机制一致。
测试初始化容器下载一个前端文件到本地并挂载共享目录,主容器从共享目录里下载前端文件。
1.创建一个Pod,编辑yaml文件。
[root@k8s-master bck]# cat init.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: init666
spec:
## 初始化容器
initContainers: ##定义初始化容器
- image: busybox ##容器镜像
name: bs ##容器名称
command: ##执行动作,下载访问aliang官网前端文件到/data/index.html,并共享/data目录。
- wget
- "-O"
- "/data/index.html"
- "https://www.aliangedu.cn"
volumeMounts: ## 数据卷挂载
- name: log ## 指定挂载的数据卷名称
mountPath: /data ## 数据卷挂载到容器中的路径
## 主容器
containers:
- image: nginx
name: nginx
volumeMounts: ## 数据卷挂载
- name: log ## 指定挂载的数据卷名称
mountPath: /usr/share/nginx/html/ ## 共享目录,此时该目录下也有下载的aliang官网前端文件。
volumes: # 定义数据卷
- name: log # 数据卷名称
emptyDir: {} # 数据卷类型
2.导入yaml文件,查看Pod状态。先是运行初始化容器,再运行主容器。 3.进入容器内检查下载文件,验证成功。
九、静态Pod
为什么会有静态Pod?
只是一种使用kubeadm方式部署k8S集群的思路,和k8s集群没有直接关系,是分开的。正常情况下,K8s集群搭建完成后才能创建Pod,而使用Kubeadm方式搭建集群时组件又需要使用Pod来启动,这时候就需要没有容器化的Kubelet来管理静态Pod,通过静态Pod拉起K8s组件,也就是master节点上/etc/kubernetes/manifests/目录下的yaml文件。
静态Pod的特点:
Pod由特定节点上的kubelet管理。不能使用控制器,不能通过API Server进行管理,无法与ReplicationController、Deployment、DaemonSet进行关联,也无法对它们进行健康检查。Pod名称标识当前节点名称
实现方式:
配置文件方式。在kubelet配置文件/var/lib/kubelet/config.yaml中设置参数staticPodPath,指定需要监控的配置文件所在目录,kubelet会定期扫描该目录,并根据该目录下的.yaml或.json文件进行创建操作。HTTP方式。在kubelet配置文件中设置参数“–manifest-url”,kubelet将会定期从该URL地址下载Pod的定义文件,并以.yaml或.json文件的格式进行解析,然后创建Pod。
注意事项:
在kubelet配置文件启用静态Pod的参数: vi /var/lib/kubelet/config.yaml … staticPodPath: /etc/kubernetes/manifests …将部署的pod yaml放到该目录会由kubelet自动创建。业务层面上用不到静态Pod,都是从K8s集群层面上拉取Pod。
1.在master节点上查看这几个Pod名称是带有节点说明的,这些Pod就是静态Pod。
2.在node1节点上的/etc/kubernetes/manifests目录下添加pod.yaml文件后,会自动创建此pod。 3.也可以在master节点上查看此pod存在node1节点上。 4.讲该pod.yaml文件移到别的目录,该pod会自动被删除。
相关阅读
发表评论