首页 > 其他分享 >pod详解

pod详解

时间:2023-12-13 15:22:41浏览次数:35  
标签:容器 nginx 详解 pod k8s root Pod

Pod是什么

Pod是Kubernetes创建或部署的最小单位。一个Pod封装一个或多个容器(container)、存储资源(volume)、一个独立的网络IP以及管理控制容器运行方式的策略选项。

Pod使用主要分为两种方式:

  • Pod中运行一个容器。这是Kubernetes最常见的用法,您可以将Pod视为单个封装的容器,但是Kubernetes是直接管理Pod而不是容器。
  • Pod中运行多个需要耦合在一起工作、需要共享资源的容器。通常这种场景下应用包含一个主容器和几个辅助容器(SideCar Container),如图1所示,例如主容器为一个web服务器,从一个固定目录下对外提供文件服务,而辅助容器周期性的从外部下载文件存到这个固定目录下。

 

实际使用中很少直接创建Pod,而是使用Kubernetes中称为Controller的抽象层来管理Pod实例,例如Deployment和Job。

Controller可以创建和管理多个Pod,提供副本管理、滚动升级和自愈能力。

通常,Controller会使用Pod Template来创建相应的Pod。

创建Pod

kubernetes中资源可以使用YAML描述(如果您对YAML格式不了解,可以参考YAML语法),也可以使用JSON

https://support.huaweicloud.com/devg-cci/cci_05_1001.html

如下示例描述了一个名为nginx的Pod,这个Pod中包含一个名为container-0的容器,使用nginx:alpine镜像,使用的资源为100m core CPU、200Mi内存。

apiVersion: v1                      # Kubernetes的API Version
kind: Pod                           # Kubernetes的资源类型
metadata:
  name: nginx                       # Pod的名称
spec:                               # Pod的具体规格(specification)
  containers:
  - image: nginx:alpine             # 使用的镜像为 nginx:alpine
    name: container-0               # 容器的名称
    resources:                      # 申请容器所需的资源
      limits:
        cpu: 100m
        memory: 200Mi
      requests:
        cpu: 100m
        memory: 200Mi
  #imagePullSecrets:                 # 拉取镜像使用的证书,在CCE上必须为default-secret
 # - name: default-secret

如上面YAML的注释,YAML描述文件主要为如下部分:

  • metadata:一些名称/标签/namespace等信息。
  • spec:Pod实际的配置信息,包括使用什么镜像,volume等。

如果去查询Kubernetes的资源,您会看到还有一个status字段,status描述kubernetes资源的实际状态,创建时不需要配置。这个示例是一个最小集,其他参数定义后面会逐步介绍。

Pod定义好后就可以使用kubectl创建,如果上面YAML文件名称为nginx.yaml,则创建命令如下所示,-f表示使用文件方式创建。

[root@k8s-master-10 ~]#kubectl create -f cce-pod.yaml 
pod/nginx created

[root@k8s-master-10 ~]#kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
dep-nginx-779c7fd666-cvg8v   1/1     Running   0          34m
nginx                        1/1     Running   0          12s
yuchao-nginx                 1/1     Running   0          19h
[root@k8s-master-10 ~]#

pod状态查看

可以看到此处nginx这个Pod的状态为Running,表示正在运行;READY为1/1,表示这个Pod中有1个容器,其中1个容器的状态为Ready。

可以使用kubectl get命令查询具体Pod的配置信息,如下所示,-o yaml表示以YAML格式返回,还可以使用-o json,以JSON格式返回。

$ kubectl get pod nginx -o yaml
$ kubectl get pod nginx -o json

pod详情查看

[root@k8s-master-10 ~]#kubectl describe pod nginx

常用来查看资源创建事件
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  92s   default-scheduler  Successfully assigned default/nginx to k8s-node-12
  Normal  Pulled     92s   kubelet            Container image "nginx:alpine" already present on machine
  Normal  Created    92s   kubelet            Created container container-0
  Normal  Started    92s   kubelet            Started container container-0

删除pod时,Kubernetes终止Pod中所有容器。 Kubernetes向进程发送SIGTERM信号并等待一定的秒数(默认为30)让容器正常关闭。

如果它没有在这个时间内关闭,Kubernetes会发送一个SIGKILL信号杀死该进程。

pod停止删除

Pod的停止与删除有多种方法,比如按名称删除,如下所示。

一次性删除多个pod。

[root@k8s-master-10 ~]#kubectl delete pod nginx yuchao-nginx
pod "nginx" deleted
pod "yuchao-nginx" deleted

清理当前namespace下所有的pod,默认就是default

[root@k8s-master-10 ~]#kubectl describe pod dep-nginx-779c7fd666-cvg8v |grep -i ^namespace
Namespace:    default

# --all参数,危险命令!
[root@k8s-master-10 ~]#kubectl delete pod --all
pod "dep-nginx-779c7fd666-cvg8v" deleted

标签选择器删除pod

kubectl delete pod -l name=www.yuchaoit.cn

pod使用环境变量

环境变量是容器运行环境中设定的一个变量。

环境变量为应用提供极大的灵活性,您可以在应用程序中使用环境变量,在创建容器时为环境变量赋值,容器运行时读取环境变量的值,从而做到灵活的配置,而不是每次都重新编写应用程序制作镜像。

