k8s(pod)详解

  • k8s(pod)详解已关闭评论
  • 57 次浏览
  • A+
所属分类:linux技术
摘要

pod资源的各种配置和原理关于很多yaml文件的编写,都是基于配置引出来的 每个Pod中都可以包含一个或者多个容器,这些容器可以分为2大类:


一:Pod介绍

pod资源的各种配置和原理

关于很多yaml文件的编写,都是基于配置引出来的

1:pod的结构和定义

k8s(pod)详解

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

  1:用户所在的容器,数量可多可少(用户容器)

  2:pause容器,这是每个pod都会有的一个跟容器,作用有2个

    1、可以以它为根据,评估整个pod的健康状态

    2、可以在根容器上面设置ip地址,其他容器都以此ip,实现Pod内部的网络通信

      这里的Pod内部通讯是,pod之间采用二层网络技术来实现

      ;其他容器都共享这个根容器的ip地址,外界访问这个根容器ip地址+端口即可

2:pod定义

pod的资源清单:

属性,依次类推的进行查找

[root@master /]# kubectl  explain pod #查看二级属性 [root@master /]# kubectl  explain pod.metadata 

 

介绍

apiVersion 版本 #查看所有的版本 [root@master /]# kubectl  api-versions admissionregistration.k8s.io/v1 apiextensions.k8s.io/v1 apiregistration.k8s.io/v1 apps/v1 authentication.k8s.io/v1 authorization.k8s.io/v1 autoscaling/v1 autoscaling/v2 batch/v1 certificates.k8s.io/v1 coordination.k8s.io/v1 discovery.k8s.io/v1 events.k8s.io/v1 flowcontrol.apiserver.k8s.io/v1beta2 flowcontrol.apiserver.k8s.io/v1beta3 networking.k8s.io/v1 node.k8s.io/v1 policy/v1 rbac.authorization.k8s.io/v1 scheduling.k8s.io/v1 storage.k8s.io/v1 v1  kind 类型 #查看资源的类型 [root@master /]# kubectl  api-resources   metadata  元数据,资源的名字,标签等等 [root@master /]# kubectl  explain  pod.metadata   status   状态信息,自动的进行生成,不需要自己定义 [root@master /]# kubectl  get pods -o yaml  spec  定义资源的详细信息, 下面的子属性 containers:object  容器列表,用于定义容器的详细信息 nodename:string   根据nodename的值将pod的调度到指定的node节点,pod部署在哪个Pod上面 nodeselector:pod标签选择器,可以将pod调度到包含这些label的Node上 hostnetwork:默认是false,k8s自动的分配一个ip地址,如果设置为true,就使用宿主机的ip volumes:存储卷,用于定义pod上面挂载的存储信息 restartpolicy:重启策略,表示pod在遇到故障的时候处理的策略

3:pod配置

主要关于pod.spec.containers属性

里面有的是数组,就是可以选择多个值,在里面的话,有的只是一个值,看情况进行区分

[root@master /]# kubectl  explain pod.spec.containers KIND:       Pod VERSION:    v1  name:容器名称 image:容器需要的镜像地址 imagePullPolicy:镜像拉取策略  本地的还是远程的 command:容器的启动命令列表,如不指定,使用打包时使用的启动命令  string args:容器的启动命令需要的参数列表,也就是上面的列表的命令   string env:容器环境变量的配置   object ports:容器需要暴露的端口列表   object resources:资源限制和资源请求的设置   object 

1、基本配置

[root@master ~]# cat pod-base.yaml  apiVersion: v1 kind: Pod metadata:   name: pod-base   namespace: dev   labels:     user: qqqq spec:    containers:      - name: nginx        image: nginx:1.17.1      - name: busybox        image: busybox:1.30  简单的Pod的配置,里面有2个容器 nginx轻量级的web软件 busybox:就是一个小巧的Linux命令集合  [root@master ~]# kubectl create  -f pod-base.yaml  pod/pod-base created  #查看Pod状态, ready:只有里面有2个容器,但是只有一个是准备就绪的,还有一个没有启动 restarts:重启的次数,因为有一个容器故障了,Pod一直重启试图恢复它 [root@master ~]# kubectl get pods -n dev NAME       READY   STATUS             RESTARTS      AGE pod-base   1/2     CrashLoopBackOff   4 (29s ago)   2m36s  #可以查看pod详情 [root@master ~]# kubectl describe  pods pod-base -n dev Events:   Type     Reason     Age                   From               Message   ----     ------     ----                  ----               -------   Normal   Scheduled  4m51s                 default-scheduler  Successfully assigned dev/pod-base to node2   Normal   Pulling    4m51s                 kubelet            Pulling image "nginx:1.17.1"   Normal   Pulled     4m17s                 kubelet            Successfully pulled image "nginx:1.17.1" in 33.75s (33.75s including waiting)   Normal   Created    4m17s                 kubelet            Created container nginx   Normal   Started    4m17s                 kubelet            Started container nginx   Normal   Pulling    4m17s                 kubelet            Pulling image "busybox:1.30"   Normal   Pulled     4m9s                  kubelet            Successfully pulled image "busybox:1.30" in 8.356s (8.356s including waiting)   Normal   Created    3m27s (x4 over 4m9s)  kubelet            Created container busybox   Normal   Started    3m27s (x4 over 4m9s)  kubelet            Started container busybox   Warning  BackOff    2m59s (x7 over 4m7s)  kubelet            Back-off restarting failed container busybox in pod pod-base_dev(2e9aeb3f-2bec-4af5-853e-2d8473e115a7)   Normal   Pulled     2m44s (x4 over 4m8s)  kubelet            Container image "busybox:1.30" already present on machine  

之后再来进行解决

2、镜像拉取

imagePullPolicy

就是pod里面有个容器,一个有本地镜像,一个没有,可以使用这个参数来进行控制是本地还是远程的

imagePullPolicy的值,

  Always:总是从远程仓库进行拉取镜像(一直用远程下载)

  ifNotPresent:本地有则使用本地的镜像,本地没有则使用从远程仓库拉取镜像

  Never:一直使用本地的,不使用远程下载

如果镜像的tag为具体的版本号:默认值是ifNotPresent,

 如果是latest:默认策略是always

[root@master ~]# cat pod-policy.yaml  apiVersion: v1 kind: Pod metadata:   name: pod-imagepullpolicy   namespace: dev   labels:     user: qqqq spec:    containers:      - name: nginx        image: nginx:1.17.2        imagePullPolicy: Never      - name: busybox        image: busybox:1.30  [root@master ~]# kubectl create -f pod-policy.yaml  pod/pod-imagepullpolicy created  #查看pods状态 [root@master ~]# kubectl get pods -n dev NAME                  READY   STATUS             RESTARTS        AGE pod-base              1/2     CrashLoopBackOff   9 (3m59s ago)   25m pod-imagepullpolicy   0/2     CrashLoopBackOff   1 (9s ago)      19s  #查看详细的信息 [root@master ~]# kubectl describe  pods pod-imagepullpolicy -n dev  Events:   Type     Reason             Age                From               Message   ----     ------             ----               ----               -------   Normal   Scheduled          64s                default-scheduler  Successfully assigned dev/pod-imagepullpolicy to node1   Normal   Pulling            64s                kubelet            Pulling image "busybox:1.30"   Normal   Pulled             56s                kubelet            Successfully pulled image "busybox:1.30" in 8.097s (8.097s including waiting)   Normal   Created            39s (x3 over 56s)  kubelet            Created container busybox   Normal   Started            39s (x3 over 56s)  kubelet            Started container busybox   Normal   Pulled             39s (x2 over 55s)  kubelet            Container image "busybox:1.30" already present on machine   Warning  ErrImageNeverPull  38s (x6 over 64s)  kubelet            Container image "nginx:1.17.2" is not present with pull policy of Never   Warning  Failed             38s (x6 over 64s)  kubelet            Error: ErrImageNeverPull   Warning  BackOff            38s (x3 over 54s)  kubelet            Back-off restarting failed container busybox in pod pod-imagepullpolicy_dev(38d5d2ff-6155-4ff3-ad7c-8b7f4a370107)  #直接报了一个错误,就是镜像拉取失败了  #解决的措施,修改里面的策略为ifnotpresent即可 [root@master ~]# kubectl  delete  -f pod-policy.yaml  [root@master ~]# kubectl  apply  -f pod-policy.yaml  [root@master ~]# kubectl  get pods -n dev [root@master ~]# kubectl  get pods -n dev NAME                  READY   STATUS             RESTARTS         AGE pod-base              1/2     CrashLoopBackOff   11 (2m34s ago)   34m pod-imagepullpolicy   1/2     CrashLoopBackOff   4 (63s ago)      2m55s 这样就拉取成功了 

3、启动命令

command:容器启动的命令列表,如果不指定的话,使用打包时使用的启动命令

args:容器的启动命令需要的参数列表

为什么没有busybox运行了,busybox并不是一个程序,而是类似于一个工具类的集合,他会自动的进行关闭,解决的方法就是让其一直的运行,这就要使用command命令了

[root@master ~]# cat command.yaml  apiVersion: v1 kind: Pod metadata:   name: pod-command   namespace: dev spec:    containers:      - name: nginx        image: nginx:1.17.1      - name: busybox        image: busybox:1.30        command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hell0.txt;sleep 3;done;"]   #/bin/sh  命令行脚本 -c  之后的字符串作为一个命令来执行 向这个文件里面执行时间,然后执行结束后,休息3秒钟,这个就是一个进程一直在运行  [root@master ~]# kubectl  create -f command.yaml  pod/pod-command created  #这样就好了,都启动了 [root@master ~]# kubectl get pods -n dev NAME          READY   STATUS    RESTARTS   AGE pod-command   2/2     Running   0          6s  #进入这个容器 [root@master ~]# kubectl  exec pod-command -n dev -it -c busybox /bin/sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / #   这样就成功的进入里面去了 / # cat /tmp/hell0.txt ,因为有这个进程的存在,就不是关闭掉 

  

说明:发现command已经完成启动命令后和传递参数后的功能,为什么还需要提供一个args的选项了,用于传递参数呢,这其实跟docker有点关系,整个个就是覆盖dockerfile中的entrypoint的功能

k8s拉取镜像的时候,里面有一个dockerfile来构建镜像,然后k8s的command和args会替换

情况:

  1,如果command和args没有写,那么用dockerfile的配置

  2、如果command写了,但是args没有写,那么用dockerfile默认配置会被忽略,执行输入的command命令

  3、如果command没写,但是args写了,那么dockerfile中的配置的entrypoint命令会被执行,使用当前的args的参数

  4、如果都写了,那么dockerfile的配置被忽略,执行command并追上args参数

 4、环境变量(了解即可)

env向容器里面传入环境变量,object类型的数组

键值对,就是一个键加上一个值即可

