K8s-容器
K8s-容器
镜像
在 Kubernetes 的 Pod 中使用容器镜像之前,您必须将其推送到一个镜像仓库(或者使用仓库中已经有的容器镜像)。在 Kubernetes 的 Pod 定义中定义容器时,必须指定容器所使用的镜像,容器中的 image
字段支持与 docker
命令一样的语法,包括私有镜像仓库和标签。
例如:my-registry.example.com:5000/example/web-example:v1.0.1
由如下几个部分组成:
my-registry.example.com:5000/example/web-example:v1.0.1
- my-registry.example.com:registry 地址
- 5000:registry 端口
- example:repository 名字
- web-example:image 名字
- v1.0.1:image 标签
如果您使用 hub.dokcer.com
Registry 中的镜像,可以省略 registry 地址和 registry 端口。例如:nginx:latest
,eipwork/kuboard
更新镜像
更新策略
Kubernetes中,默认的镜像抓取策略是 IfNotPresent
,使用此策略,kubelet在发现本机有镜像的情况下,不会向镜像仓库抓取镜像
如果期望每次启动 Pod 时,都强制从镜像仓库抓取镜像:
- 设置 container 中的
imagePullPolicy
为Always
- 省略
imagePullPolicy
字段,并使用:latest
tag 的镜像 - 省略
imagePullPolicy
字段和镜像的 tag - 激活 AlwaysPullImages (opens new window)管理控制器
更新过程:
imagePullPolicy: IfNotPresent
仅在节点上没有该镜像时,从镜像仓库抓取imagePullPolicy: Always
每次启动 Pod 时,从镜像仓库抓取imagePullPolicy
未填写,镜像 tag 为:latest
或者未填写,则同Always
每次启动 Pod 时,从镜像仓库抓取imagePullPolicy
未填写,镜像 tag 已填写但不是:latest
,则同IfNotPresent
仅在节点上没有该镜像时,从镜像仓库抓取imagePullPolicy: Never
,Kubernetes 假设本地存在该镜像,并且不会尝试从镜像仓库抓取镜像
使用私有仓库中的docker镜像
因为企业以下需求通常会有自建仓库的需求:
- 限制 docker 镜像的分发范围,例如:只允许在内网分发,或者只允许被授权的用户获取 docker 镜像
- 提高推送 docker 镜像以及抓取 docker 镜像时的网络传输速度
一个镜像仓库需要以下的要求:
⚠️需要支持HTTPS
参数名称 | 参数值 | 备注 |
registry地址 | my-registry.example.com | 推荐使用域名,也可以是 ip 地址 |
registry端口 | 5000 | 必须支持 HTTPS |
registry用户名 | myusername | |
registry密码 | mypassowrd | |
repository名字 | example | |
image名字 | web-example | |
image标签 | v1.0.1 |
容器的环境变量
容器的信息
在容器中执行 hostname
命令或者在libc 中执行 gethostname (opens new window)函调用,获得的是容器所在 Pod 的名字。
Pod 的名字,以及 Pod 所在名称空间可以通过 downward API (opens new window)注入到容器的环境变量里。
用户也可以为容器自定义环境变量,请参考 使用ConfigMap配置您的应用程序
集群的信息
在容器创建时,集群中所有的 Service 的连接信息将以环境变量的形式注入到容器中。例如,已创建了一个名为 Foo 的 Service,此时再创建任何容器时,该容器将包含如下环境变量: |
Runtime Class
可以通过 RuntimeClass,使不同的 Pod 使用不同的容器引擎,以在性能和安全之间取得平衡。例如,如果某些工作负载需要非常高的信息安全保证,您可能想要将其 Pod 运行在那种使用硬件虚拟化的容器引擎上;同时,将其他的 Pod 运行在另外一种容器引擎上,以获得更高的性能。K8s-Runtime Class
容器生命周期
PostStart
此钩子函数在容器创建后将立刻执行。但是,并不能保证该钩子函数在容器的
ENTRYPOINT
之前执行。该钩子函数没有输入参数。PreStop
此钩子函数在容器被 terminate(终止)之前执行,例如:
- 通过接口调用删除容器所在 Pod
- 某些管理事件的发生:健康检查失败、资源紧缺等
如果容器已经被关闭或者进入了
completed
状态,preStop 钩子函数的调用将失败。该函数的执行是同步的,即,kubernetes 将在该函数完成执行之后才删除容器。该钩子函数没有输入参数
Hook handler的实现
容器只要实现并注册 hook handler 便可以使用钩子函数。Kubernetes 中,容器可以实现两种类型的 hook handler:
- Exec - 在容器的名称空进和 cgroups 中执行一个指定的命令,例如
pre-stop.sh
。该命令所消耗的 CPU、内存等资源,将计入容器可以使用的资源限制。 - HTTP - 向容器的指定端口发送一个 HTTP 请求
Hook handler的执行
当容器的生命周期事件发生时,Kubernetes 在容器中执行该钩子函数注册的 handler。
对于 Pod 而言,hook handler 的调用是同步的。即,如果是 PostStart
hook,容器的 ENTRYPOINT
和 hook 是同时出发的,然而如果 hook 执行的时间过长或者挂起了,容器将不能进入到 Running
状态。
PreStop
hook 的行为与此相似。如果 hook 在执行过程中挂起了,Pod phase 将停留在 Terminating
的状态,并且在 terminationGracePeriodSeconds
超时之后,Pod被删除。如果 PostStart
或者 PreStop
hook 执行失败,则 Kubernetes 将 kill(杀掉)该容器。
用户应该使其 hook handler 越轻量级越好。例如,对于长时间运行的任务,在停止容器前,调用 PreStop
钩子函数,以保存当时的计算状态和数据
定义postStart和preStop处理程序
apiVersion: v1 |