环境变量的使用方法如下所示,配置spec.containers.env字段即可。

[root@k8s-master-10 ~]#kubectl explain pod.spec.containers.env

# 查看关于容器资源的cpu限制
[root@k8s-master-10 ~]#kubectl explain pod.spec.containers.resources.limits.cpu

# 官网pod限制cpu资源
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-cpu-resource/

测试yaml

apiVersion: v1
kind: Pod
metadata:
  name: yuchao-nginx
spec:
    containers:
    - image: nginx:alpine
      name: container-0
      resources:
        limits:
          cpu: 100m
          memory: 200Mi
        requests:
          cpu: 100m
          memory: 200Mi
      env:                            # 环境变量
      - name: env_name
        value: env_www.yuchaoit.cn
  #  imagePullSecrets:
  #  - name: default-secret

创建pod

[root@k8s-master-10 ~]#kubectl create -f env-pod.yaml 
pod/yuchao-nginx created
[root@k8s-master-10 ~]#

查看pod内环境变量

[root@k8s-master-10 ~]#kubectl exec -it yuchao-nginx -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=yuchao-nginx
TERM=xterm
env_name=env_www.yuchaoit.cn
KUBERNETES_SERVICE_HOST=10.1.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.1.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.1.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.1.0.1
NGINX_VERSION=1.21.5
NJS_VERSION=0.7.1
PKG_RELEASE=1
HOME=/root

环境变量还可以引用ConfigMap和Secret,具体使用方法请参见在环境变量中引用ConfigMap在环境变量中引用Secret

容器启动命令

启动容器就是启动主进程,但有些时候,启动主进程前,需要一些准备工作。

比如MySQL类的数据库,可能需要一些数据库配置、初始化的工作,这些工作要在最终的MySQL服务器运行之前做完。

这些操作,可以在制作镜像时通过在Dockerfile文件中设置ENTRYPOINT或CMD来完成,如下所示的Dockerfile中设置了ENTRYPOINT ["curl", "www.yuchaoit.cn"]命令,其将会在容器启动时执行。

实际使用时,只需配置Pod的containers.command参数,该参数是list类型,第一个参数为执行命令,后面均为命令的参数。

apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: chaoge-linux # 单独开一个ns环境
spec:
  containers:
  - image: nginx:alpine
    name: container-0
    resources:
      limits:
        cpu: 100m
        memory: 200Mi
      requests:
        cpu: 100m
        memory: 200Mi
    command:                     # 启动命令
    - curl
    - "www.yuchaoit.cn"
 # imagePullSecrets:
  # - name: default-secret

创建namespace下的pod

[root@k8s-master-10 ~]#kubectl create ns chaoge-linux
namespace/chaoge-linux created

[root@k8s-master-10 ~]#kubectl create -f cmd-pod.yaml 
pod/mynginx created
[root@k8s-master-10 ~]#

查看ns下的pod

[root@k8s-master-10 ~]#kubectl get pods -n chaoge-linux 
NAME      READY   STATUS             RESTARTS   AGE
mynginx   0/1     CrashLoopBackOff   4          2m12s
[root@k8s-master-10 ~]#

发现咋挂了?

查看pod事件

Events:
  Type     Reason     Age                   From               Message
  ----     ------     ----                  ----               -------
  Normal   Scheduled  2m37s                 default-scheduler  Successfully assigned chaoge-linux/mynginx to k8s-node-12
  Normal   Pulled     61s (x5 over 2m37s)   kubelet            Container image "nginx:alpine" already present on machine
  Normal   Created    61s (x5 over 2m37s)   kubelet            Created container container-0
  Normal   Started    61s (x5 over 2m36s)   kubelet            Started container container-0
  Warning  BackOff    60s (x10 over 2m35s)  kubelet            Back-off restarting failed container



[root@k8s-master-10 ~]#kubectl describe pod mynginx -n chaoge-linux

查看pod日志

[root@k8s-master-10 ~]#kubectl -n chaoge-linux logs mynginx |grep 于超
    <title itemprop="name">于超带你学linux</title>
            <h1 class="center-text glitch" data-text="于超老师带你学linux">于超老师带你学linux</h1>
                        <h1 class="site-title"><a href="http://yuchaoit.cn:8090">于超带你学linux</a></h1>
            <h1 class="site-title"><a href="http://yuchaoit.cn:8090">于超带你学linux</a></h1>
        <p style="text-align: center; color: #333; font-weight: 900; font-family: 'Ubuntu', sans-serif; letter-spacing: 1.5px">于超老师带你学linux</p>
        "sitename": "于超带你学linux",
[root@k8s-master-10 ~]#


# 因为我们修改了容器启动执行命令,并非是启动nginx了,删除该pod即可。

[root@k8s-master-10 ~]#kubectl -n chaoge-linux delete pod mynginx 
pod "mynginx" deleted

1.pod网络空间原理

pause容器

https://jimmysong.io/kubernetes-handbook/concepts/pause-container.html


像 Pod 这样一个东西,本身是一个逻辑概念。那在机器上,它究竟是怎么实现的呢?这就是我们要解释的一个问题。