[root@master ~]# cat pod-env.yaml  apiVersion: v1 kind: Pod metadata:   name: pod-command   namespace: dev spec:    containers:      - name: nginx        image: nginx:1.17.1      - name: busybox        image: busybox:1.30        command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hell0.txt;sleep 3;done;"]        env:        - name: "username"           vaule : "admin"        - name: "password"          vaule: "123456"   #创建Pod [root@master ~]# kubectl create -f pod-env.yaml  pod/pod-command created [root@master ~]# kubectl get pods -n dev NAME          READY   STATUS    RESTARTS   AGE pod-command   2/2     Running   0          47s   #进入容器里面 -c选项,只有一个容器的话,可以省略掉即可 [root@master ~]# kubectl  exec -ti pod-command -n dev -c busybox /bin/sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / # ls bin   dev   etc   home  proc  root  sys   tmp   usr   var / # echo $username admin / # echo password password 

5、端口设置(ports)

查看端口一些选项  

[root@master ~]# kubectl  explain  pod.spec.containers.ports ports     name:端口的名称,必须是在Pod中是唯一的    containerport 容器要监听的端口    hostport 容器要在主机上公开的端口,如果设置,主机上只能运行容器的一个副本,会有冲突,多个Pod会占用一个端口    hostip  要将外部端口绑定到主机的Ip(一般省略了)    protocol  端口协议,默认是TCP,UTP,SCTP    

k8s(pod)详解

 

案例:

[root@master ~]# cat pod-port.yaml  apiVersion: v1 kind: Pod metadata:   name: pod-ports   namespace: dev spec:    containers:    - name: nginx      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80        protocol: TCP  kubectl create -f pod-port.yaml  [root@master ~]# kubectl get pod -n dev -o wide NAME          READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES pod-command   2/2     Running   0          27m     10.244.1.2   node2   <none>           <none> pod-ports     1/1     Running   0          2m58s   10.244.2.2   node1   <none>           <none>  #访问容器里面的程序的话,需要使用Pod的ip加上容器的端口即可,进行访问 [root@master ~]# curl 10.244.2.2:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>     body {         width: 35em;         margin: 0 auto;         font-family: Tahoma, Verdana, Arial, sans-serif;     } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>  <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p>  <p><em>Thank you for using nginx.</em></p> </body> </html> 

6、资源限制(resources)

因为容器的运行需要占用一些资源,就是对某些容器进行资源的限制,如果某个资源突然大量的值内存的话,其他的容器就不能正常的工作了,就会出现问题

就是规定A容器只需要600M内存,如果大于的话,就出现了问题,进行重启容器的操作

有2个字选项:

limits:用于限制运行时容器的最大占用资源,当容器占用的资源超过了limits会被终止,并就进行重启(上限)

requests:用于设置容器需要的最小资源,如果环境资源不够的话,容器无法进行启动(下限)  

  作用:

    1、只针对cpu,内存

案例:

[root@master ~]# cat pod-r.yaml  apiVersion: v1 kind: Pod metadata:   name: pod-resources   namespace: dev spec:    containers:    - name: nginx      image: nginx:1.17.1      resources:         limits:            cpu: "2"            memory: "10Gi"         requests:             cpu: "1"             memory: "10Mi"  kubectl create -f pod-r.yaml  [root@master ~]# kubectl get pods -n dev NAME            READY   STATUS    RESTARTS   AGE pod-command     2/2     Running   0          41m pod-ports       1/1     Running   0          16m pod-resources   1/1     Running   0          113s   #规定最少需要10G才能启动容器,但是不会进行启动 [root@master ~]# cat pod-r.yaml  apiVersion: v1 kind: Pod metadata:   name: pod-resources   namespace: dev spec:    containers:    - name: nginx      image: nginx:1.17.1      resources:         limits:            cpu: "2"            memory: "10Gi"         requests:             cpu: "1"             memory: "10G" [root@master ~]# kubectl create -f pod-r.yaml  pod/pod-resources created  #查找状态 [root@master ~]# kubectl get pods -n dev NAME            READY   STATUS    RESTARTS   AGE pod-command     2/2     Running   0          44m pod-ports       1/1     Running   0          19m pod-resources   0/1     Pending   0          89s  #查看详细的信息 [root@master ~]# kubectl  describe  pods pod-resources -n dev  cpu和内存的单位 cpu为整数 内存为Gi Mi  G M等形式

二:pod生命周期    

 1:概念

一般是指Pod对象从创建至终的时间范围称为pod的生命周期,主要包含一下过程

  1、pod创建过程

  2、运行初始化容器过程,它是容器的一种,可多可少,一定在主容器运行之前执行

  3、运行主容器过程

    容器启动后钩子,容器终止前钩子,就是启动之后的一些命令,2个特殊的点

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

  4、pod终止过程

k8s(pod)详解

在整个生命周期中,pod会出现5中状态

挂起(pending):apiserver,已经创建了pod资源对象,但它尚未被调度,或者仍然处于下载镜像的过程中;创建一个pod,里面有容器,需要拉取

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

成功(succeeded):Pod中的所有容器都已经被成功终止,并且不会被重启;就是运行一个容器,30秒后,打印,然后退出

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

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

2:pod创建和终止

pod的创建过程:

k8s(pod)详解

都监听到apiserver上面了 

开始创建就已经返回一个信息了,给etcd了,

scheduler:开始为pod分配主机,将结果告诉apiserver

node节点上面发现有pod调度过来,调用docker启动容器,并将结果告诉apiserver

apiserver将接收的信息pod状态信息存入etcd中

pod的终止过程:

k8s(pod)详解

service就是Pod的代理,访问pod通过service即可

 向apiserver发送一个请求,apiserver更新pod的状态,将pod标记为terminating状态,kubelet监听到为terminating,就启动关闭pod过程

3:初始化容器

主要做的就是主容器的前置工作(环境的准备),2个特点

  1、初始化容器必须运行在完成直至结束,若某初始化容器运行失败了,那么k8s需要重启它知道成功完成

  2、初始化容器必须按照定义的顺序执行,当且仅当前一个成功了,后面的一个才能运行,否则不运行

初始化容器应用场景:

  提供主容器进行不具备工具程序或自定义代码

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

      nginx,mysql,redis,  先连mysql,不成功,则会一直处于连接, 一直连成功了,就会去连接redis,这2个条件都满足了,nginx这个主容器就会启动了

测试:

规定mysql 192.168.109.201  redis 192.168.109.202

 

[root@master ~]# cat pod-init.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-init    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80    initContainers:    - name: test-mysql      image: busybox:1.30      command: ['sh','-c','util ping 192.168.109.201 -c 1;do echo waiting for mysql;sleep 2;done;']    - name: test-redis      image: busybox:1.30      command: ['sh','-c','util ping 192.168.109.202 -c 1;di echo waiting for redis;sleep 2;done'] #由于没有地址,所以的话,初始化失败 [root@master ~]# kubectl get pods -n dev NAME       READY   STATUS                  RESTARTS      AGE pod-init   0/1     Init:CrashLoopBackOff   3 (27s ago)   83s  #添加地址,第一个初始化容器就能运行了 [root@master ~]# ifconfig  ens33:1 192.168.109.201 netmask 255.255.255.0 up  #再次添加地址,第二个初始化容器也能运行了 [root@master ~]# ifconfig  ens33:2 192.168.109.202 netmask 255.255.255.0 up [root@master ~]# kubectl get pods -n dev -w NAME       READY   STATUS     RESTARTS   AGE pod-init   0/1     Init:0/2   0          6s pod-init   0/1     Init:1/2   0          13s pod-init   0/1     Init:1/2   0          14s pod-init   0/1     PodInitializing   0          27s pod-init   1/1     Running           0          28s  主容器就运行成功了 

4:主容器钩子函数

就是主容器上面的一些点,能够允许用户使用一些代码

2个点  

k8s(pod)详解

post start:容器启动后钩子,容器启动之后会立即的执行,成功了,则启动,否则,会重启

prestop:容器终止前钩子,容器在删除之前执行,就是terming状态,会阻塞容器删除,执行成功了,就会删除

1、钩子处理器(三种方式定义动作)

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

用的最多的exec方式

lifecycle:    podstart:      exec:        command:         - cat         - /tmp/healthy 

tcpsocket:在当前容器内尝试访问指定socket,在容器内部访问8080端口

lifecycle:    podstart:       tcpsocket:          port:8080   #会尝试连接8080端口  

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

lifecycle:    poststart:     httpGet:      path: url地址      port:   80      host: 主机地址      schme: HTTP 支持的协议  

案例:

apiVersion: v1 kind: Pod metadata:    name: pod-exec    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80  #容器内部的端口,一般是service将公开pod端口,将pod端口映射到主机上面      lifecycle:        postStart:          exec:   ###在启动的时候,执行一个命令,修改默认网页内容             command: ["/bin/sh","-c","echo poststart > /usr/share/nginx/html/index.html"]        preStop:           exec:    ###停止容器的时候,-s传入一个参数,优雅的停止nginx服务              command: ["/usr/sbin/nginx","-s","quit"]  [root@master ~]# kubectl create -f pod-exec.yaml  pod/pod-exec created [root@master ~]# kubectl get pods -n dev -o wide NAME       READY   STATUS    RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES pod-exec   1/1     Running   0          53s   10.244.1.7   node1   <none>           <none> pod-init   1/1     Running   0          27m   10.244.1.6   node1   <none>           <none>  访问一下pod里面容器的服务即可 格式为pod的ip+容器的端口 [root@master ~]# curl 10.244.1.7:80 poststart

5:容器探测  

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

分别是:

  liveness probes:存活性探针,用于检测应用实例,是否处于正常的运行状态,如果不是,k8s会重启容器;用于决定是否重启容器

  readiness probes:就绪性探针,用于检测应用实例是否可以接受请求,如果不能,k8s不会转发流量;nginx需要读取很多的web文件,在读取的过程中,service认为nginx已经成功了,如果有个请求的话,那么就无法提供了服务;所以就不会将请求转发到这里了

就是一个service来代理许多的pod,请求来到了pod,如果有一个pod出现了问题,如果没有了探针的话,就会出现了问题

作用

  1、找出这些出了问题的pod

  2、服务是否已经准备成功了

三种探测方式:

exec:退出码为0,则正常

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

tcpsocket:

livenessProbe:     tcpSocket:        port: 8080

httpget:

返回的状态码在200个399之间,则认为程序正常,否则不正常

livenessProbe:     httpGet:       path: /  url地址        port:80  主机端口        host:主机地址        scheme:http       

案例:

exec案例:

[root@master ~]# cat pod-live-exec.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-liveness-exec    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80      livenessProbe:         exec:           command: ["/bin/cat","/tmp/hello.txt"]   #由于没有这个文件,所以就会一直进行重启  #出现了问题,就会处于一直重启的状态 [root@master ~]# kubectl get pods -n dev NAME                READY   STATUS    RESTARTS      AGE pod-exec            1/1     Running   0             38m pod-init            1/1     Running   0             65m pod-liveness-exec   1/1     Running   2 (27s ago)   97s  #查看pod的详细信息 [root@master ~]# kubectl describe  pod -n dev pod-liveness-exec  Events:   Type     Reason     Age                 From               Message   ----     ------     ----                ----               -------   Normal   Scheduled  2m13s               default-scheduler  Successfully assigned dev/pod-liveness-exec to node2   Normal   Pulling    2m12s               kubelet            Pulling image "nginx:1.17.1"   Normal   Pulled     2m                  kubelet            Successfully pulled image "nginx:1.17.1" in 12.606s (12.606s including waiting)   Normal   Created    33s (x4 over 2m)    kubelet            Created container main-container   Normal   Started    33s (x4 over 2m)    kubelet            Started container main-container   Warning  Unhealthy  33s (x9 over 113s)  kubelet            Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory   Normal   Killing    33s (x3 over 93s)   kubelet            Container main-container failed liveness probe, will be restarted   Normal   Pulled     33s (x3 over 93s)   kubelet            Container image "nginx:1.17.1" already present on machine  #一直在重启 [root@master ~]# kubectl get pods -n dev NAME                READY   STATUS             RESTARTS      AGE pod-exec            1/1     Running            0             39m pod-init            1/1     Running            0             66m pod-liveness-exec   0/1     CrashLoopBackOff   4 (17s ago)   2m57s   #一个正常的案例 [root@master ~]# cat pod-live-exec.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-liveness-exec    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80      livenessProbe:         exec:           command: ["/bin/ls","/tmp/"] [root@master ~]# kubectl create -f pod-live-exec.yaml  pod/pod-liveness-exec created  #就不会一直重启了 [root@master ~]# kubectl get pods -n dev NAME                READY   STATUS    RESTARTS   AGE pod-exec            1/1     Running   0          42m pod-init            1/1     Running   0          69m pod-liveness-exec   1/1     Running   0          56s  #查看详细的信息,发现没有错误 

  

tcpsocket:  

[root@master ~]# cat tcp.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-liveness-tcp    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80      livenessProbe:         tcpSocket:            port: 8080    访问容器的8080端口   kubectl create -f tcp.yaml #发现一直在进行重启,没有访问到8080端口 [root@master ~]# kubectl get pods -n dev NAME               READY   STATUS    RESTARTS      AGE pod-liveness-tcp   1/1     Running   5 (72s ago)   3m43s  #查看详细的信息 [root@master ~]# kubectl describe  pod -n dev pod-liveness-tcp   Events:   Type     Reason     Age                    From               Message   ----     ------     ----                   ----               -------   Normal   Scheduled  3m22s                  default-scheduler  Successfully assigned dev/pod-liveness-tcp to node2   Normal   Pulled     112s (x4 over 3m22s)   kubelet            Container image "nginx:1.17.1" already present on machine   Normal   Created    112s (x4 over 3m22s)   kubelet            Created container main-container   Normal   Started    112s (x4 over 3m22s)   kubelet            Started container main-container   Normal   Killing    112s (x3 over 2m52s)   kubelet            Container main-container failed liveness probe, will be restarted   Warning  Unhealthy  102s (x10 over 3m12s)  kubelet            Liveness probe failed: dial tcp 1 

正常的案例:

[root@master ~]# cat tcp.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-liveness-tcp    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80      livenessProbe:         tcpSocket:            port: 80   #查看效果,没有任何的问题 [root@master ~]# kubectl describe  pods -n dev  pod-liveness-tcp  Events:   Type    Reason     Age   From               Message   ----    ------     ----  ----               -------   Normal  Scheduled  27s   default-scheduler  Successfully assigned dev/pod-liveness-tcp to node2   Normal  Pulled     28s   kubelet            Container image "nginx:1.17.1" already present on machine   Normal  Created    28s   kubelet            Created container main-container   Normal  Started    28s   kubelet            Started container main-container

httpget

[root@master ~]# cat tcp.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-liveness-http    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80      livenessProbe:         httpGet:            scheme: HTTP            port: 80            path: /hello   # http://127.0.0.1:80/hello   #发现一直在进行重启的操作 [root@master ~]# kubectl describe pod  -n dev  pod-liveness-http  [root@master ~]# kubectl get pods -n dev NAME                READY   STATUS    RESTARTS      AGE pod-liveness-http   1/1     Running   1 (17s ago)   48s pod-liveness-tcp    1/1     Running   0             4m21s  #正常的情况 [root@master ~]# cat tcp.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-liveness-http    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80      livenessProbe:         httpGet:            scheme: HTTP            port: 80            path: / [root@master ~]# kubectl describe  pods -n dev pod-liveness-http  Events:   Type    Reason     Age   From               Message   ----    ------     ----  ----               -------   Normal  Scheduled  21s   default-scheduler  Successfully assigned dev/pod-liveness-http to node1   Normal  Pulled     22s   kubelet            Container image "nginx:1.17.1" already present on machine   Normal  Created    22s   kubelet            Created container main-container   Normal  Started    22s   kubelet            Started container main-container

容器探测补充

[root@master ~]# kubectl explain pod.spec.containers.livenessProbe initialDelaySeconds	<integer>  容器启动后等待多少秒执行第一次探测 timeoutSeconds	<integer>   探测超时时间,默认是1秒,最小1秒 periodSeconds	<integer>   执行探测的频率,默认是10秒,最小是1秒 failureThreshold	<integer>    连续探测失败多少次后才被认为失败,默认是3,最小值是1 successThreshold	<integer>  连续探测成功多少次后才被认定为成功,默认是1

案例:

6:重启策略

就是容器探测出现了问题,k8s就会对容器所在的Pod进行重启,这个由pod的重启策略决定的,pod的重启策略有三种

  always:容器失效时,自动重启该容器,默认值

  onfailure:容器终止运行且退出码不为0时重启,异常终止

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

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

案例:

apiVersion: v1 kind: Pod metadata:    name: restart-pod    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:      - name: nginx-port        containerPort: 80      livenessProbe:         httpGet:            scheme: HTTP            port: 80            path: /hello   # http://127.0.0.1:80/hello    restartPolicy: Always  #会一直进行重启  #改为Never 容器监听失败了,就不会进行重启,直接停止了 状态是完成的状态, [root@master ~]# kubectl get pods -n dev NAME                READY   STATUS      RESTARTS      AGE pod-liveness-http   1/1     Running     1 (16h ago)   16h pod-liveness-tcp    1/1     Running     1 (22m ago)   16h restart-pod         0/1     Completed   0             41s  [root@master ~]# kubectl describe  pod -n dev  restart-pod   Events:   Type     Reason     Age                From               Message   ----     ------     ----               ----               -------   Normal   Scheduled  84s                default-scheduler  Successfully assigned dev/restart-pod to node1   Normal   Pulled     84s                kubelet            Container image "nginx:1.17.1" already present on machine   Normal   Created    84s                kubelet            Created container main-container   Normal   Started    84s                kubelet            Started container main-container   Warning  Unhealthy  55s (x3 over 75s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404   Normal   Killing    55s                kubelet            Stopping container main-container

三:pod调度

默认的情况下,一个Pod在哪个节点上面运行,是有scheduler组件采用相应的算法计算出来,这个过程是不受人工控制的,但是在实际中,这不满足需求,需要控制pod在哪个节点上面运行,这个就需要调度的规则了,四大类调度的方式

自动调度:经过算法自动的调度

定向调度:通过nodename属性(node的名字),nodeselector(标签)

亲和性调度:nodeAffinity(node的亲和性),podAffinity(pod的亲和性),podANtiAffinity(这个就是跟Pod的亲和性差,所以就去相反的一侧)

污点(容忍调度):站在node节点上面完成的,有一个污点,别人就不能在;容忍站在pod上面来说的,可以在node上面的污点进行就是容忍调度

1:定向调度

指定的是pod声明nodename,或者nodeselector,依次将pod调度到指定的node节点上面,这个是强制性的,即使node不存在,也会被调度,只不过是pod运行失败而已

1、nodename

强制的调度,直接跳过了scheduler的调度逻辑,直接将pod调度到指定的节点上面

[root@master ~]# cat pod-nodename.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-nodename    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1      ports:    nodeName: node1  [root@master ~]# kubectl create  -f pod-nodename.yaml  pod/pod-nodename created #运行在node1上面运行 [root@master ~]# kubectl get pods -n dev -o wide NAME                READY   STATUS    RESTARTS      AGE   IP            NODE    NOMINATED NODE   READINESS GATES pod-liveness-http   1/1     Running   1 (16h ago)   17h   10.244.2.8    node1   <none>           <none> pod-liveness-tcp    1/1     Running   1 (42m ago)   17h   10.244.1.7    node2   <none>           <none> pod-nodename        1/1     Running   0             41s   10.244.2.10   node1   <none>           <none>  #将节点改为不存在的,pod会失败而已 [root@master ~]# kubectl get pods -n dev -o wide NAME                READY   STATUS    RESTARTS      AGE   IP           NODE    NOMINATED NODE   READINESS GATES pod-liveness-http   1/1     Running   1 (16h ago)   17h   10.244.2.8   node1   <none>           <none> pod-liveness-tcp    1/1     Running   1 (43m ago)   17h   10.244.1.7   node2   <none>           <none> pod-nodename        0/1     Pending   0             9s    <none>       node3   <none>           <none>  

2、nodeselector

看的就是节点上面的标签,标签选择器,强制性的

[root@master ~]# kubectl label  nodes node1 nodeenv=pro node/node1 labeled [root@master ~]# kubectl label  nodes node2 nodeenv=test node/node2 labeled [root@master ~]# cat pod-selector.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-select    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1    nodeSelector:        nodeenv: pro  [root@master ~]# kubectl get pods -n dev -o wide NAME                READY   STATUS    RESTARTS      AGE     IP            NODE    NOMINATED NODE   READINESS GATES pod-liveness-http   1/1     Running   1 (17h ago)   17h     10.244.2.8    node1   <none>           <none> pod-liveness-tcp    1/1     Running   1 (51m ago)   17h     10.244.1.7    node2   <none>           <none> pod-select          1/1     Running   0             2m16s   10.244.2.11   node1   <none>           <none>  #不存在的标签 改为pr1,调度失败 [root@master ~]# kubectl get pods -n dev NAME                READY   STATUS    RESTARTS      AGE pod-liveness-http   1/1     Running   1 (17h ago)   17h pod-liveness-tcp    1/1     Running   1 (51m ago)   17h pod-select          0/1     Pending   0             5s 

2:亲和性调度

上面的问题,就是强制性的调度,就是如果没有节点的话,Pod就会调度失败

