Kubernetes之管理pod资源对象
1. 概念
pod对象是一组容器的集合,这些容器共享Network,UTS及IPC名称空间,因此具有相同的域名,主机名和网络接口,并可通过IPC直接通信。
为一个pod对象中的各容器提供网络名称空间等共享机制的是底层基础容器pause。

2. 定义一个pod对象
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers: #必选项
- name: nginx #必选字段
image: nginx #可选项
3. 镜像及其获取策略
工作节点上运行容器运行引擎,启动容器时,首先在本地查找指定的镜像文件,不存在的镜像从指定的镜像仓库下载至本地
imagepullpolicy字段有三个值:
always: 镜像标签为latest或镜像不存在时总是从指定的仓库拉取镜像
IfNotPresent: 仅当本地镜像缺失时才从目标仓库下载镜像
Never: 禁止从仓库下载镜像,仅使用本地镜像
对于标签为latest的镜像文件,其默认的镜像获取策略为Always
对于标签为其他标签的镜像,其默认策略为IfNotPresent
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: Always
4. 暴露端口
ports字段的值是一个列表,它常用的嵌套字段包括以下几个
containerPort: 必选字段,指定在pod对象的IP地址暴露的容器端口,有效范围(0,65535)
name: 当前端口的名称
protocol: 端口相关的协议,默认为TCP
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 80
protocol: TCP
5. 环境变量
向pod对象中的容器环境变量传递数据的方法有两种:env和envFrom
需要在容器配置段中嵌套使用env字段
环境变量通常由name和value字段构成
name: 环境变量的名称,必选字段
value: 传递给环境变量的值,通过$(VAR_NAME)引用
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: TOMCAT_IP
value: 192.168.1.100
- name: LOG_LEVEL
value: info
6. 共享节点的网络名称空间
同一个pod对象的各容器均运行于一个独立的隔离的Network名称空间中,共享同一个网络协议栈及相关的网络设备 这是a
特殊的pod对象:以kubeadm部署的kubernetes集群中的kube-apiserver 、 kube-controller-manager kube-scheduler ,以及 kube-proxy 和 kube-flannel 这是b

