Kubernetes之管理pod资源对象

1.  概念

    pod对象是一组容器的集合,这些容器共享Network,UTS及IPC名称空间,因此具有相同的域名,主机名和网络接口,并可通过IPC直接通信。

    为一个pod对象中的各容器提供网络名称空间等共享机制的是底层基础容器pause。

    

2.  定义一个pod对象  

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
     app: nginx
spec:
  containers:      #必选项       
  - name: nginx    #必选字段
    image: nginx    #可选项

3.  镜像及其获取策略

    工作节点上运行容器运行引擎,启动容器时,首先在本地查找指定的镜像文件,不存在的镜像从指定的镜像仓库下载至本地

    imagepullpolicy字段有三个值:

      always:  镜像标签为latest或镜像不存在时总是从指定的仓库拉取镜像

      IfNotPresent:  仅当本地镜像缺失时才从目标仓库下载镜像    

      Never:  禁止从仓库下载镜像,仅使用本地镜像

    对于标签为latest的镜像文件,其默认的镜像获取策略为Always

    对于标签为其他标签的镜像,其默认策略为IfNotPresent

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
     app: nginx
spec:
  containers:      
  - name: nginx    
    image: nginx:latest
    imagePullPolicy: Always

4.  暴露端口

    ports字段的值是一个列表,它常用的嵌套字段包括以下几个

      containerPort:  必选字段,指定在pod对象的IP地址暴露的容器端口,有效范围(0,65535)

      name:  当前端口的名称       

      protocol:  端口相关的协议,默认为TCP

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
     app: nginx
spec:
  containers:      
  - name: nginx    
    image: nginx:latest
    imagePullPolicy: Always
    ports:
    - name: http
      containerPort: 80
      protocol: TCP  

5.  环境变量  

    向pod对象中的容器环境变量传递数据的方法有两种:env和envFrom

    需要在容器配置段中嵌套使用env字段

    环境变量通常由name和value字段构成

      name:  环境变量的名称,必选字段

      value:  传递给环境变量的值,通过$(VAR_NAME)引用

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
     app: nginx
spec:
  containers:      
  - name: nginx    
    image: nginx:latest
    imagePullPolicy: Always
    ports:
    - name: http
      containerPort: 80
      protocol: TCP
    env:
    -  name: TOMCAT_IP
       value: 192.168.1.100
    -  name: LOG_LEVEL
       value: info

6.  共享节点的网络名称空间  

    同一个pod对象的各容器均运行于一个独立的隔离的Network名称空间中,共享同一个网络协议栈及相关的网络设备   这是a

    特殊的pod对象:以kubeadm部署的kubernetes集群中的kube-apiserver 、 kube-controller-manager   kube-scheduler ,以及 kube-proxy 和 kube-flannel       这是b   
    

    当需要把一个pod对象修改为共享节点网络名称空间的pod对象,只需要把spec.hostNetwork设置为true   

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/config.hash: 70a49ea9b8a3a74014b8cd2183400ff6
    kubernetes.io/config.mirror: 70a49ea9b8a3a74014b8cd2183400ff6
    kubernetes.io/config.seen: "2021-11-01T17:06:41.487417494+08:00"
    kubernetes.io/config.source: file
  creationTimestamp: "2021-11-01T09:08:32Z"
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver-k8s-master
  namespace: kube-system
  resourceVersion: "458"
  selfLink: /api/v1/namespaces/kube-system/pods/kube-apiserver-k8s-master
  uid: 0a4b6519-e4d6-412b-9f7b-f43bb4ab5ba1
spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=172.16.1.232
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --enable-admission-plugins=NodeRestriction
    - --enable-bootstrap-token-auth=true
    - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
    - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
    - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
    - --etcd-servers=https://127.0.0.1:2379
    - --insecure-port=0
    - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
    - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
    - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
    - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
    - --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
    - --requestheader-allowed-names=front-proxy-client
    - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
    - --requestheader-extra-headers-prefix=X-Remote-Extra-
    - --requestheader-group-headers=X-Remote-Group
    - --requestheader-username-headers=X-Remote-User
    - --secure-port=6443
    - --service-account-key-file=/etc/kubernetes/pki/sa.pub
    - --service-cluster-ip-range=10.1.0.0/16
    - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
    - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
    image: registry.aliyuncs.com/google_containers/kube-apiserver:v1.16.0
    imagePullPolicy: IfNotPresent
    livenessProbe:
      failureThreshold: 8
      httpGet:
        host: 172.16.1.232
        path: /healthz
        port: 6443
        scheme: HTTPS
      initialDelaySeconds: 15
      periodSeconds: 10
      successThreshold: 1
      timeoutSeconds: 15
    name: kube-apiserver
    resources:
      requests:
        cpu: 250m
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /etc/ssl/certs
      name: ca-certs
      readOnly: true
    - mountPath: /etc/pki
      name: etc-pki
      readOnly: true
    - mountPath: /etc/kubernetes/pki
      name: k8s-certs
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  hostNetwork: true
  nodeName: k8s-master
  priority: 2000000000
  priorityClassName: system-cluster-critical
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    operator: Exists
  volumes:
  - hostPath:
      path: /etc/ssl/certs
      type: DirectoryOrCreate
    name: ca-certs
  - hostPath:
      path: /etc/pki
      type: DirectoryOrCreate
    name: etc-pki
  - hostPath:
      path: /etc/kubernetes/pki
      type: DirectoryOrCreate
    name: k8s-certs

    注:在pod对象中还可以分别使用spec.hostPID和spec.hostIPC来共享工作节点的PID和IPC名称空间  

7.  标签与标签选择器

    1.  标签概述

        常用的标签

          版本的标签:"releaset" : "stable"

          环境的标签:"environment" : "dev"

          应用的标签:“app” : "ui"

          架构层级标签: "tier" : "frontend"

          分区标签:"partition" : "cutstomerA"

          品控级别标签:"track" : "daily"

        标签名称最多63个字符,要么为空,要么是以字母或数字开头及结尾,且中间仅适用了字母,数字,连接号(-),下划线或点号等字符的数据

    2.  管理资源标签

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
     app: nginx
spec:
  # nodeName: node01
  nodeSelector:
    env_role: dev
  containers:
  - name: nginx
    image: nginx

        1.  可以在yaml文件指定资源的标签

        2.  查看pod的标签

            kubectl get pods --show-labels  查看所有的pod的信息,包含标签

            kubectl get pods -L app  查看所有pod的信息,包含标签app

        3.  添加pod的新标签

            kubectl label pods/tomcat-order-64746fddd8-qfknd appname=yang

        4.  强制覆盖原有的键值

            kubectl label pods/tomcat-order-64746fddd8-qfknd appname=yi --overwrite

            kubectl label pod tomcat-order-64746fddd8-qfknd appname=yi --overwrite

        5.  删除pod的标签

            kubectl label pod tomcat-order-64746fddd8-qfknd appname-

    3.  标签选择器

        1.  标签选择器的逻辑

            1.  同时指定多个选择器之间的逻辑关系为"与"

            2.  使用空值的标签选择器意味着每个资源对象都将被选中

            3.  空的标签选择器将无法选出任何资源

            4.  标签选择器用于表达标签的查询条件:基于等值关系以及基于集合关系                

        2.  基于等值关系

            等值关系的操作符:"="   "=="   "!="

            kubectl get pod -l "appname=luo" -L appname  获取等于luo的pod

            kubectl get pod -l "appname!=luo" -L appname  获取不等于luo的pod

            kubectl get pod -l "appname!=luo,app=tomcat-adapter" -L appname  获取获取appname不等于luo,并且app等于tomcat-adapter的pod

        3.  基于集合关系                            

            集合关系的操作符:“in” "notin"  "exists"

            kubectl get pod -l "app in (tomcat-backend,tomcat-cachemq)" 

            kubectl get pod -l "app notin (tomcat-backend,tomcat-cachemq)"

            kubectl get pod -l '!tomcat-order'  注意要是用单引号,因为shell会解释感叹号

        4.  常用的标签选择器

            matchLabels:  通过直接给定键值对来指定标签选择器

            matchExpressions:  基本表达式指定的标签选择器列表 

 

selector :
matchLabels:
component: redis
matchExpressions:
- {key : tier , operator : In , values : [cache]}
- {key : environment, operator: Exists , values : }

    4.  pod节点选择器nodeSelector       

        设置一个节点的标签

          kubectl label node k8s-node2 app=product

        查看节点的标签

          kubectl describe node k8s-node2 

        查看具有某个标签的节点信息

          kubectl get node -l "app=product"

        删除节点的标签

          kubectl label node k8s-node2 app-  在标签后面加一个减号  

        修改节点的标签

          kubectl label node k8s-node1 app=haha --overwrite  覆盖原来的标签   

