六、Kubernetes Pod (2)

 一、Pod的生命周期

  1. pod的创建过程;

  2. 运行初始化容器的过程;init container

  3. 运行主容器过程:main container

            -容器启动后钩子(port start) 、容器终止前钩子(pre stop)

            -容器的存活性探测(liveness probe)、就绪性探测(readiness probe)  

     4.pod终止的过程

1、整个生命周期,Pod会出现5种状态或者说是5种相位

Pending

挂起

apiserver已经创建pod,但他未完成调度或者处于镜像下载过程

Running

运行中

pod已经被调度到节点上面了,并且pod上面所有需要的容器服务都已经被kubelet创建完成

Succeeded

成功

pod中毒的所有容器都已经被成功终止并且不会被重启(pod已经被创建成功)

Failed

失败

返回一个非0的推出状态码

Unknown

未知

apiserver暂时无法获取pod对象的状态信息,通常由网络通信失败导致

2、Pod的创建和终止过程

创建:

1.用户通过kubectl或其他api客户端提交需要创建的pod给apiserver;

2.apiserver之后就生成pod信息,并存入etcd(键值对),然后向客户端返回确认信息;

3.apiserver开始反映etcd中的pod对象的变化,其他组件使用watch(监听)机制来跟踪检查apiserver上的pod对象的变动;

4.scheduler发现有新的pod的对象要创建,开始为pod分配主机并将结果信息更新到apiserver;

5.node节点上的kubelet发现有pod调度请求,尝试启动容器,并将调度结果返回到apiserver

6.apiserver将接收到的pod状态信息存入etcd中去;

终止:

1.用户向apiserver发送删除pod对象的命令

2.apiserver中的pod对象信息会随着时间的推移而更新,在宽限期内(30s),pod被视为dead

3.将pod标记为terminating状态

4.kubelet在watch到pod对象变成terminating状态的时候,会启动pod的关闭过程

5.端点控制器检测到pod对象有关闭的行为时,会将pod对象到此端点的所有service资源删除

6.如果被删除的pod定义了一个prestop钩子处理器的时候,那么将会在pod成为terminating状态的时候执行

7.pod对象收到停止的信号

8.30s宽限期结束后,不管什么状态下,pod都会立即终止

9.kubelet请求apiserver将此pod资源的宽限期设置为0从而完成删除操作,此时pod对于用户已不可见

3、初始化容器

        Kubernetes按照顺序执行,必须上一个容器完成才能启动下一个,如果其中上一个启动失败的话,Kubernetes将会进入重启,必须要有容器都初始化完成!

# 我们创建一个pod,里面运行两个容器

vim init.yml

apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: v1
kind: Pod
metadata:
  name: init-test
  namespace: dev
spec:
  containers:
  - name: nginx-init
    image: nginx:1.17.1
    ports:
    - name: nginx-ports
      containerPort: 80
  initContainers:
  - name: test-mysql
    image: busybox:1.30  # 创建之后 pod状态一直是INIT,初始化状态;镜像版本号不对
    command: ['sh', '-c', 'until ping 172.16.52.201 -c 1 ; do echo waiting for mysql...; sleep 2; done;']

#查看pod状态

kubectl get pods -n dev -o wide

NAME        READY   STATUS              RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
init-test   0/1     Init:ErrImagePull   0          28s   10.244.166.129   node1   <none>           <none>

#修改配置文件中的版本号为latest;在执行create;

kubectl get pods -n dev -o wide -w

NAME        READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
init-test   1/1     Running   0          18s   10.244.166.130   node1   <none>           <none>

4、钩子函数

Exec命令

在容器内执行一次命令

TCPSocket

在当前容器访问指定的Socket

HTTPGet

在当前容器中向某个url发送http请求

#钩子函数


#Exec命令:在容器内执行一次命令

    
lifecycle:
  postSatrt:
      exec:
         commmand:
         - cat
         - /tmp/healthy

#TCPSocket:在当前容器访问指定的Socket
    

lifecycle:
  postSatrt:
      tcpSocket:
          port: 8080

#HTTPGet:在当前容器中向某个url发送http请求
    

lifecycle:
   postSatrt:
       httpGet:
           path: / #URL地址
           port: 80 #端口号
           host: X.X.X.X #IP地址
           scheme: HTTP  #支持的协议,HTTP或者HTTPS
#配置钩子函数

vim poststart.yml

apiVersion: v1
kind: Pod
metadata:
  name: poststart
  namespace: dev
spec:
  containers:
  - name: nginxpod
    image: nginx:latest
    ports:
    - name: nginxport
      containerPort: 80
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
      preStop:
        exec:
          command: ["/usr/sbin/nginx", "-s", "quit"]


