Kubernetes 容器 - 镜像
Table of Contents
https://kubernetes.io/docs/concepts/containers/images
容器镜像封装了应用程序和它的所有软件依赖的二进制数据。容器镜像是可执行的独立运行的软件包,并且对他们的运行时环境进行了明确的定义。
通常,你在 Pod 中引用应用程序之前,先创建应用程序的容器镜像,然后推送到镜像仓库(registry)。
1. 镜像名
镜像通常有一个名字,比如 pause
, example/mycontainer
或者 kube-apiserver
。镜像也可以包含镜像仓库的主机名;比如:
fictional.registry.example/imagename
,还可能包含一个端口号;比如 fictional.registry.example:10443/imagename
。
如果你没有指定仓库主机名,Kubernetes 会认为你使用的是 Docker 公共的仓库。
镜像部分之后你可以添加一个 标签(tag) (可以与 docker
和 podman
之类的工具一起使用)。标签标记镜像的不同版本。
镜像标签由小写字母和大写字母,数字,下划线,点和短横线组成。关于将分隔符 _, - , .
放在镜像标签中的位置,还有其他规则。
如果你不指定一个标签,Kubernetes 认为你使用的是 latest
标签。
警告:
在生产环境中部署容器时,应避免使用
latest
标签,因为它很难跟踪镜像具体哪本版本在运行,并且版本回滚也非常困难。建议使用一个有意义的标签,比如
v1.42.0
。
2. 更新镜像
当你第一次创建 Deployment,StatefulSet,Pod 或者其他包含 Pod 模板的对象时,如果没有明确指定,默认的镜像拉取策略是 IfNotPresent
。
如果镜像已经存在,该策略会导致 kubelet 跳过拉取镜像。
如果你想使用强制拉取,则可以自行一下操作之一:
- 设置容器的
imagePullPolicy
为Always
; - 忽略
imagePullPolicy
并且使用:latest
作为镜像标签;Kubernetes 会设置策略为Always
; - 忽略
imagePullPolicy
和要使用的镜像标签; - 开启 AlwaysPullImages 准入控制器;
注意:
容器
imagePullPolicy
的值始终在首次创建对象时设置,并且以后更改镜像的 tag 也不会修改该值。比如说,你创建一个 Deployment 的镜像标签不是
:latest
,但是之后把 Deployment 的镜像设置为:latest
标签,imagePullPolicy
的字段不会改为Always
。首次创建之后,你必须手动修改对象的拉取策略。
当定义 imagePullPolicy
时不指定特定值,默认值也是 Always
。
3. 具有镜像索引的多体系架构镜像
As well as providing binary images, a container registry can also serve a container image index.
An image index can point to multiple image manifests for architecture-specific versions of a container.
The idea is that you can have a name for an image (for example: pause
, example/mycontainer
, kube-apiserver
)
and allow different systems to fetch the right binary image for the machine architecture they are using.
Kubernetes itself typically names container images with a suffix -$(ARCH)
. For backward compatibility, please
generate the older images with suffixes. The idea is to generate say pause
image which has the manifest for all
the arch(es) and say pause-amd64
which is backwards compatible for older configurations or YAML files which
may have hard coded the images with suffixes.
4. 使用私有仓库
私有仓库可能需要密钥才能拉取镜像。证书可以有以下几种方式:
- 给私有仓库配置节点认证
- 所有的 pods 都可以从已配置的私有仓库中读取
- 需要节点管理员配置节点
- 预拉取镜像
- 所有的 Pod 都可以使用节点上缓存的镜像
- 需要所有节点的 root 权限才能进行设置
- 在 Pod 上指定 ImagePullSecrets
- 只有提供自己密钥的 Pod 才能访问仓库
- 供应商特定(Vendor-specific)或本地扩展
- 如果你使用的是自定义的节点配置,你(或者你的云提供商)可以实现你的向容器仓库验证节点的机制
这些选项将在下面更详细的说明。
4.1. TODO 配置节点向私有仓库认证
4.2. TODO 预拉取(Pre-pulled)镜像
4.3. TODO 在 Pod 上指定 imagePullSecrets
5. 使用案例
有许多的用于配置私有仓库的的解决方案,以下是一些常见的案例和建议的解决方案。
- 集群仅运行非私有的镜像(比如说开源的)。不需要隐藏镜像。
- 使用 Docker hub 的公共镜像
- 不需要配置;
- 一些云厂商会自动缓存或者镜像(mirror)公共镜像,从而提高性能并减少拉取镜像的时间;
- 使用 Docker hub 的公共镜像
- 集群使用一些专有镜像,这些镜像对公司的外部人员不可见,但对所有集群的用户可见。
- 使用私有托管的 Docker registry
- 可以托管在 Docker Hub,或者其他地方;
- 在每个节点上如上所述的手动管理 .docker/config.json;
- 或者,在具有开放只读权限的防火墙后内部运行私有仓库
- 不需要 Kubernetes 配置;
- 使用托管的容器镜像仓库服务来控制镜像访问
- 与手动配置节点相比,它在群集自动扩展方面会更好地工作;
- 或者,在不方便更改节点配置的集群上,使用
imagePullSecrets
- 使用私有托管的 Docker registry
- 集群使用专有镜像,其中一些镜像需要严格的访问控制
- 确保 AlwaysPullImages 准入控制器 是激活状态。否则所有的 Pods 都可以访问所有的镜像;
- 将敏感数据移动到『Secret』资源,而不是打包在镜像中;
- 一个多租户集群,其中每个租户都需要自己的私有镜像仓库
- 确保 AlwaysPullImages 准入控制器激活。否则,所有租户的所有 Pod 都可能有权访问所有的镜像;
- 在需要授权的情况下运行私有注册表;
- 为每个租户生成仓库凭证,并放到 secret 中,然后向每个租户的空间中设置 secret;
- 租户将 secret 添加到每个空间的 imagePullSecrets 中;
如果你需要访问多个仓库,你可以为每一个仓库创建一个 secret。Kubelet 会合并任何 imagePullSecrets
到单个虚拟的 .docker/config.json
中。