kubernetes-guide/tencent/install-apps/install-harbor-on-tke.md

9.4 KiB
Raw Blame History

自建 Harbor 镜像仓库

概述

腾讯云有 容器镜像服务 TCR,企业级容器镜像仓库,满足绝大多数镜像仓库的需求,如果需要使用镜像仓库,可以首选 TCR如果是考虑到成本或想使用 Harbor 的高级功能(如 Proxy Cache) 等因素,可以考虑自建 Harbor 镜像仓库,本文介绍如何在腾讯云容器服务中部署 Harbor 作为自建的容器镜像仓库。

前提条件

操作步骤

准备 COS 对象存储

镜像的存储建议是放对象存储,因为容量大,可扩展,成本低,速度还快。腾讯云上的对象存储是 COS,而 harbor 的存储驱动暂不支持 COS不过 COS 自身兼容 S3所以可以配置 harbor 使用 S3 存储驱动。

下面我们登录腾讯云账号,在 COS 控制台 创建一个存储桶:

记录一下如下信息后面用:

  • region: 存储桶所在地域,如 ap-chengdu,参考 地域和可用区
  • bucket: 存储桶名称,如 registry-12*******6 (有 appid 后缀)。
  • regionendpoint: 类似 https://cos.<REGION>.myqcloud.com 这种格式的 urlhttps://cos.ap-chengdu.myqcloud.com

创建云 API 密钥

访问密钥 这里新建密钥:

如果之前已经新建过,可跳过此步骤。

记录一下生成的 SecretIdSecretKey,后面需要用。

准备 chart

helm repo add harbor https://helm.goharbor.io
helm fetch harbor/harbor --untar

准备配置

harbor-values.yaml:

expose:
  type: clusterIP
  tls:
    enabled: false # 建议关闭 tls如果对外需要 https 访问,可以将 TLS 放到前面的 7 层代理进行配置。
externalURL: https://registry.imroc.cc # 镜像仓库的对外访问地址
persistence:
  imageChartStorage:
    type: s3
    s3: # 务必修改! COS 相关配置
      region: ap-chegndu
      bucket: harbor-12*******6
      accesskey: AKI*******************************zv # SecretId
      secretkey: g5****************************FR # SecretKey
      regionendpoint: https://cos.ap-chengdu.myqcloud.com
      rootdirectory: / # 存储桶中存储镜像数据的路径
  persistentVolumeClaim:
    registry:
      existingClaim: 'registry-registry'
    jobservice:
      existingClaim: "registry-jobservice"
harborAdminPassword: '123456' # 务必修改! harbor 管理员登录密码
chartmuseum:
  enabled: false
trivy:
  enabled: false
notary:
  enabled: false
database:
  type: external
  external:
    host: 'pgsql-postgresql.db'
    username: 'postgres'
    password: '123456'
    coreDatabase: 'registry'
redis:
  type: external
  external:
    addr: 'redis.db:6379'
    coreDatabaseIndex: "10"
    jobserviceDatabaseIndex: "11"
    registryDatabaseIndex: "12"
    chartmuseumDatabaseIndex: "13"
    trivyAdapterIndex: "14"

注意事项:

  • expose 配置暴露服务,我这里打算用其它方式暴露(istio-ingress-gateway),不使用 Ingress, LoadBalancer 之类的方式,所以 type 置为 clusterIP (表示仅集群内访问)另外tls 也不需要,都是在 gateway 上配置就行。
  • s3 配置实为 COS 相关配置,将前面步骤记录的信息填上去。
  • chartmuseum, trivy, notary 我都不需要,所以 enabled 都设为 false
  • harborAdminPassword 是 harbor 管理员登录密码,设置一下。
  • database 是配置 postgresql 数据库,我使用现成的数据库,配置 type 为 external 并写上相关连接配置。
  • redis 是配置 redis 缓存,我使用现成的 redis配置 type 为 external 并写上相关连接配置。
  • persistentVolumeClaim 配置持久化存储,我这里只有 registryjobservice 模块需要挂载存储,存储我挂载的 CFS (腾讯云 NFS 服务),指定 existingClaim 为提前创建好的 pvc参考附录【挂载 CFS】。