#查看运行状态

[root@master ~]# kubectl exec -it poststart -n dev -- /bin/sh
# cat /usr/share/nginx/html/index.html
postStart...

5.容器的探测和使用

        主要作用是检测pod中的容器是否正常工作,如果探测对象的pod没有达到预期的状态的话,那么kubernetes将会把出现问题的pod进行移除;

        kubernetes主要有一下两种探测的类型:

libeness probes

存活性探测

readiness probes

就绪性探针

(1)libeness probes

        主要决定是否重启容器,检测pod的资源是否处于正常状态,kubernetes根据状态绝对是否重启容器;

(2)readiness probes:

        主要决定是否将请求转发给容器,检测pod资源是否完成启动,可以接受请求,如过不是,kubernetes则不会向该pod转发流量 ;

———————————————————————————————————————————

        我们通过之前文章里面提到explain命令可以去查看livenessProbe下的资源清单:

kubectl expalin pod.spec.containers.livenessProbe

        我们可以得到很多很多英文,我也看不懂哈哈;所以通过某站老师的课做了个总结:

exec<object>

#

tcpSocket<object>

#

httpGet<object>

#

initialDelaySeconds <integer>

容器启动后等待多少秒执行第一次探测

timeoutDeconds <integer>

探测超过时间。默认和最小值都是1秒

periodSeconds <integer>

执行探测间隔多少时间,默认是10秒,最小是1秒

failureThreshold <integer>

连续探测失败多少次才被认定失败。默认的时候是3,最小值是1

successThreshold <integer>

连续探测成功多少次才被认定成功。默认是1

#测试,存活性探针

vim podliveness.yml

apiVersion: v1
kind: Pod
metadata:
  name: liveness-pod
  namespace: dev
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      exec:
        command: ["bin/cat", "/tmp/hello.txt" ] # nginx本身是没有hello.txt的文件,所以无法查看


# 查看创建的pod对象

# 因为nginx本身是没有hello.txt的文件所以 command没有办法执行存活测试所以不断重启
[root@master ~]# kubectl get pod -n dev -o wide -w
NAME           READY   STATUS    RESTARTS         AGE   IP               NODE    NOMINATED NODE   READINESS GATES

liveness-pod   1/1     Running   0                27s   10.244.166.167   node1   <none>           <none>

liveness-pod   1/1     Running   0                31s   10.244.166.167   node1   <none>           <none>

liveness-pod   0/1     CreateContainerError   0                31s   10.244.166.167   node1   <none>           <none>

liveness-pod   0/1     CreateContainerError   0                31s   10.244.166.167   node1   <none>           <none>

liveness-pod   1/1     Running                1 (2s ago)       32s   10.244.166.168   node1   <none>           <none>

liveness-pod   1/1     Running                1 (3s ago)       33s   10.244.166.168   node1   <none>           <none>

6.容器的重启策略

        重启策略是为了在我们进行探测的时候出现问题,kubernetes就会按照我们配置的重启策略对pod进行重启;

Always

容器失效时,自动重启容器(默认)

OnFailure

容器终止运行且退出码不为0时重启

Never

不论状态是什么都不会重启该容器

        我们使用上一步使用的liveness配配置文件,因为我们在配置文件中有一个command是查看容器中的Hello.txt文件,但是我们容器本身是没有的所以容器就会不断重启,我们使用重启策略设置从不重启;

vim podliveness.yml

apiVersion: v1
kind: Pod
metadata:
  name: liveness-pod
  namespace: dev
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      exec:
        command: ["bin/cat", "/tmp/hello.txt" ] # nginx本身是没有hello.txt的文件,所以无法查看
  restartPolicy: Never # 重启策略

二、Pod的调度

定向调度

NodeName、NodeSelector

亲和性调度

NodeAffinity、PodAffinity、PodAntiAffinity

污点(容忍)调度

Taints、Toleration

1.定向调度

NodeName:根据节点Node的名字进行定向调度;

apiVersion: v1
kind: Pod
metadata:
  name: nginx-nodename
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
      - name: nginx-port
        containerPort: 80
  nodeName: node1 # 通过nodename对pod进行定向调度

NodeSelector:根据节点Node的标签进行定向调度;

apiVersion: v1
kind: Pod
metadata:
  name: nginx-nodeselector
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
      - name: nginx-port
        containerPort: 80
  nodeSelector:
    test: run  # 通过标签为test=run对pod的进行定向调度