既然说 Pod 要解决这个问题,核心就在于如何让一个 Pod 里的多个容器之间最高效的共享某些资源和数据。

因为容器之间原本是被 Linux Namespace 和 cgroups 隔开的,所以现在实际要解决的是怎么去打破这个隔离,然后共享某些事情和某些信息。这就是 Pod 的设计要解决的核心问题所在。

所以说具体的解法分为两个部分:网络和存储。

Pause 容器就是为解决 Pod 中的网络问题而生的。

kubernetes 中的 pause 容器主要为每个业务容器提供以下功能:

在 pod 中担任 Linux 命名空间共享的基础;

启用 pid 命名空间,开启 init 进程。

 

pod内共享网络空间

1.pod内的所有容器,都通过container模式,使用pause容器的网络空间
2.容器看到的网络环境,就是根容器的环境
3.pod内的一组容器可以直接走localhost通信
4.pod内的多个容器不能重复用同一端口
5.pod的生命周期,代表了内部的所有容器生命周期

查看pod内容器的网络信息

[root@k8s-node-11 ~]#docker inspect 2c3 |grep -i networkmode
            "NetworkMode": "container:403fbe24581c63631b036f4d7f0b9b372b8e24e3c675943c87eee11ccdc8780e",
[root@k8s-node-11 ~]#

查看pod内共享的文件系统

默认情况下的pod内的容器,是隔离文件系统的
如果要让多个容器共享文件数据,基于volume即可实现,然后分别进行volumeMounts挂载即可。

pod内运行多个容器

提示信息

# 指定节点运行pod
[root@k8s-master-10 ~]#kubectl explain pod.spec.nodeName
KIND:     Pod
VERSION:  v1

FIELD:    nodeName <string>

DESCRIPTION:
     NodeName is a request to schedule this pod onto a specific node. If it is
     non-empty, the scheduler simply schedules this pod onto that node, assuming
     that it fits resource requirements.
[root@k8s-master-10 ~]#

# pod数据映射给宿主机
https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#hostpath

yaml

apiVersion: v1
kind: Pod
metadata:
  name: two-nginx
  namespace: yuchao-linux # 单独开一个ns环境
spec:
  nodeName: k8s-node-12

  volumes:
  - name: nginx-log
    hostPath:
      path: /var/log/nginx/

  containers:
  - name: nginx-two
    image: nginx:alpine
    volumeMounts:
      - name: nginx-log
        mountPath: /var/log/nginx/

  - name: tail-log
    image: busybox
    args: [/bin/sh,-c,'tail -f /var/log/nginx/access.log']
    volumeMounts:
      - name: nginx-log
        mountPath: /var/log/nginx/

图解多容器pod

 

[root@k8s-master-10 ~]#kubectl create ns yuchao-linux
namespace/yuchao-linux created
[root@k8s-master-10 ~]#kubectl create -f tail-nginx.yml 
pod/two-nginx created
[root@k8s-master-10 ~]#


[root@k8s-master-10 ~]#kubectl -n yuchao-linux get po -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP         NODE          NOMINATED NODE   READINESS GATES
two-nginx   2/2     Running   0          89m   10.2.2.8   k8s-node-12   <none>           <none>
[root@k8s-master-10 ~]#

进入pod中的某个容器

注意语法

[root@k8s-master-10 ~]#kubectl -n yuchao-linux exec -it two-nginx  -c nginx-two -- sh


[root@k8s-master-10 ~]#kubectl -n yuchao-linux exec -it two-nginx  -c tail-log -- sh

图解多容器下的日志访问与映射

 

2.pod生命周期

pod状态与生命周期

2.1 pod运行状态

 

Pod的状态如下表所示:

状态值描述
Pending API Server已经创建该Pod,等待调度器调度
ContainerCreating 拉取镜像启动容器中
Running Pod内容器均已创建,且至少有一个容器处于运行状态、正在启动状态或正在重启状态
Succeeded\ Completed Pod内所有容器均已成功执行退出,且不再重启
Failed\ Error Pod内所有容器均已退出,但至少有一个容器退出为失败状态
CrashLoopBackOff Pod内有容器启动失败,比如配置文件丢失导致主进程启动失败
Unknown 由于某种原因无法获取该Pod的状态,可能由于网络通信不畅导致
pending,pod已经被k8s组件确认处理中,但是一个、或者多个容器还在创建中,这个等待时间包括pod创建、或者镜像拉取时间。

running、pod已经运行到了具体Node上,且所有容器都被创建好,并且只要有一个容器还在运行中都是running。

succeeded 、pod中所有的容器都已成功终止、且不会再自动重启了。

Failed、pod中的容器都退出了、但是有一个容器非正常状态结束,异常挂了,退出码非0。

Unknown、如网络问题,导致的pod状态无法获取。

2.2 容器生命周期钩子

Kubernetes提供了容器生命周期钩子,在容器的生命周期的特定阶段执行调用,比如容器在停止前希望执行某项操作,就可以注册相应的钩子函数。目前提供的生命周期钩子函数如下所示。

  • 启动后处理(PostStart):容器启动后触发。
  • 停止前处理(PreStop):容器停止前触发。

