k8s-No.3-pod进阶
作者:互联网
本章目录
- pod环境变量env
- pod的资源限制resources
- pod的健康检查-探针
- 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中文社区或者通过官网文档来获取相关知识,我们这些野鸡文档仅供参考,不做权威标签:容器,探针,cpu,No.3,mysql,pod,k8s,docker 来源: https://www.cnblogs.com/mhy-blog/p/10775936.html