当需要把一个pod对象修改为共享节点网络名称空间的pod对象,只需要把spec.hostNetwork设置为true
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/config.hash: 70a49ea9b8a3a74014b8cd2183400ff6
kubernetes.io/config.mirror: 70a49ea9b8a3a74014b8cd2183400ff6
kubernetes.io/config.seen: "2021-11-01T17:06:41.487417494+08:00"
kubernetes.io/config.source: file
creationTimestamp: "2021-11-01T09:08:32Z"
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver-k8s-master
namespace: kube-system
resourceVersion: "458"
selfLink: /api/v1/namespaces/kube-system/pods/kube-apiserver-k8s-master
uid: 0a4b6519-e4d6-412b-9f7b-f43bb4ab5ba1
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=172.16.1.232
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction
- --enable-bootstrap-token-auth=true
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
- --etcd-servers=https://127.0.0.1:2379
- --insecure-port=0
- --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
- --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
- --requestheader-allowed-names=front-proxy-client
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User
- --secure-port=6443
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --service-cluster-ip-range=10.1.0.0/16
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
image: registry.aliyuncs.com/google_containers/kube-apiserver:v1.16.0
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 172.16.1.232
path: /healthz
port: 6443
scheme: HTTPS
initialDelaySeconds: 15
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 15
name: kube-apiserver
resources:
requests:
cpu: 250m
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/ssl/certs
name: ca-certs
readOnly: true
- mountPath: /etc/pki
name: etc-pki
readOnly: true
- mountPath: /etc/kubernetes/pki
name: k8s-certs
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
hostNetwork: true
nodeName: k8s-master
priority: 2000000000
priorityClassName: system-cluster-critical
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
operator: Exists
volumes:
- hostPath:
path: /etc/ssl/certs
type: DirectoryOrCreate
name: ca-certs
- hostPath:
path: /etc/pki
type: DirectoryOrCreate
name: etc-pki
- hostPath:
path: /etc/kubernetes/pki
type: DirectoryOrCreate
name: k8s-certs
注:在pod对象中还可以分别使用spec.hostPID和spec.hostIPC来共享工作节点的PID和IPC名称空间
7. 标签与标签选择器
1. 标签概述
常用的标签
版本的标签:"releaset" : "stable"
环境的标签:"environment" : "dev"
应用的标签:“app” : "ui"
架构层级标签: "tier" : "frontend"
分区标签:"partition" : "cutstomerA"
品控级别标签:"track" : "daily"
标签名称最多63个字符,要么为空,要么是以字母或数字开头及结尾,且中间仅适用了字母,数字,连接号(-),下划线或点号等字符的数据
2. 管理资源标签
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
# nodeName: node01
nodeSelector:
env_role: dev
containers:
- name: nginx
image: nginx
1. 可以在yaml文件指定资源的标签
2. 查看pod的标签
kubectl get pods --show-labels 查看所有的pod的信息,包含标签
kubectl get pods -L app 查看所有pod的信息,包含标签app
3. 添加pod的新标签
kubectl label pods/tomcat-order-64746fddd8-qfknd appname=yang
4. 强制覆盖原有的键值
kubectl label pods/tomcat-order-64746fddd8-qfknd appname=yi --overwrite
kubectl label pod tomcat-order-64746fddd8-qfknd appname=yi --overwrite
5. 删除pod的标签
kubectl label pod tomcat-order-64746fddd8-qfknd appname-
3. 标签选择器
1. 标签选择器的逻辑
1. 同时指定多个选择器之间的逻辑关系为"与"
2. 使用空值的标签选择器意味着每个资源对象都将被选中
3. 空的标签选择器将无法选出任何资源
4. 标签选择器用于表达标签的查询条件:基于等值关系以及基于集合关系
2. 基于等值关系
等值关系的操作符:"=" "==" "!="
kubectl get pod -l "appname=luo" -L appname 获取等于luo的pod
kubectl get pod -l "appname!=luo" -L appname 获取不等于luo的pod
kubectl get pod -l "appname!=luo,app=tomcat-adapter" -L appname 获取获取appname不等于luo,并且app等于tomcat-adapter的pod
3. 基于集合关系
集合关系的操作符:“in” "notin" "exists"
kubectl get pod -l "app in (tomcat-backend,tomcat-cachemq)"
kubectl get pod -l "app notin (tomcat-backend,tomcat-cachemq)"
kubectl get pod -l '!tomcat-order' 注意要是用单引号,因为shell会解释感叹号
4. 常用的标签选择器
matchLabels: 通过直接给定键值对来指定标签选择器
matchExpressions: 基本表达式指定的标签选择器列表
selector :
matchLabels:
component: redis
matchExpressions:
- {key : tier , operator : In , values : [cache]}
- {key : environment, operator: Exists , values : }
4. pod节点选择器nodeSelector
设置一个节点的标签
kubectl label node k8s-node2 app=product
查看节点的标签
kubectl describe node k8s-node2
查看具有某个标签的节点信息
kubectl get node -l "app=product"
删除节点的标签
kubectl label node k8s-node2 app- 在标签后面加一个减号
修改节点的标签
kubectl label node k8s-node1 app=haha --overwrite 覆盖原来的标签
8. 资源注解
注解也是key-value类型的数据,仅用于为资源提供"元数据"信息
1. 查看资源注解
kubectl describe pods
annotations字段
2. 设置资源注释
kubectl annotate pods tomcat-adapter-646b7fccd4-t4rn7 name="后台adapter"

