一、Pod 基础概念

Pod 是 K8s 中最小可部署调度单元,一个 Pod 封装一个或多个容器。

  1. Pod 内容器共享网络命名空间:同一个 Pod 内所有容器共用同一个 Pod IP,容器之间可以localhost互相访问。
  2. Pod 内容器共享存储卷 Volume,实现容器之间文件数据共享。
  3. Pod 是临时的,不建议直接使用 Pod IP 访问业务;Pod 销毁重建后 IP 会发生变化。
  4. 分为两种 Pod:
  • 自主式 Pod:直接 yaml 创建,无控制器管理,Pod 挂掉不会自动重建,生产环境不推荐。
  • 控制器管理 Pod:由各类控制器创建维护,具备自愈、扩缩容能力,生产环境标准用法。

二、Pod 资源清单 yaml 详解

# 利用命令生成 yaml 模板文件
[root@k8s-master ~] # kubectl create deployment --image nginx webcluster --dry
run=client -o yaml > webcluster.yml

yaml结构

apiVersion: v1          # API版本,Pod属于core/v1组
kind: Pod               # 对象类型
metadata:               # 元数据
  name: nginx-pod       # pod名称
  namespace: default    # 所属命名空间
  labels:               # 标签,用于控制器筛选pod
    app: nginx
spec:                   # Pod期望状态,核心配置
  containers:           # 容器列表
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
    resources:          # 资源限制requests/limits
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 200m
        memory: 256Mi
  restartPolicy: Always # 重启策略 Always|OnFailure|Never

重启策略 restartPolicy

  1. Always:容器退出,总是重启,默认值;
  2. OnFailure:容器异常退出(返回码≠0)才重启;
  3. Never:无论容器怎么退出,绝不重启。

三、Pod 完整生命周期

1. Pending:API 创建 Pod,调度器未完成调度,拉取镜像中。
2. Running:Pod 已经调度到节点,所有容器启动完成。
3. Failed:所有容器退出,至少一个容器异常终止。
4. Succeeded:所有容器正常执行完成退出,不会重启。
5. Unknown:节点失联,无法获取 Pod 状态。

init容器

Init 容器与普通的容器非常像,除了如下两点:
    它们总是运行到完成
    init 容器不支持 Readiness ,因为它们必须在 Pod 就绪之前运行完成,每个 Init 容器必须运行
成功,下一个才能够运行。
功能
    1.Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。
    2.Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
    3.应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
    4.Init 容器能以不同于 Pod 内应用容器的文件系统视图运行。因此, Init 容器可具有访问 Secrets 的权限,而应用容器不能够访问。
    5.由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod 内的所有的应用容器会并行启动。
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: initpod
name: initpod
spec:
containers:
- image: myapp:v1
name: myapp
initContainers:
- name: init-myservice
image: busybox
command: ["sh","-c","until test -e /testfile;do echo wating for myservice;
sleep 2;done"]
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/initpod created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
initpod 0/1 Init:0/1 0 3s
[root@k8s-master ~]# kubectl logs pods/initpod init-myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
[root@k8s-master ~]# kubectl exec pods/initpod -c init-myservice -- /bin/sh -c
"touch /testfile"
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
initpod 1/1 Running 0 62s

探针

探针是由 kubelet 对容器执行的定期诊断 :
    ExecAction :在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
    TCPSocketAction :对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
    HTTPGetAction :对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码
    大于等于 200 且小于 400 ,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
    成功:容器通过了诊断。
    失败:容器未通过诊断。
    未知:诊断失败,因此不会采取任何行动。

存活探针

[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: liveness
name: liveness
spec:
containers:
- image: myapp:v1
name: myapp
livenessProbe:
tcpSocket: #检测端口存在性
port: 8080
initialDelaySeconds: 3 #容器启动后要等待多少秒后就探针开始工作,默认是 0
periodSeconds: 1 #执行探测的时间间隔,默认为 10s
timeoutSeconds: 1 #探针执行检测请求后,等待响应的超时时间,默认为 1s
#测试:
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/liveness created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness 0/1 CrashLoopBackOff 2 (7s ago) 22s
[root@k8s-master ~]# kubectl describe pods
Warning Unhealthy 1s (x9 over 13s) kubelet Liveness probe failed:
dial tcp 10.244.2.6:8080: connect: connection refused

就绪探针

[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: readiness
name: readiness
spec:
containers:
- image: myapp:v1
name: myapp
readinessProbe:
httpGet:
path: /test.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
#测试:
[root@k8s-master ~]# kubectl expose pod readiness --port 80 --target-port 80
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness 0/1 Running 0 5m25s
[root@k8s-master ~]# kubectl describe pods readiness
Warning Unhealthy 26s (x66 over 5m43s) kubelet Readiness probe
failed: HTTP probe failed with statuscode: 404
[root@k8s-master ~]# kubectl describe services readiness
Name: readiness
Namespace: default
Labels: name=readiness
Annotations: <none>
Selector: name=readiness
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.171.244
IPs: 10.100.171.244
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: #没有暴漏端口,就绪探针探测不满足暴漏
条件
Session Affinity: None
Events: <none>
kubectl exec pods/readiness -c myapp -- /bin/sh -c "echo test >
/usr/share/nginx/html/test.html"
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness 1/1 Running 0 7m49s
[root@k8s-master ~]# kubectl describe services readiness
Name: readiness
Namespace: default
Labels: name=readiness
Annotations: <none>
Selector: name=readiness
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.171.244
IPs: 10.100.171.244
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.8:80 #满组条件端口暴漏
Session Affinity: None
Events: <none>

四、kubectl Pod 常用管理命令

#查看pod
kubectl get pods
kubectl get pods -o wide
# 创建pod
kubectl apply -f pod.yaml
# 查看pod详细信息
kubectl describe pod nginx-pod
# 查看pod日志
kubectl logs nginx-pod
# 进入pod容器
kubectl exec -it nginx-pod -- /bin/bash
# 删除pod
kubectl delete pod nginx-pod
kubectl delete -f pod.yaml

五、Pod 调度

  1. nodeSelector:节点标签简单筛选,把 Pod 调度到带指定标签的节点。
  2. nodeAffinity 节点亲和性:更灵活,支持偏好(软约束 preferred)和强制要求(硬约束 required)。
  3. podAffinity Pod 亲和性:让 Pod 和其他 Pod 部署在一起。
  4. podAntiAffinity Pod 反亲和性:避免多个相同业务 Pod 部署到同一个节点,保障高可用

更多推荐