资源约束

当界说 Pod时可以挑选性地为每个容器设定所需求的资源数量。最常见的可设定资源是CPU和内存大小,以及其他类型的资源。

当为 pod 中的容器指定了request资源时,调度器就运用该信息来决定将Pod 调度到哪个节点上。当还为容器指定了limit资源时,kubelet就会保证运转的容器不会运用超出所设的 limit资源量。kubelet还会为容器预留所设的 request资源量,供该容器运用。

假如Pod运转地点的节点具有满足的可用资源,容器可以运用超出所设置的 request资源量。不过,容器不可以运用超出所设置的 limit资源量。 假如给容器设置了内存的 limit值,但未设置内存的 request值,Kubernetes会主动为其设置与内存 limit相匹配的 request 值。类似的,假如给容器设置了 CPU的 limit值但未设置cPU的 request值,则 Kubernetes主动为其设置CPU 的 request值并使之与CPU的 limit值匹配。

官网示例:kubernetes.io/docs/concep…

Pod 和容器的资源恳求和约束

  • 界说创立容器时预分配的CPU资源:spec.containers[].resources.requests.cpu
  • 界说创立容器时预分配的内存资源:spec.containers[].resources.requests.memory
  • 界说cpu的资源上限:spec.containers[].resources.limits.cpu
  • 界说内存的资源上限:spec.containers[].resources.limits.memory

CPU资源单位

CPU资源的request和 limit 以cpu为单位。Kubernetes 中的一个 cpu相当于1个 vCPU(1个超线程)。

Kubernetes也支撑带小数CPU 的恳求。spec.containers[].resources.requests.cpu为0.5的容器可以取得一个cpu 的一半CPU

资源(类似于Cgroup对CPU资源的时刻分片)。表达式0.1等价于表达式100m(毫核),表明每1000毫秒内容器可以运用的CPU时刻总量为0.1*1000毫秒。
Kubernetes 不允许设置精度小于1m 的CPU资源。

内存资源单位

内存的 request和 limit 以字节为单位。可以以整数表明,或许以10为底数的指数的单位(E、P、T、G、M、K)来表明,或许以2为底数的指数的单位(Ei、Pi、Ti、Gi、Mi、Ki)来表明。

如: 1KB=10^3=1000,1MB=10^6=1000000=1000KB,1GB=10^9=1000000000=1000MB;1KiB=2^10=1024,1MiB=2^20=1048576=1024KiB

PS:在买硬盘的时分,操作系统报的数量要比产品标出或商家号称的小一些,首要原因是标出的是以MB、GB为单位的,1GB就是1,000,000Byte,而操作系统是以2进制为处理单位的,因而检查硬盘容量时是以MiB、GiB为单位,1GiB=2^30=1,073,741,824,相比较而言,1GiB要比1GB多出1,073,741,824-1,000, 000,000=73,741,824Byte,所以检测实际成果要比标出的少一些。

示例

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: web
    image: nginx
    env:
    - name: WEB_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "abc123"
    resources:
      requests:
        memory: "512Mi"
        cpu: "0.5"
      limits:
        memory: "1Gi"
        cpu: "1"
  1. 修正数据库的资源约束

    Pod进阶

  2. 履行yaml文件创立pod

    Pod进阶

  3. 检查pod的状况(OOMKilled是指内存不行的状况)

    Pod进阶

  4. 修正yaml文件,给数据库满足的资源

    Pod进阶
    Pod进阶
    Pod进阶

  5. 检查资源运用状况

    Pod进阶
    Pod进阶

健康检查:又称为探针(Probe)

探针是由kubelet对容器履行的定期确诊。

探针的三种规则

  • livenessProbe:判别容器是否正在运转。假如勘探失利,则kubelet会杀死容器,而且容器将根据restartRolicy来设置Pod状况。假如容器不提供存活探针,则默许状况为Success。
  • readinessProbe:判别容器是否预备好接受恳求。假如勘探失利,端点控制器将从与 pod 匹配的一切 service endpoints中除掉删去该Pod的IP地址。初始推迟之前的安排妥当状况默许为Failure。假如容器不提供安排妥当探针,则默许状况为Success。
  • startupProbe(这个1.17版别添加的):判别容器内的运用程序是否已发动,首要针对于不能确认详细发动时刻的运用。假如装备了startupProbe勘探,在则在startupProbe状况为Success之前,其他一切探针都处于无效状况,直到它成功后其他探针才起作用。假如startupProbe失利,kubelet将杀死容器,容器将根据restartPolicy来重启。假如容器没有装备 startupProbe,则默许状况为Success。

注:以上规则可以一起界说。在readinessProbe检测成功之前,Pod的running状况是不会变成ready状况的。

