【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 文件。

posted @ 2021-07-26 14:14  Varden  阅读(553)  评论(0)    收藏  举报