就是声明一个调度的节点,如果找到了,就调度,否则,找其他的;这个就是亲和性

  nodeAffinity:node的亲和性,以node为目标,主要就是标签()

  podAffinity:pod的亲和性,以pod为目标,就是以正在运行的pod为目标,就是一个web的pod需要和一个mysql的pod在一起,向其中一个打个标签,另外一个就会来找他

  podAntAffinity:pod的反亲和性,以pod为目标,讨厌和谁在一起,就选择其他的

 

场景的说明:

如果2个应用时频繁交互,那么就有必要利用亲和性让2个应用尽可能的靠近,这样就能减少因为网络通信带来的性能损耗了,调度到了pod1上面就都在一个节点上面,通信的性能就损耗减少了

 

反亲和性的应用:

当应用的采用多副本部署时,有必要采用反亲和性让各个应用实列打散分布在各个node上面,这样就能提高服务的高可用性

应用的功能是相同的,使用反亲和性,都分布在不同的节点上面,高可用性,就是坏了一个节点,其他的节点也能正常的提供工作

参数:

[root@master ~]# kubectl explain pod.spec.affinity.nodeAffinity  requiredDuringSchedulingIgnoredDuringExecution  node节点必须满足的指定的所有规划才可以,相当于硬限制    nodeSelectorTerms:节点选择列表        matchFields:按节点字段列出的节点选择器要求列表        matchExpressions  按节点标签列出的节点选择器要求列表(标签)          key:          vaules:          operator:关系符,支持in, not exists  如果有符合的条件,就调度,没有符合的条件就调度失败  preferredDuringSchedulingIgnoredDuringExecution 	<NodeSelector>  软限制,优先找这些满足的节点     preference    一个节点选择器,以相应的权重相关联             matchFields:按节点字段列出的节点选择器要求列表             matchExpressions  按节点标签列出的节点选择器要求列表                    key:键                  vaules:                  operator:     weight:倾向权重,1~100  ##就是倾向调度       如果找不到的话,就从其他的节点调度上去  关系符  - key:nodedev   匹配存在标签的key为noddev的节点     operator: exists   - key:  nodedev   匹配标签的key为nodedev,且vaule是xxx或者yyy的节点    operator:in    vaules:['xxx','yyy']     

  

1、nodeAffinity

node的亲和性,2大类,硬限制,软限制,节点上面的标签作为选择

[root@master ~]# cat pod-aff-re.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-aff    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1    affinity:        nodeAffinity:   ##亲和性设置           requiredDuringSchedulingIgnoredDuringExecution:  #设置node亲和性,硬限制              nodeSelectorTerms:                        matchExpressions:     匹配nodeenv的值在[xxx,yyy]中的标签                     - key: nodeenv                       operator: In                       vaules: ["xxx","yyy"]  [root@master ~]# kubectl create -f pod-aff-re.yaml  pod/pod-aff created [root@master ~]# kubectl get pod -n dev NAME                READY   STATUS    RESTARTS      AGE pod-aff             0/1     Pending   0             23s pod-liveness-http   1/1     Running   1 (17h ago)   18h pod-liveness-tcp    1/1     Running   1 (94m ago)   18h pod-select          0/1     Pending   0             43m  #调度失败  #值改为pro,就能在node1上面调度了 [root@master ~]# kubectl create -f pod-aff-re.yaml  pod/pod-aff created [root@master ~]# kubectl get pods -n dev NAME                READY   STATUS    RESTARTS      AGE pod-aff             1/1     Running   0             5s pod-liveness-http   1/1     Running   1 (17h ago)   18h pod-liveness-tcp    1/1     Running   1 (96m ago)   18h pod-select          0/1     Pending   0             45m 

  

软限制

#软限制 [root@master ~]# cat pod-aff-re.yaml  apiVersion: v1 kind: Pod metadata:    name: pod-aff    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1    affinity:      nodeAffinity:        preferredDuringSchedulingIgnoredDuringExecution:   #软限制        - weight: 1              preference:             matchExpressions:             - key: nodeenv               operator: In               values: ["xxx","yyy"]   #直接调度在node2上面了 [root@master ~]# kubectl get pods -n dev -o wide NAME                READY   STATUS    RESTARTS       AGE   IP           NODE     NOMINATED NODE   READINESS GATES pod-aff             1/1     Running   0              41s   10.244.1.9   node2    <none>           <none> pod-liveness-http   1/1     Running   1 (17h ago)    18h   10.244.2.8   node1    <none>           <none> pod-liveness-tcp    1/1     Running   1 (102m ago)   18h   10.244.1.7   node2    <none>           <none> pod-select          0/1     Pending   0              50m   <none>       <none>   <none>           <none> 

 

注意:

如果同时定义了nodeSelector和nodeAffinity,那么必须满足这2个条件,pod才能在指定的node上面运行 如果nodeaffinity指定了多个nodeSelectorTerms,那么只要有一个能够匹配成功即可 如果一个nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有的才能匹配成功 如果一个Pod所在node在pod运行期间标签发生了改变,不符合该pod的节点亲和性需求,则系统将忽略此变化

 这个调度就是只在调度的时候生效,所以的话,就是如果调度成功后,标签发生了变化,不会对这个pod进行什么样的变化

2、podAffinitly

就是以正在运行的pod为参照,硬限制和软限制

kubectl explain pod.spec.affinity.podAffinity  requiredDuringSchedulingIgnoredDuringExecution   硬限制     namespace:指定参照pod的名称空间,如果不指定的话,默认的参照物pod就跟pod一眼的     topologkey:调度的作用域,靠近到节点上,还是网段上面,操作系统了                         ###hostname的话,就是以node节点为区分的范围,调度到node1的节点上面                                 os的话,就是以操作系统为区分的,调度到跟pod1操作系统上一样的      labeSelector:标签选择器           matchExpressions: 按节点列出的节点选择器要求列表                key:                vaules:                operator:           matchLbales:   指多个matchExpressions映射的内容 preferredDuringSchedulingIgnoredDuringExecution  软限制     namespace:指定参照pod的名称空间,如果不指定的话,默认的参照物pod就跟pod一眼的     topologkey:调度的作用域,靠近到节点上,还是网段上面,操作系统了                         ###hostname的话,就是以node节点为区分的范围,调度到node1的节点上面                                 os的话,就是以操作系统为区分的,调度到跟pod1操作系统上一样的      labeSelector:标签选择器           matchExpressions: 按节点列出的节点选择器要求列表                key:                vaules:                operator:           matchLbales:   指多个matchExpressions映射的内容     weight:倾向权重1~100 

 

案例:

软亲和性:

apiVersion: v1 kind: Pod metadata:   #元数据的信息    name: pods-1   #pod的名字    namespace: dev   #名称空间 spec:      containers:   #容器     - name: my-tomcat   #镜像的名字       image: tomcat    #拉取的镜像       imagePullPolicy: IfNotPresent   #策略为远程和本地都有   affinity:      podAffinity:   #pod的亲和性        preferredDuringSchedulingIgnoredDuringExecution:   #软限制        - weight: 1    #权重为1          podAffinityTerm:    #定义了具体的pod亲和性的条件           labelSelector:    #标签选择器              matchExpressions:   #一个或者多个标签匹配式                  - key: user   #标签的键                    operator: In                       values:    #标签的值                       - "qqqq"           topologyKey: kubernetes.io/hostname   #按照主机进行区分   就是这个pod会被调度到节点上面有pod,并且标签为user=qqqq这个节点上面去 

 

硬亲和性:

apiVersion: v1 kind: Pod metadata:    name: pod-5    namespace: dev spec:   containers:     - name: my-tomcat       image: tomcat       imagePullPolicy: IfNotPresent   affinity:      podAffinity:        requiredDuringSchedulingIgnoredDuringExecution:  #软限制          - labelSelector:   #标签选择器              matchExpressions:    #匹配列表                  - key: user                       operator: In                    values: ["qqqq"]               topologyKey: kubernetes.io/hostname    #按照主机来进行划分 

  

  

3、反亲和性

就是不在这个pod上面进行调度,在另外的一个pod上面进行调度即可

案例:

[root@master mnt]# cat podaff.yaml  apiVersion: v1 kind: Pod metadata:    name: podaff    namespace: dev spec:    containers:    - name: main-container      image: nginx:1.17.1    affinity:      podAntiAffinity:        requiredDuringSchedulingIgnoredDuringExecution:        - labelSelector:            matchExpressions:            - key: podenv              operator: In              values: ["pro"]          topologyKey: kubernets.io/hostname  发现在node2节点上面创建了 [root@master mnt]# kubectl get pods -n dev -o wide NAME         READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES pod-podaff   1/1     Running   0          61m     10.244.2.14   node1   <none>           <none> podaff       1/1     Running   0          2m57s   10.244.1.12   node2   <none>           <none>

 3:污点(taints)

 前面都是站在pod的角度上面来进行配置的属性,那么就是可以站在node的节点上面,是否允许这些pod调度过来,这些在node上面的信息就是被称为了污点

就是一个拒绝的策略

污点作用:

  可以将拒绝Pod调度过来

  甚至还可以将已经存在的pod赶出去

污点的格式:

key=value:effect

key和value:是污点的标签,effect描述污点的作用

effect三种的选项为:

  PreferNoSchedule:k8s尽量避免把Pod调度到具有该污点的node上面,除非没有其他的节点可以调度了

  NoSchedule:k8s不会把pod调度到该具有污点node上面,但不会影响当前node上已经存在的pod

  NoExecue:k8s将不会把Pod调度该具有污点的node上面,同时也会将node已经存在的Pod驱离,一个pod也没有了

k8s(pod)详解

 设置污点:

#设置污点 [root@master mnt]# kubectl taint  nodes node1 key=vaule:effect  #去除污点 [root@master mnt]# kubectl taint  nodes node1 key:effect-  #去除所有的污点 [root@master mnt]# kubectl taint  nodes node1 key- 

  

案例:

准备节点node1,先暂时停止node2节点 为node1节点一个污点,tag=heima:PreferNoSchedule;  然后创建pod1 修改node1节点设置一个污点;tag=heima:NoSchedule: 然后创建pod2,不在接收新的pod,原来的也不会离开 修改node1节点设置一个污点;tag=heima:NoExecute;然后创建pod3,pod3也不会被创建,都没有了pod了  #关掉node2节点即可  #设置node1污点 [root@master mnt]# kubectl taint  nodes node1 tag=heima:PreferNoSchedule node/node1 tainted #查看污点 [root@master mnt]# kubectl describe  nodes -n dev node1| grep heima Taints:             tag=heima:PreferNoSchedule  #第一个pod可以进行运行 [root@master mnt]# kubectl run taint1 --image=nginx:1.17.1 -n dev pod/taint1 created [root@master mnt]# kubectl  get pods -n dev  NAME         READY   STATUS        RESTARTS   AGE pod-podaff   1/1     Running       0          90m podaff       1/1     Terminating   0          31m taint1       1/1     Running       0          6s  #修改node1的污点 [root@master mnt]# kubectl taint  nodes node1 tag=heima:PreferNoSchedule- node/node1 untainted  [root@master mnt]# kubectl taint  nodes node1 tag=heima:NoSchedule node/node1 tainted  #第一个正常的运行,第二个运行不了 [root@master mnt]# kubectl run taint2 --image=nginx:1.17.1 -n dev pod/taint2 created [root@master mnt]# kubectl get pods -n dev NAME         READY   STATUS        RESTARTS   AGE pod-podaff   1/1     Running       0          94m podaff       1/1     Terminating   0          35m taint1       1/1     Running       0          3m35s taint2       0/1     Pending       0          3s  #第三种污点的级别 [root@master mnt]# kubectl taint  nodes node1 tag=heima:NoSchedule- node/node1 untainted 设置级别 [root@master mnt]# kubectl taint  nodes node1 tag=heima:NoExecute node/node1 tainted #新的pod也会不能创建了 [root@master mnt]# kubectl run taint3 --image=nginx:1.17.1 -n dev pod/taint3 created [root@master mnt]# kubectl get pods -n dev NAME     READY   STATUS        RESTARTS   AGE podaff   1/1     Terminating   0          39m taint3   0/1     Pending       0          4s 

  