安装

helm upgrade --install -n registry -f harbor-values.yaml registry ./harbor

后续如需卸载可以执行: helm uninstall registry

检查 pod 是否正常启动:

$ kubectl -n registry get pod
NAME                                         READY   STATUS    RESTARTS   AGE
registry-harbor-core-55d577c7-l9k5j          1/1     Running   0          1m
registry-harbor-jobservice-66846c575-dbvdz   1/1     Running   0          1m
registry-harbor-nginx-7d94c9446c-z6rkn       1/1     Running   0          1m
registry-harbor-portal-d87bc7554-psp2r       1/1     Running   0          1m
registry-harbor-registry-66d899c9c9-v2w7r    2/2     Running   0          1m

检查自动创建的 service:

$ kubectl -n registry get svc
NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
harbor                       ClusterIP   172.16.195.61    <none>        80/TCP              1m
registry-harbor-core         ClusterIP   172.16.244.174   <none>        80/TCP              1m
registry-harbor-jobservice   ClusterIP   172.16.219.62    <none>        80/TCP              1m
registry-harbor-portal       ClusterIP   172.16.216.247   <none>        80/TCP              1m
registry-harbor-registry     ClusterIP   172.16.146.201   <none>        5000/TCP,8080/TCP   1m

暴露服务

我这里使用 istio-ingressgateway 进行暴露,创建 VirtualService 与 Gateway 绑定:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: registry-imroc-cc
  namespace: registry
spec:
  gateways:
  - external/imroc
  hosts:
  - 'registry.imroc.cc'
  http:
  - route:
    - destination:
        host: harbor
        port:
          number: 80

而 Gateway 则是提前创建好的,监听 443并配置了证书:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: imroc
  namespace: external
spec:
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  servers:
  - hosts:
    - imroc.cc
    - '*.imroc.cc'
    port:
      name: HTTPS-443
      number: 443
      protocol: HTTPS
    tls:
      credentialName: imroc-cc-crt-secret
      mode: SIMPLE

验证服务与 COS 最终一致性问题

最后,可以登录一下 registry 并 push 下镜像试试:

以上直接 push 成功是比较幸运的情况,通常往往会报 500 错误:

什么原因? 是因为 COS 是保证最终一致性,当镜像数据 put 成功后,并不能保证马上能 list 到,导致 harbor 以为没 put 成功,从而报错,参考 这篇文章

如何解决?可以提工单将指定存储桶改为强一致性。但是由于 COS 底层架构升级的原因,暂时无法后台改配置,预计今年年底后才可以申请,相关工单截图:

临时规避的方法可以是:上传失败时重试下,直至上传成功。

附录

挂载 CFS

使用如下 yaml 将 CFS 作为 jobservice 和 registry 模块的持久化存储进行挂载:

registry-nfs-pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: registry-registry
spec:
  accessModes:
  - ReadWriteMany
  capacity:
    storage: 10Gi
  nfs:
    path: /registry/registry
    server: 10.10.0.15
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ""
  volumeMode: Filesystem

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: registry-registry
  namespace: registry
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: ""
  volumeMode: Filesystem
  volumeName: registry-registry

jobservice-nfs-pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: registry-jobservice
spec:
  accessModes:
  - ReadWriteMany
  capacity:
    storage: 10Gi
  nfs:
    path: /registry/jobservice
    server: 10.10.0.15
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ""
  volumeMode: Filesystem

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: registry-jobservice
  namespace: registry
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: ""
  volumeMode: Filesystem
  volumeName: registry-jobservice

注意:

  • 确保创建的 CFS 与 TKE/EKS 集群在同一个 VPC。
  • nfs 的 server ip 在 CFS 控制台 可以查看,替换 yaml 中的 ip 地址。
  • yaml 中如果指定 path ,确保提前创建好,且 chmod 0777 <DIR> 一下,避免因权限问题导致无法启动。