本章目录

  1. pod环境变量env
  2. pod的资源限制resources
  3. pod的健康检查-探针
  4. pod的imagepullsecrets

 

一   pod-env

  环境变量就是系统或者程序运行时的预定义的参数。比如说我们用docker启动一个mysql的容器,那么容器里面的msyql账号密码是多少呢?这时我们就可以通过环境变量来预定义。

  在docker中运行一个mysql的命令可以是docker run --name test-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 -d mysql:latest,其中-e就是定义的env参数,那么我们在k8s里面该如何定义呢

  

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: mysql
  name: mysql
spec:
  containers:
  - image: mysql
    imagePullPolicy: Always
    name: mysql
    ports:
    - containerPort: 3306
    env:
    - name: MYSQL_ROOT_PASSWORD    #指定root账号密码
      value: "123456"              #指定密码的值

  这样我们就指定好了mysql的环境变量,创建好pod以后,我们就可以通过我们指定的密码登录到mysql里面了

 

 

二  pod的resources限制

  pod的本质是container的集合,那么当container运行的时候它占用的内存与cpu是随着容器里面程序变化而变化的,如果没对程序做资源限制,那么很有可能导致某些pod直接占满我们的内存或者cpu,从而导致k8s集群出现问题。

  我们该如何防止此类问题的出现呢?方法一般有俩种

  • 对容器内的程序的配置文件做限制,比如java程序限制jvm的参数
  • 对pod的资源做限制,限制pod最高占用cpu与内存分别是多少,从而杜绝出现上述问题,下面我们主要介绍第二种

  

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: mysql
  name: mysql
spec:
  containers:
  - image: mysql
    imagePullPolicy: Always
    name: mysql
    ports:
    - containerPort: 3306
    env:
    - name: MYSQL_ROOT_PASSWORD    #指定root账号密码
      value: "123456"              #指定密码的值
    resources:
      limits:
        cpu: 100M     #限制最高占用0.1个cpu
        memory: 512Mi  #限制最高占用521M内存
      requests:
        cpu: 50M    #调度分配节点的时候请求最少分配0.05个cpu
        memory: 256Mi    #调度分配节点的时候请求最少分配256M内存

  

  • spec.containers[].resources.limits.cpu:CPU上限,可以短暂超过,容器也不会被停止
  • spec.containers[].resources.limits.memory:内存上限,不可以超过;如果超过,容器可能会被停止或调度到其他资源充足的机器上
  • spec.containers[].resources.requests.cpu:CPU请求,可以超过
  • spec.containers[].resources.requests.memory:内存请求,可以超过;但如果超过,容器可能会在Node内存不足时清理

  这就是对pod资源的限制,上面的内存限制用Mi做单位大家都可以理解,那么cpu中的M是什么意思呢?在k8s中,1个cpu资源=1000M,所以100M就相当于0.1个cpu,注意这是一个绝对值,不是相对值,这点要记住

  

三   探针

  是不是说只要你的pod资源处于running状态,它就能正常对外提供服务呢?比如说你自己写的一个程序,封装进一个基于ubantu的镜像里面,这个程序依托于ubantu启动。

  那么只要ubantu正常运行,你的程序挂了,pod依旧会显示正常运行,因为你的ubantu没挂啊。所以为了检测你的pod是否健康,只依靠pod运行的状态去判断是不合理的。

  此时我们需要引入探针来检测pod内的主容器是否健康,在上一篇中,我们提过探针的类型有俩种

  • livenessProbe探针:用于判断容器是否存活
  • readinessProbe探针:用于判断容器是否启动完成

 

 livenessprobe

  下面我们先说一下第一种探针livenessProbe

  livenessprobe用于判断容器是否存活。如果pod没有running,那么kubelet会kill掉这个pod,并根据重启的策略决定是否重启。

  如果一个容器不包含LivenessProbe探针,则Kubelet认为容器的LivenessProbe探针的返回值永远成功。  

  

  livenessprobe检测方法分类

  • exec:通过执行命令来检查服务是否正常,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康。这里面我们只介绍这种
  • httpGet:通过发送http请求检查服务是否正常,返回200-399状态码则表明容器健康。
  • tcpSocket:通过容器的IP和Port执行TCP检查,如果能够建立TCP连接,则表明容器健康。

  

1 exec-liveness.yaml  
 2 apiVersion: v1
 3 kind: Pod
 4 metadata:
 5   labels:
 6     test: liveness
 7   name: liveness-exec
 8 spec:
 9   containers:
10   - name: liveness
11     image: k8s.gcr.io/busybox
12     args:
13     - /bin/sh 
14     - -c
15     - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600   #容器启动时,创建一个healthy文件,沉睡30s后删除掉此文件,然后在沉睡10分钟
16     livenessProbe:
17       exec:           #探针检测方式 ,通过命令来执行
18         command:          #探针命令  cat 这个healthy文件
19         - cat
20         - /tmp/healthy                
21       initialDelaySeconds: 5      #容器启动后多少秒开始检查,我们总不能刚启动就开始检查吧,毕竟你要检测的程序运行起来还需要时间
22       periodSeconds: 5    #隔多少秒检查一次

  (此部分节选自k8s中文社区https://www.kubernetes.org.cn/2362.html)

 

  通过我上面写的注释,  你应该知道了这是一个什么样的流程,在容器生命的最初30秒内有一个 /tmp/healthy 文件,在这30秒内 cat /tmp/healthy命令会返回一个成功的返回码。30秒后, cat /tmp/healthy 将返回失败的返回码。

  

 readnessprobe

  readnessprobe检测方法分类(跟livenessprobe一样)

  • exec:通过执行命令来检查服务是否正常,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康。
  • httpGet:通过发送http请求检查服务是否正常,返回200-399状态码则表明容器健康。
  • tcpSocket:通过容器的IP和Port执行TCP检查,如果能够建立TCP连接,则表明容器健康。

  

  有时,应用程序暂时无法对外部流量提供服务。 例如,应用程序可能需要在启动期间加载大量数据或配置文件。 在这种情况下,你不想杀死应用程序,但你也不想发送请求。

  Kubernetes提供了readiness probe来检测和减轻这些情况。 Pod中的容器可以报告自  己还没有准备,不能处理Kubernetes服务发送过来的流量。

  Readiness probe的配置跟liveness probe很像。唯一的不同是使用 readinessProbe而不是livenessProbe

readinessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

  

  Probe中有很多精确和详细的配置,通过它们你能准确的控制liveness和readiness检查:

  • initialDelaySeconds:容器启动后第一次执行探测是需要等待多少秒。
  • periodSeconds:执行探测的频率。默认是10秒,最小1秒。
  • timeoutSeconds:探测超时时间。默认1秒,最小1秒。
  • successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。
  • failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。

  HTTP probe中可以给 httpGet设置其他配置项:

  • host:连接的主机名,默认连接到pod的IP。你可能想在http header中设置”Host”而不是使用IP。
  • scheme:连接使用的schema,默认HTTP。
  • path: 访问的HTTP server的path。
  • httpHeaders:自定义请求的header。HTTP运行重复的header。
  • port:访问的容器的端口名字或者端口号。端口号必须介于1和65525之间。

  对于HTTP探测器,kubelet向指定的路径和端口发送HTTP请求以执行检查。 Kubelet将probe发送到容器的IP地址,除非地址被httpGet中的可选host字段覆盖。

  在大多数情况下,你不想设置主机字段。 有一种情况下你可以设置它。 假设容器在127.0.0.1上侦听,并且Pod的hostNetwork字段为true。 然后,在httpGet下的

  host应该设置为127.0.0.1。 如果你的pod依赖于虚拟主机,这可能是更常见的情况,你不应该是用host,而是应该在httpHeaders中设置Host头。

  (以上探针部分均来自k8s中文社区作者宋净超)

 

 

四  imagepullsecrets

   pod内部的容器是基于镜像来运行的,公有镜像库内的镜像我们可以随便下载,那么当我们想啦取私有镜像库的镜像还能正常拉取么?经过测试,k8s提示我们ErroroPull,

  原因就在于我们拉取私有镜像库的时候需要现在k8s上面配一个对应的secret资源。

 

  创建secret命令

  

kubectl create secret docker-registry regsecret --docker-server=registry.cn-men.aliyuncs.com --docker-username=2919823123@aliyun.com --docker-password=xxxxxx --docker-email=asdlkjsadf@aliyun.com

  regsecret: 指定密钥的键名称, 可自行定义
  --docker-server: 指定docker仓库地址
  --docker-username: 指定docker仓库账号
  --docker-password: 指定docker仓库密码
  --docker-email: 指定邮件地址(选填)

 

五  小结

   这章是把上一章的知识点做一下查缺补漏,当然还有很多知识点没有覆盖到,我们可以去k8s中文社区或者通过官网文档来获取相关知识,我们这些野鸡文档仅供参考,不做权威