在容器中获取Pod信息
我们可以通过Downward API获取Pod的信息,在Pod被创建后,会被系统分配名字、IP、namespace等信息。这些信息都可以在容器内部获取到。
两种方式将Pod信息注入容器:
- 环境变量
- Volume挂载
通过环境变量
yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: ["/bin/sh","-c","env"]
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
查看结果
bash
[root@master1 pod]# kubectl logs dapi-test-pod
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.10.0.1:443
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
MY_POD_NAMESPACE=pod-ns
MY_POD_IP=10.244.166.145
KUBERNETES_PORT_443_TCP_ADDR=10.10.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.10.0.1:443
KUBERNETES_SERVICE_HOST=10.10.0.1
PWD=/
MY_POD_NAME=dapi-test-pod
Downward API 提供了以下变量:
- metadata.name: 获取Pod的名称。
- status.podIP:获取Pod的IP,这里为什么没有用metadata.podIP?是因为IP在Pod中是状态数据,而非元数据。
- metadata.namespace:获取Pod的命名空间
环境变量--资源信息
yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod-container-vars
spec:
containers:
- name: test-container
image: busybox
imagePullPolicy: Never
command: ["sh","-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 3600;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory
restartPolicy: Never
创建并查询结果
bash
[root@master1 pod]# kubectl logs dapi-test-pod-container-vars
1
1
33554432
67108864
通过Downward API的语法 resourceFieldRef可以将容器的资源请求和资源限制参数设置为容器内的环境变量。
- requests.cpu
- limits.cpu
- requests.memory
- limits.memory
通过查询容器日志,我们可以看到已经将资源请求和限制信息保存到了Pod环境变量中。
Volume 挂载方式
volumes字段中DownWard API语法,通过items的设置,系统会根据path的名称生成文件。根据以上设置,将在容器内生成/etc/labels和/etc/annotations两个文件夹,包含metadata.labels和metadata.annotations的全部内容。
api
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod-volume
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: test-container
image: busybox
imagePullPolicy: Never
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/labels ]]; then
echo -en '\n\n'; cat /etc/labels; fi;
if [[ -e /etc/annotations ]]; then
echo -en '\n\n'; cat /etc/annotations; fi;
sleep 3600;
done;
volumeMounts:
- name: podinfo
mountPath: /etc
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
volumes字段中DownWard API语法,通过items的设置,系统会根据path的名称生成文件。根据以上设置,将在容器内生成/etc/labels和/etc/annotations两个文件夹,包含metadata.labels和metadata.annotations的全部内容。
Downward API有什么作用?
主要作用是进行服务的注册发现,通过initC 方式获取Pod的名称、IP、等信息。将信息写入主程序的配置文件中。
生命周期和重启策略
状态值 | 描述 |
---|---|
Pending | API Server已经创建Pod,但在Pod中还有一个或者多个容器镜像没有创建,包括正在下载镜像过程 |
Running | Pod内所有容器均已创建,至少有一个容器处于运行状态、正在启动状态、正在重启状态 |
Succeeded | Pod内的容器都已经成功执行后退出,且不会重启 |
Failed | Pod内的容器都已经退出,至少有一个容器的退出为失败状态 |
Unknown | 无法获取到该Pod的状态,可能是网络原因 |
Pod重启策略应用于Pod内的所有容器,只由本Node上的kubelet判断,根据RestartPolicy进行操作。
Pod重启策略包括:
- Always:只要失效就重启。
- OnFailure:容器终止且退出代码不为0。
- Never:不论容器状态如何,永不重启。
Kubelet重启失效容器时间为2n,例如:1、2、4、8等。最长5分钟,成功重启10分钟后重置该时间。
管理Pod的控制器包括:
- RC和DaemonSet:必须设置Always。保持持续运行。
- Job:OnFailure和Never,确保执行完不被重启。
健康检查和服务可用性
探针类型:
- LivenessProbe:判断容器是否存活(Running),如果检测到不健康,杀掉容器,根据重启策略处理。如果不包含该探针,默认Success。
- ReadinessProbe:判断容器是否可用(Ready),Ready状态才能接收请求,和Endpoint有关联。只有Pod是ready,Endpoint增加,否则删除。
LivenessProbe和ReadinessProbe均可配置如下三种方式
HTTPGetAction
通过IP、端口、路径调用HTTP Get方法,如果响应吗在200到400之间,则健康
yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-healthcheck
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /_status/healthz
port: 80
initialDelaySeconds: 30
timeoutSeconds: 1
创建并查看结果
bash
[root@master1 pod]# kubectl apply -f 12.yaml
pod/pod-with-healthcheck created
[root@master1 pod]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
pod-with-healthcheck 1/1 Running 0 7s
TCPSocketAction
通过容器的IP和端口执行 TCP 检查,如果能够建立连接,则表明容器健康
yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-healthcheck
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
timeoutSeconds: 1
运行并查看结果
bash
[root@master1 pod]# kubectl apply -f 11.yaml
pod/pod-with-healthcheck created
[root@master1 pod]# kubectl describe pod pod-with-healthcheck
Name: pod-with-healthcheck
Namespace: pod-ns
Priority: 0
Node: node1/192.168.40.182
Start Time: Wed, 06 Mar 2024 09:42:09 -0500
Labels: <none>
Annotations: cni.projectcalico.org/podIP: 10.244.166.150/32
cni.projectcalico.org/podIPs: 10.244.166.150/32
Status: Running
IP: 10.244.166.150
IPs:
IP: 10.244.166.150
Containers:
nginx:
Container ID: docker://c9181484353e6634dcafb8c5f6a0abeb21d7fb99baa1bebdeba40bba55a7e697
Image: nginx
Image ID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 06 Mar 2024 09:42:19 -0500
Ready: True
Restart Count: 0
Liveness: tcp-socket :80 delay=30s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-9p2fw (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-9p2fw:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-9p2fw
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 22s default-scheduler Successfully assigned pod-ns/pod-with-healthcheck to node1
Normal Pulling 22s kubelet Pulling image "nginx"
Normal Pulled 12s kubelet Successfully pulled image "nginx" in 9.089412561s
Normal Created 12s kubelet Created container nginx
Normal Started 12s kubelet Started container nginx
ExecAction
容器内执行命令,返回码为零,则容器健康
yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
labels:
test: liveness
spec:
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/health
initialDelaySeconds: 15
timeoutSeconds: 1
在容器中执行命令 cat /tmp/health,Pod运行后,创建 /tmp/health,10秒后删除该文件夹。健康检查配置的是15秒后,所以探测结果为失败,kubelet杀掉该容器并重启。
bash
[root@master1 pod]# kubectl apply -f 10.yaml
pod/liveness-exec created
[root@master1 pod]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
liveness-exec 0/1 ContainerCreating 0 10s
liveness-exec 1/1 Running 0 17s
liveness-exec 1/1 Running 1 104s
liveness-exec 1/1 Running 2 3m15s
liveness-exec 1/1 Running 3 4m44s
liveness-exec 1/1 Running 4 6m14s
liveness-exec 1/1 Running 5 7m44s
liveness-exec 1/1 Running 6 8m59s
liveness-exec 0/1 CrashLoopBackOff 6 10m
两个关键参数:
- initialDelaySeconds:容器启动后进行首次检查时间,单位 秒
- timeoutSeconds:检查发出请求后等待响应时间,单位 秒,超时,重启该服务。