Probe支撑三种检查方法

  • exec:在容器内履行指定指令。假如指令退出时回来码为0则以为确诊成功。
  • tcpSocket:对指定端口上的容器的IP地址进行TCP检查(三次握手)。假如端口打开,则确诊被以为是成功的。
  • httplet:对指定的端口和途径上的容器的IP地址履行HTTPGet恳求。假如响应的状况码大于等于200且小于400,则确诊被以为是成功的

每次勘探都将取得以下三种成果之一

  • 成功:容器经过了确诊。
  • 失利:容器未经过确诊。
  • 未知:确诊失利,因而不会采纳任何举动

官网示例:kubernetes.io/docs/tasks/…

示例

exec方法

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    images: k8s.gcr.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      failureThreshold: 1
      initialDelaySeconds: 5
      periodSeconds: 5
  • initialDelaySeconds:指定kubelet 在履行第一次勘探前应该等候5秒,即第一次勘探是在容器发动后的第6秒才开端履行。默许是0秒,最小值是0
  • periodSeconds:指定了kubelet 应该每5秒履行一次存活勘探。默许是10秒。最小值是1
  • failureThreshold:当勘探失利时,Kubernetes 将在抛弃之前重试的次数。存活勘探状况下的抛弃就意味着重新发动容器。安排妥当勘探状况下的抛弃 Pod会被打上未安排妥当的标签。默许值是3。最小值是1。
  • timeoutSeconds:勘探的超时后等候多少秒。默许值是1秒。最小值是1。(在Kubernetes 1.20 版别之前,exec探针会忽略timeoutSeconds探针会无限期地继续运转,甚至或许超过所装备的限期,直到回来成果停止。)

可以看到 pod 中只要一个容器。kubelet 在履行第一次勘探前需求等候5秒,kubelet 会每5秒履行一次存活勘探。kubelet在容器内履行指令cat /tmp/healthy来进行勘探。假如指令履行成功而且回来值为 0,kutbelet就会以为这个容器是健康存活的。当抵达第 31秒时,这个指令回来非0值,kubelet会杀死这个容器并重新发动它。

测验进程(运用存活探针)
  1. 这儿直接仿制前面的demo1.yaml文件进行运用,修正demo3.yaml文件

    Pod进阶
    Pod进阶

  2. 履行yaml文件

    Pod进阶
    Pod进阶

  3. 检查pod详细信息

    Pod进阶
    Pod进阶

httpGet方法

apiVersion: v1
kind: Pod
metadata:
  lables:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    arg:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

在这个装备文件中,可以看到Pod 也只要一个容器。initialDelaySeconds 字段告诉 kubelet 在履行第一次勘探前应该等候3秒。periodSeconds 字段指定了kubelet每隔3秒履行一次存活勘探。kubelet 会向容器内运转的服务(服务会监听8080端口)发送一个HTTP GET恳求来履行勘探。假如服务器上/healthz途径下的处理程序回来成功代码,则 kubelet 以为容器是健康存活的。假如处理程序回来失利代码,则kubelet 会杀死这个容器而且重新发动它。

任何大于或等于200而且小于400 的回来代码表明成功,其它回来代码都表明失利。

测验进程(运用存活探针)
  1. 直接仿制前面的demo3.yaml文件进行运用,修正demo4.yaml文件

    Pod进阶
    Pod进阶

  2. 履行yaml文件

    Pod进阶
    Pod进阶
    Pod进阶

  3. 检查pod的日志记载

    Pod进阶

  4. 删去index.html文件

    Pod进阶
    Pod进阶
    Pod进阶

  5. 重启后再次检查日志,又能勘探成功
    原因:K8S 中不支撑重启 Pod资源,只要删去重建。由于仍是基于同一个镜像,所以又康复到index.html违反删去的状况。

    Pod进阶

tcpSocket方法

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    images: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initalDelaySeconds: 15
      periodSeconds: 20

这个例子一起运用readinesspProbe和 livenessProbe 勘探。kubelet会在容器发动5秒后发送第一个readinessProbe勘探。这会测验衔接 gproxy 容器的 8080端口。假如勘探成功,kubelet 将继续每隔10秒运转一次检测。除了readinessProbe 勘探,这个装备包含了一个livenessProbe 勘探。kubelet 会在容器发动15秒后进行第一次 livenessProbe 勘探。就像readinessProbe 勘探一样,会测验衔接goproxy容器的 8080端口。假如livenessProbe勘探失利,这个容器会被重新发动。

测验进程1(运用存活探针)
  1. 直接仿制前面的demo4.yaml文件进行运用,修正demo5.yaml文件

    Pod进阶
    Pod进阶

  2. 履行yaml文件

    Pod进阶
    Pod进阶

  3. 检查pod详细信息

    Pod进阶

