Home
Cron Job
DNS Pod 与 Service
DaemonSet
Deployments
Docker 用户使用 kubectl 命令指南
Init 容器
JSONPath 支持
Kubernetes 中的代理
Kubernetes 组件
Kubernetes集群中使用Sysctls
Managing Compute Resources for Containers
Master 节点通信
Nodes
Pod Preset
Pod 安全策略
Pod 的生命周期
Secret
Service
kubectl概述
为容器设置启动时要执行的命令及其入参
为容器设置环境变量
云供应商
使用 Calico 来提供 NetworkPolicy
使用 HostAliases 向 Pod /etc/hosts 文件添加条目
使用 PodPreset 将信息注入 Pods
使用 Romana 来提供 NetworkPolicy
使用 Secret 安全地分发凭证
使用 Service 把前端连接到后端
使用 Weave 网络来提供 NetworkPolicy
使用Deployment运行一个无状态应用
关键插件 Pod 的调度保证
同 Pod 内的容器使用共享卷通信
在 Kubernetes 中配置私有 DNS 和上游域名服务器
垃圾收集
基于Replication Controller执行滚动升级
声明网络策略
安装扩展(Addons)
容器环境变量
对 DaemonSet 执行回滚
应用故障排查
应用资源配额和限额
应用连接到 Service
弹缩StatefulSet
控制节点上的CPU管理策略
改变默认 StorageClass
更改 PersistentVolume 的回收策略
概念模板示例
理解 Kubernetes 对象
知名标签(Label)、注解(Annotation)和 Taints
管理巨页(HugePages)
给容器分配非透明整型资源
网络策略
联邦
认识 Kubernetes?
认识 Kubernetes?
设备插件
设置 Pod CPU 和内存限制
访问集群上运行的服务
证书
证书轮换
调度 GPU
调试Pods和Replication Controllers
调试StatefulSet
资源配额
运行一个单实例有状态应用
通过文件将Pod信息呈现给容器
通过环境变量将Pod信息呈现给容器
通过配置文件设置 Kubelet 参数
配置你的云平台防火墙
配置命名空间下pod总数
配置对多集群的访问
镜像
集群故障排查
集群管理
集群管理概述
静态Pods

Edit This Page

镜像

在Kubernetes pod中引用镜像前,请创建Docker镜像,并将之推送到镜像仓库中。 容器的“image”属性支持和Docker命令行相同的语法,包括私有仓库和标签。

升级镜像

默认的镜像拉取策略是“IfNotPresent”,在镜像已经存在的情况下,kubelet将不在去拉取镜像。 如果总是想要拉取镜像,必须设置拉取策略为“Always”或者设置镜像标签为“:latest”。

如果没有指定镜像的标签,它会被假定为“:latest”,同时拉取策略为“Always”。

注意应避免使用“:latest”标签,参见 Best Practices for Configuration 获取更多信息。

使用私有仓库

从私有仓库读取镜像时可能需要密钥。 凭证可以用以下方式提供:

使用 Google Container Registry

Kuberetes运行在Google Compute Engine (GCE)时原生支持Google ContainerRegistry (GCR)。如果kubernetes集群运行在GCE 或者Google Kubernetes Engine 上,使用镜像全名(e.g. gcr.io/my_project/image:tag)即可。

集群中的所有pod都会有读取这个仓库中镜像的权限。

Kubelet将使用实例的Google service account向GCR认证。实例的service account拥有 https://www.googleapis.com/auth/devstorage.read_only,所以它可以从项目的GCR拉取,但不能推送。

使用 AWS EC2 Container Registry

当Node是AWS EC2实例时,Kubernetes原生支持AWS EC2 ContainerRegistry

在pod定义中,使用镜像全名即可 (例如 ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag)

集群中可以创建pod的用户都可以使用ECR中的任意镜像运行pod。

Kubelet会获取并且定期刷新ECR的凭证。它需要以下权限

要求:

诊断

使用 Azure Container Registry (ACR)

当使用Azure Container Registry时,可以使用admin user或者service principal认证。 任何一种情况,认证都通过标准的Dokcer authentication完成。本指南假设使用azure-cli 命令行工具。

首先,需要创建仓库并获取凭证,完整的文档请参考 Azure container registry documentation

创建好容器仓库后,可以使用以下凭证登录:

填写以上变量后,就可以 configure a Kubernetes Secret and use it to deploy a Pod

配置Nodes对私有仓库认证

注意: 如果在Google Kubernetes Engine 上运行集群,每个节点上都会有.dockercfg文件,它包含对Google Container Registry的凭证。 不需要使用以下方法。

注意: 如果在AWS EC2上运行集群且准备使用EC2 Container Registry (ECR),每个node上的kubelet会管理和更新ECR的登录凭证。不需要使用以下方法。

注意: 该方法适用于能够对节点进行配置的情况。该方法在GCE及在其它能自动配置节点的云平台上并不适合。

Docker将私有仓库的密钥存放在$HOME/.dockercfg$HOME/.docker/config.json文件中。Kubelet上,docker会使用root用户$HOME路径下的密钥。

推荐如下步骤来为node配置私有仓库。以下示例在PC或笔记本电脑中操作

1.对于想要使用的每一种凭证,运行 docker login [server],它会更新$HOME/.docker/config.json。 1.使用编辑器查看$HOME/.docker/config.json,保证文件中包含了想要使用的凭证 1.获取node列表,例如 - 如果使用node名称,nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}') - 如果使用node IP ,nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}') 1.将本地的.docker/config.json拷贝到每个节点root用户目录下 - 例如: for n in $nodes; do scp ~/.docker/config.json root@$n:/root/.docker/config.json; done