为什么创建pod的时候,不能往master节点上面进行调度了,因为有污点的作用

4、容忍

 容忍就是忽略,node上面有污点,但是pod上面有容忍,进行忽略,可以进行调度

k8s(pod)详解

 案例:

apiVersion: v1 kind: Pod metadata:    name: pod-aff    namespace: dev spec:    containers:        - name: main-container      image: nginx:1.17.1    tolerations:     #添加容忍    - key: "tag"    #要容忍的key      operator: "Equal"     #操作符      values: "heima"            #容忍的污点      effect: "NoExecute"    #添加容忍的规划,这里必须和标记的污点规则相同  #首先创建一个没有容忍的pod,看能不能进行创建 #无法进行创建 [root@master mnt]# kubectl get pods -n dev NAME      READY   STATUS        RESTARTS   AGE pod-aff   0/1     Pending       0          6s podaff    1/1     Terminating   0          55m  #有容忍的创建 [root@master mnt]# kubectl create -f to.yaml  pod/pod-aff created [root@master mnt]# kubectl get pods -n dev NAME      READY   STATUS        RESTARTS   AGE pod-aff   1/1     Running       0          3s podaff    1/1     Terminating   0          57m 

  

容忍的详细信息

Key:对应的容忍的污点的值,空意味着匹配的所有的键 value:对应着容忍的污点的值 operator:key-value的运算符,支持Equal和Exists(默认),对于所有的键进行操作,跟值就没有关系了 effect:对应的污点的effect,空意味着匹配所有的影响 tolerationSeconds    容忍的时间,当effect为NoExecute时生效,表示pod在node上停留的时间 

  

 四:pod控制器

1、pod的控制器的介绍

1:pod的分类:

  自主式pod,k8s直接创建出来的pod,这种pod删除后就没有了。也不会重建

  控制器创建的pod,通过控制器创建的Pod,这种pod删除后,还会自动重建

作用

 pod控制器管理pod的中间层,使用了pod控制器后,我们需要告诉pod控制器,想要多少个pod即可,他会创建满足条件的pod并确保pod处于用户期望的状态,如果pod运行中出现了故障,控制器会基于策略重启或者重建pod

 

2:控制器类型

k8s(pod)详解

replicaSet:保证指定数量的pod运行支持数量变更

deployment:通过控制replicaSet来控制pod,支持滚动升级,版本回退的功能

horizontal pod autoscaler:可以根据集群负载均衡自动调整pod的数量

 

 2:控制器的详细介绍

replicaSet(rs)

:创建的数量的Pod能够正常的运行,会持续监听pod的运行状态

支持对pod数量的扩容缩容,

k8s(pod)详解

案例:副本数量

k8s(pod)详解

apiVersion: apps/v1 kind: ReplicaSet metadata:   name: pc-replicaset   #pod控制器的名字   namespace: dev   spec:    replicas: 3   #创建的pod的数量,    selector:   #pod标签选择器规则,选择app=nginx-pod的pod的标签用来进行管理,用来管理pod上面有相同的标签      matchLabels:    #标签选择器规则       app: nginx-pod      template:   副本,也就是创建pod的模版      metadata:    #pod元数据的信息        labels:    #pod上面的标签          app: nginx-pod          spec:            containers:   #容器里面的名字          - name: nginx               image: nginx:1.17.1     #查看控制器 [root@master ~]# kubectl get rs -n dev NAME            DESIRED   CURRENT   READY   AGE pc-replicaset   3         3         3       70s RESIRED 期望的pod数量 CURRENT:当前有几个 READY:准备好提供服务的有多少  #查看pod [root@master ~]# kubectl get rs,pods -n dev NAME                            DESIRED   CURRENT   READY   AGE replicaset.apps/pc-replicaset   3         3         3       2m31s  NAME                      READY   STATUS    RESTARTS      AGE pod/pc-replicaset-448tq   1/1     Running   0             2m31s pod/pc-replicaset-9tdhd   1/1     Running   0             2m31s pod/pc-replicaset-9z64w   1/1     Running   0             2m31s pod/pod-pod-affinity      1/1     Running   1 (47m ago)   12h  

案例2:实现扩缩容的pod

#编辑yaml文件 edit [root@master ~]# kubectl edit rs -n dev pc-replicaset  replicaset.apps/pc-replicaset edited [root@master ~]# kubectl get pods -n dev NAME                  READY   STATUS    RESTARTS      AGE pc-replicaset-448tq   1/1     Running   0             10m pc-replicaset-9tdhd   1/1     Running   0             10m pc-replicaset-9z64w   1/1     Running   0             10m pc-replicaset-q6ps9   1/1     Running   0             94s pc-replicaset-w5krn   1/1     Running   0             94s pc-replicaset-zx8gw   1/1     Running   0             94s pod-pod-affinity      1/1     Running   1 (55m ago)   12h [root@master ~]# kubectl get rs -n dev NAME            DESIRED   CURRENT   READY   AGE pc-replicaset   6         6         6       10m   #第二种方式 [root@master ~]# kubectl scale  rs -n dev pc-replicaset --replicas=2 -n dev replicaset.apps/pc-replicaset scaled [root@master ~]# kubectl get rs,pod -n dev  NAME                            DESIRED   CURRENT   READY   AGE replicaset.apps/pc-replicaset   2         2         2       12m  NAME                      READY   STATUS    RESTARTS      AGE pod/pc-replicaset-448tq   1/1     Running   0             12m pod/pc-replicaset-9tdhd   1/1     Running   0             12m pod/pod-pod-affinity      1/1     Running   1 (57m ago)   12h 

 

案例3、镜像的版本的升级

#编辑镜像的版本 [root@master ~]# kubectl edit rs -n dev pc-replicaset  replicaset.apps/pc-replicaset edited [root@master ~]# kubectl get rs -n dev pc-replicaset -o wide NAME            DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR pc-replicaset   2         2         2       15m   nginx        nginx:1.17.2   app=nginx-pod  #命令来进行编辑,但是一般使用edit来进行编辑即可 [root@master ~]# kubectl get rs -n dev -o wide NAME            DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR pc-replicaset   2         2         2       17m   nginx        nginx:1.17.1   app=nginx-pod 

  

案例4、删除replicaSet

就是先删除pod再来删除控制器

#文件来进行删除 root@master ~]# kubectl delete -f replicas.yaml  replicaset.apps "pc-replicaset" deleted [root@master ~]# kubectl get rs -n dev No resources found in dev namespace.  #命令来进行删除 [root@master ~]# kubectl delete rs -n dev pc-replicaset  replicaset.apps "pc-replicaset" deleted [root@master ~]# kubectl get rs -n dev No resources found in dev namespace.  

deployment(deploy)  

k8s(pod)详解

支持所有的RS的功能

 

k8s(pod)详解 

保留历史的版本,就是可以进行回退版本

滚动更新的策略

 更新策略:

案例:创建deployment

[root@master ~]# cat deploy.yaml  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.1 [root@master ~]# kubectl get deploy -n dev NAME            READY   UP-TO-DATE   AVAILABLE   AGE pc-deployment   3/3     3            3           53s  update:最新版本的pod数量 available:当前可用的pod的数量  #所以也会创建一个rs出来 [root@master ~]# kubectl get rs -n dev NAME                       DESIRED   CURRENT   READY   AGE pc-deployment-6cb555c765   3         3         3       2m9s  

扩缩容:

基本上和之前的一样的操作

#命令来进行编辑 [root@master ~]# kubectl scale deployment -n dev pc-deployment --replicas=5  deployment.apps/pc-deployment scaled [root@master ~]# kubectl get pods -n dev NAME                             READY   STATUS    RESTARTS      AGE pc-deployment-6cb555c765-8qc9g   1/1     Running   0             4m52s pc-deployment-6cb555c765-8xss6   1/1     Running   0             4m52s pc-deployment-6cb555c765-m7wdf   1/1     Running   0             4s pc-deployment-6cb555c765-plkbf   1/1     Running   0             4m52s pc-deployment-6cb555c765-qh6gk   1/1     Running   0             4s pod-pod-affinity                 1/1     Running   1 (81m ago)   13h  #编辑文件 [root@master ~]# kubectl edit deployments.apps -n dev pc-deployment  deployment.apps/pc-deployment edited [root@master ~]# kubectl get pods -n dev NAME                             READY   STATUS    RESTARTS      AGE pc-deployment-6cb555c765-8qc9g   1/1     Running   0             5m41s pc-deployment-6cb555c765-8xss6   1/1     Running   0             5m41s pc-deployment-6cb555c765-plkbf   1/1     Running   0             5m41s pod-pod-affinity                 1/1     Running   1 (82m ago)   13h 

 

镜像更新

分为重建更新,滚动更新

重建更新

一次性删除所有的来老版本的pod,然后再来创建新版本的pod

滚动更新:(默认)

先删除一部分的内容,进行更新,老的版本越来越少,新的版本越来越多

k8s(pod)详解

 

#重建策略 #先创建pod,实时观看 [root@master ~]# cat deploy.yaml  apiVersion: apps/v1 kind: Deployment metadata:    name: pc-deployment    namespace: dev spec:    strategy:      type: Recreate    replicas: 3    selector:       matchLabels:        app: nginx-pod    template:       metadata:          labels:            app: nginx-pod       spec:         containers:         - name: nginx           image: nginx:1.17.1  [root@master ~]# kubectl get pods -n dev -w  #然后更新镜像的版本 [root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.2 -n dev  #查看 pc-deployment-6cb555c765-m92t8   0/1     Terminating   0             60s pc-deployment-6cb555c765-m92t8   0/1     Terminating   0             60s pc-deployment-6cb555c765-m92t8   0/1     Terminating   0             60s pc-deployment-5967bb44bb-bbkzz   0/1     Pending       0             0s pc-deployment-5967bb44bb-bbkzz   0/1     Pending       0             0s pc-deployment-5967bb44bb-kxrn5   0/1     Pending       0             0s pc-deployment-5967bb44bb-zxfwl   0/1     Pending       0             0s pc-deployment-5967bb44bb-kxrn5   0/1     Pending       0             0s pc-deployment-5967bb44bb-zxfwl   0/1     Pending       0             0s pc-deployment-5967bb44bb-bbkzz   0/1     ContainerCreating   0             0s pc-deployment-5967bb44bb-kxrn5   0/1     ContainerCreating   0             0s pc-deployment-5967bb44bb-zxfwl   0/1     ContainerCreating   0             0s pc-deployment-5967bb44bb-kxrn5   1/1     Running             0             1s 

  

