如何为依赖于 Amazon ECR 图像的 kubernetes 服务制作部署文件?

How to make a deployment file for a kubernetes service that depends on images from Amazon ECR?

一位同事为我创建了一个 K8s 集群。我可以 运行 在该集群中提供服务,没有任何问题。但是,我不能 运行 依赖于来自 Amazon ECR 的图像的服务,我真的不明白。可能是我在部署文件中犯了一个小错误,因此导致了这个问题。

这是我的部署文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment
  labels:
    app: hello
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: xxxxxxxxx.yyy.ecr.eu-zzzzz.amazonaws.com/test:latest
        ports:
        - containerPort: 5000

这是我的服务文件:

apiVersion: v1
kind: Service
metadata:
  name: hello-svc
  labels:
    app: hello
spec:
  type: NodePort
  ports:
  - port: 5000
    nodePort: 30002
    protocol: TCP
  selector:
    app: hello

在主节点上,我运行确保 kubernetes 知道部署和服务。

kubectl create -f dep.yml
kubectl create -f service.yml

我使用 K8s extension in vscode 检查我的 pods 的日志。

这是我得到的错误:

Error from server (BadRequest): container "hello" in pod "hello-deployment-xxxx-49pbs" is waiting to start: trying and failing to pull image.

显然,拉动是个问题..... 使用来自 public docker 集线器的 public 图像时不会发生这种情况。从逻辑上讲,这将是一个权利问题。但看起来好像不是。 运行在主节点上执行此命令时,我没有收到任何错误消息:

docker pull xxxxxxxxx.yyy.ecr.eu-zzzzz.amazonaws.com/test:latest

这个命令只是拉取我的图像。

我现在很迷茫。我可以在主节点上使用 docker pull 拉取我的图像。但是 K8s 无法拉动。我的部署文件中是否缺少某些内容?有些 属性 说:“repositoryIsPrivateButDoNotComplain”?我只是不明白。

如何解决此问题以便 K8s 可以轻松使用我来自 Amazon ECR 的图像?

对于 12 小时问题,如果您使用的是 Kubernetes 1.20,请配置并使用 Kubelet 镜像凭证提供程序

https://kubernetes.io/docs/tasks/kubelet-credential-provider/kubelet-credential-provider/

您需要在您的 kubelet 中启用 alpha 功能门 KubeletCredentialProviders

如果使用较低的 Kubernetes 版本并且此功能不可用,则使用 https://medium.com/@damitj07/how-to-configure-and-use-aws-ecr-with-kubernetes-rancher2-0-6144c626d42c

您应该为 ECR 授权创建和使用机密。

这就是你需要做的。

  1. 为 Kubernetes 集群创建一个秘密,从一台机器上执行下面给出的 shell 脚本,您可以从该机器访问托管 ECR 注册表的 AWS 帐户。请根据您的设置更改占位符。请确保您执行此 shell 脚本的机器应该安装了 aws cli 并配置了 aws 凭据。如果您使用的是 windows 机器,则在 Cygwin 或 git bash 控制台中执行此脚本。
#!/bin/bash
ACCOUNT=<AWS_ACCOUNT_ID>
REGION=<REGION>
SECRET_NAME=<SECRETE_NAME>
EMAIL=<SOME_DUMMY_EMAIL>

TOKEN=`/usr/local/bin/aws ecr --region=$REGION --profile <AWS_PROFILE> get-authorization-token --output text --query authorizationData[].authorizationToken | base64 -d | cut -d: -f2`

kubectl delete secret --ignore-not-found $SECRET_NAME
kubectl create secret docker-registry $SECRET_NAME \
 --docker-server=https://${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com \
 --docker-username=AWS \
 --docker-password="${TOKEN}" \
 --docker-email="${EMAIL}"
  1. 更改部署并添加您 pods 从 ECR 下载图像时将使用的秘密部分。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment
  labels:
    app: hello
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: xxxxxxxxx.yyy.ecr.eu-zzzzz.amazonaws.com/test:latest
        ports:
        - containerPort: 5000
      imagePullSecrets:
        - name: SECRET_NAME
  1. 创建 pods 和服务。

  2. 如果成功,那么秘密仍将在 12 小时后过期,以克服该设置一个 crone(用于定期在 Kubernetes 集群上重新创建秘密。设置 crone 使用相同的脚本以上给出。

如需了解幕后发生的完整情况,请参阅下图。

问候 阿米特·米纳