1. 基本概念

Pod 是 kubernetes 的最基本调度单元

img

Pod 只是个逻辑概念,真正起作用的是 Linux 容器的 Namespace 和 Cgroup,Pod 本质上一个共享某些资源的容器组。

Infra 容器:在 Pod 中共享同一个 Network Namespace 和 Volume

img

2. 生命周期

img

1)kubectl --> apiserver --> CRI --> kubelet 环境初始化

2)启动Pause容器: 初始化网络和数据卷。其镜像由汇编写成,永远处于“pause”状态的容器,解压后大小100~200KB,运行时占用极小的资源

3)init C初始化。多个initC时,必须串行执行,且每个必须执行成功才向下走

4)Main C,开始运行时,启动Start命令/脚本;结束时,执行Stop命令(做哪些清理操作等)

5)Readiness 就绪检测:若干秒后,进行是否就绪的探测。只有当Readiness成功后,Pod才会显示Ready状态

6)Liveness 生存检测:探测Main C中的进程是否正常,不正常则执行重启、删除等命令

3. 状态值

  • Pending:Pod 信息已经提交给了集群,但是还没有被调度器调度到合适的节点或者 Pod 里的镜像正在下载
  • Running:该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态
  • Succeeded:Pod 中的所有容器都被成功终止,并且不会再重启
  • Failed:Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止
  • Unknown:未知原因无法获取Pod状态,通常是因为与Pod所在主机的通信失败

4. 重启策略

容器的重启策略restartPolicy

  • Always,默认
  • OnFailure
  • Never

通过 kubelet 重新启动的退出容器将以指数增加延迟(10s,20s,40s…)重新启动,上限为 5 分钟,在成功执行 10 分钟后重置。不同类型的的控制器可以控制 Pod 的重启策略:

  • Job:适用于一次性任务如批量计算,任务结束后 Pod 会被此类控制器清除。重启策略只能是"OnFailure"或者"Never"
  • ReplicaSet 和 Deployment:此类控制器希望 Pod 一直运行下去,它们的重启策略只能是"Always"
  • DaemonSet:每个节点上启动一个 Pod,此类控制器的重启策略也应该是"Always"

5. initC 容器

Init Container 容器作用:

  • initC 容器可作为 Pod 中其他容器的初始化工具

  • 出于安全考虑,将应用容器中的某些实用工具(python, awk等)单独拆开放入initC容器

  • 应用容器的启动是并行的,而 initC 容器可阻塞应用容器的启动,直到满足一些先决条件

apiVersion: v1
kind: Pod
metadata:
  name: test-initc
  labels:
    app: myapp
spec:
  initContainers:
  - name: init-mysvc
    image: e2eteam/dnsutils:1.1
    command: ['sh', '-c', 'until nslookup mysvc; do echo "waiting for mysvc"; sleep 2; done']
  - name: init-mydb
    image: e2eteam/dnsutils:1.1
    command: ['sh', '-c', 'until nslookup mydb; do echo "waiting for mydb"; sleep 2; done']
  containers:
  - name: myapp
    image: busybox
    command: ['sh', '-c', 'while true; do echo "myapp is running!"; sleep 3600; done']
---
apiVersion: v1
kind: Service
metadata:
  name: mysvc
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9001
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9002

6. Pod Hook

容器生命周期的钩子,它由 kubelet 发起,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中

两种钩子函数:

  • PostStart:这个钩子在容器创建后立即执行。但是,并不能保证钩子将在容器 ENTRYPOINT 之前运行,因为没有参数传递给处理程序。主要用于资源部署、环境准备等。不过需要注意的是如果钩子花费太长时间以至于不能运行或者挂起,容器将不能达到 running 状态。
  • PreStop:这个钩子在容器终止之前立即被调用。它是阻塞的,意味着它是同步的,所以它必须在删除容器的调用发出之前完成。主要用于优雅关闭应用程序、通知其他系统等。如果钩子在执行期间挂起,Pod 阶段将停留在 running 状态并且永不会达到 failed 状态。

如果 PostStart 或者 PreStop 钩子失败, 它会杀死容器。所以我们应该让钩子函数尽可能的轻量。当然有些情况下,长时间运行命令是合理的, 比如在停止容器之前预先保存状态。

