基于Harbor私有仓库的镜像推送和拉取

4,040 阅读2分钟

趁热记录下,给未来的自己

前言

最近在搭建团队的 devops 平台,其中有一步骤是通过 gitlab-runner 将代码打包成 docker 镜像,推送到 Harbor 仓库,K8S 集群再从 Harbor 中拉取镜像。

考虑到 docker 镜像的安全性,需要将 Harbor 中存放 docker 镜像的项目设为私有。这样的话,在 push 和 pull 镜像的时候,就需要提供 Harbor 的鉴权信息。所以,本文就是记录下,如何对私有 docker 镜像仓库进行image 的 push 和 pull 操作

Harbor账号准备

Harbor 提供两种账户类型,一种是普通用户,一种是机器人用户。机器人用户,通过 token 访问,提供账号过期时间,细粒度的对镜像资源的访问:拉取,推送,查看,删除等等。考虑到 CICD 的业务特性,这里选用机器人用户。 创建一个机器人用户为:robot$push_pull,权限为可推送和可拉取镜像。

镜像推送

在将 docker 镜像推送到 Harbor 私有仓库时,如果之前没有登录过私有仓库,需要先:

docker login -u${harbor_account} -p${harbor_passwd} -h${harbor_ip}

这里:

  • harbor_account: 我们创建的机器人账号robot$push_pull
  • harbot_passwd: 为机器人账号对应的token
  • harbot_ip: Harbor的私有仓库地址 登录成功后,会生成一个~/.docker/config.json文件,config.json保存了机器人账号的登录信息,下次登录 harbor 就无需再docker login,直至机器人账号的 token 有效期到了。

docker login 可以作为一条命令,写到.gitlab-ci.yml里,然后将${harbor_account}, ${harbor_passwd}, ${harbor_ip} 以变量的形式配置在 gitlab 里或者配置到 gitlab-runner 所在的系统上。也可以,将~/.docker/config.json分发到各自的 gitlab-runner 所在的系统上,这样,就无需每次都docker login了。

镜像获取

在 K8S 里获取私有镜像,需要创建一个 secret 资源:imagePullSecrets。创建该资源的方式有两种:

方式一:通过kubectl create secret docker-registry命令:

kubectl create secret docker-registry 
harbor-pullpush-key --docker-server=10.1.32.6:28080 --docker-username=robot$push_pull --docker-password=#{robot$push_pull对应的token信息} -n #{namespace}
  • harbor-pullpush-key: k8s secret 名称
  • docker-server: Harbor 地址
  • docker-username:机器人账号名
  • docker-password:机器人 token
  • namespace: 要和对应的服务在一个 namesapce 下,所以这里必填

方式二:手工创建harbor-pullpush-secret.yml

思路是先将config.json文件进行base64编码,然后放到harbor-pullpush-secret.yml文件里。

config.json对应的base64编码:

cat ~/.docker/config.json | base64 -w

创建 harbor-pullpush-secret.yml 文件,内容如下(.dockerconfigjson 的值为上面输出的内容):

apiVersion: v1
kind: Secret
metadata:
  name: harbor-pullpush-key
  namespace: ${指定你的namespace}
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ${config.json对应的base64编码字符串}

创建该 secret 资源

kubectl apply -f harbor-pullpush-secret.yml

在k8s使用镜像

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:  
        app: my-app
    spec:
      containers:
      - name: my-app
        image: 10.1.32.6:28080/my-app:latest # 使用 Harbor 上私有仓库的镜像
        imagePullPolicy: Always
        ports:
        - containerPort: 8080 
      imagePullSecrets:
      - name: harbor-pullpush-key # 使用刚刚创建的 Harbor Secrets