实际使用时,只需配置Pod的lifecycle.postStart或lifecycle.preStop参数,如下所示。

 

2.3 pod生命周期完整示意

 

文字详解pod生命周期

init container
1.初始化容器就是指,主容器启动之前做一些准备环境初始化工作,例如两个容器都用到了volume,可以先用init容器进行目录授权修改。

2. 例如业务容器需要读取数据库,可以基于init容器先尝试数据库连接,确认正常后再启动业务容器。


# 钩子字段查询
[root@k8s-master-10 ~]#kubectl explain pod.spec.containers.lifecycle

poststart:在容器启动后,立即执行,但是时间有限,否则容器不会进入running状态
prestop:在容器停止前执行,一般用于优雅的关闭容器,环境清理。


# 容器存活、就绪探针
liveness probe:用于探测容器内的应用是否还运行中,如一个http服务。

readiness probe:用于探测容器内的应用是否就绪,可以干活了,例如在扩容pod后,得确保pod里的程序完全启动完毕,就绪后才应该将流量纷发给新pod。

init初始化容器

https://jimmysong.io/kubernetes-handbook/concepts/init-containers.html

pause容器

https://jimmysong.io/kubernetes-handbook/concepts/pause-container.html

3.pod如何封装容器

我们已知道pod是可以运行一个、多个容器的抽象组件。

在实际工作中该如何考虑,一个pod运行一个、还是多个容器?

图解POD部署思路

 

很明显,应用和数据库绑在一起,要升级,要迁移,牵一发动全身。

拆开应用与数据库要灵活地多。

 

小结

当容器与容器之间需要联合发布,比较密切的时候,可以放在同一个POD里
如nignx、php/python
但php/python 和mysql必然是要分开放的

思考POD在负载均衡下的扩缩容,合理性即可。

4.初始化容器

关于emptyDir提示


emptyDir的生命周期与所属的pod相同。pod删除时,其emptyDir中的数据也会被删除。

emptyDir类型的volume在pod分配到node上时被创建,kubernetes会在node上自动分配 一个目录,因此无需指定宿主机node上对应的目录文件。

emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。

yaml

利用初始化容器,在nginx容器启动前,修改默认首页内容

apiVersion: v1
kind: Pod
metadata:
  name: nginx-init
  namespace: yuchaoit
  labels:
    app: myapp
spec:
  nodeName: k8s-node-12
  volumes:
    - name: nginx-index
      emptyDir: {}

  initContainers:
    - name: init 
      image: busybox
      args: [/bin/sh,-c,"echo 'k8s yuchaoit.cn 666' > /usr/share/nginx/html/index.html"]
      volumeMounts:
        - name: nginx-index
          mountPath: "/usr/share/nginx/html"

  containers:
    - name: nginx-app
      image: nginx:alpine
      ports:
        - containerPort: 80
      volumeMounts:
        - name: nginx-index
          mountPath: "/usr/share/nginx/html"

创建、访问nginx-init容器

[root@k8s-master-10 ~]#kubectl create ns yuchaoit
namespace/yuchaoit created

[root@k8s-master-10 ~]#kubectl create -f init-nginx.yml 
pod/nginx-init created

[root@k8s-master-10 ~]#kubectl create -f init-nginx.yml 
pod/nginx-init created
[root@k8s-master-10 ~]#kubectl get po -n yuchaoit -w
NAME         READY   STATUS    RESTARTS   AGE
nginx-init   1/1     Running   0          5s



[root@k8s-master-10 ~]#kubectl get po -n yuchaoit -owide
NAME         READY   STATUS    RESTARTS   AGE   IP          NODE          NOMINATED NODE   READINESS GATES
nginx-init   1/1     Running   0          18s   10.2.2.10   k8s-node-12   <none>           <none>
[root@k8s-master-10 ~]#
[root@k8s-master-10 ~]#
[root@k8s-master-10 ~]#
[root@k8s-master-10 ~]#curl 10.2.2.10
k8s yuchaoit.cn 666

5.pod生命周期钩子

postStart

启动后处理(PostStart):容器启动后触发。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-hook
  namespace: yuchaoit
  labels:
    app: myapp-hook
spec:
  nodeName: k8s-node-12


  containers:
    - name: nginx-hook
      image: nginx:alpine
      ports:
        - containerPort: 80
      lifecycle:
        postStart:
          exec:
            command: [/bin/sh,-c,'echo k8s www.yuchaoit.cn 666 >> /usr/share/nginx/html/index.html']

创建、访问pod以及钩子效果

[root@k8s-master-10 ~]#kubectl delete -f poststart-pod.yml 
pod "nginx-hook" deleted



[root@k8s-master-10 ~]#kubectl create -f poststart-pod.yml 
pod/nginx-hook created

[root@k8s-master-10 ~]#kubectl -n yuchaoit get po -w
NAME         READY   STATUS    RESTARTS   AGE
nginx-hook   1/1     Running   0          4s
nginx-init   1/1     Running   0          3h52m

访问

[root@k8s-master-10 ~]#curl 10.2.2.12
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
k8s www.yuchaoit.cn 666