9. pod对象的生命周期
pod对象从其创建开始至其终止退出的时间范围称为其生命周期
1. pod的几个阶段
1. pending API Server创建了pod资源对象并已存入了etcd中,但它尚未被调度完成或者仍处于从仓库下载镜像的过程中
2. running pod已经被调度到某节点,并且所有容器都已经被kubelet创建完成
3. succeeded pod中的所有容器都已经成功终止并且不会被重启
4. failed 所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态或已经被系统终止
5. unknown api server无法正常获取到pod对象的状态信息,通常是由于其无法与所在工作节点的kubelet通信所致
2. pod的创建过程
1. 用户通过kubectl或其它api客户端提交pod spce给API Server
2. API Server尝试着将pod对象的相关信息存入etcd中,待写入操作执行完成,API Server即会返回确认信息至客户端
3. API Server开始反映etcd中的状态变化
4. 所有的 Kubernetes 组件均使用“ watch ”机制来跟踪检查 API Server 上 的相关的变动
5. kube-scheduler (调度器)通过其“ watcher ”觉察到 API Server 创建了新的 Pod 对象但尚未绑定至任何工作节点
6. kube-scheduler 为 Pod 对象挑选一个工作节点并将结果信息更新至 API Server
7. 调度结果信息由 API Server 更新至 etcd 存储系统,而且 API Server 也开始反映此Pod 对象的调度结果 。
8. Pod 被调度到的目标工作节点上的 kubelet 尝试在当前节点上调用 Docker 启动容器,并将容器的结果状态回送至 API Server。
9. API Server 将 Pod 状态信息存入 etcd 系统中 。
10. 在etcd 确认写入操作成功完成后 , API Server 将确认信息发送至相关的 kubelet,事件将通过它被接受 。