2.亲和性调度

        亲和性调度的原则:通过配置优先选择满足节点需求的Node上去,如果都不满足会分配到其他节点;如果有一些pod之间存在资源依赖的情况我们可以使用亲和性调度;如果一个应用,如nginx需要多个node上面至少有一个,我们可以使用反亲和性,这样可以提高资源的利用率;

(1)NodeAffinity

requiredDuringDchedulingIgnoredDuringExecution (硬限制,Node节点必须满足指定的所有条件才行)
    nodeSelectorTerms  节点选择列表
        matchFields  按节点字段列出的节点选择器要求列表
        matchExpressions  按节点标签列出的节点选择器要求列表 (一般这个比较推荐使用)
            key
            values
            operator 关系符, Exists,DoesNotExist,In,NotIn,Gt,Lt

preferredDuringSchedulingIgnoredDuringExecution (软限制,优先调度满足规则的Node上去)
    preference  一个节点选择器项,与相应的权重相关联
       matchFields  按节点字段列出的节点选择器要求列表
       matchExpressions  按节点标签列出的节点选择器要求列表 (一般这个比较推荐使用)
            key
            values
            operator 关系符, Exists,DoesNotExist,In,NotIn,Gt,Lt
    weight # 权重 1-100


# 关系符使用说明

- matchExpressions:
 - key: nodetest
   operator: Exists  # 匹配存在标签的key为nodetest的节点
 - key: nodetest
   operator: In      # 匹配标签的key为nodetest的节点,且value是x或者y的节点
   value: ["x","y"]
 - key: nodetest
   operator: Gt      # 匹配标签的key为nodetest的节点,且value大于x的节点
   values: "x"

##其他的都是以此类摧!!!
#硬限制

apiVersion: v1
kind: Pod
metadata:
  name: pod-affinity
  namespace: test
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.17.1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:#硬限制
        nodeSelectorTerms:
        - matchExpressions:#匹配存在nodeenv标签的node加入进去
          - key: nodeenv
            operator: Exists #In,该类型需要多一个value字段,会同时符合key的值的情况下也要复合values中的一个;
           #values: ["pro","max"]

#软限制

apiVersion: v1
kind: Pod
metadata:
  name: pod-aaffinity
  namespace: test
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.17.1
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:#软限制
      - weight: 1
        preference:
          matchExpressions:
          - key: nodeenv
            operator: In
            values: ["xxx","yyy"]   # 优先找符合要求的,没有则选择其他

nodeAffinity注意事项:

1.如果同时定义了nodeAffinity和nodeSelector,那么必须两个条件都满足,pod才能运行到指定的node上去;

2.如果nodeAffinity指定了多个nodeSelectorTerms,那么只需要其中一个能满足就能匹配成功

3.如果一个nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有的才能匹配成功

4.如果一个pod所在的Node在pod运行期间其标签发生了改变,不再符合该pod的节点亲和性需求,则系统将忽略此变化

(2) podAffinity

requiredDuringDchedulingIgnoredDuringExecution (硬限制)
    namespaces  #指定pod的名称空间
    topplogKey  #指定调度作用域
    labelSelector #标签选择器
        matchExpressions  #按节点标签列出的节点选择器要求列表 (一般这个比较推荐使用)
            key
            values
            operator #关系符, Exists,DoesNotExist,In,NotIn.
        matchLabels  #指定多个matchExpressions映射的内容

preferredDuringSchedulingIgnoredDuringExecution (软限制)
    podAffinityTerm #选项
        namespaces  #指定pod的名称空间
        topplogKey  #指定调度作用域
        labelSelector #标签选择器
            matchExpressions  #按节点标签列出的节点选择器要求列表 (一般这个比较推荐使用)
                key
                values
                operator #关系符, Exists,DoesNotExist,In,NotIn.
            matchLabels  #指定多个matchExpressions映射的内容
    weight 权重1-100

#topplogKey指定调度作用域如下

1.如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围;

2.如果指定beta.kubernetes.io/os,则以Node节点的操作系统类型来区分;
#测试,我们举一个例子,环境,先准备一个标签为run:pro的pod,使用nodename定向调度到node1上去;
apiVersion: v1
kind: Pod
metadata:
  name: pod
  namespace: test
  labels:
    run: pro
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.17.1
  nodeName: node1
#我们创建一个新的pod,使用In,亲和性调度,让他根据标签调度到Node1上去;
apiVersion: v1
kind: Pod
metadata:
  name: podaff
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: run
            operator: In
            values: ["pro","xxx"]
        topologyKey: kubernetes.io/hostname

(3)podAntiAffinity

apiVersion: v1
kind: Pod
metadata:
  name: podaff
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:
    podAntiAffinity: #反亲和性
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: run
            operator: In
            values: ["pro","xxx"]
        topologyKey: kubernetes.io/hostname