滚动更新:

[root@master ~]# cat deploy.yaml  apiVersion: apps/v1 kind: Deployment metadata:    name: pc-deployment    namespace: dev spec:    strategy:      type: RollingUpdate      rollingUpdate:         maxUnavailable: 25%         maxSurge: 25%    replicas: 3    selector:       matchLabels:        app: nginx-pod    template:       metadata:          labels:            app: nginx-pod       spec:         containers:         - name: nginx           image: nginx:1.17.1  #更新 [root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.3 -n dev deployment.apps/pc-deployment image updated  #就会更新 [root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.3 -n dev deployment.apps/pc-deployment image updated 

 

k8s(pod)详解

 

总结:

镜像版本更新的话,会先创建一个新的RS,老RS也会存在,pod会在新的RS里面,老RS就会删除一个,到最后老的rs里面没有了pod,新的rs里面就会有pod了

留这个老的rs的作用的话,就是版本回退作用

 

版本回退:

k8s(pod)详解

 

undo回滚到上一个版本

#记录整个更新的deployment过程 [root@master ~]# kubectl create -f deploy.yaml --record Flag --record has been deprecated, --record will be removed in the future deployment.apps/pc-deployment created #更新版本就会有历史记录 [root@master ~]# kubectl edit deployments.apps  -n dev pc-deployment  deployment.apps/pc-deployment edited  [root@master ~]# kubectl rollout history deployment -n dev pc-deployment  deployment.apps/pc-deployment  REVISION  CHANGE-CAUSE 1         kubectl create --filename=deploy.yaml --record=true 2         kubectl create --filename=deploy.yaml --record=true 3         kubectl create --filename=deploy.yaml --record=true  #直接回退到到指定的版本,如果不指定的话,默认是上一个版本  [root@master ~]# kubectl rollout undo deployment  -n dev  pc-deployment --to-revision=1 deployment.apps/pc-deployment rolled back    #rs也发生了变化,pod回到了老的rs里面了 [root@master ~]# kubectl get rs -n dev NAME                       DESIRED   CURRENT   READY   AGE pc-deployment-5967bb44bb   0         0         0       4m11s pc-deployment-6478867647   0         0         0       3m38s pc-deployment-6cb555c765   3         3         3       5m28s [root@master ~]# kubectl rollout  history deployment -n dev  deployment.apps/pc-deployment  REVISION  CHANGE-CAUSE 2         kubectl create --filename=deploy.yaml --record=true 3         kubectl create --filename=deploy.yaml --record=true 4         kubectl create --filename=deploy.yaml --record=true   #这个就相当于是1了 

   

金丝雀发布:

deployment支持更新过程中的控制,暂停,继续更新操作

就是在更新的过程中,仅存在一部分的更新的应用,主机部分是一些旧的版本,将这些请求发送到新的应用上面,不能接收请求就赶紧回退,能接受请求,就继续更新,这个就被称为金丝雀发布

#更新,并且立刻暂停 [root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.2 -n dev && kubectl rollout pause deployment  -n dev pc-deployment  deployment.apps/pc-deployment image updated deployment.apps/pc-deployment paused  #rs的变化 [root@master ~]# kubectl get rs -n dev NAME                       DESIRED   CURRENT   READY   AGE pc-deployment-5967bb44bb   1         1         1       21m pc-deployment-6478867647   0         0         0       20m pc-deployment-6cb555c765   3         3         3       22m  #有一个已经更新完毕了 [root@master ~]# kubectl rollout  status  deployment  -n dev Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...  #发送一个请求  #继续更新 [root@master ~]# kubectl rollout  resume deployment  -n dev pc-deployment  deployment.apps/pc-deployment resumed  #查看状态 [root@master ~]# kubectl rollout  status  deployment  -n dev Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated... Waiting for deployment spec update to be observed... Waiting for deployment spec update to be observed... Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated... Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated... Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "pc-deployment" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "pc-deployment" rollout to finish: 1 old replicas are pending termination... deployment "pc-deployment" successfully rolled out  #查看rs [root@master ~]# kubectl get rs -n dev NAME                       DESIRED   CURRENT   READY   AGE pc-deployment-5967bb44bb   3         3         3       24m pc-deployment-6478867647   0         0         0       24m pc-deployment-6cb555c765   0         0         0       26m  

 hpa控制器

k8s(pod)详解

 

k8s(pod)详解

 

总的来说就是,就是获取每个pod的利用率,与pod上面的hpa定义的指标进行比较,如果大于的话,就直接自动的增加pod,当访问量减少了话,会删除增加的pod

通过监控pod负载均衡的情况,实现pod数量的扩缩容

安装一个软件,拿到pod的负载

metries-server可以用来收集集群中的资源使用情况。pod。node都可以以进行监控

# 下载最新版配置软件包 wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.3/components.yaml  #到每台服务器上系在阿里云版本的相关版本 ctr image pull registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.6.3  #修改配置文件 containers: - args:   - --cert-dir=/tmp   - --secure-port=4443   - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname   - --kubelet-use-node-status-port   - --metric-resolution=15s   - --kubelet-insecure-tls  #增加证书忽略   image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.6.3 #修改image为阿里云下载的这个  #应用下配置文件 kubectl apply -f   components.yaml  #查看执行结果 [root@master ~]# kubectl get pod -n kube-system  NAME                              READY   STATUS    RESTARTS       AGE coredns-66f779496c-88c5b          1/1     Running   33 (55m ago)   10d coredns-66f779496c-hcpp5          1/1     Running   33 (55m ago)   10d etcd-master                       1/1     Running   14 (55m ago)   10d kube-apiserver-master             1/1     Running   14 (55m ago)   10d kube-controller-manager-master    1/1     Running   14 (55m ago)   10d kube-proxy-95x52                  1/1     Running   14 (55m ago)   10d kube-proxy-h2qrf                  1/1     Running   14 (55m ago)   10d kube-proxy-lh446                  1/1     Running   15 (55m ago)   10d kube-scheduler-master             1/1     Running   14 (55m ago)   10d metrics-server-6779c94dff-dflh2   1/1     Running   0              2m6s 

 

查看资源的使用情况

#查看node的使用情况信息 [root@master ~]# kubectl top nodes NAME     CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%    master   104m         5%     1099Mi          58%        node1    21m          1%     335Mi           17%        node2    22m          1%     305Mi           16%        #查看pod的使用情况 [root@master ~]# kubectl top pods -n dev NAME        CPU(cores)   MEMORY(bytes)    pod-aff     3m           83Mi             pod-label   0m           1Mi     

 

实现这个hpa的操作,就是pod上面要有资源的限制才可以,

然后使用命令即可

k8s(pod)详解

 

测试:

 

[root@master ~]# cat deploy.yaml  apiVersion: apps/v1 kind: Deployment metadata:    name: nginx    namespace: dev spec:    replicas: 1   #一个副本数量    selector:       matchLabels:        app: nginx-pod    #标签选择器    template:       metadata:          labels:            app: nginx-pod       spec:         containers:         - name: nginx           image: nginx:1.17.1           resources:              requests:                cpu: 100m   #最少需要100毫核才能启动   #创建deployment kubectl create  -f deploy.yaml  #创建service kubectl expose deployment  nginx --type=NodePort --port=80 -n dev  #创建一个hpa [root@master ~]# cat hpa.yaml  apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata:    name: pc-hpa    namespace: dev spec:    minReplicas: 1    maxReplicas: 10    targetCPUUtilizationPercentage: 3   #cpu的指标为%3,方便测试用的    scaleTargetRef:  #选择的控制器       apiVersion: apps/v1       kind: Deployment   #deploy控制器       name: nginx   #查看hpa控制器 [root@master ~]# kubectl get hpa -n dev NAME     REFERENCE          TARGETS        MINPODS   MAXPODS   REPLICAS   AGE pc-hpa   Deployment/nginx   <unknown>/3%   1         10        0          5s [root@master ~]# kubectl get hpa -n dev NAME     REFERENCE          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE pc-hpa   Deployment/nginx   0%/3%     1         10        1          114s   #进行压力测试,就是超过%3 [root@master ~]# cat f.sh  while `true`: do 	curl 192.168.109.100:30843 &> /dev/null done  [root@master ~]# kubectl get hpa -n dev -w pc-hpa   Deployment/nginx   1%/3%     1         10        1          22m pc-hpa   Deployment/nginx   0%/3%     1         10        1          22m pc-hpa   Deployment/nginx   42%/3%    1         10        1          25m pc-hpa   Deployment/nginx   92%/3%    1         10        4          25m pc-hpa   Deployment/nginx   23%/3%    1         10        8          25m pc-hpa   Deployment/nginx   0%/3%     1         10        10         26m  [root@master ~]# kubectl get deployment -n dev -w NAME    READY   UP-TO-DATE   AVAILABLE   AGE nginx   1/1     1            1           39m nginx   1/4     1            1           60m nginx   1/4     1            1           60m nginx   1/4     1            1           60m nginx   1/4     4            1           60m nginx   2/4     4            2           60m nginx   3/4     4            3           60m nginx   4/4     4            4           60m nginx   4/8     4            4           60m nginx   4/8     4            4           60m nginx   4/8     4            4           60m nginx   4/8     8            4           60m nginx   5/8     8            5           60m nginx   6/8     8            6           60m nginx   7/8     8            7           60m nginx   8/8     8            8           60m nginx   8/10    8            8           61m nginx   8/10    8            8           61m nginx   8/10    8            8           61m nginx   8/10    10           8           61m nginx   9/10    10           9           61m nginx   10/10   10           10          61m  [root@master ~]# kubectl get pod-n dev -w nginx-7f89875f58-gt67w   0/1     Pending             0          0s nginx-7f89875f58-gt67w   0/1     Pending             0          0s nginx-7f89875f58-545rj   0/1     Pending             0          0s nginx-7f89875f58-gt67w   0/1     ContainerCreating   0          0s nginx-7f89875f58-545rj   0/1     Pending             0          0s nginx-7f89875f58-545rj   0/1     ContainerCreating   0          0s nginx-7f89875f58-545rj   1/1     Running             0          1s nginx-7f89875f58-gt67w   1/1     Running             0          1s  #当访问量减少的时候,这个pod里面自动的减少,只不过需要一点时间  