创建使用私有仓库的pod来验证,例如:

$ cat <<EOF > /tmp/private-image-test-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: private-image-test-1
spec:
  containers:
    - name: uses-private-image
      image: $PRIVATE_IMAGE_NAME
      imagePullPolicy: Always
      command: [ "echo", "SUCCESS" ]
EOF
$ kubectl create -f /tmp/private-image-test-1.yaml
pod "private-image-test-1" created
$

如果一切正常,一段时间后,可以看到:

$ kubectl logs private-image-test-1
SUCCESS

如果失败,则可以看到:

$ kubectl describe pods/private-image-test-1 | grep "Failed"
  Fri, 26 Jun 2015 15:36:13 -0700    Fri, 26 Jun 2015 15:39:13 -0700    19    {kubelet node-i2hq}    spec.containers{uses-private-image}    failed        Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found

必须保证集群中所有的节点都有相同的.docker/config.json文件。否则,pod会在一些节点上正常运行而在另一些节点上无法启动 例如,如果使用node自动弹缩,那么每个实例模板都需要包含.docker/config.json,或者挂载一个包含这个文件的驱动器。

.docker/config.json中配置了私有仓库密钥后,所有pod都会能读取私有仓库中的镜像。

该方法已在6月26日的docker私有仓库和kubernetes v0.19.3上测试通过,其他私有仓库,如quay.io应该也可以运行,但未测试过。

提前拉取镜像

注意: 如果在Google Kubernetes Engine 上运行集群,每个节点上都会有.dockercfg文件,它包含对Google Container Registry的凭证。 不需要使用以下方法。

注意: 该方法适用于能够对节点进行配置的情况。该方法在GCE及在其它能自动配置节点的云平台上并不适合。

默认情况下,kubelet会尝试从指定的仓库拉取每一个镜像 但是,如果容器属性imagePullPolicy设置为IfNotPresent或者Never, 则会使用本地镜像(优先、唯一、分别)。

如果依赖提前拉取镜像代替仓库认证, 必须保证集群所有的节点提前拉取的镜像是相同的。

可以用于提前载入指定的镜像以提高速度,或者作为私有仓库认证的一种替代方案

所有的pod都可以使用node上缓存的镜像

在pod上指定ImagePullSecrets

注意: Google Kubernetes Engine,GCE及其他自动创建node的云平台上,推荐使用本方法。

Kubernetes支持在pod中指定仓库密钥。

使用Docker Config创建Secret

运行以下命令,将大写字母代替为合适的值

$ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret "myregistrykey" created.

如果需要接入多个仓库,可以为每个仓库创建一个secret。 当为pod拉取镜像时,kubelet会将imagePullSecrets合入一个独立虚拟的.docker/config.json

Pod只能引用和它相同namespace的ImagePullSecrets, 所以需要为每一个namespace做配置

通过kubectl创建secret

由于某种原因在一个.docker/config.json中需要多个项或者需要非上述命令给出的secret,可以create a secret using json or yaml

请保证:

示例:

apiVersion: v1
kind: Secret
metadata:
  name: myregistrykey
  namespace: awesomeapps
data:
  .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
type: kubernetes.io/dockerconfigjson

如果收到错误消息error: no objects passed to create,可能是 base64 编码后的字符串非法。 如果收到错误消息类似Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ..., 说明数据已经解码成功,但是不满足.docker/config.json文件的语法。

在pod中引用imagePullSecrets

现在,在创建pod时,可以在pod定义中增加imagePullSecrets小节来引用secret

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: myregistrykey

对每一个使用私有仓库的pod,都需要做以上操作。

也可以在serviceAccount 资源中设置imagePullSecrets自动设置imagePullSecrets

imagePullSecrets可以和每个node上的.docker/config.json一起使用,他们将共同生效。本方法在Google Kubernetes Engine 也能正常工作。

使用场景

配置私有仓库有多种方案,以下是一些常用场景和建议的解决方案。

  1. 集群运行非专有(例如 开源镜像)镜像。镜像不需要隐藏。
    • 使用Docker hub上的公有镜像
    • 无需配置
    • 在GCE/GKE上会自动使用高稳定性和高速的Docker hub的本地mirror
  2. 集群运行一些专有镜像,这些镜像对外部公司需要隐藏,对集群用户可见
    • 使用自主的私有Docker registry.
      • 可以放置在Docker Hub,或者其他地方。
      • 按照上面的描述,在每个节点手动配置.docker/config.json
    • 或者,在防火墙内运行一个内置的私有仓库,并开放读取权限
      • 不需要配置Kubenretes
    • 或者,在GCE/GKE上时,使用项目的Google Container Registry
      • 使用集群自动伸缩比手动配置node工作的更好
    • 或者,在更改集群node配置不方便时,使用imagePullSecrets
  3. 使用专有镜像的集群,有更严格的访问控制
  4. 多租户集群下,每个租户需要自己的私有仓库
    • 保证AlwaysPullImages admission controller开启。否则,所有租户的所有的pod都可以使用镜像
    • 私有仓库开启认证
    • 为每个租户获取仓库凭证,放置在secret中,并发布到每个租户的namespace下
    • 租户将secret增加到每个namespace下的imagePullSecrets中