MENU

在k8s上使用ecr作为业务镜像库

• 2021 年 12 月 15 日 • Docker,Kubernetes

在k8s上使用ecr作为镜像仓库。

ECR是aws提供的一种弹性伸缩的容器镜像仓库,价格便宜,性能强劲。

下面来自官网介绍:
“Amazon Elastic Container Registry (ECR) 是完全托管的容器注册表,使您能够在任何地方轻松存储、管理、共享和部署您的容器映像和构件。Amazon ECR 使您无需操作自己的容器注册表,或使您不必为扩展底层基础架构而感到担心。Amazon ECR 将您的映像存储在高度可用、高性能的基础架构中,使您能够为容器应用程序可靠地部署映像。您可以与您的组织私密地共享容器软件,或在全世界公开发布供任何人发现和下载。”

这个比自己搭建私有HUB经济划算,靠谱!

如果自建的话,你的考虑稳定性、服务器数量、服务器规格、磁盘容量、https证书、域名、权限账号体系、网络流量资费等等一系列的问题。

然而你使用ECR根本不用担心这些,而且很便宜。

ECR的认证使用一般过程:

1.检索身份验证令牌并向注册表验证 Docker 客户端身份。 使用 AWS CLI:

aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 888880xxx380.dkr.ecr.us-east-1.amazonaws.com

2.使用以下命令生成 Docker 映像:

docker build -t api .

3.生成完成后,标记您的映像,以便将映像推送到此存储库:

docker tag api:latest 888880xxx380.dkr.ecr.us-east-1.amazonaws.com/sso:latest

但是作为yaml工程师来说,上述过程在CD的时候会出现一定的难度。

在k8s上进行服务部署时,一般是这样的:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: server
  labels:
    app: server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: server
      version: v1
  template:
    metadata:
      labels:
        app: server
        version: v1
    spec:
      imagePullSecrets:
      - name: ecr-registry-key   //这里定义使用什么secret去ecr获取镜像
    spec:
      containers:
      - name: server
        image: 888880xxx380.dkr.ecr.us-east-1.amazonaws.com/sso:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8888

ecr-registry-key 上面的secret如何建立?

1.创建定时任务,在集群内部定时创建secret,因为aws的cli创建的认证凭据会在一定时间范围内过期,可能是1天或者36小时左右。

apiVersion: batch/v1beta1
kind: CronJob # 定时任务对象
metadata:
  annotations:
  name: ecr-cred-helper # 任务名称
  namespace: default
spec:
  concurrencyPolicy: Allow
  failedJobsHistoryLimit: 1
  jobTemplate:
    metadata:
      creationTimestamp: null
    spec:
      template:
        metadata:
          creationTimestamp: null
        spec:
          containers: # 定义容器
            - image: odaniait/aws-kubectl:latest # 镜像
              imagePullPolicy: IfNotPresent #拉取镜像策略
              name: ecr-cred-helper # 容器名称
              command: # 自定义命令
                - /bin/sh 
                - -c # standard
                - |- # actuall script starts + some stuff to execute pipe script when config is sent ot kuber'
                  ACCOUNT=888880xxx380      # 你的aws账号id  
                  REGION=us-east-1      # 你的ecr所在region
                  SECRET_NAME=${REGION}-ecr-registry  # 定义secret名称
                  EMAIL=diy@sklinux.com   # 邮件地址
                  TOKEN=`aws ecr get-login --region ${REGION} --registry-ids ${ACCOUNT} | cut -d' ' -f6` 
                  #获取登录密码
                  echo "ENV variables setup done."
                  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}"
                  echo "Secret created by name. $SECRET_NAME"
                  kubectl patch serviceaccount default -p '{"imagePullSecrets":[{"name":"'$SECRET_NAME'"}]}'   # 为pod设置缺省SA(SA=serviceaccount)
                  echo "All done."
              env: # container | aws config的环境变量
                - name: AWS_DEFAULT_REGION # 区域
                  value: us-east-1
                - name: AWS_SECRET_ACCESS_KEY # SK
                  value: SKxxxxxxxxxxxxxxxxxxxxx
                - name: AWS_ACCESS_KEY_ID # AK
                  value: AKxxxxxxxxxxxxxxxxxxxxx
              resources: {}
              securityContext:
                capabilities: {}
              terminationMessagePath: /dev/termination-log
              terminationMessagePolicy: File
          dnsPolicy: Default # workload | custom | sometimes pod wont have intenet acces in 'clsuter first'
          hostNetwork: true
          restartPolicy: Never # workload | standard | as per requirement
          schedulerName: default-scheduler # workload | standard | as per requirement
          securityContext: {}
          terminationGracePeriodSeconds: 30
  schedule: "*/1 * * * *" # 第一次可以来个1分钟就建一个,后期可以更改为每8个小时干一次。 分时日月周格式
  successfulJobsHistoryLimit: 3
  suspend: false

2.为定时任务创建SA管理集群授权账号

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: fabric8-rbac
subjects:
  - kind: ServiceAccount
    name: default # we are just giving our deafult account more access OR  you can Reference to upper's `metadata.name`
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io