+v ljx97609760
一起沟通学习
容器镜像
容器镜像(Image)所承载的是封装了应用程序及其所有软件依赖的二进制数据。 容器镜像是可执行的软件包,可以单独运行
你通常会创建应用的容器镜像并将其推送到某仓库(Registry),然后在 Pod 中引用它
镜像名称
如果你不指定仓库的主机名,Kubernetes 认为你在使用 Docker 公共仓库
在镜像名称之后,你可以添加一个标签(Tag)(与使用 docker 或 podman 等命令时的方式相同)使用标签能让你辨识同一镜像序列中的不同版本
镜像标签可以包含小写字母、大写字母、数字、下划线()、句点(.)和连字符(-)。 关于在镜像标签中何处可以使用分隔字符(、- 和 .)还有一些额外的规则。 如果你不指定标签,Kubernetes 认为你想使用标签 latest
更新镜像
当你最初创建一个 Deployment、 StatefulSet、Pod 或者其他包含 Pod 模板的对象时,如果没有显式设定的话, Pod 中所有容器的默认镜像拉取策略是 IfNotPresent。这一策略会使得 kubelet 在镜像已经存在的情况下直接略过拉取镜像的操作
镜像拉取策略
容器的 imagePullPolicy 和镜像的标签会影响 kubelet 尝试拉取(下载)指定的镜像
以下列表包含了 imagePullPolicy 可以设置的值,以及这些值的效果:
IfNotPresent
只有当镜像在本地不存在时才会拉取
Always
每当 kubelet 启动一个容器时,kubelet 会查询容器的镜像仓库, 将名称解析为一个镜像摘要。 如果 kubelet 有一个容器镜像,并且对应的摘要已在本地缓存,kubelet 就会使用其缓存的镜像; 否则,kubelet 就会使用解析后的摘要拉取镜像,并使用该镜像来启动容器
Never
Kubelet 不会尝试获取镜像。如果镜像已经以某种方式存在本地, kubelet 会尝试启动容器;否则,会启动失败
默认镜像拉取策略
当你(或控制器)向 API 服务器提交一个新的 Pod 时,你的集群会在满足特定条件时设置 imagePullPolicy 字段:
- 如果你省略了 imagePullPolicy 字段,并且你为容器镜像指定了摘要, 那么 imagePullPolicy 会自动设置为 IfNotPresent
- 如果你省略了 imagePullPolicy 字段,并且容器镜像的标签是 :latest, imagePullPolicy 会自动设置为 Always
- 如果你省略了 imagePullPolicy 字段,并且没有指定容器镜像的标签, imagePullPolicy 会自动设置为 Always
- 如果你省略了 imagePullPolicy 字段,并且为容器镜像指定了非 :latest 的标签, imagePullPolicy 就会自动设置为 IfNotPresent
必要的镜像拉取
如果你想总是强制执行拉取,你可以使用下述的一中方式:
- 设置容器的 imagePullPolicy 为 Always
- 省略 imagePullPolicy,并使用 :latest 作为镜像标签; 当你提交 Pod 时,Kubernetes 会将策略设置为 Always
- 省略 imagePullPolicy 和镜像的标签; 当你提交 Pod 时,Kubernetes 会将策略设置为 Always。
- 启用准入控制器 AlwaysPullImages
ImagePullBackOff
当 kubelet 使用容器运行时创建 Pod 时,容器可能因为 ImagePullBackOff 导致状态为 Waiting
ImagePullBackOff 状态意味着容器无法启动, 因为 Kubernetes 无法拉取容器镜像(原因包括无效的镜像名称,或从私有仓库拉取而没有 imagePullSecret)。 BackOff 部分表示 Kubernetes 将继续尝试拉取镜像,并增加回退延迟
Kubernetes 会增加每次尝试之间的延迟,直到达到编译限制,即 300 秒(5 分钟)
串行和并行镜像拉取
默认情况下,kubelet 以串行方式拉取镜像。 也就是说,kubelet 一次只向镜像服务发送一个镜像拉取请求, 其他镜像拉取请求必须等待,直到正在处理的那个请求完成
节点独立地做出镜像拉取的决策。即使你使用串行的镜像拉取,两个不同的节点也可以并行拉取相同的镜像
如果你想启用并行镜像拉取,可以在 kubelet 配置 中将字段 serializeImagePulls 设置为 false
当serializeImagePulls 设置为 false 时,kubelet 会立即向镜像服务发送镜像拉取请求,多个镜像将同时被拉动
启用并行镜像拉取时,请确保你的容器运行时的镜像服务可以处理并行镜像拉取
kubelet 从不代表一个 Pod 并行地拉取多个镜像
例如,如果你有一个 Pod,它有一个初始容器和一个应用容器,那么这两个容器的镜像拉取将不会并行。 但是,如果你有两个使用不同镜像的 Pod,当启用并行镜像拉取时,kubelet 会代表两个不同的 Pod 并行拉取镜像
最大并行镜像拉取数量
特性状态: Kubernetes v1.27 [alpha]
当 serializeImagePulls 被设置为 false 时,kubelet 默认对同时拉取的最大镜像数量没有限制, 如果你想限制并行镜像拉取的数量,可以在 kubelet 配置中设置字段 maxParallelImagePulls, 当 maxParallelImagePulls 设置为 n 时,只能同时拉取 n 个镜像, 超过 n 的任何镜像都必须等到至少一个正在进行拉取的镜像拉取完成后,才能拉取
当启用并行镜像拉取时,限制并行镜像拉取的数量可以防止镜像拉取消耗过多的网络带宽或磁盘 I/O
你可以将 maxParallelImagePulls 设置为大于或等于 1 的正数。 如果将 maxParallelImagePulls 设置为大于等于 2,则必须将 serializeImagePulls 设置为 false。 kubelet 在无效的 maxParallelImagePulls 设置下会启动失败
使用私有仓库
从私有仓库读取镜像时可能需要密钥。 凭据可以用以下方式提供:
在 Pod 上指定 ImagePullSecrets
说明:
运行使用私有仓库中镜像的容器时,建议使用这种方法
Kubernetes 支持在 Pod 中设置容器镜像仓库的密钥。 imagePullSecrets 必须全部与 Pod 位于同一个名字空间中。 引用的 Secret 必须是 kubernetes.io/dockercfg 或 kubernetes.io/dockerconfigjson 类型
使用 Docker Config 创建 Secret
你需要知道用于向仓库进行身份验证的用户名、密码和客户端电子邮件地址,以及它的主机名。 运行以下命令,注意替换适当的大写值
c
kubectl create secret docker-registry <name> \
--docker-server=DOCKER_REGISTRY_SERVER \
--docker-username=DOCKER_USER \
--docker-password=DOCKER_PASSWORD \
--docker-email=DOCKER_EMAIL
在 Pod 中引用 ImagePullSecrets
在创建 Pod 时,可以在 Pod 定义中增加 imagePullSecrets 部分来引用该 Secret。 imagePullSecrets 数组中的每一项只能引用同一名字空间中的 Secret
例如:
c
cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: myregistrykey
EOF
cat <<EOF >> ./kustomization.yaml
resources:
- pod.yaml
EOF
你需要对使用私有仓库的每个 Pod 执行以上操作