• Pod


              user containerN
              user imageN
              
               ......
               
               user contaner1
               user image1
               
                   Pause
       gcr.io/google_containers/pause-amd64
    

    每个Pod中都可以包含一个或者多个容器,这些容器可以分为两类:

    • 用户程序所在的容器,数量可多可少
    • Pause容器,这是每个Pod都会有一个根容器,它的作用有两个 : 1.可以以它为依据,评估整个Pod的健康状态。2.可以在根容器上设置IP地址,其他容器共享此IP,实现pod内部的网络通信
    这里是Pod的内部通信,Pod之间的通信采用虚拟二层网络技术来实现,当前环境使用的是flanne

    Pod的定义

    以下是Pod的资源清单,也就是yml配置

    apiVersion: v1  #必选,版本号
    kind: Pod  #必选,资源类型,例如Pod,service,deployment
    metadata:   #必选,元数据
      name: string #必选,Pod名称
      namespace: string  #Pod所在的名称空间,默认为“default”
      labels:  #自定义标签
        - name: string
    spec: #必选,Pod中容器的详细定义
      containers: #必选,Pod中容器列表
      - name: string #必选,容器名称
        image: #必选,容器镜像名称
        imagePillPolicy: [Always|Never|IfNotPresent] #获取镜像策略
        command: [string] #启动容器的命令参数列表,如不指定,使用打包时使用的启动命令
        args: [string] #容器启动的参数列表
        workingDir: string  #容器的工作目录
        volumeMounts: #挂载到容器内部的存储卷配置
        - name: string #引用pod定义的共享存储卷民初,需要使用volumes[]部分定义的卷名
          mountPath: string #存储卷在容器mount的绝对路径
          readOnly: boolean #是否为只读模式
        ports: #需要暴露的端口库号列表
        - name: string  #端口的名称
          containerPort: int #容器需要监听的端口号
          hostPort: int #容器所在主机需要监听的端口号,默认于Container相同
          protocol: string #端口协议默认TCP
        env: # 容器运行前设置环境变量列表
        - name: staring # 环境变量名称
          value: 环境变量值
        resources: #资源现在和请求的设置
          limits: #资源限制的设置
            cpu: string #cpu限制,单位为core数,将用于docker run --cpu-share参数
            memory: string # 内存限制,单位Mib/Gib,将用于docker run --memory参数
          requests: #资源请求的设置
            cpu: string #cpu请求,容器启动的初始可用数量
            memory: string #内存请求,容器启动的初始可用量
        lifecycle: #生命周期钩子
            postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
            preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
        livenessProbe: #对Pod内各个容器健康检查的设置,当探测无响应几次后将自动重启该容器
          exec: #对Pod容器内检查方式设置为exec方式
            command: [string] #exec方式需要自定的命令或脚本
          httpGet: #对Pod内容器检查方式设置我Httpget,需要制定path,port
            path: string
            port: int
            host: string
            scheme: string
            HttpHeaders:
            - name: string
              value: string
          tcpSocket: #对Pod容器健康检查方式这种问tcpSocket方式
              port: number
            initialDelaySecondes: 0 #容器启动完成后首次探测的时间,单位为秒
            timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
            periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
            successThreshold:0
            failuerThreshold:0
            securityContext:
              privileged: false
    restarPolicy: [Always|Never|OnFailure] #Pod的重启策略
    nodeName: <string> #设置NodeName表示将该Pod调度到指定名称的node节点上
    nodeSeletor: obeject #设置NodeSeletor表示将该Pod调度到包含这个label的node上
    imagePullSecrets:#Pull镜像时使用的Secret名称,以Key:secretkey格式指定
    - name: string
    hostNetwork: false  #是否使用主机网络模式,默认false
    voulmes: #在该Pod上定义共享存储卷列表
    - name: string #共享存储卷名称(volumes类型有很多种)
      emptyDir: {} #类型为emtDir的存储卷,与Pod同生命周期的一个临时目录。为空值
      hostPath: string #类型为HostPath的存储卷,表示挂载Pod所在的宿主机的目录
        path: string  #pod所在的宿主机的目录,将被用于同期种mount的目录
      secret: #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
        secretname: string
        itmes:
        - key: string
          path: string
     configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器
       name:string
       items:
       - key: string
         path: string
    

     可以使用以下命令查询每种资源的配置方式

    # kubectl explain 资源类型
    # kubectl explain 资源类型.属性
    

    Pod配置

    创建一个pod-base.yml文件,内容如下

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-base
      namespace: dev
      labels:
        version: test
    spec: 
      containers:
      - name: nginx
        image: nginx:1.17.2
      - name: busybox
        image: busybox:1.30
    

    上面定义了一个比较简单的Pod的配置,里面有两个容器:

    • nginx: 用1.17.2版本的nginx镜像创建
    • busybox: 用1.30版本的busybox镜像创建
    #创建Pod
    kubectl apply -f pod-bose.yml
    
    #查看Pod状态
     kubectl  get pod -n dev
    NAME                     READY   STATUS             RESTARTS   AGE
    nginx-64777cd554-7p7xt   1/1     Running            2          31h
    nginx-64777cd554-cqbjd   1/1     Running            1          25h
    nginx-64777cd554-tv5g2   1/1     Running            2          31h
    pod-base                 1/2     CrashLoopBackOff   5          5m9s
    
    
    #可以通过describe查看内部的详情
    #此时已经运行了一个基本的pod,虽然出现了一些问题
    [root@master ~]# kubectl  describe  pod  pod-base -n dev
    ............
    Events:
      Type     Reason     Age                    From               Message
      ----     ------     ----                   ----               -------
      Normal   Scheduled  4m34s                  default-scheduler  Successfully assigned dev/pod-base to node1
      Normal   Pulling    4m31s                  kubelet, node1     Pulling image "nginx:1.17.2"
      Normal   Pulled     3m42s                  kubelet, node1     Successfully pulled image "nginx:1.17.2"
      Normal   Created    3m41s                  kubelet, node1     Created container nginx
      Normal   Started    3m40s                  kubelet, node1     Started container nginx
      Normal   Pulling    3m40s                  kubelet, node1     Pulling image "busybox:1.30"
      Normal   Pulled     3m22s                  kubelet, node1     Successfully pulled image "busybox:1.30"
      Normal   Created    2m39s (x4 over 3m22s)  kubelet, node1     Created container busybox
      Normal   Pulled     2m39s (x3 over 3m20s)  kubelet, node1     Container image "busybox:1.30" already present on machine
      Normal   Started    2m38s (x4 over 3m22s)  kubelet, node1     Started container busybox
      Warning  BackOff    2m8s (x8 over 3m19s)   kubelet, node1     Back-off restarting failed container
    

    镜像拉取

    创建pod-imagePullPolicy.yml文件,内容如下

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-imagepullpolicy
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.3
        imagePullPolicy: Always
      - name: busybox
        image: busybox:1.30
    

    imagePullPolicy,用于设置镜像拉取策略,kubernetes中支持配置的三种拉取策略

    • Always:总是从远程仓库拉取镜像
    • IfNotPresent: 本地有镜像则使用本地,没有则远程拉取
    • Never: 只能使用本地镜像,从不去远程拉取

    默认值说明:

    如果镜像tag为具体版本号,默认策略就是IfNotPersent

    如果镜像tag为latest,默认策略时always

    #创建Pod
    kubectl apply -f pod-imagePullPolicy.yml
    
    # 查看pod
    kubectl get pod -n dev
    
    # 查看详细信息
    kubectl get pod pod-imagepullpolicy -n dev 
    

    启动命令

    上面的容器案例中,有一个问题没有解决,就是busybox运行一直没有成功,因为busybox并不是一个程序,而是一个类似工具类的集合,kubernetes集群启动管理后,它会自动关闭,解决办法就是让其一直运行,就需要使用到command配置,

    vim pod-command.yml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-command
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
        imagePullPolicy: IfNotPresent
      - name: busybox
        image: busybox:1.30
        command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3;done"]
        
        
    # 创建pod
    kubectl apply -f pod-command.yml
    
    #查看状态,可以看到两个Pod都正常运行了
    [root@master ~]# kubectl  get pod  pod-command -n dev
    NAME          READY   STATUS    RESTARTS   AGE
    pod-command   2/2     Running   0          85s
    
    #进入pod中的busybox容器,查看文件内容
    kubectl exec pod-command -n dev --it -c  busybox /bin/sh
    

    说明:

    通过上面方向command已经可用完成启动命令和传递参数的功能,为什么这里还要通过args选项,用于传递参数?

    这其实和docker有点关系,kubernetes中的comand,arges两项其实是实现覆盖DockerfileHon中的ENTRYPOINT的功能。

    • 如果command和args均没有写,那么就用Dockerfile的配置。
    • 如果command写了,arges没有写,那么Dockerfile默认的配置会被忽略,执行输入的command
    • 如果command没写,但args写了,那么Dockerfile中配置的ENTRYPOINT的命令会被执行,使用当前args的参数
    • 如果command和args都写了,那么Dockerfile的配置被忽略,执行command并追加上args参数

    环境变量

    vim pod-env.yml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-env
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
        imagePullPolicy: IfNotPresent
      - name: busybox
        image: busybox:1.30
        command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3;done"]
        env:
        - name: "username"
          value: "admin"
        - name: "password"
          value: "123456"
    

     env,环境变量,用于Pod中容器设置环境变量

    # 创建Pod
    kubectl create -f pod-env.yml
    
    #进入容器查看环境变量
    [root@master ~]# kubectl exec pod-env -n dev -it -c busybox /bin/sh
    / # echo $username
    admin
    / # echo $password
    123456
    

     不推荐使用这种方式,推荐这些配置在单独存储的配置文件中

    端口设置

    vim pod-ports.yml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-ports
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
        imagePullPolicy: IfNotPresent
        ports:
        - name: nginx-port
          containerPort: 80
          protocol: TCP
    
    
    #启动pod
    kubectl create -f  pod-ports.yml
    
    # 查看
    kubectl get pod pod-ports -n dev
    

    资源配额

    容器中的程序要运行坑,而程序的运行肯定要占用一定的资源,如果不对某一个容器限定资源,可能会在某一瞬间吃掉大量的资源,导致其他容器无法运行。针对这种情况,kuberneters提供了对内存和cpu资源进行配额的机制,这个机制主要是在resources选项实现,其有两个子选线。

    • limits: 用于限制运行时容器的最大占用资源,当容器超过limits时会被终止,并进行重启
    • requests:用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动

    可用通过以上两个选项色泽资源的上下限

    vim pod-resources.yml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-resuorces
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            cpu: "1"
            memory: "1Gi"
          requests:
            cpu: "0.2"
            memory: "10Mi"
    
    
    # 运行pod
     kubectl  create -f pod-resources.yml
     
    # 查看pod
    kubectl  get pod pod-resuorces  -n dev
    

    Pod生命周期

    我们一般将pod对象从创建至终的这断时间范围称为pod的生命周期,它主要包含下面的过程:

    • Pod创建过程

    • 运行初始化容器过程

    • 运行主容器过程

      容器启动后钩子,容器终止前钩子

      容器的存活性探测,就绪性探测

    • pod终止过程

    在整个生命周期种Pod会出现5种状态(相位),分别如下;

    • 挂起(Pending):apiserver已经创建了Pod资源对象,但它尚未被调度完成或者仍处于镜像下载状态

    • 运行中(running):pod已经被调到至某节点,并且所有容器都已经被kubelet创建完成

    • 成功(Succeded): pod中的所有容器都已经成功并且不会被重启

    • 失败(Failed): 所有容器都已经终止,但至少有一个容器终止失败,即容器返回非0值的退出状态

    • 未知(Unkown): apiserver无法正常获取到pod对象的状态信息,通常由网络通信失败导致

    初始化容器

    初始化容器是在pod的主容器启动前需要运行的容器,主要是做一些主容器的前置工作,它具有两大特征:

    1.初始化容器必选运行完成至结束,若某一个初始化容器运行失败,那么kubernetes需要重启直到完成为止。

    2.初始化容器必选按照定义的顺序执行,当且仅当前一个成功之后,后面一个才能运行

    初始化容器由很多的应用场景,下面列出的是最常见的几个;

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

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

    示例:

    假设要以主容器来运行nginx,但是需要在运行nginx之前先要能够连接上MySQL和redis所在的服务器,为了简化测试,事先规定号MySQL(192.168.248.4)和redis(192.168.248.24)服务器的地址。

    创建pod-initcontainer.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-initcontainer
      namespace: dev
    spec:
      containers:
      - name: main-container
        image: nginx:1.17.2
        ports:
        - name: nginx-port
          containerPort: 80
      initContainers:
      - name: test-mysql
        image: busybox:1.30
        command: ['sh','-c','until ping 192.168.248.4 -c 1;do echo waiting for mysql ... ;sleep 2;done']
      - name: test-redis
        image: busybox:1.30
        command: ['sh','-c','until ping 192.168.248.24 -c 1;do echo waiting for redis ... ;sleep 2;done'] 
        
    # 启动pod
    kubectl create -f pod-initcontainer.yml 
    
    #查看状态
    [root@master ~]# kubectl  get pod pod-initcontainer -n dev
    NAME                READY   STATUS     RESTARTS   AGE
    pod-initcontainer   0/1     Init:0/2   0          18s
    
    #动态查看状态
    [root@master ~]# kubectl  get pod pod-initcontainer -n dev -w
    NAME                READY   STATUS     RESTARTS   AGE
    pod-initcontainer   0/1     Init:0/2   0          52s
    
    
    #新开一个窗口,为当前服务器增加两个IP
    ifconfig  ens33:1 192.168.248.4 netmask 255.255.255.0 up
    ifconfig  ens33:1 192.168.248.24 netmask 255.255.255.0 up
    
    [root@master ~]# kubectl  get pod pod-initcontainer -n dev -w
    NAME                READY   STATUS     RESTARTS   AGE
    pod-initcontainer   0/1     Init:0/2   0          52s
    pod-initcontainer   0/1     Init:1/2   0          2m37s
    pod-initcontainer   0/1     Init:1/2   0          2m38s
    pod-initcontainer   0/1     PodInitializing   0          2m51s
    pod-initcontainer   1/1     Running           0          2m52s
    

    钩子函数

    钩子函数能够感知自身生命周期中的事件,并在相应的时候到来之运行用户指定的程序代码。

    kubeernetes在主容器启动之后和停止之前提供了两个钩子函数:

    • post start: 容器创建之后执行,如果失败了会重启容器
    • pre stop: 容器终止之前执行,执行完后后容器将成功终止,在其完成之前会删除阻塞容器的操作

    钩子处理器支持使用下面三种方式定义动作:

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

    ......
        lifecycle:
          postStart:
            exec:
              command:
              - cat
              - /tmp/healthy
    ......
    

     TCPSocket: 在放弃容器尝试访问指定的socket

    .....
        lifecycle:
          postStart:
            tcpoSocket:
              port: 8080
    .....
    

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

    .....
        lifecycle:
          postStart:
            httpGet:
              path: / #url地址
              post: 80 #端口号
              host: 192.168.248.11 #主机地址
              scheme: HTTP #支持协议,http或者https
    ......  
    

     下面以exec方式为例,演示钩子函数的使用,创建pod-hook-exec.yml文件

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-hook-exec
      namespace: dev
    spec:
      containers:
      - name: main-container
        image: nginx:1.17.2
        ports:
        - name: nginx-pod
          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"]
    
    
    
    # 创建pod
    kubectl create -f pod-hook-exec.yml
    
    # 查看pod
    [root@master ~]# kubectl  get pod pod-hook-exec -n dev -o wide
    NAME            READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-hook-exec   1/1     Running   0          57s   10.244.1.43   node1   <none>           <none>
    
    # 访问测试
    [root@master ~]# curl 10.244.1.43
    postStart...
    

    容器探测

    容器探测用于检测容器中的应用示例是否正常工作,是保证业务可用性的一种传统机制。如果经过探测,示例的状态不符合预期,那块kubernetes就会把该问题实例"摘除",不承担业务流量。kubernetes提供了两种探针来实现容器探测,分别是:

    • liveness probes:存活性探针,用于检测应用实例当前是否处于正常运行状态,如果不是,ks会重启容器

    • rediness probes: 就绪性探针,用于检测应用实例当前是否可用接受到请求,如果不能,k8s不会转发流量

    上面两种探针目前均支持三种探测方式:

    Exec命令:在容器内执行一次命令,如果命令执行的退出吗为0,则程序认为正常,否则不正常

      livenessProbe: 
          exec:
            command:
            - cat 
            - /tmp/healthy
    

     TCPSocket:将会尝试访问一个用户容器的端口,如果能建立连接,则认为正常,否则不正常

     livenessProbe:
          tcpSocket:
            port: 8080
    

     HTTPGet:调用web应用url,如果返回在200-399,则认为程序正常,否则不正常

     lifecycle:
          postStart:
            httpGet:
              path: / #url地址
              post: 80 #端口号
              host: 192.168.248.11 #主机地址
              scheme: HTTP #支持协议,http或者https
    

    下面以liveness probes为例,做几个演示:

    创建文件pod-liveness.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-liveness
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          exec:
            command: ["/bin/cat","/tmp/hello.txt"]
    
    #创建pod
    [root@master ~]# kubectl create -f pod-liveness.yml 
    pod/pod-liveness created
    
    #查看pod详情
    [root@master ~]# kubectl describe pod pod-liveness -n dev
    ....................
    Events:
      Type     Reason     Age                From               Message
      ----     ------     ----               ----               -------
      Normal   Scheduled  <unknown>          default-scheduler  Successfully assigned dev/pod-liveness to node2
      Normal   Pulled     28s (x2 over 50s)  kubelet, node2     Container image "nginx:1.17.2" already present on machine
      Normal   Created    28s (x2 over 50s)  kubelet, node2     Created container nginx
      Normal   Started    28s (x2 over 50s)  kubelet, node2     Started container nginx
      Normal   Killing    28s                kubelet, node2     Container nginx failed liveness probe, will be restarted
      Warning  Unhealthy  8s (x5 over 48s)   kubelet, node2     Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory
    Events:
      Type     Reason     Age                From               Message
      ----     ------     ----               ----               -------
      Normal   Scheduled  <unknown>          default-scheduler  Successfully assigned dev/pod-liveness to node2
      Normal   Pulled     28s (x2 over 50s)  kubelet, node2     Container image "nginx:1.17.2" already present on machine
      Normal   Created    28s (x2 over 50s)  kubelet, node2     Created container nginx
      Normal   Started    28s (x2 over 50s)  kubelet, node2     Started container nginx
      Normal   Killing    28s                kubelet, node2     Container nginx failed liveness probe, will be restarted
      Warning  Unhealthy  8s (x5 over 48s)   kubelet, node2     Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory
    
    #因为没有hello.txt文件,存活性探针会一直重启这个Pod
    [root@master ~]# kubectl get  pod pod-liveness -n dev
    NAME           READY   STATUS    RESTARTS   AGE
    pod-liveness   1/1     Running   4          2m21s
    
    
    #正确示例
    [root@master ~]# kubectl delete -f pod-liveness.yml 
    pod "pod-liveness" deleted
    
    [root@master ~]# vim pod-liveness.yml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-liveness
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          exec:
            command: ["/bin/ls","/tmp"]
    
    # 创建pod
    [root@master ~]# kubectl create -f pod-liveness.yml 
    pod/pod-liveness created
    
    #创建成功并没有重启
    [root@master ~]# kubectl get  pod pod-liveness -n dev
    NAME           READY   STATUS    RESTARTS   AGE
    pod-liveness   1/1     Running   0          11s
    

    TCPSocket

    创建pod-liveness-tcpsocket.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-tcpsocket
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          tcpSocket:
            port: 8080   #尝试访问8080端口
    
    
    # 创建Pod
    [root@master ~]# kubectl create  -f pod-liveness-tcpsocket.yml 
    pod/pod-tcpsocket created
    
    #查看信息
    [root@master ~]# kubectl describe pod pod-tcpsocket -n dev
    ...........
    Events:
      Type     Reason     Age        From               Message
      ----     ------     ----       ----               -------
      Normal   Scheduled  <unknown>  default-scheduler  Successfully assigned dev/pod-tcpsocket to node1
      Normal   Pulled     15s        kubelet, node1     Container image "nginx:1.17.2" already present on machine
      Normal   Created    15s        kubelet, node1     Created container nginx
      Normal   Started    15s        kubelet, node1     Started container nginx
      Warning  Unhealthy  9s         kubelet, node1     Liveness probe failed: dial tcp 10.244.1.46:8080: connect: connection refused
    

    HTTPGet

    创建文件pod-liveness-httpget.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-httpget
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          httpGet:
            scheme: HTTP
            port: 80
            path: /
    
    
    # 创建pod
    [root@master ~]# kubectl  create -f  pod-liveness-httpget.yml 
    pod/pod-httpget created
    
    #查看pod详情
    [root@master ~]# kubectl describe  pod pod-httpget -n dev
    .............
    Events:
      Type    Reason     Age        From               Message
      ----    ------     ----       ----               -------
      Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned dev/pod-httpget to node2
      Normal  Pulled     29s        kubelet, node2     Container image "nginx:1.17.1" already present on machine
      Normal  Created    29s        kubelet, node2     Created container nginx
      Normal  Started    29s        kubelet, node2     Started container nginx
    [root@master ~]# vim pod-liveness-httpget.yml
    

    重启策略

    一旦容器探测出现了问题,kubernetes就会对容器所在的Pod进行重启,其实这是由pod重启策略决定的,pod的重启策略有3种,分别是:

    • Always: 容器失效时,自动重启该容器,这也是默认从值

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

    • Never: 不论状态为何,都不重启该容器

    重启策略适用于pod对象中的所有容器,首次需要重启的容器,将在其需要时立即进行重启,随后在次需要重启的操作将由kubelet延迟一段时间后进行,并且反复的重启操作的延迟时长为10s,20s,40s,80s,160s和300s,300s是最大延迟时长。

    创建pod-restarpolicy.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-restartpolicy
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          httpGet:
            scheme: HTTP
            port: 80
            path: /hello
      restartPolicy: Never
      
    # 创建Pod
    [root@master ~]# kubectl  create -f pod-restartpolicy.yml 
    pod/pod-restartpolicy created
    
    # 查看Pod详情发现nginx容器重启失败
    [root@master ~]# kubectl  describe pod pod-restartpolicy -n dev
    .......
    Events:
      Type     Reason     Age                   From               Message
      ----     ------     ----                  ----               -------
      Normal   Scheduled  <unknown>             default-scheduler  Successfully assigned dev/pod-restartpolicy to node1
      Normal   Pulled     2m20s                 kubelet, node1     Container image "nginx:1.17.2" already present on machine
      Normal   Created    2m20s                 kubelet, node1     Created container nginx
      Normal   Started    2m19s                 kubelet, node1     Started container nginx
      Warning  Unhealthy  114s (x3 over 2m14s)  kubelet, node1     Liveness probe failed: HTTP probe failed with statuscode: 404
      Normal   Killing    114s                  kubelet, node1     Stopping container nginx
    
    # 由于策略定义的是Never所以容器不会重启
    [root@master ~]# kubectl  get pod pod-restartpolicy -n dev
    NAME                READY   STATUS      RESTARTS   AGE
    pod-restartpolicy   0/1     Completed   0          3m41
    

    Pod调度

    在默认情况下,一个Pod在那个Node节点上与性能,是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的,但是在实际使用中,这并不能满足需求,因为在很多情况下,我们想控制某些Pod到达某些节点上,应该怎么做呢?这就需要了解Kubernetes对Pod的调度规则,kubernetes提供了四大类的调度。

    • 自动调度: 运行在那个节点上完全由Scheduler经过一系列是算法得出

    • 定性调度: NodeName,NodeSelector

    • 亲和性调度: NodeAffinity,PodAffinity,PodAntiAffinity

    • 污点(容忍)调度: Taints,Toleration

    定向调度

    定向调度,指的是利用在Pod上声明的NodeName或者NodeSelector,以此将Pod调度到期望的node节点上。注意,这里的调 是强制的,这就意味着即使要调度的目标Node不存在,也会向上面进行调度,只不过是Pod运行失败而已。

    NodeName

    NodeName用于强制约束将Pod调度到指定的node上,着种方式直接跳过了Scheduler的调度逻辑,直接写入PodList列表中

    测试一些,创建一个pod-nodename.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-nodename
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
      nodeName: node1
    
    # 创建pod
    [root@master ~]# kubectl  create -f pod-nodename.yml 
    pod/pod-nodename created
    
    # 查看pod调度到Node属性,确实调度到了node1节点上
    [root@master ~]# kubectl  get pod pod-nodename -n dev -o wide
    NAME           READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-nodename   1/1     Running   0          69s   10.244.1.56   node1   <none>           <none>
    

    NodeSeletor

    NodeSeletor用于将Pod调度到添加了指定标签的node节点上,它通过kubernetes的label-selector机制实现,也就是说,在Pod创建之前,会有scheduler使MatchNodeSelector调度策略进行label匹配,找出目标node,然后将Pod调度到目标节点,该匹配规则是强制约束。

    示例:

    # 首先分别给node节点加上标签
    [root@master ~]# kubectl label nodes node1 nodeenv=pro
    node/node1 labeled
    [root@master ~]# kubectl label nodes node2 nodeenv=dev
    node/node2 labeled
    
    # 创建一个pod-nodeselector.yml文件,并使用它创建pod
    vim pod-nodeselector.yml
    apiVersion: v1
    kind: Pod
    metadata:
     name: pod-nodeselector
     namespace: dev
    spec:
     containers:
     - name: nginx
       image: nginx:1.17.2
     nodeSelector:
       nodeenv: dev
       
    #创建Pod
    [root@master ~]# kubectl  create -f pod-nodeselector.yml 
    pod/pod-nodeselector created
    
    #查看pod调度到NODE属性,确实调度到了node2节点上
    [root@master ~]# kubectl  get pod pod-nodeselector -n dev -o wide
    NAME               READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-nodeselector   1/1     Running   0          22s   10.244.2.74   node2   <none>           <none>
    
    # 删除Pod,修改nodeSelector的值为一个不存在的标签
    [root@master ~]# kubectl delete -f pod-nodeselector.yml 
    pod "pod-nodeselector" deleted
    
    [root@master ~]# vim pod-nodeselector.yml 
    [root@master ~]# kubectl  create -f pod-nodeselector.yml 
    pod/pod-nodeselector created
    
    # 再次查看发现Pod我i发正常运行,Node的值问none
    [root@master ~]# kubectl  get pod pod-nodeselector -n dev -o wide
    NAME               READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
    pod-nodeselector   0/1     Pending   0          56s   <none>   <none>   <none>           <none>
    
    # 查看详情发现node selector匹配失败的提示
    [root@master ~]# kubectl  describe  pod pod-nodeselector -n dev
    ....................
    Events:
     Type     Reason            Age        From               Message
     ----     ------            ----       ----               -------
     Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.
     Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.
    

    亲和性调度

    定向调度使用起来非常方便,但是也有一定的问题,那就是如果没有满足条件的Node,那么Pod将不会运行,即使在集群中还有可以的Node列表也不行,这就限制了它的使用场景。

    基于上面的问题,kubeneter还提供了一种亲和性调度(Affinity)。它在NodeSelector的基础上进行了扩展,可以通过匹配的形式,实现优先选择满足条件的Node进行调度,如果没有,也可以调度到不满足的节点上,使调度更加灵活。

    Affinity主要分为三类:

    • nodeAffinity(node亲和性):以node为目标,解决pod可以调度到那些node的问题

    • podAffinity(pod亲和性): 以pod为目标,解决Pod可以和那些已存在的Pod部署在同一个拓扑域中的问题

    • podAntiAffinity(pod反亲和性): 以pod为目标,解决pod不能和那些已存在pod部署在同一个拓扑域中的问题

    关于亲和性(反亲和性)使用场景说明:
    
    亲和性: 如果两个应用频繁交互,那就有必要利用亲和性让两个应用尽可能的靠近,这样可以减少网络通信而带来的性能损耗。
    
    反亲和性:当应用采用多副本部署使,有必要采用反亲和性让各个应用实例打散分布在各个node上,这样可以提高服务的高可用性。
    

    NodeAffinity

    首先来看一下NodeAffinity的可配置文件

    od.spec.affinity.nodeAffinity
      requiredDuringSchedulingIgnoredDuringExecution 必须满足指定的规则才可以调度,相当于应限制
        nodeSelectorTerms  节点选择列表
          matchFields  按节点字段列出的节点选择器要求列表
          matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
            key 
            values
            operator 关系符 支持Exists,DoesNotExist,In,NotIn,Gt,Lt
      preferredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则Node,相等于软限制(倾向)
        preference 一个节点选择器,于相应的权重相关联
          matchFields 按节点字段列出的节点选择器要求列表
          matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
            key
            values
            operator 关系符 支持In,NotIn,Exists,DoesNotExist,Gt,Lt
        weight 倾向权重,在范围1-100
        
    关系符使用说明
    - matchExpressions:
      - key: nodeenv  # 匹配存在标签的key为nodeenv的节点
        operator: Exists 
      - key: nodeenv   # 匹配标签的key为nodeenv,且value是"xxx"或"yyy"的节点
        operator: In
        values: ["xxx","yyy"]
      - key: nodeenv  #匹配标签的key为nodeenv,且value大于"xxx"的节点
        operator: Gt
        values: "xxx"
    

    演示一下requireDuringSchedulingIgnoredDuringExecution

    创建pod-nodeaffinity-required.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-nodeaffinity-required
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: nodeenv
                operator: In
                values: ["xxx","yyy"]
                
    # 创建pod
    [root@master ~]# kubectl  create -f  pod-nodeaffinity-required.yml 
    pod/pod-nodeaffinity-required created
    
    # 查看pod状态发现运行失败
    [root@master ~]# kubectl  get pod pod-nodeaffinity-required -n dev
    NAME                        READY   STATUS    RESTARTS   AGE
    pod-nodeaffinity-required   0/1     Pending   0          3m19s
    
    # 查看pod发现调度失败,提示node选择失败
    [root@master ~]# kubectl  describe  pod pod-nodeaffinity-required -n dev
    .................
    Events:
      Type     Reason            Age        From               Message
      ----     ------            ----       ----               -------
      Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.
      Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.
      
     # 接下来停止pod
     [root@master ~]# kubectl  delete -f pod-nodeaffinity-required.yml 
    pod "pod-nodeaffinity-required" deleted
    
    # 修改文件,将values: ["xxx","yyy" ]------->["dev","yyy"]后在次启动
    [root@master ~]# kubectl create -f pod-nodeaffinity-required.yml 
    pod/pod-nodeaffinity-required created
    
    #此时查看,发现已经调度成功,已经将pod调度到了node1上
    [root@master ~]# kubectl  get pod pod-nodeaffinity-required -n dev -o wide
    NAME                        READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-nodeaffinity-required   1/1     Running   0          42s   10.244.1.73   node1   <none>           <none>
     
    

    下面在演示preferredDuringSchedulingIgnoredDuringExecution

    创建pod-nodeaffinity-preferred

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-nodeaffinity-preferred
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: nodeenv
                operator: In
                values: ["xxx","yyy"]
                
    # 创建pod
    [root@master ~]# kubectl  create -f pod-nodeaffinity-prefereed.yml 
    pod/pod-nodeaffinity-preferred created
    
    # 查看pod状态(运行成功)
    [root@master ~]# kubectl  get pod pod-nodeaffinity-preferred -n dev -o wide
    NAME                         READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-nodeaffinity-preferred   1/1     Running   0          44s   10.244.2.83   node2   <none>           <none>
    
    NodeAffinity规则设置的注意事项:
     1.如果同时定义了nodeSelector和nodeAffinity,那么必须两个条件都得到满足,Pod才能运行在指定的node上
     2.如果nodeAffinity指定了多个nodeSelectorTerms,那么只需要其中一个能够匹配成功即可
     3.如果一个nodeSelectorTerms中有多个matchExperssions,则一个节点必须满足所有的才能匹配成功
     4.如果一个pod所在的Node在Pod运行期间其标签发生了改变,不再符合该Pod的节点亲和性需求,则系统将忽略此变化
    

    podAffinity配置

    PodAffinty主要实现以运行的Pod为参照,实现让新创建的Pod跟参照pod在一个区域的功能。

    PodAffinity的可配置项:

    pod.spec.affinity.podAffinity
      requiredDuringSchedulingIgnoredDuringExecution: 硬限制
        namespaces 指定参照pod的namespace
        topologKet 指定调度作用域
        labelSelector 标签选择器
          matcheExpressions 按节点标签列出的节点选择器要求列表(推荐)
            key
            values
            operator 关系符
        matchLabels 值多个matchExperssions映射的内容
        
      preferredDuringSchedulingIgnoredDuringExecution: 软限制
        podAffinityTerm 选项
          namespace
          topologyKey
          labelSelector
            matchExpressions
              key
              values
              operator
            matchLabels
        weight: 权重倾向,1-100
    
    topologyKey用于指定调度时作用域,例如:
      如果指定为kubernetes.io/hostname,那么就是以Node节点为区分范围
      如果指定为beta.kubernetes.io/os,则是以Node节点的操作系统类型来区分范围
    

    下面演示一下requiredDuringSchedulingIgnoredDuringExecution

    创建一个pod-podaffinity-target.yml文件

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod_podaffinity-target
      namespace: dev
      labels:
        version: v1
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
      nodeName: node1
    
    # 创建pod
    [root@master ~]# kubectl  create -f pod-podaffinity-target.yml 
    pod/pod-podaffinity-target created
    
    # 查看pod状态
    [root@master ~]# kubectl  get pod pod-podaffinity-target -n dev -o wide
    NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-podaffinity-target   1/1     Running   0          39s   10.244.1.83   node1   <none>           <none>
    
    
    # 创建pod-podaffinity-required.yml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-podaffinity-required
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: version
                operator: In
                values: ["v1","yyy"]
            topologyKey: kubernetes.io/hostname
    上面配置表达的意思: 新的Pod必须要与拥有标签version=v1或者version=yyy的pod在一个node上
    
    # 创建Pod
    [root@master ~]# kubectl create -f pod-podaffinity-required.yml 
    pod/pod-podaffinity-required created
    
    # 查看pod
    [root@master ~]# kubectl  get  pod pod-podaffinity-required -n dev -o wide
    NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-podaffinity-required   1/1     Running   0          89s   10.244.1.84   node1   <none>           <none>
    

    PodAntiAffinity

    PodAntiAffinity主要实现以运行的Pod为参照,让新创建的Pod跟参照的pod不在同一个区域中的功能,其配置方式和PodAffinity是一样的。

    继续使用上一个例子中目标pod

    创建pod-podantiaffinity-required.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-podantiaffinity-required
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: version
                operator: In
                values: ["v1","yyy"]
            topologyKey: kubernetes.io/hostname
    
    #创建pod
    [root@master ~]# kubectl  create -f pod-podantiaffinity-required.yml 
    pod/pod-podantiaffinity-required created
    
    # 查看pod信息,可以看到调度到了node2上
    [root@master ~]# kubectl  get pod pod-podantiaffinity-required -n dev -o wide
    NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-podantiaffinity-required   1/1     Running   0          47s   10.244.2.93   node2   <none>           <none>
    

    污点和容忍

    污点(Taints)

    前面的调度方式都是站在Pod的角度上,通过在Pod上添加属性,来确定Pod是否调度到指定的Node上,可以通过在Node上添加污点,来决定是否允许Pod调度。

    Node被设置上污点一会就和Pod之间存在一种相斥的关系,从而拒绝Pod的调度,甚至可以将Pod驱逐出去

    污点格式为: key=value:effect, key和value是污点的标签,effect描叙污点的作用,支持如下3个选项:

    • PreferNoSchedule: kubernetes将尽量避免把Pod调度都具有该污点的Node上,除非没有其他可调度的节点
    • NoSchedlue: kubernetes将不会把Pod调度到具有该污点的Node上,但不会影响当前Node上存在的Pod
    • NoExecute: kubernetes将不会把Pod调度到具有该污点的Node上,同是将Node上已存在的Pod驱逐

    使用kubectl设置和去除污点的命令如下:

    #设置污点
    kubectl taint nodes node1 key=values:effect
    
    #去除污点
    kubectl taint nodes node1 key:effect-
    
    #去除所有污点
    kubectl taint nodes node1 key-
    

    下面演示污点效果:

    1. 准备节点node1(为了演示效果,暂时停止node2)
    2. 为node1节点设置一个污点: tag=test:PreferNoSchedule,然后创建pod1
    3. 修改为node1节点设置一个污点: tag=test:NoSchedule,然后创建pod2
    4. 修改为node1节点设置一个污点: tag=test:NoExectue,然后创建pod2
    [root@master ~]# kubectl cordon node2
    
    #为node1设置污点PreferNoSchedule
    [root@master ~]# kubectl  taint nodes node1 tag=test:PreferNoSchedule
    node/node1 tainted
    
    # 创建pod1
    [root@master ~]# kubectl  run tainit1 --image=nginx:1.17.2 -n dev
    [root@master ~]# kubectl  get pods -n dev -o wide
    tainit1-68d6b64b66-6bx5k       1/1     Running            0          2m7s    10.244.1.85   node1    <none>           <none>
    
    
    #将node1污点修改为NoSchedule
    [root@master ~]# kubectl  taint nodes node1 tag=test:PreferNoSchedule-
    node/node1 untainted
    [root@master ~]# kubectl  taint nodes node1 tag=test:NoSchedule
    node/node1 tainted
    
    #创建pod2
    [root@master ~]# kubectl  run tainit2 --image=nginx:1.17.2 -n dev
    [root@master ~]# kubectl  get pods -n dev -o wide
    tainit2-7f6d6975b-2bc9k        0/1     Pending            0          5s      <none>        <none>   <none>           <none>
    
    
    #将node1污点修改为NoExecute
    [root@master ~]# kubectl  taint nodes node1 tag-
    node/node1 untainted
    
    #创建pod3
    [root@master ~]# kubectl  run tainit3 --image=nginx:1.17.2 -n dev
    [root@master ~]# kubectl  get pods -n dev -o wide
    tainit1-68d6b64b66-9ps7p       0/1     Pending            0          62s     <none>        <none>   <none>           <none>
    tainit2-7f6d6975b-drvk4        0/1     Pending            0          62s     <none>        <none>   <none>           <none>
    tainit3-6f647d4d94-lj5bn       0/1     Pending            0          36s     <none>        <none>   <none>           <none>
    

    容忍(Toleration) 上面介绍了污点的作用,我们可以在Node上添加污点用于拒绝pod调度上了,但是如果就是想将一个pod调度到一个有污点的Node上去,这个时候就可以使用容忍

    污点就是拒绝,容忍就是忽略,Node通过污点拒绝pod调度上去,Pod通过容忍忽略拒绝

    上面已经在node1上打上了NoExecute的污点,此时pod是调度不上去的,可以通过个pod添加容忍,然后将其调度上去

    创建pod-toleration.yml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-tolertion
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.2
      tolerations: # 添加容忍
      - key: "tag"  # 要容忍的污点的key
        operator: "Equal"  # 操作符
        value: "test"  # 容忍的污点的value
        effect: "NoExecute"  # 容忍规则,必须和标记污点相同
    
    
    # 创建pod
    [root@master ~]# kubectl create -f pod-toleration.yml 
    pod/pod-tolertion created
    [root@master ~]# kubectl  get pods  pod-tolertion -n dev -o wide
    NAME            READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pod-tolertion   1/1     Running   0          19s   10.244.1.93   node1   <none>           <none>
    

    Pod控制器详解

    在Kubernetes中,按照Pod的创建方式可以将其分为两类:

    • 自主式pod: kubernetes直接创建出来的pod,这种pod删除后就没有了,也不会重建
    • 控制器创建的pod: 通过控制器创建的Pod,这种pod删除了之后还会重建

    Pod控制器式管理pod的中间层,使用了pod控制器后,我们只需要告诉pod创建,想要多少个什么样的pod就可以了,他就会创建满足条件的pod并确保每一个pod处于用户期望的状态,如果pod在运行种出现故障,控制器会基于指定策略重启或者重建pod。

    在kubernetes种,有很多类型的pod控制器,每种都有自己的合适场景,常见的有下面几种:

    • ReplicationController: 比较原始的pod控制器,已经被废弃,由ReplicaSet替代

    • ReplicaSet: 保证指定数量的pod运行,并支持pod数量变更,镜像版本变更

    • Deployment: 通过控制ReplicaSet来控制pod,并支持滚动升级,版本回退

    • Horizontal Pod Autoscaler: 可以根据集群负载自动调整pod的数量,实现削峰填谷

    • DaemonSet:在集群中的指定Node上都运行一个副本,一般用于手好进程类的任务

    • Job: 它创建出来的pod只要完成任务后立即退出,用于执行一次性任务

    • Cronjob: 它创建的pod会周期性的执行,用于执行周期性任务

    • StatefulSet: 管理有状态的应用

    ReplicaSet

    ReplicaSet的主要作用式保证一定数量的Pod能够正常运行,它会持续监听这些pod的运行状态,一旦pod发生故障,就会重启或重建。同时它还支持对pod数量的扩容和版本镜像的升级。

    ReplicaSet的资源清单文件:

    apiVersion: apps/V1 #版本号
    kind: ReplicaSet  #类型
    metadata: #元数据
      name:  #rs名称
      namespace: #所属名称空间
      labels: #标签
        controller: rs
    spec: #详情描述
      replicas: 3 #副本数量
      selector: #选择器,通过它自动该控制器管理那些pod
        matchLabels:  #label匹配规则
          app: nginx-pod
        matchExpressions: # Expressions匹配规则
          - {key: app,operator: IN, values: [nginx-pod]}
      template: #模板,当副本数量不足时,会根据下面的模板创建pod
        metadata:
          labels:
            app: nginx-pod
        spec:
          containers:
          - name: nginx
            image: nginx:1.17.2
            ports:
            - containerPort: 80
    

    在这里需要新了解的配置项就是spec下面几个选项:

    • replicas: 指定副本数量,其实就是当前rs创建出来的pod数量,默认为1
    • selector: 选择器,它的作用是建立pod控制器和pod之间的关联关系,采用了Label Selector机制,在pod模板上定义label,在控制器上定义选择器,就可以表明当前控制器能管理那些pod了
    • template: 模板,就是当前控制器创建pod所使用的模板

    创建ReplicaSet

    创建pc-replicaset.yml

    apiVersion: apps/v1
    kind: ReplicaSet
    metadata:
      name: pc-replicaset
      namespace: dev
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx-pod
      template:
        metadata:
          labels:
            app: nginx-pod
        spec:
          containers:
          - name: nginx
            image: nginx:1.17.2
    
    
    # 创建rs
    [root@master ~]# kubectl create -f pc-replicaset.yml 
    replicaset.apps/pc-replicaset created
    
    # 查看ReplicaSet信息 
    [root@master ~]# kubectl get rs pc-replicaset -n dev -o wide
    NAME            DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES         SELECTOR
    pc-replicaset   3         3         3       9m22s   nginx        nginx:1.17.2   app=nginx-pod
    

     扩容缩容

    # 编辑rs副本数量,修改spec:replicas:数量即可
    [root@master ~]# kubectl  edit rs pc-replicaset -n dev
    replicaset.apps/pc-replicaset edited
    
    #查看pod
    ][root@master ~]# kubectl  get pod -n dev -o wide
    NAME                  READY   STATUS              RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pc-replicaset-4s6rz   0/1     ContainerCreating   0          28s   <none>        node2   <none>           <none>
    pc-replicaset-5cdzq   1/1     Running             0          62m   10.244.1.98   node1   <none>           <none>
    pc-replicaset-s2wlt   0/1     ContainerCreating   0          28s   <none>        node2   <none>           <none>
    pc-replicaset-xt7cf   1/1     Running             0          65m   10.244.1.95   node1   <none>           <none>
    pc-replicaset-zhf2z   1/1     Running             0          65m   10.244.1.96   node1   <none>           <none>
    
    
    #也可以使用命令直接实现,使用scale命令实现扩缩容,后面--replicas=n直接指定目标数量即可
    [root@master ~]# kubectl  scale rs pc-replicaset --replicas=2 -n dev
    replicaset.apps/pc-replicaset scaled
    
    #命令运行完毕,查看pod,发现有3个退出
    [root@master ~]# kubectl  get pod -n dev -o wide
    NAME                  READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
    pc-replicaset-xt7cf   1/1     Running   0          68m   10.244.1.95   node1   <none>           <none>
    pc-replicaset-zhf2z   1/1     Running   0          68m   10.244.1.96   node1   <none>           <none>
    

     镜像升级

    #编辑rs的 容器镜像 - image: nginx:1.17.3
    [root@master ~]# kubectl  edit rs pc-replicaset -n dev
    replicaset.apps/pc-replicaset edite
    
    #再次查看,发现镜像版本已经变更
    [root@master ~]# kubectl  get rs -n dev -o wide
    NAME            DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR
    pc-replicaset   2         2         2       72m   nginx        nginx:1.17.3   app=nginx-pod
    
    #也可以使用命令完成,kubectl set image rs  rs名称 容器=镜像版本 -n namespace
    [root@master ~]# kubectl  set image rs pc-replicaset  nginx=nginx=1.17.1 -n dev
    replicaset.apps/pc-replicaset image updated
    
    #再次查看,可以看到镜像版本已经更新
    [root@master ~]# kubectl  get rs -n dev -o wide
    NAME            DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR
    pc-replicaset   2         2         2       74m   nginx        nginx=1.17.1   app=nginx-pod
    

     删除ReplicaSet

    #使用kubectl delete命令会三次此RS以及它管理的pod
    #在kubernetes删除RS前,会将RS的replicasclear调整为0,等待所有的Pod删除后,在执行RS对象删除
    [root@master ~]# kubectl  delete rs pc-replicaset -n dev
    replicaset.apps "pc-replicaset" deleted
    
    
    #如果希望仅仅删除RS对象(保留pod),可以使用kubectl delete命令是添加--cascade=false选项(不推荐)
    [root@master ~]# kubectl  delete rs pc-replicaset -n dev --cascade=false
    replicaset.apps "pc-replicaset" deleted
    [root@master ~]# kubectl  get pod -n dev
    NAME                  READY   STATUS              RESTARTS   AGE
    pc-replicaset-9556m   0/1     ContainerCreating   0          57s
    pc-replicaset-qvznw   1/1     Running             0          57s
    
    #也可以使用哦那个yml直接删除
    [root@master ~]# kubectl  delete -f pc-replicaset.yml
    

    Deployment(Deploy)

    为了更好的解决服务编排的问题,kubernetes在v1.2版本开始,引入Deployment控制器。值得一提的是,这种控制器并不直接管理pod,而是通过ReplicaSet来间接管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加强大。

    Deployment主要功能有下面几个:

    • 支持ReplicaSet的所用功能
    • 支持发布的停止,继续
    • 支持版本滚动升级和版本回退

    Deploymenr的资源清单文件:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: #rs名称
      namespace: #所属的名称空间
    spec:
      replicas: 3 #副本数量
      revisionHistoryLimit: 3 #保留历史版本,默认10
      paused: false  #暂停部署,默认false
      progressDeadlineSeconds: 600 #部署超时时间,默认600s
      strategy: #策略
        type: RollingUpdate #滚动更新策略
        rolliingUpdate: #滚动更新
          maxSurge: 30% #最大额外可以存在的副本数,可以为百分比可以为整数
          maxUnavailable: 30% #最大不可以状态的pod,可以为百分比可以为整数
      selector: # 选择器,通过它指定该控制器管理那些pod
        matchLabels:  #Label匹配规则
          app: nginx-pod
        matchExpressions: # Expressions匹配规则
          - {key:app, operator: IN , values:[nginx-pod]}
        template: #模板
          metadata:
            labels:
              app: nginx-pod
          spec:
            containers:
            - name: nginx
              image: nginx:1.17.2
              ports:
                containerPorts: 80
    

    创建Deployment

    创建文件pc-deployment.yml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pc-deployment
      namespace: dev
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx-pod
      template:
        metadata:
          labels:
            app: nginx-pod
        spec:
          containers:
          - name: nginx
            image: nginx:1.17.2
            
    # 创建deployment
    # --record=true 记录每次的版本变化
    [root@master ~]# kubectl create -f  pc-deployment.yml --record=true
    deployment.apps/pc-deployment created
    
    #查看deployment,UP-TO-DATE最新版本的pod的数量,AVAILABLE 当前可用pod的数量
    [root@master ~]# kubectl  get deploy -n dev -o wide
    NAME            READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
    pc-deployment   1/3     3            1           40s   nginx        nginx:1.17.2   app=nginx-pod
    
    #查看rs,发现rs的名称是在原来deployment的名字后面添加了一个随机10位数的随机串
    [root@master ~]# kubectl  get rs -n dev 
    NAME                       DESIRED   CURRENT   READY   AGE
    pc-deployment-675d469f8b   3         3         1       3m37
    
    #查看pod
    [root@master ~]# kubectl  get pod -n dev 
    NAME                             READY   STATUS    RESTARTS   AGE
    pc-deployment-675d469f8b-2jqkd   1/1     Running   1          9m55s
    pc-deployment-675d469f8b-n8vmx   1/1     Running   1          9m55s
    pc-deployment-675d469f8b-stswc   1/1     Running   0          9m55s
    

     扩缩容

    #变更副本数量为5个
    [root@master ~]# kubectl  scale deploy pc-deployment -n dev --replicas=5
    deployment.apps/pc-deployment scaled
    
    #查看deployment
    [root@master ~]# kubectl get deploy -n dev
    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    pc-deployment   5/5     5            5           11m
    
    #查看pod
    [root@master ~]# kubectl  get pod -n dev
    NAME                             READY   STATUS    RESTARTS   AGE
    pc-deployment-675d469f8b-2jqkd   1/1     Running   1          12m
    pc-deployment-675d469f8b-fqfld   1/1     Running   0          48s
    pc-deployment-675d469f8b-khwr2   1/1     Running   0          48s
    pc-deployment-675d469f8b-n8vmx   1/1     Running   1          12m
    pc-deployment-675d469f8b-stswc   1/1     Running   0          12m
    
    # 编译deployment的副本数量,修改spec:replicas: 3
    [root@master ~]# kubectl  edit deploy pc-deployment -n dev
    deployment.apps/pc-deployment edited
    
    # 查看pod
    [root@master ~]# kubectl  get pod -n dev
    NAME                             READY   STATUS    RESTARTS   AGE
    pc-deployment-675d469f8b-2jqkd   1/1     Running   1          13m
    pc-deployment-675d469f8b-fqfld   1/1     Running   0          2m33s
    pc-deployment-675d469f8b-stswc   1/1     Running   0          13m
    

    镜像更新

    Deployment支持两种镜像更新的策略: 重建镜像和滚动跟新(默认),可用通过strategy选项进行配置

    strategy: 指定新的Pod替换旧的Pod的策略,支持两个属性
      type: 指定策略类型,支持两种策略
        Recreate: 在创建出新的Pod之前会先杀掉所有已存在的pod
        RollingUpdate: 滚动跟新,就是杀死部分,就启动一部分,在更新的过程中存在两个版本的Pod
      rollingUpdate: 当type为RollingUpdate是生效,用于为RollingUpdate设置参数,支持两个属性:
        maxUnavailabe: 用来指定在升级过程中不可以pod的最大数量,默认25%
        maxSurge: 用来指定在升级过程中可用超过期望的Pod的最大数量,默认25%
    

     重建更新:

    #1.编辑pc-deployment.yml,在spec节点下添加更新策略
    spec:
      strategy:
        type: Recrate
    # 应用策略
    [root@master ~]# kubectl apply -f pc-deployment.yml
    
    # 2.创建deploy进行验证
    #变更镜像
    [root@master ~]# kubectl  set image deployment pc-deployment nginx=nginx:1.17.4 -n dev
    deployment.apps/pc-deployment image updated
    root@master ~]# kubectl  get pod -n dev -w
    NAME                             READY   STATUS    RESTARTS   AGE
    pc-deployment-675d469f8b-2jqkd   1/1     Running   1          94m
    pc-deployment-675d469f8b-fqfld   1/1     Running   0          82m
    pc-deployment-675d469f8b-stswc   1/1     Running   0          94m
    pc-deployment-675d469f8b-stswc   1/1     Terminating   0          94m
    pc-deployment-675d469f8b-2jqkd   1/1     Terminating   1          94m
    pc-deployment-675d469f8b-fqfld   1/1     Terminating   0          83m
    pc-deployment-675d469f8b-2jqkd   0/1     Terminating   1          94m
    pc-deployment-675d469f8b-stswc   0/1     Terminating   0          94m
    pc-deployment-675d469f8b-fqfld   0/1     Terminating   0          83m
    pc-deployment-675d469f8b-2jqkd   0/1     Terminating   1          94m
    pc-deployment-675d469f8b-2jqkd   0/1     Terminating   1          94m
    pc-deployment-675d469f8b-fqfld   0/1     Terminating   0          83m
    pc-deployment-675d469f8b-fqfld   0/1     Terminating   0          83m
    pc-deployment-675d469f8b-stswc   0/1     Terminating   0          94m
    pc-deployment-675d469f8b-stswc   0/1     Terminating   0          94m
    pc-deployment-6c9f56fcfb-wrdtj   0/1     Pending       0          0s
    pc-deployment-6c9f56fcfb-zpmv7   0/1     Pending       0          0s
    pc-deployment-6c9f56fcfb-v2vl6   0/1     Pending       0          0s
    pc-deployment-6c9f56fcfb-wrdtj   0/1     Pending       0          0s
    pc-deployment-6c9f56fcfb-zpmv7   0/1     Pending       0          0s
    pc-deployment-6c9f56fcfb-v2vl6   0/1     Pending       0          0s
    pc-deployment-6c9f56fcfb-zpmv7   0/1     ContainerCreating   0          0s
    pc-deployment-6c9f56fcfb-wrdtj   0/1     ContainerCreating   0          0s
    pc-deployment-6c9f56fcfb-v2vl6   0/1     ContainerCreating   0          0s
    pc-deployment-6c9f56fcfb-zpmv7   1/1     Running             0          16s
    pc-deployment-6c9f56fcfb-v2vl6   1/1     Running             0          32s
    pc-deployment-6c9f56fcfb-wrdtj   1/1     Running             0          47s
    

     滚动更新

    1.编辑pc-deployment.yml,在spec节点下添加跟新策略
    spec:
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxUnavailable: 25%
          maxSurge: 25%
    
    #应用
    [root@master ~]# kubectl apply -f pc-deployment.yml 
    deployment.apps/pc-deployment configured
    
    #变更镜像
    [root@master ~]# kubectl  set image deployment pc-deployment nginx=nginx:1.17.1 -n dev
    deployment.apps/pc-deployment image updated
    [root@master ~]# kubectl  get pod -n dev -w
    NAME                             READY   STATUS    RESTARTS   AGE
    pc-deployment-6c9f56fcfb-v2vl6   1/1     Running   0          3m1s
    pc-deployment-6c9f56fcfb-wrdtj   1/1     Running   0          3m1s
    pc-deployment-6c9f56fcfb-zpmv7   1/1     Running   0          3m1s
    pc-deployment-675d469f8b-gsvgm   0/1     Pending   0          0s
    pc-deployment-675d469f8b-gsvgm   0/1     Pending   0          0s
    pc-deployment-675d469f8b-gsvgm   0/1     ContainerCreating   0          0s
    pc-deployment-675d469f8b-gsvgm   1/1     Running             0          3s
    pc-deployment-6c9f56fcfb-wrdtj   1/1     Terminating         0          6m5s
    pc-deployment-675d469f8b-vtgbs   0/1     Pending             0          0s
    pc-deployment-675d469f8b-vtgbs   0/1     Pending             0          0s
    pc-deployment-675d469f8b-vtgbs   0/1     ContainerCreating   0          0s
    pc-deployment-6c9f56fcfb-wrdtj   0/1     Terminating         0          6m6s
    pc-deployment-6c9f56fcfb-wrdtj   0/1     Terminating         0          6m7s
    pc-deployment-675d469f8b-vtgbs   1/1     Running             0          2s
    pc-deployment-6c9f56fcfb-v2vl6   1/1     Terminating         0          6m7s
    pc-deployment-675d469f8b-4l4zz   0/1     Pending             0          0s
    pc-deployment-675d469f8b-4l4zz   0/1     Pending             0          0s
    pc-deployment-675d469f8b-4l4zz   0/1     ContainerCreating   0          0s
    pc-deployment-6c9f56fcfb-v2vl6   0/1     Terminating         0          6m8s
    pc-deployment-675d469f8b-4l4zz   1/1     Running             0          2s
    pc-deployment-6c9f56fcfb-zpmv7   1/1     Terminating         0          6m9s
    pc-deployment-6c9f56fcfb-wrdtj   0/1     Terminating         0          6m10s
    pc-deployment-6c9f56fcfb-wrdtj   0/1     Terminating         0          6m10s
    pc-deployment-6c9f56fcfb-zpmv7   0/1     Terminating         0          6m10s
    pc-deployment-6c9f56fcfb-zpmv7   0/1     Terminating         0          6m11s
    pc-deployment-6c9f56fcfb-zpmv7   0/1     Terminating         0          6m11s
    pc-deployment-6c9f56fcfb-v2vl6   0/1     Terminating         0          6m20s
    pc-deployment-6c9f56fcfb-v2vl6   0/1     Terminating         0          6m20s
    pc-deployment-5d89bdfbf9-xt428   0/1     Pending             0          0s
    pc-deployment-5d89bdfbf9-xt428   0/1     Pending             0          0s
    pc-deployment-5d89bdfbf9-xt428   0/1     ContainerCreating   0          0s
    pc-deployment-5d89bdfbf9-xt428   1/1     Running             0          2s
    pc-deployment-675d469f8b-4l4zz   1/1     Terminating         0          42s
    pc-deployment-5d89bdfbf9-cjpp2   0/1     Pending             0          0s
    pc-deployment-5d89bdfbf9-cjpp2   0/1     Pending             0          0s
    pc-deployment-5d89bdfbf9-cjpp2   0/1     ContainerCreating   0          0s
    pc-deployment-675d469f8b-4l4zz   0/1     Terminating         0          43s
    pc-deployment-5d89bdfbf9-cjpp2   1/1     Running             0          1s
    pc-deployment-675d469f8b-vtgbs   1/1     Terminating         0          45s
    

     镜像更新中rs的变化:

    #查看rs,发现原来的rs依旧存在,只是pod变为了0,然后新产生一个rs,pod数量为3
    [root@master ~]# kubectl  get rs -n dev
    NAME                       DESIRED   CURRENT   READY   AGE
    pc-deployment-5d89bdfbf9   3         3         3       2m
    pc-deployment-675d469f8b   0         0         0       103m
    pc-deployment-6c9f56fcfb   0         0         0       8m47s
    

    版本回退

    deployment支持版本升级过程中暂停,继续功能以及版本回退等诸多功能。

    kubectl rollout: 版本升级相关功能,支持下面的选项:

    • status 显示当前升级状态
    • history 显示升级历史记录
    • pause 暂停版本升级过程
    • resume 继续以及暂停的版本升级过程
    • restart 重启版本升级过程
    • undo 回滚到上一个版本(可用使用--to-revision回滚到指定版本)
    # 查看当前升级的版本状态
    [root@master ~]# kubectl  rollout status deployment pc-deployment -n dev
    deployment "pc-deployment" successfully rolled out
    
    # [root@master ~]# kubectl  rollout history  deployment pc-deployment -n dev
    deployment.apps/pc-deployment 
    REVISION  CHANGE-CAUSE
    2         kubectl create --filename=pc-deployment.yml --record=true
    3         kubectl create --filename=pc-deployment.yml --record=true
    4         kubectl create --filename=pc-deployment.yml --record=true
    
    # 版本回滚
    # 这里直接使用--to-revision=2回滚到2版本,如果省略这个选项就是回退到上一个版本
    [root@master ~]# kubectl  rollout undo  deployment pc-deployment --to-revision=2 -n dev
    deployment.apps/pc-deployment rolled back
    
    #查看发现,通过nginx进行版本可用发现到了1.17.4版本
    [root@master ~]# kubectl  get rs -n dev -o wide
    NAME                       DESIRED   CURRENT   READY   AGE    CONTAINERS   IMAGES         SELECTOR
    pc-deployment-5d89bdfbf9   0         0         0       16m    nginx        nginx:1.17.1   app=nginx-pod,pod-template-hash=5d89bdfbf9
    pc-deployment-675d469f8b   0         0         0       117m   nginx        nginx:1.17.2   app=nginx-pod,pod-template-hash=675d469f8b
    pc-deployment-6c9f56fcfb   3         3         3       23m    nginx        nginx:1.17.4   app=nginx-pod,pod-template-hash=6c9f56fcfb
    

    金丝雀发布 deployment支持更新过程中的控制,如“暂停(pause)”或“继续(resume)”更新操作

    比如有一批新的pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本应用,主体部分还是旧版本。然后,在筛选一小部分的用户请求路由到新版本的pod应用,继续概观察能否稳定的按期望的方式运行,确定没问题后在举行完成余下的pod资源滚动更新,否则立即回滚更新操作。

    # 更新deployment的版本,并配置暂停deployment
    [root@master ~]# kubectl  set image deploy pc-deployment nginx=nginx:1.17.3 -n dev && kubectl rollout pause deployment pc-deployment -n dev
    deployment.apps/pc-deployment image updated
    deployment.apps/pc-deployment paused
    
    #观察更新状态
    [root@master ~]# kubectl rollout status  deploy pc-deployment -n dev
    Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
    
    # 监控更新过程,可用看到已经新增了一个资源,但是并未按照预期的状态删除一个旧的资源,就是因为使用了pause暂停命令
    [root@master ~]# kubectl  get rs -n dev -o wide
    NAME                       DESIRED   CURRENT   READY   AGE    CONTAINERS   IMAGES         SELECTOR
    pc-deployment-5d89bdfbf9   0         0         0       25m    nginx        nginx:1.17.1   app=nginx-pod,pod-template-hash=5d89bdfbf9
    pc-deployment-675d469f8b   0         0         0       126m   nginx        nginx:1.17.2   app=nginx-pod,pod-template-hash=675d469f8b
    pc-deployment-6c9f56fcfb   3         3         3       31m    nginx        nginx:1.17.4   app=nginx-pod,pod-template-hash=6c9f56fcfb
    pc-deployment-6dfdf96cc5   1         1         0       119s   nginx        ngnix:1.17.3   app=nginx-pod,pod-template-hash=6dfdf96cc5
    
    
    # 继续更新
    [root@master ~]# kubectl rollout resume  deployment pc-deployment -n dev
    deployment.apps/pc-deployment resumed
    
    #查看deploy
    [root@master ~]# kubectl  get rs  -n dev
    NAME                       DESIRED   CURRENT   READY   AGE
    pc-deployment-5d89bdfbf9   0         0         0       35m
    pc-deployment-675d469f8b   0         0         0       136m
    pc-deployment-6c9f56fcfb   0         0         0       41m
    pc-deployment-6dfdf96cc5   0         0         0       11m
    pc-deployment-7865c58bdf   3         3         3       63s
    

    Horizonta Pod Autoscaler(HPA)

    可用通过手工执行kubectl scale命令实现Pod扩容,但是这显然不符合kubernetes的定位目标--自动化、智能化。Kubernetes期望可用通过监测Pod的使用情况,实现pod数量的自动调整,于是就产生了HPA这种控制器。

    HPA可以获取每个pod利用率,然后和PHPA中定义的指标进行对比,同时计算出需要伸缩的具体值,最后实现pod的数量的调整。其实HPA与之前的Deployment一样,也属于一种Kubernetes资源对象,它通过追踪分析目标pod的负载变化情况,来确定是否需要针对性的调整目标Pod的数量

    1.安装metrice-server

    metrucs-server可以用来收集集群中的资源使用情况

    #安装git
    [root@master ~]# yum -y install git
    #获取metrics-server,注意使用版本
    [root@master ~]# git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
    #修改deployment,注意修改的是镜像和初始化参数
    [root@master ~]# cd metrics-server/deploy/1.8+/
    [root@master 1.8+]# vim metrics-server-deployment.yaml
    [root@master 1.8+]# vim metrics-server-deployment.yaml
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: metrics-server
      namespace: kube-system
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: metrics-server
      namespace: kube-system
      labels:
        k8s-app: metrics-server
    spec:
      selector:
        matchLabels:
          k8s-app: metrics-server
      template:
        metadata:
          name: metrics-server
          labels:
            k8s-app: metrics-server
        spec:
          hostNetwork: true
          serviceAccountName: metrics-server
          volumes:
          # mount in tmp so we can safely use from-scratch images and/or read-only containers
          - name: tmp-dir
            emptyDir: {}
          containers:
          - name: metrics-server
            image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6 
            imagePullPolicy: Always
            args:
            - --kubelet-insecure-tls
            - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
            volumeMounts:
            - name: tmp-dir
              mountPath: /tmp
    #查看pod运行状态
    [root@master 1.8+]# kubectl  get pod -n kube-system
    metrics-server-6b976979db-2hqm6   1/1     Running                 0          2m21s
    
    #使用kubectl top node 查看资源使用状态
    [root@master 1.8+]# kubectl  top node
    NAME     CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
    master   111m         5%     970Mi           56%       
    node1    28m          1%     388Mi           44%       
    node2    34m          1%     426Mi           48% 
    [root@master 1.8+]# kubectl  top pod  -n kube-system
    NAME                              CPU(cores)   MEMORY(bytes)   
    coredns-6955765f44-sch82          4m           15Mi            
    coredns-6955765f44-thfs7          4m           15Mi            
    etcd-master                       15m          86Mi            
    kube-apiserver-master             33m          294Mi           
    kube-controller-manager-master    15m          63Mi  
    ..........................
    #至此,metrics-server安装完成
    

    2.准备deployment和service

    # 创建deployment
    vim nginx.yml
    apiVersion: apps/v1 # 版本号
    kind: Deployment # 类型
    metadata: # 元数据
      name: nginx # deployment的名称
      namespace: dev # 命名类型
    spec: # 详细描述
      selector: # 选择器,通过它指定该控制器可以管理哪些Pod
        matchLabels: # Labels匹配规则
          app: nginx-pod
      template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本
        metadata:
          labels:
            app: nginx-pod
        spec:
          containers:
            - name: nginx # 容器名称
              image: nginx:1.17.1 # 容器需要的镜像地址
              ports:
                - containerPort: 80 # 容器所监听的端口
              resources: # 资源限制
                requests:
                  cpu: "100m" # 100m表示100millicpu,即0.1个CPU
    
    #创建Deployment
    [root@master 1.8+]# kubectl create -f nginx.yml 
    deployment.apps/nginx created
    
    #查看Deployment和Pod
    [root@master 1.8+]# kubectl get pod,deploy -n dev
    NAME                        READY   STATUS    RESTARTS   AGE
    pod/nginx-7b766dbb7-8qrdv   1/1     Running   0          31s
    
    NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/nginx   1/1     1            1           31s
    
    #创建Service
    [root@master 1.8+]# kubectl expose deployment nginx --name=nginx --type=NodePort --port=80 --target-port=80 -n dev
    service/nginx exposed
    
    #查看Service
    [root@master 1.8+]# kubectl get svc -n dev
    NAME    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
    nginx   NodePort   10.105.180.5   <none>        80:31628/TCP   35s
    

    3.部署HPA

    创建pc-hpa.yaml文件

    apiVersion: autoscaling/v1 # 版本号
    kind: HorizontalPodAutoscaler # 类型
    metadata: # 元数据
      name: pc-hpa # deployment的名称
      namespace: dev # 命名类型
    spec:
      minReplicas: 1 # 最小Pod数量
      maxReplicas: 10 # 最大Pod数量
      targetCPUUtilizationPercentage: 3 # CPU使用率指标
      scaleTargetRef:  # 指定要控制的Nginx的信息
        apiVersion: apps/v1
        kind: Deployment
        name: nginx
        
    #创建hpa
    [root@master 1.8+]# kubectl create -f pc-hpa.yaml
    horizontalpodautoscaler.autoscaling/pc-hpa created
    
    #查看hpa
    [root@master 1.8+]# kubectl get hpa -n dev
    NAME     REFERENCE          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    pc-hpa   Deployment/nginx   0%/3%     1         10        1          42s
    

    4.测试

    ● 使用压测工具如Jmeter对service的地址http://192.168.248.11:31628进行压测,然后通过控制台查看hpa和pod的变化

    hpa的变化
    [root@master ~]# kubectl  get hpa -n dev -w
    NAME     REFERENCE          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    pc-hpa   Deployment/nginx   0%/3%     1         10        1          3m28s
    pc-hpa   Deployment/nginx   0%/3%     1         10        1          5m18s
    pc-hpa   Deployment/nginx   1%/3%     1         10        1          9m6s
    pc-hpa   Deployment/nginx   0%/3%     1         10        1          10m
    pc-hpa   Deployment/nginx   1%/3%     1         10        1          12m
    pc-hpa   Deployment/nginx   0%/3%     1         10        1          13m
    pc-hpa   Deployment/nginx   0%/3%     1         10        1          18m
    pc-hpa   Deployment/nginx   20%/3%    1         10        1          20m
    pc-hpa   Deployment/nginx   20%/3%    1         10        4          21m
    pc-hpa   Deployment/nginx   20%/3%    1         10        7          21m
    pc-hpa   Deployment/nginx   4%/3%     1         10        7          21m
    pc-hpa   Deployment/nginx   1%/3%     1         10        7          23m
    

    DaemonSet(DS)

    DaemonSet类型的控制器可以保证集群中的每一台(或指定)节点上都运行一个副本,一般适用于日志收集、节点监控等场景。也就是说,如果一个Pod提供的功能是节点级别的(每个节点都需要且只需要一个),那么这类Pod就适合使用DaemonSet类型的控制器创建。

    DaemonSet控制器的特点:

    • 每向集群中添加一个节点的时候,指定的Pod副本也将添加到该节点上。
    • 当节点从集群中移除的时候,Pod也会被垃圾回收。

    DaemonSet的资源清单:

    apiVersion: apps/v1 # 版本号
    kind: DaemonSet # 类型
    metadata: # 元数据
      name: # 名称
      namespace: #命名空间
      labels: #标签
        controller: daemonset
    spec: # 详情描述
      revisionHistoryLimit: 3 # 保留历史版本
      updateStrategy: # 更新策略
        type: RollingUpdate # 滚动更新策略
        rollingUpdate: # 滚动更新
          maxUnavailable: 1 # 最大不可用状态的Pod的最大值,可用为百分比,也可以为整数
      selector: # 选择器,通过它指定该控制器管理那些Pod
        matchLabels: # Labels匹配规则
          app: nginx-pod
        matchExpressions: # Expressions匹配规则
          - key: app
            operator: In
            values:
              - nginx-pod
      template: # 模板,当副本数量不足时,会根据下面的模板创建Pod模板
         metadata:
           labels:
             app: nginx-pod
         spec:
           containers:
             - name: nginx
               image: nginx:1.17.1
               ports:
                 - containerPort: 80
    

    创建DaemonSet

    创建pc-daemonset.yml文件

    apiVersion: apps/v1 # 版本号
    kind: DaemonSet # 类型
    metadata: # 元数据
      name: pc-damonset # 名称
      namespace: dev #命名空间
    spec: # 详情描述
      selector: # 选择器,通过它指定该控制器管理那些Pod
        matchLabels: # Labels匹配规则
          app: nginx-pod
      template: # 模板,当副本数量不足时,会根据下面的模板创建Pod模板
         metadata:
           labels:
             app: nginx-pod
         spec:
           containers:
             - name: nginx
               image: nginx:1.17.1
               ports:
                 - containerPort: 80
    
    #创建DaemonSet
    [root@master ~]# kubectl create -f pc-daemonset.yml
    daemonset.apps/pc-damonset created
    
    
    #查看DaemonSet
    [root@master ~]# kubectl get ds -n dev -o wide
    NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE   CONTAINERS   IMAGES         SELECTOR
    pc-damonset   2         2         2       2            2           <none>          25s   nginx        nginx:1.17.1   app=nginx-pod
    
    
    #删除DaemonSet
    [root@master ~]# kubectl delete ds pc-damonset -n dev
    daemonset.apps "pc-damonset" deleted
    

    job

    Job主要用于负责批量处理短暂的一次性任务。

    Job的特点:

    • 当Job创建的Pod执行成功结束时,Job将记录成功结束的Pod数量。
    • 当成功结束的Pod达到指定的数量时,Job将完成执行

    job资源清单

    apiVersion: batch/v1 # 版本号
    kind: Job # 类型
    metadata: # 元数据
      name:  # 名称
      namespace:  #命名空间
      labels: # 标签
        controller: job
    spec: # 详情描述
      completions: 1 # 指定Job需要成功运行Pod的总次数,默认为1
      parallelism: 1 # 指定Job在任一时刻应该并发运行Pod的数量,默认为1
      activeDeadlineSeconds: 30 # 指定Job可以运行的时间期限,超过时间还没结束,系统将会尝试进行终止
      backoffLimit: 6 # 指定Job失败后进行重试的次数,默认为6
      manualSelector: true # 是否可以使用selector选择器选择Pod,默认为false
      selector: # 选择器,通过它指定该控制器管理那些Pod
        matchLabels: # Labels匹配规则
          app: counter-pod
        matchExpressions: # Expressions匹配规则
          - key: app
            operator: In
            values:
              - counter-pod
      template: # 模板,当副本数量不足时,会根据下面的模板创建Pod模板
         metadata:
           labels:
             app: counter-pod
         spec:
           restartPolicy: Never # 重启策略只能设置为Never或OnFailure
           containers:
             - name: counter
               image: busybox:1.30
               command: ["/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 20;done"]
               
    关于模板中的重启策略的说明:
    # 如果设置为OnFailure,则Job会在Pod出现故障的时候重启容器,而不是创建Pod,failed次数不变。
    # 如果设置为Never,则Job会在Pod出现故障的时候创建新的Pod,并且故障Pod不会消失,也不会重启,failed次数+1。
    #如果指定为Always的话,就意味着一直重启,意味着Pod任务会重复执行,这和Job的定义冲突,所以不能设置为Always。
    

     创建pc-job.yml文件

    apiVersion: batch/v1 # 版本号
    kind: Job # 类型
    metadata: # 元数据
      name: pc-job # 名称
      namespace: dev #命名空间
    spec: # 详情描述
      manualSelector: true # 是否可以使用selector选择器选择Pod,默认为false
      selector: # 选择器,通过它指定该控制器管理那些Pod
        matchLabels: # Labels匹配规则
          app: counter-pod
      template: # 模板,当副本数量不足时,会根据下面的模板创建Pod模板
        metadata:
          labels:
            app: counter-pod
        spec:
          restartPolicy: Never # 重启策略只能设置为Never或OnFailure
          containers:
            - name: counter
              image: busybox:1.30
              command: [ "/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 3;done" ]
              
    # 创建job
    [root@master ~]# kubectl  create -f pc-job.yml 
    job.batch/pc-job created
    
    # 查看job
    [root@master ~]# kubectl  get job -n dev -o wide -w
    NAME     COMPLETIONS   DURATION   AGE   CONTAINERS   IMAGES         SELECTOR
    pc-job   0/1           2s         2s    counter      busybox:1.30   app=counter-pod
    pc-job   1/1           28s        28s   counter      busybox:1.30   app=counter-pod
    
    #查看pod
    [root@master ~]# kubectl  get pod -n dev -w
    NAME           READY   STATUS    RESTARTS   AGE
    pc-job-5s9ck   0/1     Pending   0          0s
    pc-job-5s9ck   0/1     Pending   0          0s
    pc-job-5s9ck   0/1     ContainerCreating   0          0s
    pc-job-5s9ck   1/1     Running             0          1s
    pc-job-5s9ck   0/1     Completed           0          28s
    
    #删除job
    [root@master ~]# kubectl  delete  -f pc-job.yml 
    job.batch "pc-job" deleted
    

    CronJob(CJ)

    CronJob控制器以Job控制器为其管控对象,并借助它管理Pod资源对象,Job控制器定义的作业任务在其控制器资源创建之后便会立即执行,但CronJob可以以类似Linux操作系统的周期性任务作业计划的方式控制器运行时间点及重复运行的方式,换言之,CronJob可以在特定的时间点反复去执行Job任务

    CronJob的资源清单

    apiVersion: batch/v1beta1 # 版本号
    kind: CronJob # 类型
    metadata: # 元数据
      name:  # 名称
      namespace:  #命名空间
      labels:
        controller: cronjob
    spec: # 详情描述
      schedule: # cron格式的作业调度运行时间点,用于控制任务任务时间执行
      concurrencyPolicy: # 并发执行策略
      failedJobsHistoryLimit: # 为失败的任务执行保留的历史记录数,默认为1
      successfulJobsHistoryLimit: # 为成功的任务执行保留的历史记录数,默认为3
      jobTemplate: # job控制器模板,用于为cronjob控制器生成job对象,下面其实就是job的定义
        metadata: {}
        spec:
          completions: 1 # 指定Job需要成功运行Pod的总次数,默认为1
          parallelism: 1 # 指定Job在任一时刻应该并发运行Pod的数量,默认为1
          activeDeadlineSeconds: 30 # 指定Job可以运行的时间期限,超过时间还没结束,系统将会尝试进行终止
          backoffLimit: 6 # 指定Job失败后进行重试的次数,默认为6
          template: # 模板,当副本数量不足时,会根据下面的模板创建Pod模板
            spec:
              restartPolicy: Never # 重启策略只能设置为Never或OnFailure
              containers:
                - name: counter
                  image: busybox:1.30
                  command: [ "/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 20;done" ]
    schedule:cron表达式,用于指定任务的执行时间。
    ● */1  *  *  *  *:表示分钟  小时  日  月份  星期。
    ● 分钟的值从0到59。
    ● 小时的值从0到23。
    ● 日的值从1到31。
    ● 月的值从1到12。
    ● 星期的值从0到6,0表示星期日。
    ● 多个时间可以用逗号隔开,范围可以用连字符给出:* 可以作为通配符,/表示每...
    concurrencyPolicy:并发执行策略
    ● Allow:运行Job并发运行(默认)。
    ● Forbid:禁止并发运行,如果上一次运行尚未完成,则跳过下一次运行。
    ● Replace:替换,取消当前正在运行的作业并使用新作业替换它。
    

     创建pc-cronjob.yml文件

    apiVersion: batch/v1beta1 # 版本号
    kind: CronJob # 类型
    metadata: # 元数据
      name: pc-cronjob # 名称
      namespace: dev  #命名空间
    spec: # 详情描述
      schedule: "*/1 * * * * " # cron格式的作业调度运行时间点,用于控制任务任务时间执行
      jobTemplate: # job控制器模板,用于为cronjob控制器生成job对象,下面其实就是job的定义
        metadata: {}
        spec:
          template: # 模板,当副本数量不足时,会根据下面的模板创建Pod模板
            spec:
              restartPolicy: Never # 重启策略只能设置为Never或OnFailure
              containers:
                - name: counter
                  image: busybox:1.30
                  command: [ "/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 2;done" ]
                
    #创建CronJob
    [root@master ~]# kubectl create -f pc-cronjob.yml
    cronjob.batch/pc-cronjob created
    
    #查看cronjob
    [root@master ~]# kubectl get cronjob -n dev -w
    NAME         SCHEDULE       SUSPEND   ACTIVE   LAST SCHEDULE   AGE
    pc-cronjob   */1 * * * *    False     0        <none>          0s
    pc-cronjob   */1 * * * *    False     1        8s              23s
    pc-cronjob   */1 * * * *    False     0        28s             43s
    pc-cronjob   */1 * * * *    False     1        8s              83s
    pc-cronjob   */1 * * * *    False     0        28s             103s
    
    #删除CronJob
    [root@master ~]# kubectl  delete -f pc-cronjob.yml 
    cronjob.batch "pc-cronjob" deleted
    
     
  • 相关阅读:
    350. Intersection of Two Arrays II
    94. Binary Tree Inorder Traversal
    623. Add One Row to Tree
    JS判断是否为数字,中文,小写、大写字母
    ASP.NET 操作Cookie详解 增加,修改,删除
    ASP.NET MVC 入门1、简介
    通过LINQ TO SQL类显示数据库表的数据
    OutputCache缓存优化asp.net代码 提高网页性能
    数据库读取二进制图片显示到PictureBox中
    WinForm窗体间如何传值的几种方法
  • 原文地址:https://www.cnblogs.com/diqiyao/p/15523878.html
Copyright © 2020-2023  润新知