8.  资源注解

     注解也是key-value类型的数据,仅用于为资源提供"元数据"信息      

    1.  查看资源注解

        kubectl describe pods         

        annotations字段

    2.  设置资源注释

        kubectl annotate pods tomcat-adapter-646b7fccd4-t4rn7 name="后台adapter"

        

9.  pod对象的生命周期 

    pod对象从其创建开始至其终止退出的时间范围称为其生命周期

    1.  pod的几个阶段

        1.  pending  API Server创建了pod资源对象并已存入了etcd中,但它尚未被调度完成或者仍处于从仓库下载镜像的过程中

        2.  running  pod已经被调度到某节点,并且所有容器都已经被kubelet创建完成 

        3.  succeeded  pod中的所有容器都已经成功终止并且不会被重启

        4.  failed  所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态或已经被系统终止 

        5.  unknown  api server无法正常获取到pod对象的状态信息,通常是由于其无法与所在工作节点的kubelet通信所致 

    2.  pod的创建过程 

        1.  用户通过kubectl或其它api客户端提交pod spce给API Server

        2.  API Server尝试着将pod对象的相关信息存入etcd中,待写入操作执行完成,API Server即会返回确认信息至客户端

        3.  API Server开始反映etcd中的状态变化

        4.  所有的 Kubernetes 组件均使用“ watch ”机制来跟踪检查 API Server 的相关的变动        

        5.  kube-scheduler (调度器)通过其“ watcher ”觉察到 API Server 创建了新的 Pod 但尚未绑定至任何作节点

        6.  kube-scheduler 为 Pod 对象挑选作节点并将结果信息更新至 API Server 

        7.  调度结果信息由 API Server 更新至 etcd 存储系统,而且 API Server 也开始反映此Pod 对象的调度结果

        8.  Pod 被调度到的目标工作节点上的 kubelet 尝试在前节点上调用 Docker 启动容器,并将容器的结果状态回送至 API Server

        9.  API Server 将 Pod 状态信息存入 etcd 系统中

        10.  在etcd 确认写入操作成功完成后 API Server 将确认信息发送相关的 kubelet,事件将通过它被接受

        

    3.  pod生命周期中的重要行为

        1.  初始化容器

            应用程序的主容器启动之前要运行的容器,常用于为主容器执行一些预置操作

apiVersion : vl
kind : Pod
metadata :
  name : myapp-pod
  labels :
    app : myapp
spec:
  containers :
  - name : myapp-container
    image : ikubernetes/myapp:vl
  initContainers:
  - name: init-something
    image : busybox
    command .: [ 'sh','-c','sleep 10' ]          

            1.  初始化容器典型特征

                1.  初始化容器必须运行完成直至结束,若运行失败,那么k8s需要重启它直到成功完成。

                2.  多个初始化容器都必须按定义的顺序串行运行

            2.  初始化容器应用场景

                1.  用于运行特定的工具程序,出于安全等方面的原因,这些程序不适合包含在主容器镜像中。

                2.  提供主容器镜像中不具备的工具程序或自定义代码

                3.  初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足    

        2.  生命周期钩子函数

            postStart  容器创建完成之后立即运行的钩子处理器

            preStop  容器终止操作之前立刻运行的钩子处理器            

apiVersion : vl
kind : Pod
metadata :
  name : lifecvcle-demo
spec :
  containers :
  - name : lifecycle-demo-container
    image : ikubernetes/myapp:vl
    1ifecycle :
      postStart :
        exec :
          command: [" /bin/sh","-c","echo ' lifecycle hooks handler ' > /usr/share/nginx/html/test.html"]

        3.  容器探测

            1.  livenessProbe

                如果检查失败,将杀死容器,根据pod的restartPolicy来操作

            2.  readinessProbe

                如果检查失败,kubernetes会把pod从service endpoints中剔除  

        4.  容器的重启策略             

            1.  Always:  当容器停止,总是重建容器,默认策略  

            2.  OnFailure:  当容器异常退出时,才重启容器

            3.  Never:  当容器终止退出,从不重启容器

        5.  pod的终止过程

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

            2.  API服务器中的pod对象会随着时间的推移而更新,在宽限期内(默认为30秒),pod被视为dead

            3.  将 Pod 标记为“ Terminating ”状态

            4.  (与第 3 步同时运行) kubelet 在监控到 Pod 对象转为“ Terminating ”状态的同时启动 Pod 关闭过程

            5.  (与第 3 步同时运行)端点控制器监控到 Pod 对象的关闭行为时将其从所有匹配到此端点的 Service 资源的端点列表中移除

            6.  如果当前 Pod 对象定义了 pre Stop 钩子处理器,则在其标记为“ te rminating ” 后即会以同步的方式启动执行;如若宽限期结束后, preStop 仍未执行结束,则第 2 步会被重新执行并额外获取个时长为 2 秒的小宽限期

            7.  Pod 对象中的容器进程收到 TERM 信号

            8.  宽限期结束后,若存在任何一个仍在运行的进程,那么 Pod 对收到 SIGKILL信号

            9.  Kubelet 请求 API Server 将此 Pod 资源的宽限期设置为 0 从而完成删除操作,它变得对用户不再可见

            默认情况下,所有删除操作的宽限期为30秒,手动修改宽限期kubectl delete --grace-period=<seconds>   

    4.  pod存活性探测

        1.  设置exec探针

            在目标容器中执行由用户自定义的命令来判定容器的健康状态,若命令状态返回值为0表示成功,否则失败