spec.containers[].lifecycle.postStart|preStop

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo 'hello world' > /tmp/hello.txt"]
      preStop:
        exec:
          command: ["/usr/sbin/nginx", "-s", "quit"]

7. 容器探针

健康状态探针:

  • ReadinessProbe: 判断容器服务是否可用,成功显示ready, 失败不触发重启
  • LivenessProbe: 判断容器是否存活,如果探测到不健康,将触发重启策略。如果未配置该探针,则永远返回成功.

探针的三种实现方式:

  • ExecAction: 容器内执行命令,返回码等于0则认为成功
  • TCPSocketAction: 在指定端口上的容器IP地址进行TCP检查,如果端口打开,则认为成功
  • HTTPGetAction: 在指定端口和路径的容器IP地址执行HTTP GET请求,状态码在 [200, 399] 表示成功

探测结果:

  • success
  • failed:失败,按策略处理
  • unknown:诊断失败,但不会采取任何行动

7.1 就绪检测

检测失败,状态非Ready,但不会重启容器

spec.containers[].readinessProbe.httpGet

apiVersion: v1
kind: Pod
metadata:
  name: readiness-test
spec:
  containers:
  - name: nginx
    image: nginx
    readinessProbe:
      httpGet:
        port: 80
        path: /index1.html
      initialDelaySeconds: 1
      periodSeconds: 3
$ kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
readiness-test   0/1     Running   0          76s

$ kubectl describe pod readiness-test
Warning  Unhealthy  35s (x21 over 94s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404

# 更新容器
$ kubectl exec -it readiness-test -- /bin/sh
# echo '<h1>hello world</h1>' > /usr/share/nginx/html/index1.html
# logout

$ kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
readiness-test   1/1     Running   0          6m4s

7.2 存活检测

检测失败,直接重启Pod

spec.containers[].livenessProbe.exec

apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-test
spec:
  containers:
  - name: busybox
    image: busybox
    command: ["/bin/sh", "-c", "touch /tmp/abc.txt; sleep 60; rm -f /tmp/abc.txt; sleep 3600"]
    livenessProbe:
      exec:
        command: ["test", "-e", "/tmp/abc.txt"]
      initialDelaySeconds: 1
      periodSeconds: 3
# 失败,重启自动重启
$ kubectl get pod -w
NAME                 READY   STATUS    RESTARTS   AGE
liveness-exec-test   1/1     Running   0          8s
liveness-exec-test   1/1     Running   1          108s
liveness-exec-test   1/1     Running   2          3m30s
liveness-exec-test   1/1     Running   3          5m11s

spec.containers[].livenessProbe.tcpSocket

apiVersion: v1
kind: Pod
metadata:
  name: readiness-tcpsocket
spec:
  containers:
  - name: redis
    image: redis
    livenessProbe:
      tcpSocket:
        port: 6379
      initialDelaySeconds: 5
      periodSeconds: 3
      timeoutSeconds: 1

8. 资源限制

    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 0.1
            memory: 256Mi
          limits:
            cpu: 0.5
            memory: 512Mi

Pod 中的资源限制,指的是使用 CGroup 来对容器 CPU 和 Memory 资源进行限制

CGroup 中 CPU 资源的单位换算:

1 CPU = 1000 millicpu       # m 毫、毫核
0.5 CPU = 500 millicpu      # 对于4核CPU,总毫量为4000m,使用 0.5 core,则为 4000*0.5=2000m

限制参数:

  • spec.containers[].resources.limits.cpu:CPU 上限值,可以短暂超过,容器也不会被停止

  • spec.containers[].resources.requests.cpu:CPU请求值,Kubernetes 调度算法里的依据值,可以超过

  • spec.containers[].resources.limits.memory:内存上限值,可以短暂超过,容器也不会被停止

  • spec.containers[].resources.requests.memory:内存请求值,Kubernetes 调度算法里的依据值,可以超过

apiVersion: v1
kind: Pod
metadata:
  name: resource-demo
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: 50Mi
        cpu: 50m    # 0.05core,占了 1CPU 的 5% 资源
      limits:
        memory: 100Mi
        cpu: 100m
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