daemonset(DS)控制器

k8s(pod)详解

 在每个节点上面创建一个副本(并且只能有一个),就是节点级别的,一般用于日志收集,节点监控等

当节点移除的话,自然Pod也就没有了

k8s(pod)详解

 

案例:

[root@master ~]# cat daemonset.yaml  apiVersion: apps/v1 kind: DaemonSet metadata:    name: daemon    namespace: dev spec:    selector:       matchLabels:         app: nginx-pod    template:         metadata:           labels:              app: nginx-pod         spec:           containers:           - name: nginx             image: nginx:1.17.1  [root@master ~]# kubectl get pod -n dev -o wide NAME                     READY   STATUS    RESTARTS   AGE     IP             NODE    NOMINATED NODE   READINESS GATES daemon-g8b4v             1/1     Running   0          2m30s   10.244.1.102   node2   <none>           <none> daemon-t5tmd             1/1     Running   0          2m30s   10.244.2.89    node1   <none>           <none> nginx-7f89875f58-prf9c   1/1     Running   0          79m     10.244.2.84    node1   <none>           <none>  #每个副本上面都有一个pod 

  

job控制器

k8s(pod)详解

 批量处理(依次处理指定数量的任务),一次性任务(每个任务仅运行一次就结束)

由job创建的pod执行成功时,job会记录成功结束的Pod数量

当成功结束的pod达到指定的数量时,job将完成执行

里面的job都是存放的一次性文件

k8s(pod)详解

重启策略:在这里不能设置为always,因为这个是一次性任务,结束了,都要进行重启

只能设置为onfailure和never才行

onfailure:pod出现故障时,重启容器,不是创建pod,failed次数不变

never:出现故障,并且故障的pod不会消失也不会重启,failed次数=1

 

案例:

[root@master ~]# cat jod.yaml  apiVersion: batch/v1 kind: Job metadata:    name: pc-job    namespace: dev spec:    manualSelector: true    completions: 6  #一次性创建6个pod    parallelism: 3   #允许三个一起执行,2轮就结束了    selector:       matchLabels:         app: counter-pod    template:         metadata:           labels:              app: counter-pod         spec:           restartPolicy: Never           containers:           - name: busybox             image: busybox:1.30             command: ["/bin/sh","-c","for i in 1 2 3 4 5 6 7 8 9;do echo $i;sleep 3;done"]  [root@master ~]# kubectl get job -n dev -w NAME     COMPLETIONS   DURATION   AGE pc-job   0/6                      0s pc-job   0/6           0s         0s pc-job   0/6           2s         2s pc-job   0/6           29s        29s pc-job   0/6           30s        30s pc-job   3/6           30s        30s pc-job   3/6           31s        31s pc-job   3/6           32s        32s pc-job   3/6           59s        59s pc-job   3/6           60s        60s pc-job   6/6           60s        60s [root@master ~]# kubectl get pod -n dev -w NAME                     READY   STATUS    RESTARTS   AGE daemon-g8b4v             1/1     Running   0          20m daemon-t5tmd             1/1     Running   0          20m nginx-7f89875f58-prf9c   1/1     Running   0          97m pc-job-z2gmb             0/1     Pending   0          0s pc-job-z2gmb             0/1     Pending   0          0s pc-job-z2gmb             0/1     ContainerCreating   0          0s pc-job-z2gmb             1/1     Running             0          1s pc-job-z2gmb             0/1     Completed           0          28s pc-job-z2gmb             0/1     Completed           0          29s pc-job-z2gmb             0/1     Completed           0          30s pc-job-z2gmb             0/1     Completed           0          30s

cronjob控制器(cj)

k8s(pod)详解

 就是指定时间的周期执行job任务

k8s(pod)详解

 

案例:

[root@master ~]# cat cronjob.yaml  apiVersion: batch/v1 kind: CronJob metadata:    name: pc-cronjob    namespace: dev    labels:        controller: cronjob spec:     schedule: "*/1 * * * *"     jobTemplate:         metadata:           name: pc-cronjob           labels:              controller: cronjob         spec:           template:               spec:                 restartPolicy: Never                 containers:                 - name: counter                   image: busybox:1.30                   command: ["/bin/sh","-c","for i in 1 2 3 4 5 6 7 8 9;do echo$i;sleep 3;done"]  [root@master ~]# kubectl get job -n dev -w NAME                  COMPLETIONS   DURATION   AGE pc-cronjob-28604363   0/1           21s        21s pc-job                6/6           60s        33m pc-cronjob-28604363   0/1           28s        28s pc-cronjob-28604363   0/1           29s        29s pc-cronjob-28604363   1/1           29s        29s pc-cronjob-28604364   0/1                      0s pc-cronjob-28604364   0/1           0s         0s pc-cronjob-28604364   0/1           1s         1s pc-cronjob-28604364   0/1           29s        29s pc-cronjob-28604364   0/1           30s        30s pc-cronjob-28604364   1/1           30s        30s ^C[root@master ~]#   [root@master ~]# kubectl get pod -n dev -w NAME                     READY   STATUS      RESTARTS   AGE daemon-g8b4v             1/1     Running     0          57m daemon-t5tmd             1/1     Running     0          57m nginx-7f89875f58-prf9c   1/1     Running     0          134m pc-job-2p6p6             0/1     Completed   0          32m pc-job-62z2d             0/1     Completed   0          32m pc-job-6sm97             0/1     Completed   0          32m pc-job-97j4j             0/1     Completed   0          31m pc-job-lsjz5             0/1     Completed   0          31m pc-job-pt28s             0/1     Completed   0          31m   [root@master ~]# kubectl get pod -n dev -w pc-cronjob-28604363-fcnvr   0/1     Pending     0          0s pc-cronjob-28604363-fcnvr   0/1     Pending     0          0s pc-cronjob-28604363-fcnvr   0/1     ContainerCreating   0          0s pc-cronjob-28604363-fcnvr   1/1     Running             0          0s pc-cronjob-28604363-fcnvr   0/1     Completed           0          27s pc-cronjob-28604363-fcnvr   0/1     Completed           0          29s pc-cronjob-28604363-fcnvr   0/1     Completed           0          29s  #就是这个job执行结束后,每隔1分钟再去执行 

四:service详解

 流量负载组件service和ingress

serverice用于四层的负载ingress用于七层负载

1、service介绍

 pod有一个ip地址,但是不是固定的,所以的话,service就是一部分的pod的代理,有一个ip地址,可以通过这个地址来进行访问pod

service就是一个标签选择器的机制

k8s(pod)详解

 kube-proxy代理

k8s(pod)详解

 核心就是kube-proxy机制发生的作用,当创建service时,api-server向etcd存储service相关的信息,kube-proxy监听到发生了变化,就会将service相关的信息转换为访问规则

查看规则

k8s(pod)详解

 

kube-proxy支持的三种模式

userspace模式:用户空间模式

k8s(pod)详解

 kube-proxy会为每一个service创建一个监听的端口,发给service的ip的请求会被iptables规则重定向到kube-proxy监听的端口上,kube-proxy根据算法选择一个提供服务的pod并建立连接,以将请求转发到pod上

kube-proxy相当于一个负载均衡器的样子

 缺点:效率比较低,进行转发处理时,增加内核和用户空间

 

iptables模式

k8s(pod)详解

 

当请求来的时候,不经过了kube-proxy了,经过clusterip(规则即可),然后进行轮询(随机)转发到pod上面

缺点:没有负载均衡,一但又问题,用户拿到的就是错误的页面

 

ipvs模式:

k8s(pod)详解

 

 

 

 开启ipvs模块

编辑里面的配置文件为mode为ipvs [root@master /]# kubectl edit cm kube-proxy -n kube-system  #删除里面的pod,带有标签的 [root@master /]# kubectl delete pod -l k8s-app=kube-proxy -n kube-system root@master /]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags   -> RemoteAddress:Port           Forward Weight ActiveConn InActConn TCP  172.17.0.1:30203 rr  轮询的规则,就是将地址转发到这里面去即可   -> 10.244.2.103:80              Masq    1      0          0          TCP  192.168.109.100:30203 rr   -> 10.244.2.103:80              Masq    1      0          0          TCP  10.96.0.1:443 rr   -> 192.168.109.100:6443         Masq    1      0          0          TCP  10.96.0.10:53 rr   -> 10.244.0.44:53               Masq    1      0          0            -> 10.244.0.45:53               Masq    1      0          0          TCP  10.96.0.10:9153 rr   -> 10.244.0.44:9153             Masq    1      0          0            -> 10.244.0.45:9153             Masq    1      0          0          TCP  10.100.248.78:80 rr   -> 10.244.2.103:80              Masq    1      0          0          TCP  10.110.118.76:443 rr   -> 10.244.1.108:10250           Masq    1      0          0            -> 10.244.2.102:10250           Masq    1      0          0          TCP  10.244.0.0:30203 rr

2:service类型

k8s(pod)详解

标签选择器只是一个表象,本质就是规则,通过标签,来进行确定里面的pod的ip

session亲和性,如果不配置的话,请求会将轮询到每一个pod上面,特殊的情况下,将多个请求发送到同一个pod上面,就需要session亲和性 

type:就是service类型

  ClusterIP:默认值,k8s自动分配的虚拟ip,只能在集群内部访问

  NodePort:将service通过指定的node上面端口暴露给外部,可以实现集群外面访问服务,节点上面的端口暴露给外部

  LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境

  ExternalName:把集合外部的服务引入集群内部,直接使用

 

1、环境准备

k8s(pod)详解

 

三个pod。deploy控制器来创建,  

[root@master ~]# cat service-example.yaml  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.1             ports:             - containerPort: 80 [root@master ~]# kubectl get pod -n dev -o wide NAME                             READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES pc-deployment-5cb65f68db-959hm   1/1     Running   0          62s   10.244.2.104   node1   <none>           <none> pc-deployment-5cb65f68db-h6v8r   1/1     Running   0          62s   10.244.1.110   node2   <none>           <none> pc-deployment-5cb65f68db-z4k2f   1/1     Running   0          62s   10.244.2.105   node1   <none>           <none> #访问pod的ip和容器里面的端口 [root@master ~]# curl 10.244.2.104:80  修改里面的网页文件,观察请求发送到哪一个节点上面去了,依次修改网页文件即可 [root@master ~]# kubectl exec -ti -n dev pc-deployment-5cb65f68db-h6v8r  /bin/bash root@pc-deployment-5cb65f68db-z4k2f:/# echo 10.244.2.10 > /usr/share/nginx/html/index.html  

 2、ClusterIP类型的service

k8s(pod)详解

 service的端口可以随便写

