K8S Pod概述
1. 基本概念Pod 是 kubernetes 的最基本调度单元Pod 只是个逻辑概念,真正起作用的是 Linux 容器的 Namespace 和 Cgroup,Pod 本质上一个共享某些资源的容器组。Infra 容器:在 Pod 中共享同一个Network Namespace 和 Volume2. 生命周期1)kubectl --> apiserver --> CRI -->
1. 基本概念
Pod 是 kubernetes 的最基本调度单元
Pod 只是个逻辑概念,真正起作用的是 Linux 容器的 Namespace 和 Cgroup,Pod 本质上一个共享某些资源的容器组。
Infra 容器:在 Pod 中共享同一个 Network Namespace 和 Volume
2. 生命周期
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
更多推荐
所有评论(0)