# k8s没有直接重启pod的命令,只能如下方法
- 基于yaml,重新replace,达到重启
-  基于deployment,进行scale调整replicaset副本数量,对pod进行重新调整,实现重启
-  删除重建pod

prestop

将nginx日志,挂载到宿主机上,然后退出pod,查看日志变化。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-hook-pre
  namespace: yuchaoit
  labels:
    app: myapp-hook-pre
spec:
  nodeName: k8s-node-12

  volumes:
    - name: nginxlog
      hostPath:
        path: /var/log/nginx/


  containers:
    - name: nginx-hook-pre
      image: nginx:alpine
      ports:
        - containerPort: 80
      lifecycle:
        postStart:
          exec:
            command: [/bin/sh,-c,'echo k8s www.yuchaoit.cn 666 >> /usr/share/nginx/html/index.html']

        preStop:
          exec:
            command: [/bin/sh,-c,'echo 再见吧您!超哥打卡下班了!www.yuchaoit.cn >> /var/log/nginx/prestop-test.log']
      volumeMounts:
        - name: nginxlog
          mountPath: /var/log/nginx/

创建访问

[root@k8s-master-10 ~]#kubectl create -f prestop-pod.yml 
pod/nginx-hook-pre created


[root@k8s-master-10 ~]#kubectl -n yuchaoit get po -owide
NAME             READY   STATUS    RESTARTS   AGE    IP          NODE          NOMINATED NODE   READINESS GATES
nginx-hook       1/1     Running   0          10m    10.2.2.12   k8s-node-12   <none>           <none>
nginx-hook-pre   1/1     Running   0          5s     10.2.2.14   k8s-node-12   <none>           <none>
nginx-init       1/1     Running   0          4h3m   10.2.2.10   k8s-node-12   <none>           <none>

干掉停止pod

 

6.Pod健康探针

Kubernetes提供了自愈的能力,具体就是能感知到容器崩溃,然后能够重启这个容器。

但是有时候例如Java程序内存泄漏了,程序无法正常工作,但是JVM进程却是一直运行的,对于这种应用本身业务出了问题的情况,Kubernetes提供了Liveness Probe机制,通过检测容器响应是否正常来决定是否重启,这是一种很好的健康检查机制。

毫无疑问,每个Pod最好都定义Liveness Probe,否则Kubernetes无法感知Pod是否正常运行。

Kubernetes支持如下三种探测机制。

  • HTTP GET:向容器发送HTTP GET请求,如果Probe收到2xx或3xx,说明容器是健康的。
  • TCP Socket:尝试与容器指定端口建立TCP连接,如果连接成功建立,说明容器是健康的。
  • Exec:Probe执行容器中的命令并检查命令退出的状态码,如果状态码为0则说明容器是健康的。

与存活探针对应的还有一个就绪探针(Readiness Probe),将在就绪探针(Readiness Probe)中会详细介绍。

存活探针、liveness probe

 

用来检测容器内的应用程序是否正常工作中、如果应用都无法提供访问,容器也没意义了、
当存活探针判断应用不正确时,就重启pod。

指定命令、探针

查询存活探针的参数

[root@k8s-master-10 ~]#kubectl explain pod.spec.containers.livenessProbe

apiVersion: v1
kind: Pod
metadata:
  name: liveness-pod
  namespace: yuchaoit
  labels:
    app: myapp-hook-pre
spec:
  nodeName: k8s-node-12

  volumes:
    - name: nginx-html
      hostPath:
        path: /usr/share/nginx/html


  containers:
    - name: nginx-liveness
      image: nginx:alpine
      imagePullPolicy: IfNotPresent
      lifecycle:
        postStart:
          exec:
            command: [/bin/sh,-c,'echo k8s www.yuchaoit.cn 666 >> /usr/share/nginx/html/index.html']
        preStop:
          exec:
            command: [/bin/sh,-c,'echo 再见吧您!超哥打卡下班了!www.yuchaoit.cn >> /usr/share/nginx/html/index.html']

      livenessProbe:
        exec:
          command:
            - cat
            - /usr/share/nginx/html/index.html
        initialDelaySeconds: 3
        periodSeconds: 1
      volumeMounts:
        - name: nginx-html
          mountPath: /usr/share/nginx/html

探针参数解释

      livenessProbe:    # 存活性探针
        exec:                # 你想咋探
          command:    # 执行什么命令,且退出状态码是0,非0就是错误
            - cat
            - /usr/share/nginx/html/index.html
        initialDelaySeconds: 3    # 第一次执行探针的时候等待3秒
        periodSeconds: 1            # 每隔3秒执行一次存活探针,默认10秒,最小1s

运行探针pod

[root@k8s-master-10 ~]#kubectl create -f liveness-pod.yml 
pod/liveness-pod created
[root@k8s-master-10 ~]#kubectl -n yuchaoit get po -owide
NAME             READY   STATUS    RESTARTS   AGE     IP          NODE          NOMINATED NODE   READINESS GATES
liveness-pod     1/1     Running   0          8s      10.2.2.18   k8s-node-12   <none>           <none>
nginx-hook       1/1     Running   0          40m     10.2.2.12   k8s-node-12   <none>           <none>
nginx-hook-pre   1/1     Running   0          12m     10.2.2.17   k8s-node-12   <none>           <none>
nginx-init       1/1     Running   0          4h33m   10.2.2.10   k8s-node-12   <none>           <none>
[root@k8s-master-10 ~]#