3.调度、污点、容忍

        污点:

        站在node的角度,在node的上面配置一些污点属性,来决定是否通过pod调度过来;如果node上面配置了污点属性,那么将拒绝pod进来,也可以将不符合污点的正在运行的pod驱逐出去。kubernetes在创建的时候 master节点会自动创建一个污点,所以pod不会调度到master节点上去;

        污点的格式为:key=value:effect, key和value是污点的标签,effect是描述污点,支持下面三个选项:

PreferNoDchedule尽量不要来,除非没有办法
NoSchedule新的就不要来了,本来的就不要动了
NoExecute新的也不要来了,本来的也赶紧走
#设置污点

kubectl taint nodes node1 key=value:effect

#去除污点

kubectl taint nodes node1 key:effect-

#去除所有污点

kubectl taint nodes node1 key-

#测试演示

1.给node1增加一个test=1的污点,设置为PreferNoSchedule

[root@master ~]# kubectl taint nodes node1 test=1:PreferNoSchedule
node/node1 tainted

2.去除node1的污点

[root@master ~]# kubectl taint nodes node1 test:PreferNoSchedule-
node/node1 untainted

3.去除所有污点

[root@master ~]# kubectl taint nodes node1 test-

容忍:

        我们可以在node上面添加污点拒绝pod调度进来,但是如果非要pod调度到有污点的node上面来 我们可以用到容忍;

key

对应着要容忍的污点的键,空意味着匹配所有的键

value对应着要容忍的污点的值
operatorkey-value的运算符,支持Equal和Exists(默认)
effect对应污点的effect,空意味着匹配所有影响
tolerationSeconds容忍时间,当effect为NodeExecte时生效,表示pod在Node上的停留时间
apiVersion: v1
kind: Pod
metadata:
  name: pod
  namespace: test
  labels:
    run: pro
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.17.1
  tolerations:          # 添加容忍
  - key: "run"
    operator: "Equal"   # 操作符 默认的话是Exists 这样就不需要value 只要key匹配上去那就容忍
    value: "run"        # 污点的value
    effect: "NoExecute" # 必须和node的污点相同

Pod基本上主要的内容都已经完成了,下面就是控制器什么,以上有问题的可以在评论区指出,共同学习,这么多我也记不住,哈哈哈哈!

### Kubernetes Pod 使用指南与常见问题排查 #### 什么是 Kubernetes PodKubernetes 中的 Pod 是最小的部署单元,它代表集群中运行的一个进程实例。一个 Pod 可能包含一个或多个容器,这些容器共享存储、网络以及如何控制它们的运行方式的规格定义[^1]。 #### 如何查看 Pod 列表及其状态? 可以使用 `kubectl get pods` 命令来获取当前命名空间下所有的 Pod 列表。然而,此命令仅返回基本信息,如名称、状态和重启次数等。为了更深入地了解某个特定 Pod 的情况,可执行以下命令: ```bash kubectl describe pod <pod-name> ``` 这将展示有关该 Pod 更详细的日志信息和其他元数据,有助于进一步分析潜在的问题所在[^2]。 #### 解决镜像拉取超时问题 当节点上的新启动 Pods 数量过多时,可能会因为大量镜像下载请求而发生排队现象。特别是如果有较大尺寸的镜像正在被加载,则后续等待的小型镜像对应的 Pods 很容易遇到时间限制错误——即所谓的“拉取超时”。默认情况下,kubelet 设置为串行模式 (`--serialize-image-pulls=true`) 下载图像文件;对于某些环境配置来说(比如 Docker 版本低于 1.9 或者采用 Aufs 存储后端),不建议更改这一参数设置以免引发其他兼容性难题[^3]。 如果频繁遭遇此类状况,考虑优化如下几个方面: - 提升宿主机带宽资源; - 缩短单个镜像大小或者分拆成若干个小部分分别上传至仓库; - 调整 kubelet 参数允许并行处理更多任务(需谨慎操作)。 #### 寻求外部支持 即便遵循以上指导原则仍未能有效缓解实际场景中的困难时刻,不妨求助于活跃的技术交流平台诸如 Stack Overflow、GitHub Issues 讨论区或是加入官方维护团队运营下的 Slack 工作组等等渠道分享具体案例描述寻求同行协助解答疑惑。 ```python import subprocess def check_pod_status(pod_name): result = subprocess.run(['kubectl', 'get', 'pods', pod_name], stdout=subprocess.PIPE) return result.stdout.decode('utf-8') print(check_pod_status('<your-pod-name>')) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值