3. pod生命周期中的重要行为
1. 初始化容器
应用程序的主容器启动之前要运行的容器,常用于为主容器执行一些预置操作
apiVersion : vl
kind : Pod
metadata :
name : myapp-pod
labels :
app : myapp
spec:
containers :
- name : myapp-container
image : ikubernetes/myapp:vl
initContainers:
- name: init-something
image : busybox
command .: [ 'sh','-c','sleep 10' ]
1. 初始化容器典型特征
1. 初始化容器必须运行完成直至结束,若运行失败,那么k8s需要重启它直到成功完成。
2. 多个初始化容器都必须按定义的顺序串行运行
2. 初始化容器应用场景
1. 用于运行特定的工具程序,出于安全等方面的原因,这些程序不适合包含在主容器镜像中。
2. 提供主容器镜像中不具备的工具程序或自定义代码
3. 初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足
2. 生命周期钩子函数
postStart 容器创建完成之后立即运行的钩子处理器
preStop 容器终止操作之前立刻运行的钩子处理器
apiVersion : vl
kind : Pod
metadata :
name : lifecvcle-demo
spec :
containers :
- name : lifecycle-demo-container
image : ikubernetes/myapp:vl
1ifecycle :
postStart :
exec :
command: [" /bin/sh","-c","echo ' lifecycle hooks handler ' > /usr/share/nginx/html/test.html"]
3. 容器探测
1. livenessProbe
如果检查失败,将杀死容器,根据pod的restartPolicy来操作
2. readinessProbe
如果检查失败,kubernetes会把pod从service endpoints中剔除
4. 容器的重启策略
1. Always: 当容器停止,总是重建容器,默认策略
2. OnFailure: 当容器异常退出时,才重启容器
3. Never: 当容器终止退出,从不重启容器
5. pod的终止过程
1. 用户发送删除pod对象的命令
2. API服务器中的pod对象会随着时间的推移而更新,在宽限期内(默认为30秒),pod被视为dead
3. 将 Pod 标记为“ Terminating ”状态 。
4. (与第 3 步同时运行) kubelet 在监控到 Pod 对象转为“ Terminating ”状态的同时启动 Pod 关闭过程 。
5. (与第 3 步同时运行)端点控制器监控到 Pod 对象的关闭行为时将其从所有匹配到此端点的 Service 资源的端点列表中移除 。
6. 如果当前 Pod 对象定义了 pre Stop 钩子处理器,则在其标记为“ te rminating ” 后即会以同步的方式启动执行;如若宽限期结束后, preStop 仍未执行结束,则第 2 步会被重新执行并额外获取一个时长为 2 秒的小宽限期
7. Pod 对象中的容器进程收到 TERM 信号 。
8. 宽限期结束后,若存在任何一个仍在运行的进程,那么 Pod 对象 即会收到 SIGKILL信号 。
9. Kubelet 请求 API Server 将此 Pod 资源的宽限期设置为 0 从而完成删除操作,它变得对用户不再可见 。
默认情况下,所有删除操作的宽限期为30秒,手动修改宽限期kubectl delete --grace-period=<seconds>
4. pod存活性探测
1. 设置exec探针
在目标容器中执行由用户自定义的命令来判定容器的健康状态,若命令状态返回值为0表示成功,否则失败
apiVersion : vl
kind : Pod
metadata :
labels :
test : liveness-exec
name : liveness-exec
spec :
containers :
- name : liveness-exec demo
image : busybox
livenessProbe :
exec :
command :["test","-e","/tmp"]
2. 设置HTTP探针
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /index.html
port: 80
3. 设置TCP探针
apiVersion : vl kind : Pod metadata : labels : test : 1 工veness name : liveness - tcp spec . containers . - name : liveness-tcp-demo image : nginx : l.12-alpine ports : - name : http containerPort : 80 livenessProbe : tcpSocket : port : http
5. pod就绪性探测
用来判断容器就绪与否的周期性(默认周期为10s)
支持Exec,http GET ,TCP Socket三种探测方式
apiVersion : vl
kind : Pod
metadata:
labels:
test : readiness-exec
name : readiness-exec
spec :
containers :
- name : readiness-demo
image : busybox
args : ["/bin/sh","-c","while true; do rm - f /tmp/ready ; sleep 30 ; touch /tmp/ready ; sleep 300 ; done"]
readinessProbe:
exec :
command : ["test" , "-e" ,"/tmp/ready"]
initialDelaySeconds : 5
periodSeconds : 5
5. 资源需求及资源限制
requests 容器运行可能用不到这些资源,软限制
limits 用于限制资源可用的最大值,硬限制
CPU: 1个单位的CPU相当于虚拟机上的一颗虚拟CPU或者物理机上的一个超线程,一个核心(1 core)相当于1000个millicore 可压缩型资源
内存: 默认单位字节,使用E,P,T,G,M,K,也可以使用Ei,Pi,Ti,Gi,Mi,Ki形式的单位后缀 不可压缩型资源
1. 资源需求
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
requests: 最低要求
memory: "64Mi"
cpu: "250m" 相对的权重值
2. 资源限制
当内存超出limits的限制时,pod对象会被OOMKilled
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
requests: 最低要求
memory: "64Mi"
cpu: "250m" 相对的权重值
limits: 最高要求
memory: "128Mi"
cpu: "500m"
当内存资源到limits时,pod对象被终止并重启,多次重启会触发k8s的重启延迟机制。10秒,20秒,40秒,80秒,160秒,300秒,最后固定在5分钟不再增加
对于总数为1000m 的 CPU 资源来说,容器 A 请求使用 200m ,容器 B 请求使用 500m,在不超出它们各自 的最大限额的前提下,余下 的 300m 在双方都需要时会以 2:5 ( 200m:500m)的方式进行配置 。
3. pod的服务质量类别
当内存不足时,发生OOMKilled,但是会终止哪些pod对象呢?
k8s会根据把pod对象分为三个服务质量
1. Guaranteed
每个容器都配置了requests和limits属性,这类pod资源具有最高优先级
2. Burstable
至少有一个容器配置了requests属性,这类pod属于中级
3. BestEffort
没有任何容器配置requests或limits,这类pod最低级别
k8s按照优先级别,从低到高,终止pod.
如果级别相同,与自身的requests属性相比,内存占比大的先被杀死

浙公网安备 33010602011771号