查看探针pod状态

[root@k8s-master-10 ~]#kubectl -n yuchaoit get po -owide

 

HTTP GET探针

yaml

apiVersion: v1
kind: Pod
metadata:
  name: liveness-http-pod
  namespace: yuchaoit
  labels:
    app: myapp-hook-pre
spec:
  nodeName: k8s-node-12

  volumes:
    - name: nginx-html
      hostPath:
        path: /usr/share/nginx/html


  containers:
    - name: nginx-liveness
      image: nginx:alpine
      imagePullPolicy: IfNotPresent
      lifecycle:
        postStart:
          exec:
            command: [/bin/sh,-c,'echo k8s www.yuchaoit.cn 666 >> /usr/share/nginx/html/index.html']
        preStop:
          exec:
            command: [/bin/sh,-c,'echo 再见吧您!超哥打卡下班了!www.yuchaoit.cn >> /usr/share/nginx/html/index.html']

      livenessProbe:
        #exec:
        #  command:
        #   - cat
        #    - /usr/share/nginx/html/index.html

        httpGet:
          path: /index.html
          port: 80

        initialDelaySeconds: 3
        periodSeconds: 1
      volumeMounts:
        - name: nginx-html
          mountPath: /usr/share/nginx/html

检查httpGet探针结果

[root@k8s-master-10 ~]#kubectl -n yuchaoit get po -owide
NAME                READY   STATUS    RESTARTS   AGE     IP          NODE          NOMINATED NODE   READINESS GATES
liveness-http-pod   1/1     Running   0          6s      10.2.2.19   k8s-node-12   <none>           <none>
liveness-pod        1/1     Running   0          8m33s   10.2.2.18   k8s-node-12   <none>           <none>
nginx-hook          1/1     Running   0          49m     10.2.2.12   k8s-node-12   <none>           <none>
nginx-hook-pre      1/1     Running   0          20m     10.2.2.17   k8s-node-12   <none>           <none>
nginx-init          1/1     Running   0          4h41m   10.2.2.10   k8s-node-12   <none>           <none>
[root@k8s-master-10 ~]#

 

参数解释

如上,这个Probe往容器的80端口发送HTTP GET请求,如果请求不成功,Kubernetes会重启容器。

      livenessProbe:
        #exec:
        #  command:
        #   - cat
        #    - /usr/share/nginx/html/index.html

        httpGet:    # 基于http请求探针
          path: /index.html        # 请求地址,在200~400都算是正常的
          port: 80    # 请求端口

        initialDelaySeconds: 3
        periodSeconds: 1

可以看到Pod当前状态是Running,Restart Count为0,说明没有重启。如果Restart Count不为0,则说明已经重启。

存活探针结果参数

这一行表示Liveness Probe的具体参数配置,其含义如下:

  • delay:延迟,delay=0s,表示在容器启动后立即开始探测,没有延迟时间
  • timeout:超时,timeout=1s,表示容器必须在1s内进行响应,否则这次探测记作失败
  • period:周期,period=10s,表示每10s探测一次容器
  • success:成功,#success=1,表示连续1次成功后记作成功
  • failure:失败,#failure=3,表示连续3次失败后会重启容器

以上存活探针表示:容器启动后立即进行探测,如果1s内容器没有给出回应则记作探测失败。每次间隔10s进行一次探测,在探测连续失败3次后重启容器。

这些是创建时默认设置的,您也可以手动配置,如下所示。

 

initialDelaySeconds一般要设置大于0,这是由于很多情况下容器虽然启动成功,但应用就绪也需要一定的时间,需要等就绪时间之后才能返回成功,否则就会导致probe经常失败。

另外failureThreshold可以设置多次循环探测,这样在实际应用中健康检查的程序就不需要多次循环,这一点在开发应用时需要注意。

配置有效的Liveness Probe

  • Liveness Probe应该检查什么

    一个好的Liveness Probe应该检查应用内部所有关键部分是否健康,并使用一个专有的URL访问,例如/health,当访问/health 时执行这个功能,然后返回对应结果。这里要注意不能做鉴权,不然probe就会一直失败导致陷入重启的死循环。

    另外检查只能限制在应用内部,不能检查依赖外部的部分,例如当前端web server不能连接数据库时,这个就不能看成web server不健康。

  • Liveness Probe必须轻量

    Liveness Probe不能占用过多的资源,且不能占用过长的时间,否则所有资源都在做健康检查,这就没有意义了。例如Java应用,就最好用HTTP GET方式,如果用Exec方式,JVM启动就占用了非常多的资源。

7.就绪探针

 

http://ebook-p6.yuchaoit.cn/k8s/pic/readnessprobe.webp

 

 

https://support.huaweicloud.com/basics-cce/kubernetes_0026.html

参考文档

一个新Pod创建后,Service就能立即选择到它,并会把请求转发给Pod,那问题就来了,通常一个Pod启动是需要时间的,如果Pod还没准备好(可能需要时间来加载配置或数据,或者可能需要执行一个预热程序之类),这时把请求转给Pod的话,Pod也无法处理,造成请求失败。

