kubernetes Pod-02 容器中获取Pod信息及重启策略

在容器中获取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:检查发出请求后等待响应时间,单位 秒,超时,重启该服务。
相关推荐
玖疯子30 分钟前
介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
docker
暴富的Tdy33 分钟前
【快速上手Docker 简单配置方法】
docker·容器·eureka
魏 无羡1 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos
Karoku0661 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes
凌虚3 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
saynaihe3 小时前
安全地使用 Docker 和 Systemctl 部署 Kafka 的综合指南
运维·安全·docker·容器·kafka
G_whang4 小时前
centos7下docker 容器实现redis主从同步
redis·docker·容器
认真学习的小雅兰.4 小时前
如何在Ubuntu上利用Docker和Cpolar实现Excalidraw公网访问高效绘图——“cpolar内网穿透”
linux·ubuntu·docker
the丶only5 小时前
单点登录平台Casdoor搭建与使用,集成gitlab同步创建删除账号
linux·运维·服务器·docker·gitlab
书生-w5 小时前
Docker部署GitLab服务器
服务器·docker·gitlab