测验进程2(运用安排妥当探针和存活探针,且两个探针参数不同)
  1. 直接仿制前面的demo4.yaml文件进行运用,修正demo6.yaml文件

    Pod进阶
    Pod进阶

  2. 履行yaml文件

    Pod进阶
    Pod进阶

  3. 检查pod的日志记载

    Pod进阶

  4. 在nginx的默许根目录/usr/share/nginx/html/下,创立abc.html

    Pod进阶
    Pod进阶
    Pod进阶

  5. 删去index.html文件,存活探针勘探失利,容器进行重启,重启后又无法进入ready状况,因为重建后的pod中abc.html又不存在了

    Pod进阶
    Pod进阶
    Pod进阶

发动、退出动作

  • spec.containers.lifecycle.postStart:装备exec.command字段设置Linux指令,完成当运用容器发动时,会履行的额外操作
  • spec.containers.lifecycle.preStop:装备exec.command字段设置 Linux指令,完成当运用容器退出时,会履行的最后一个操作
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: soscscs/myapp:v1
    lifecycle:  #此为关键字段
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo hello from the postStart handler >> /var/log/nginx/message"]
      preStop:
        exec:
          command: ["/bin/sh", "-c", "echo hello from the preStop handler >> /var/log/nginx/message"]
    volumeMounts:
    - name: message-log
      mountPath: /var/log/nginx/
      readOnly: false
  initContainers:
  - name: init-myservice
    image: soscscs/myapp:v1
    command: [ "/bin/sh","-c" , "echo 'Hello initContainers' >>/var/log/nginx/message"]
    volumeMounts:
    - name: message-log
      mountPath: /var/log/nginx/
      readOnly: false
  volumes:
  - name: message-log
    hostPath:
      path: /data/volumes/nginx/log/
      type: DirectoryOrCreate
  1. 创立demo7.yaml,当时node节点还都没有/data/volumes/nginx/log/

    Pod进阶
    Pod进阶
    Pod进阶

  2. 履行yaml文件,等候pod进入Running状况

    Pod进阶
    Pod进阶

  3. 去pod地点node节点检查,/data/volumes/nginx/log/存在

    Pod进阶
    Pod进阶

  4. 删去pod,再检查message文件

    Pod进阶
    Pod进阶

总结

Pod容器资源约束

request:设置Pod容器创立时需求预留的资源量,容器所需资源的下限<——request <——容器所需资源的上限
spec.template.spec.containers.resources.requests.cpu/memory

limit:设置Pod容器可以运用的资源量的上限
spec.template.spec.containers.resources.limits.cpu/memory

  • CPU资源量单位:cpu数,比如0.1、0.5、1、2﹔毫核,100m、500m、1000m、2000m
  • 内存资源量单位:2为底数的单位,Ki、Mi、Gi、Ti,默许单位运用字节

检查pod或许node 的资源量运用状况:kubectl describe pod/node XXX

Pod容器的探针(健康检查)3种

  • 存活探针livenessProbe)勘探容器是否运转正常。假如勘探失利则kubelet杀掉容器(不是pod),容器会根据重启战略决定是否重启
  • 安排妥当探针readinessProbe)勘探Pod是否可以进入READY状况,并做好接纳恳求的预备。假如勘探失利Pod 则会进入NOTREADY状况(READY为0/1)而且从所关联的service资源的端点(endpoints)中踢出,service将不会再把访问恳求转发给这个Pod
  • 发动探针startupProbe)勘探容器内的运用是否发动成功,在发动探针勘探成功之前,其它类型的探针都会暂时处于禁用状况

:发动探针只是在容器发动后按照装备满足一次后就不再进行后续的勘探了。存活探针和安排妥当探针会一向勘探到Pod生命周期结束停止

3种勘探方法

  • exec:经过command字段设置在容器内履行的Linux指令来进行勘探,假如指令回来码为0,则以为勘探成功,回来码非0则勘探失利
  • httpGet:经过向容器的指定端口和uri途径建议HTTP GET恳求,假如HTTP回来状况码为>=200或<400的人(2XX,3XX),则以为勘探成功,回来状况码为4XX,5XX则勘探失利
  • tcpSocket:经过向容器的指定端口发送tcp三次握手衔接,假如端口正确却tcp衔接成功,则以为勘探成功,tcp衔接失利则勘探失利

常用探针参数

  • initialDelaySeconds:容器发动后推迟几秒勘探
  • periodseconds:每次勘探的间隔时刻
  • failureThreshold:勘探失利重试的次数

Pod容器的发动和退出动作

  • spec.containers.lifecycle.postStart:装备exec.command字段设置Linux指令,完成当运用容器发动时,会履行的额外操作
  • spec.containers.lifecycle.preStop:装备exec.command字段设置 Linux指令,完成当运用容器退出时,会履行的最后一个操作