Kubernetes解决这个问题的方法就是给Pod加一个业务就绪探针Readiness Probe,当检测到Pod就绪后才允许Service将请求转给Pod。

Readiness Probe同样是周期性的检测Pod,然后根据响应来判断Pod是否就绪,与存活探针(Liveness Probe)相同,就绪探针也支持如下三种类型。

  • Exec:Probe执行容器中的命令并检查命令退出的状态码,如果状态码为0则说明已经就绪。
  • HTTP GET:往容器的IP:Port发送HTTP GET请求,如果Probe收到2xx或3xx,说明已经就绪。
  • TCP Socket:尝试与容器建立TCP连接,如果能建立连接说明已经就绪。
有时候可能pod已经起来了,但是pod内的容器还未完全就绪,能对外提供访问,那么这个时候流量进入pod就会出现请求失败。

k8s提供了一个就绪探针,能让你确认应用可访问,只有探针通过后,k8s才将流量转发给pod。

yaml

Readiness Probe的配置与存活探针(livness probe)一样,都是在Pod Template的containers里面,如下所示,这个Readiness Probe向Pod发送HTTP请求,当Probe收到2xx或3xx返回时,说明Pod已经就绪。

apiVersion: v1
kind: Pod
metadata:
  name: readiness-http-pod
  namespace: yuchaoit
  labels:
    app: myapp-readiness
spec:
  nodeName: k8s-node-12

  volumes:
    - name: nginx-html
      hostPath:
        path: /usr/share/nginx/html


  containers:
    - name: nginx-readiness
      image: nginx:alpine
      imagePullPolicy: IfNotPresent
      lifecycle:
        postStart:
          exec:
            command: [/bin/sh,-c,'echo k8s www.yuchaoit.cn 666 >> /usr/share/nginx/html/index.html']
        preStop:
          exec:
            command: [/bin/sh,-c,'echo 再见吧您!超哥打卡下班了!www.yuchaoit.cn >> /usr/share/nginx/html/index.html']

      livenessProbe:
        #exec:
        #  command:
        #   - cat
        #    - /usr/share/nginx/html/index.html

        httpGet:
          path: /index.html
          port: 80

        initialDelaySeconds: 3
        periodSeconds: 1

      readinessProbe:
        httpGet:
          path: /read
          port: 80
        initialDelaySeconds: 10    # 容器启动后多久开始探测
        timeoutSeconds: 2          # 表示容器必须在2s内做出相应反馈给probe,否则视为探测失败
        periodSeconds: 30          # 探测周期,每30s探测一次
        successThreshold: 1        # 连续探测1次成功表示成功
        failureThreshold: 3        # 连续探测3次失败表示失败

      volumeMounts:
        - name: nginx-html
          mountPath: /usr/share/nginx/html

运行就绪探针

[root@k8s-master-10 ~]#kubectl create -f readiness-pod.yml 
pod/readiness-http-pod created



[root@k8s-master-10 ~]#kubectl -n yuchaoit get po readiness-http-pod -owide
NAME                 READY   STATUS    RESTARTS   AGE   IP          NODE          NOMINATED NODE   READINESS GATES
readiness-http-pod   0/1     Running   0          21s   10.2.2.20   k8s-node-12   <none>           <none>
[root@k8s-master-10 ~]#

 

让pod就绪

[root@k8s-master-10 ~]#kubectl -n yuchaoit get po readiness-http-pod 
NAME                 READY   STATUS    RESTARTS   AGE
readiness-http-pod   0/1     Running   0          3m46s



[root@k8s-master-10 ~]#kubectl exec -n yuchaoit -it readiness-http-pod -- sh -c "echo www.yuchaoit.cn  > /usr/share/nginx/html/read"
[root@k8s-master-10 ~]#

[root@k8s-master-10 ~]#curl 10.2.2.20
k8s www.yuchaoit.cn 666
k8s www.yuchaoit.cn 666
k8s www.yuchaoit.cn 666
[root@k8s-master-10 ~]#curl 10.2.2.20/read
www.yuchaoit.cn
[root@k8s-master-10 ~]#

[root@k8s-master-10 ~]#kubectl -n yuchaoit get po readiness-http-pod -owide
NAME                 READY   STATUS    RESTARTS   AGE     IP          NODE          NOMINATED NODE   READINESS GATES
readiness-http-pod   1/1     Running   0          6m13s   10.2.2.20   k8s-node-12   <none>           <none>
[root@k8s-master-10 ~]#

就绪结果describe

 

8.Pod资源限制

之前于超老师讲过容器docker可以利用CGroup进行资源限制,CPU、内存的主要资源使用率。
POD当然也一样。

资源限制单位

1 CPU = 1000m

0.5  CPU = 500m


1 Mib = 1024 Kib

1Mb = 1000KB

yaml

apiVersion: v1
kind: Pod
metadata:
  name: limit-pod
  namespace: yuchaoit