apiVersion : vl
kind : Pod
metadata :
labels :
test : liveness-exec
name : liveness-exec
spec :
containers :
- name : liveness-exec demo
image : busybox livenessProbe :
exec :
command :["test","-e","/tmp"]

        2.  设置HTTP探针

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /index.html
        port: 80   

        3.  设置TCP探针

apiVersion : vl
kind : Pod
metadata :
labels :
test : 1 工veness
name : liveness - tcp
spec .
containers .
- name : liveness-tcp-demo
image : nginx : l.12-alpine
ports :
- name : http
containerPort : 80
livenessProbe :
tcpSocket :
port : http

    5.  pod就绪性探测

        用来判断容器就绪与否的周期性(默认周期为10s)                  

        支持Exec,http GET ,TCP Socket三种探测方式

apiVersion : vl
kind : Pod
metadata:
  labels:
    test : readiness-exec
  name : readiness-exec
spec :
  containers :
  - name : readiness-demo
    image : busybox
    args : ["/bin/sh","-c","while true; do rm - f /tmp/ready ; sleep 30 ; touch /tmp/ready ; sleep 300 ; done"]
    readinessProbe:
      exec :
        command : ["test" , "-e" ,"/tmp/ready"]
      initialDelaySeconds : 5
      periodSeconds : 5

    5.  资源需求及资源限制

        requests  容器运行可能用不到这些资源,软限制

        limits  用于限制资源可用的最大值,硬限制

        CPU:  1个单位的CPU相当于虚拟机上的一颗虚拟CPU或者物理机上的一个超线程,一个核心(1 core)相当于1000个millicore  可压缩型资源

        内存:  默认单位字节,使用E,P,T,G,M,K,也可以使用Ei,Pi,Ti,Gi,Mi,Ki形式的单位后缀  不可压缩型资源

        1.  资源需求

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
     app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      requests:  最低要求  
        memory: "64Mi"
        cpu: "250m"  相对的权重值

        2.  资源限制                      

            当内存超出limits的限制时,pod对象会被OOMKilled

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
     app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      requests:  最低要求  
        memory: "64Mi"
        cpu: "250m"  相对的权重值
      limits:    最高要求   
        memory: "128Mi"
        cpu: "500m"

            当内存资源到limits时,pod对象被终止并重启,多次重启会触发k8s的重启延迟机制。10秒,20秒,40秒,80秒,160秒,300秒,最后固定在5分钟不再增加  

            对于总数为1000m 的 CPU 资源来说,容器 A 请求使用 200m ,容器 B 请求使用 500m,在不超出它们各自 最大的前提下,余下 的 300m 在双方都需要以 2:5 ( 200m:500m)的方式进行配置

        3.  pod的服务质量类别

            当内存不足时,发生OOMKilled,但是会终止哪些pod对象呢?

            k8s会根据把pod对象分为三个服务质量

              1.  Guaranteed

                  每个容器都配置了requests和limits属性,这类pod资源具有最高优先级

              2.  Burstable

                  至少有一个容器配置了requests属性,这类pod属于中级

              3.  BestEffort

                  没有任何容器配置requests或limits,这类pod最低级别

              k8s按照优先级别,从低到高,终止pod.

              如果级别相同,与自身的requests属性相比,内存占比大的先被杀死

posted @ 2022-05-13 13:56  奋斗史  阅读(107)  评论(0)    收藏  举报