【K8s概念】镜像
参考:https://kubernetes.io/zh/docs/concepts/containers/images/
更新镜像
当你最初创建一个 Deployment、 StatefulSet、Pod 或者其他包含 Pod 模板的对象时,如果没有显式设定的话,Pod 中所有容器的默认镜像 拉取策略是 IfNotPresent。这一策略会使得 kubelet 在镜像已经存在的情况下直接略过拉取镜像的操作。
如果你希望强制总是拉取镜像,你可以执行以下操作之一:
- 设置容器的 imagePullPolicy 为 Always。
- 省略 imagePullPolicy,并使用 :latest 作为要使用的镜像的标签; Kubernetes 会将策略设置为 Always。
- 省略 imagePullPolicy 和要使用的镜像标签。
- 启用 AlwaysPullImages 准入控制器(Admission Controller)。
说明:对象被 创建 时,容器的 imagePullPolicy 总是被设置为某值,如果镜像的标签 后来发生改变,镜像拉取策略也不会被改变。
例如,如果你创建了一个 Deployment 对象,其中的镜像标签不是 :latest, 后来 Deployment 的镜像被改为 :latest,则 imagePullPolicy 不会被改变为 Always。你必须在对象被初始创建之后手动改变拉取策略。
如果 imagePullPolicy 未被定义为特定的值,也会被设置为 Always。
使用私有仓库
从私有仓库读取镜像时可能需要密钥。 凭证可以用以下方式提供:
- 配置节点向私有仓库进行身份验证
- 所有 Pod 均可读取任何已配置的私有仓库
- 需要集群管理员配置节点
- 预拉镜像
- 所有 Pod 都可以使用节点上缓存的所有镜像
- 需要所有节点的 root 访问权限才能进行设置
- 在 Pod 中设置 ImagePullSecrets
- 只有提供自己密钥的 Pod 才能访问私有仓库
- 特定于厂商的扩展或者本地扩展
- 如果你在使用定制的节点配置,你(或者云平台提供商)可以实现让节点 向容器仓库认证的机制
在 Pod 上指定 ImagePullSecrets
说明: 运行使用私有仓库中镜像的容器时,建议使用这种方法。
Kubernetes 支持在 Pod 中设置容器镜像仓库的密钥。
- 使用 Docker Config 创建 Secret
运行以下命令,将大写字母代替为合适的值:
kubectl create secret docker-registry <名称> \
--docker-server=DOCKER_REGISTRY_SERVER \
--docker-username=DOCKER_USER \
--docker-password=DOCKER_PASSWORD \
--docker-email=DOCKER_EMAIL
如果你已经有 Docker 凭据文件,则可以将凭据文件导入为 Kubernetes Secret, 而不是执行上面的命令。 基于已有的 Docker 凭据创建 Secret 解释了如何完成这一操作。
https://kubernetes.io/zh/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials
如果你在使用多个私有容器仓库,这种技术将特别有用。 原因是 kubectl create secret docker-registry 创建的是仅适用于某个私有仓库的 Secret。
说明: Pod 只能引用位于自身所在名字空间中的 Secret,因此需要针对每个名字空间 重复执行上述过程。
- 在 Pod 中引用 ImagePullSecrets
现在,在创建 Pod 时,可以在 Pod 定义中增加 imagePullSecrets 部分来引用该 Secret。
例如:
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 执行以上操作。 不过,设置该字段的过程也可以通过为 服务账号 资源设置 imagePullSecrets 来自动完成。 有关详细指令可参见 将 ImagePullSecrets 添加到服务账号。
https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/
https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account
你也可以将此方法与节点级别的 .docker/config.json 配置结合使用。 来自不同来源的凭据会被合并。
镜像使用案例
配置私有仓库有多种方案,以下是一些常用场景和建议的解决方案。
1.集群运行非专有镜像(例如,开源镜像)。镜像不需要隐藏。
- 使用 Docker hub 上的公开镜像
- 无需配置
- 某些云厂商会自动为公开镜像提供高速缓存,以便提升可用性并缩短拉取镜像所需时间
2.集群运行一些专有镜像,这些镜像需要对公司外部隐藏,对所有集群用户可见
- 使用托管的私有 Docker 仓库。
- 可以托管在 Docker Hub 或者其他地方
- 按照上面的描述,在每个节点上手动配置 .docker/config.json 文件
- 或者,在防火墙内运行一个组织内部的私有仓库,并开放读取权限
- 不需要配置 Kubenretes
- 使用控制镜像访问的托管容器镜像仓库服务
- 与手动配置节点相比,这种方案能更好地处理集群自动扩缩容
- 或者,在不方便更改节点配置的集群中,使用 imagePullSecrets
3.集群使用专有镜像,且有些镜像需要更严格的访问控制
- 确保 AlwaysPullImages 准入控制器被启用。否则,所有 Pod 都可以使用所有镜像。
- 确保将敏感数据存储在 Secret 资源中,而不是将其打包在镜像里
4.集群是多租户的并且每个租户需要自己的私有仓库
- 确保 AlwaysPullImages 准入控制器。否则,所有租户的所有的 Pod 都可以使用所有镜像。
- 为私有仓库启用鉴权
- 为每个租户生成访问仓库的凭据,放置在 Secret 中,并将 Secrert 发布到各租户的命名空间下。
- 租户将 Secret 添加到每个名字空间中的 imagePullSecrets
如果你需要访问多个仓库,可以为每个仓库创建一个 Secret。 kubelet 将所有 imagePullSecrets 合并为一个虚拟的 .docker/config.json 文件。