spec:
  containers:
    - name: resource-demo
      image: nginx:alpine
      ports:
        - containerPort: 80
      resources:
        requests: # 节点所需的最小资源
          memory: 50Mi
          cpu: 150m
        limits:   # 限制pod最大资源使用量
          memory: 100Mi
          cpu: 200m

创建资源限制pod

[root@k8s-master-10 ~]#kubectl -n yuchaoit get po limit-pod -owide
NAME        READY   STATUS    RESTARTS   AGE   IP         NODE          NOMINATED NODE   READINESS GATES
limit-pod   1/1     Running   0          22s   10.2.1.9   k8s-node-11   <none>           <none>
[root@k8s-master-10 ~]#

查看pod资源限制效果

[root@k8s-master-10 ~]#kubectl  -n yuchaoit describe pod limit-pod

 

查看容器动态信息

[root@k8s-node-11 ~]#docker inspect 9467d9e9a813 |grep Cgroup
            "Cgroup": "",
            "CgroupParent": "kubepods-burstable-pod367e53f8_ee58_4a89_97f6_552108d85be2.slice",
            "DeviceCgroupRules": null,
[root@k8s-node-11 ~]#


[root@k8s-node-11 /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod367e53f8_ee58_4a89_97f6_552108d85be2.slice]#cat cpu.cfs_quota_us 
20000

 


docker stats

 

 

标签:容器,nginx,详解,pod,k8s,root,Pod
From: https://www.cnblogs.com/sxy-blog/p/17899121.html

相关文章

  • 通过 VS Code 优雅地编辑 Pod 内的代码(非 NodePort)
    目录1.概述2.NodePort方式3.Ingress方式4.救命稻草5.其他1.概述今天聊点啥呢,话说,你有没有想过怎样用VSCode连上K8s集群内的某个Pod,然后直接更新Pod内的代码?当我听到这个需求的时候,第一反应是在Pod内搞一个sshd,然后NodePort方式暴露Pod,接着用VSCode的......
  • Java内部类详解
    内部类内部类的分类内部类分类:成员内部类静态内部类局部内部类匿名内部类内部类的概念在一个类里面定义一个完整的类packagecom.lin.clas.demo01;​publicclassBody{​ //内部类 classHead{​ }}成员内部类在类的内部定义,与实例变量,实例......
  • Unity3D 第一人称角色控制器,第一人称相机,摄像机的关系详解
    Unity3D是一款强大的游戏开发引擎,可以用于创建各种类型的游戏。在游戏中,第一人称角色控制器、第一人称相机和摄像机是密切相关的组件,它们共同协作来实现游戏的第一人称视角。下面将详细解释它们之间的关系,并给出代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游......
  • 异常详解
    异常详解异常体系结构Java把异常当成一个对象处理,并定义了一个基类java.lang.Throwable作为所有异常的超类。在JavaAPI中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception. 捕获和抛出异常关键字:try,catch,throw,throwspackagecom.paial.demo09......
  • Java方法详解
    Java方法详解1.何为方法类似于其他语言的函数Java方法是语句的集合,共同完成一个功能设计方法的原则:一个方法实现一个功能,有利于后期的管理和拓展!命名:首小写+驼峰命名。2.方法的定义修饰符返回值类型方法名(参数类型参数名){​方法体return返回值;}实参:实......
  • 使用CEF(七)详解macOS下基于CEF的多进程应用程序CMake项目搭建
    由于macOS下的应用程序结构导致了CEF这样的多进程架构程序在项目结构、运行架构上有很多细节需要关注,这一块的内容比起Windows要复杂的多,所以本文将会聚焦macOS下基于CEF的多进程应用架构的环境配置,并逐一说明了CMake的相关用法和CEF应用配置细节。前言在进行搭建之前,我们首先必......
  • MySQL中的slave_exec_mode 参数详解(MySQL从节点复制错误处理时,sql_slave_skip_counter
    原文地址:https://www.soughttech.com/front/article/7159/viewArticle  今天我偶然看到了参数slave_exec_mode。从手册中的描述可以看出,该参数与MySQL复制有关。它是一个可以动态修改的变量。默认为STRICT mode(严格模式),可选值为IDEMPOTENT mode(幂等模式)。设置为IDEMP......
  • k8s_kind-创建pod-拉取私有仓库镜像
    kind本地配置查看您创建的所有集群,您可以使用该kindgetclusters命令在kubernetes内使用私有镜像仓库之前,我们需要先有一个私有镜像仓库,并保证这个仓库是可用的检查私有镜像仓库是否可用kindcreatecluster--namedatapre##以将本机镜像导入到Kind集群中去......
  • 接口测试详解
    大多数人对于接口测试都觉得是一种高大上的测试,觉得学会接口测试就可以从小白测试员,变成了高级测试员,但其实接口测试只是测试的基础内容。什么是接口接口泛指实体把自己提供给外界的一种抽象化物(可以为另一实体),用以由内部操作分离出外部沟通方法,使其能被内部修改而不影响外界其他实......
  • Rocky Linux 9 安装 Podman
    1、安装Podmandnf-yinstallpodman2、配置镜像加速和私有镜像仓库#vim/etc/containers/registries.confunqualified-search-registries=["docker.io"][[registry]]prefix="docker.io"insecure=falseblocked=falselocation="docker.io"......