[root@master ~]# cat ClusterIP.yaml  apiVersion: v1 kind: Service metadata:    name: service-clusterip    namespace: dev spec:    selector:   #service标签选择器      app: nginx-pod    clusterIP: 10.96.0.100   #不写的话,默认生成一个ip地址    type: ClusterIP    ports:    - port: 80  #service端口      targetPort: 80  #pod的端口  [root@master ~]# kubectl create -f ClusterIP.yaml  service/service-clusterip created  [root@master ~]# kubectl get svc -n dev NAME                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE service-clusterip   ClusterIP   10.96.0.100   <none>        80/TCP    2m7s #查看service的详细的信息, [root@master ~]# kubectl describe svc service-clusterip -n dev Name:              service-clusterip Namespace:         dev Labels:            <none> Annotations:       <none> Selector:          app=nginx-pod Type:              ClusterIP IP Family Policy:  SingleStack IP Families:       IPv4 IP:                10.96.0.100 IPs:               10.96.0.100 Port:              <unset>  80/TCP TargetPort:        80/TCP Endpoints:         10.244.1.110:80,10.244.2.104:80,10.244.2.105:80   #建立pod和service的关联,主要是标签选择器,里面都是记录的Pod的访问地址,实际端点服务的集合 Session Affinity:  None Events:            <none> [root@master ~]# kubectl get pod -n dev -o wide NAME                             READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES pc-deployment-5cb65f68db-959hm   1/1     Running   0          25m   10.244.2.104   node1   <none>           <none> pc-deployment-5cb65f68db-h6v8r   1/1     Running   0          25m   10.244.1.110   node2   <none>           <none> pc-deployment-5cb65f68db-z4k2f   1/1     Running   0          25m   10.244.2.105   node1   <none>           <none>  [root@master ~]# kubectl get endpoints -n dev NAME                ENDPOINTS                                         AGE service-clusterip   10.244.1.110:80,10.244.2.104:80,10.244.2.105:80   4m48s  真正起作用的就是kube-proxy,创建service的时,会创建对应的规则 [root@master ~]# ipvsadm -Ln TCP  10.96.0.100:80 rr   -> 10.244.1.110:80              Masq    1      0          0            -> 10.244.2.104:80              Masq    1      0          0            -> 10.244.2.105:80              Masq    1      0          0       #发送一个请求,测试是谁接收了,循环访问,发现是轮询环的状态 [root@master ~]# while true;do curl 10.96.0.100:80; sleep 5;done; 10.244.2.105 10.244.2.104  10.244.1.110 10.244.2.105 10.244.2.104  10.244.1.110 

访问service的ip和主机端口

负载分发策略:(session亲和性)

默认的话,访问就是轮询或者随机

有设置的话,就是多个请求到同一个pod里面上面,就不会轮训或者随机

#设置session亲和性 [root@master ~]# cat ClusterIP.yaml  apiVersion: v1 kind: Service metadata:    name: service-clusterip    namespace: dev spec:    sessionAffinity: ClientIP   #就是通过哟个请求到同一个节点上面    selector:      app: nginx-pod    clusterIP: 10.96.0.100    type: ClusterIP    ports:    - port: 80      targetPort: 80  [root@master ~]# kubectl get svc -n dev NAME                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE service-clusterip   ClusterIP   10.96.0.100   <none>        80/TCP    78s [root@master ~]# ipvsadm -Ln TCP  10.96.0.100:80 rr persistent 10800   持久化   -> 10.244.1.112:80              Masq    1      0          0            -> 10.244.2.107:80              Masq    1      0          0            -> 10.244.2.108:80              Masq    1      0          0           这种类型的service,只能通过集群节点来进行访问,就是内部进行访问,自己的电脑访问不了这个ip [root@master ~]# curl 10.96.0.100:80 10.244.2.108 [root@master ~]# curl 10.96.0.100:80 10.244.2.108 [root@master ~]# curl 10.96.0.100:80 10.244.2.108

3、headliness类型的service

Cluster类型的service,默认是随机的负载均衡分发策略,希望自己来控制这个策略,使用headliness类型的service,不会分发Clusterip。想要访问service,只能通过service的域名来进行访问

[root@master ~]# cat headliness.yaml  apiVersion: v1 kind: Service metadata:    name: service-headliness    namespace: dev spec:    selector:      app: nginx-pod    clusterIP: None   #设置为None,就能生成headliness类型的service    type: ClusterIP    ports:    - port: 80      targetPort: 80 [root@master ~]# kubectl get svc -n dev NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE service-headliness   ClusterIP   None         <none>        80/TCP    4s  #查看域名 [root@master ~]# kubectl exec -ti -n dev pc-deployment-5cb65f68db-959hm /bin/bash root@pc-deployment-5cb65f68db-959hm:/# cat /etc/resolv.conf  search dev.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5   #访问headliness类型的service #格式为dns服务器,加上service的名字,名称空间,等;; ANSWER SECTION: [root@master ~]# dig @10.96.0.10 service-headliness.dev.svc.cluster.local  service-headliness.dev.svc.cluster.local. 30 IN	A 10.244.2.108 service-headliness.dev.svc.cluster.local. 30 IN	A 10.244.1.112 service-headliness.dev.svc.cluster.local. 30 IN	A 10.244.2.107

4、NodePort类型的service

k8s(pod)详解

 就是将service的port映射到node节点上面,通过nodeip+node端口来实现访问service

 请求来到node的端口上面时,会将请求发送到service的端口上面,再来发送到pod上面的端口,实现访问

就将service暴露到外部了

k8s(pod)详解

测试:

[root@master ~]# cat nodeport.yaml  apiVersion: v1 kind: Service metadata:    name: service-clusterip    namespace: dev spec:    selector:      app: nginx-pod    type: NodePort   #NodePort类型的service    ports:    - port: 80    #service端口      targetPort: 80   #pod端口      nodePort: 30002   默认在一个·1范围内 [root@master ~]# kubectl create -f nodeport.yaml  service/service-clusterip created [root@master ~]# kubectl get svc -n dev NAME                TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE service-clusterip   NodePort   10.106.183.217   <none>        80:30002/TCP   4s  #访问节点ip+端口就能映射到Clusterip+端口了 [root@master ~]# curl 192.168.109.100:30002 10.244.2.108 [root@master ~]# curl 192.168.109.101:30002 10.244.2.108 [root@master ~]# curl 192.168.109.102:30002 10.244.2.108  就能实现访问了service,以及内部了pod了 

5、LoadBalancer类型的service

k8s(pod)详解

 就是在nodeport的基础上面添加了一个负载均衡的设备,经过计算后得出

6、ExternalName类型的service 

k8s(pod)详解

 将这个这个服务引入www.baidu.com这个服务

k8s(pod)详解

[root@master ~]# cat service-external.yaml  apiVersion: v1 kind: Service metadata:    name: service-externalname    namespace: dev spec:    type: ExternalName    externalName: www.baidu.com [root@master ~]# kubectl create -f service-external.yaml  service/service-externalname created [root@master ~]# kubectl get svc -n dev NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE service-clusterip      NodePort       10.106.183.217   <none>          80:30002/TCP   17m service-externalname   ExternalName   <none>           www.baidu.com   <none>         7s  #访问service [root@master ~]# dig @10.96.0.10 service-externalname.dev.svc.cluster.local service-externalname.dev.svc.cluster.local. 30 IN CNAME	www.baidu.com. www.baidu.com.		30	IN	CNAME	www.a.shifen.com. www.a.shifen.com.	30	IN	A	180.101.50.188 www.a.shifen.com.	30	IN	A	180.101.50.242  #这样就能解析到了

 3:Ingress介绍

service对外暴露服务主要就是2种类型的,NodePort和LoadBalancer

缺点:

  NodePort暴露的是主机的端口,当集群服务很多的时候,这个端口就会更多

  LB方式就是每一个service都需要LB,浪费

 

k8s(pod)详解

 

k8s(pod)详解

 用户定义这个请求到service的规则,然后ingress控制器感知将其转换为nginx配置文件,然后动态更新到nginx-proxy里面去即可,这个过程是动态的

1、环境的准备

k8s(pod)详解

#下载yaml文件 kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.1/deploy/static/provider/cloud/deploy.yaml  [root@master ingress-example]# kubectl get pod,svc -n ingress-nginx  NAME                                           READY   STATUS      RESTARTS   AGE pod/ingress-nginx-admission-create-jv5n5       0/1     Completed   0          77s pod/ingress-nginx-admission-patch-tpfv6        0/1     Completed   0          77s pod/ingress-nginx-controller-597dc6d68-rww45   1/1     Running     0          77s  NAME                                         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE service/ingress-nginx-controller             NodePort    10.97.10.122   <none>        80:30395/TCP,443:32541/TCP   78s service/ingress-nginx-controller-admission   ClusterIP   10.96.17.67    <none>        443/TCP 

  

service和deployment文件,创建2个service和6个pod

[root@master ~]# cat deploy.yaml  apiVersion: apps/v1 kind: Deployment metadata:    name: nginx-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.1           ports:           - containerPort: 80 ---  apiVersion: apps/v1 kind: Deployment metadata:    name: tomcat-deployment    namespace: dev spec:    replicas: 3    selector:       matchLabels:        app: tocmat-pod    template:       metadata:          labels:            app: tocmat-pod       spec:         containers:         - name: tomcat           image: tomcat:8.5-jre10-slim           ports:           - containerPort: 8080 ---  apiVersion: v1 kind: Service metadata:    name: nginx-service    namespace: dev spec:    selector:      app: nginx-pod    clusterIP: None    type: ClusterIP    ports:    - port: 80      targetPort: 80 ---   apiVersion: v1 kind: Service metadata:    name: tomcat-service    namespace: dev spec:    selector:      app: tomcat-pod    type: ClusterIP    clusterIP: None    ports:    - port: 8080      targetPort: 8080  [root@master ~]# kubectl get deployments.apps,pod -n dev NAME                                READY   UP-TO-DATE   AVAILABLE   AGE deployment.apps/nginx-deployment    3/3     3            3           86s deployment.apps/tomcat-deployment   3/3     3            3           86s  NAME                                     READY   STATUS    RESTARTS   AGE pod/nginx-deployment-5cb65f68db-5lzpb    1/1     Running   0          86s pod/nginx-deployment-5cb65f68db-75h4m    1/1     Running   0          86s pod/nginx-deployment-5cb65f68db-nc8pj    1/1     Running   0          86s pod/tomcat-deployment-5dbff496f4-6msb2   1/1     Running   0          86s pod/tomcat-deployment-5dbff496f4-7wjc9   1/1     Running   0          86s pod/tomcat-deployment-5dbff496f4-wlgmm   1/1     Running   0          86s

2、http代理 

 创建一个yaml文件就是里面,

 

k8s(pod)详解

 访问的就是域名+path 如果path是/xxx的话,访问要带上域名/xxx

 访问的时候,就会将其转发到对应的service加上端口上面即可

3、https代理

k8s(pod)详解

 密钥要提前的生成

k8s(pod)详解