在kubernetes 集群上搭建docker 私有仓库Harbor

在kubernetes 集群上搭建docker 私有仓库Harbor

标签: kubernetes   docker   Harbor  

Harbor是一个用于存储和分发Docker 镜像的企业级Registry 服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。作为一个企业级私有Registry 服务器,Harbor 提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。Harbor 支持安装在多个Registry节点的镜像资源复制,镜像全部保存在私有Registry 中, 确保数据和知识产权在公司内部网络中管控。另外,Harbor也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。

本文将介绍如何在kubernetes 集群上搭建一个高可用的Harbor 服务。

  • 基于角色的访问控制 - 用户与Docker镜像仓库通过“项目”进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
  • 镜像复制 - 镜像可以在多个Registry实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。
  • 图形化用户界面 - 用户可以通过浏览器来浏览,检索当前Docker镜像仓库,管理项目和命名空间。
  • AD/LDAP 支持 - Harbor可以集成企业内部已有的AD/LDAP,用于鉴权认证管理。
  • 审计管理 - 所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
  • 国际化 - 已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来。
  • RESTful API - RESTful API 提供给管理员对于Harbor更多的操控, 使得与其它管理软件集成变得更容易。
  • 部署简单 - 提供在线和离线两种安装工具, 也可以安装到vSphere平台(OVA方式)虚拟设备。

基本步骤

先clone harbor 代码到本地,我们可以查看harbor 提供的kubernetes 部署方案文档:kubernetes_deployment.md

harbor 提供了一个python 脚本(make/kubernetes/prepare)来生成kubernetesConfigMap 文件,由于这个脚本是python 编写的,所以你需要一个能运行python 的环境,该脚本也需要使用openssl来生成私钥和证书,所以也要确保你的运行环境下面有可执行的openssl

下面是该脚本的一些参数:

  • -f: 默认值是../harbor.cfg,当然你可以指定另外的配置文件。
  • -k: https 私钥路径,你可以在harbor.cfg文件中修改ssl_cert_key字段。
  • -c: https 证书路径,同样可以在harbor.cfg文件中修改ssl_cert字段。
  • -s: 密码路径,必须是16位字符串,如果没有设置,脚本将自动生成。

基本配置

有些基本配置必须设置,否则不能部署成功。

  • make/harbor.cfg: Harbor 的基本配置文件。

  • make/kubernetes/**/*.rc.yaml: 一些容器的配置文件。

    你需要将所有的*.rc.yaml文件中的镜像替换成正确的镜像地址。例如:

    containers:
        - name: nginx-app
          # it's very importent that you need modify the path of image.
          image: harbor/nginx
    
  • make/kubernetes/pv/*.pvc.yaml: Persistent Volume Claim。你可以设置存储这些文件的容量,例如:

    resources:
      requests:
        # you can set another value to adapt to your needs
        storage: 100Gi
    
  • make/kubernetes/pv/*.pv.yaml: Persistent Volume, 被绑定到上面的*.pvc.yaml`,PV 和 PVC 是一一对应的,如果你改变了PVC 的容量,那么你也需要相应的设置PV 的容量,例如:

    capacity:
      # same value with PVC
      storage: 100Gi
    

将上述相关的参数修改完成后,执行下面的命令生成ConfigMap文件:

python make/kubernetes/prepare

脚本执行完成后会生成下面的一些文件:

  • make/kubernetes/jobservice/jobservice.cm.yaml
  • make/kubernetes/mysql/mysql.cm.yaml
  • make/kubernetes/nginx/nginx.cm.yaml
  • make/kubernetes/registry/registry.cm.yaml
  • make/kubernetes/ui/ui.cm.yaml

高级配置

当然了如果上面的一些基本配置不能满足你的需求,你也可以做一些更高级的配置。你可以在make/kubernetes/templates目录下面找到所有的Harbor的配置模板:

  • jobservice.cm.yaml: jobservice 的环境变量和WEB 配置
  • mysql.cm.yaml: MySQL 的Root 用户密码
  • nginx.cm.yaml: Https 的证书和nginx 配置
  • registry.cm.yaml: Token 服务认证和 Registry的相关配置,默认用文件系统来存储镜像数据,你能看到这样的数据:
    storage:
      filesystem:
        rootdirectory: /storage
    
    如果你想使用其他的存储后端的话,那么就需要去查看Docker 的相关文档了。
  • ui.cm.yaml: Token 服务的私钥,UI Dashboard 的环境变量和WEB 配置

ui 和 jobservice 是用beego编写的,如果你对beego比较熟悉的话,你可以修改相关的配置。

自定义

  • 为方便管理,这里我们在模板文件中均添加一个namespace=kube-ops,这样让Harbor都放在该namespace 下运行。
  • 由于我们的系统是通过traefik ingress来和外部进行交流的,所以这里实际上是不需要nginx 这一层的,所以可以将下面nginx 想关的操作移除掉就行。
  • make/kubernetes下面的*.rc.yaml文件中的ReplicationController改成Deployment,因为DeploymentReplicationController功能更加丰富, apiVersion 改成对应的apiVersion: extensions/v1beta1版本,将sepc 下面的selector 删除。
  • 同样的在make/kubernetes下面的所有*.rc.yaml(除mysql.rc.yaml外)和*.svc.yaml文件中添加namespace=kube-ops的命名空间。
  • 由于mysql 是有状态的应用,所以我们将mysql.rc.yaml改成StatefulSet,apiVersion 需要改成对应的apps/v1beta1版本
  • 我们这里使用共享存储nfs来存储我们的相关数据,所以我们将make/kubernetes/pv下面添加一个ops.pv.yaml(忽略其他的pv 相关的文件):
  apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: opspv
    labels:
      k8s-app: opspv
  spec:
    accessModes:
    - ReadWriteMany
    capacity:
      storage: 100Gi
    persistentVolumeReclaimPolicy: Retain
    nfs:
      path: /ops/data
      server: 192.168.1.139  # 替换成你自己的nfs 服务器地址
  ---
  apiVersion: v1
  kind: PersistentVolumeClaim
  metadata:
    name: opspvc
    namespace: kube-ops
    labels:
      k8s-app: opspvc
  spec:
    accessModes:
    - ReadWriteMany
    resources:
      requests:
        storage: 100Gi
    selector:
      matchLabels:
        k8s-app: opspv
  • 上面我们新建了一个共享的pvpvc,所以需要将*.rc.yaml下面所有的claimName的值替换成opspvc,另外需要在volumeMounts声明的地方加上subPath来区分存储的文件路径,如下:
  volumeMounts:
  - name: logs
    mountPath: /var/log/jobs
    subPath: harbor/logs
volumes:
- name: logs
  persistentVolumeClaim:
    claimName: opspvc
  • 关于镜像: 可以前往Harbor realse页面下载最新的离线包,然后解压离线安装包可以得到镜像文件harbor.*.tgz,然后可以利用下面的docker命令将相关的镜像加载进来:

    $ docker load -i harbor.*.tgz
    

    由于我们没有指定相关的POD 固定的运行在某个节点上,所以理论上是需要在每个节点上执行上面的步骤的,为了方便,我们这里直接将相关的镜像替换成vmware在docker 官方镜像仓库上的镜像

  • adminserver: 如果你clone 代码下面make/kubernetes/template下面没有adminserver.cm.yaml文件,则可以前往我整理好的github 仓库下面查看。

上面配置完成的文件可以前往github查看

运行

如果你完成了你的配置并且已经生成了ConfigMap文件,现在你可以使用下面的命令来运行Harbor了:

# create pv & pvc
$ kubectl apply -f make/kubernetes/pv/ops.pv.yaml

# create config map
$ kubectl apply -f make/kubernetes/adminserver/adminserver.cm.yaml
$ kubectl apply -f make/kubernetes/jobservice/jobservice.cm.yaml
$ kubectl apply -f make/kubernetes/mysql/mysql.cm.yaml
$ kubectl apply -f make/kubernetes/registry/registry.cm.yaml
$ kubectl apply -f make/kubernetes/ui/ui.cm.yaml

# create service
$ kubectl apply -f make/kubernetes/adminserver/adminserver.svc.yaml
$ kubectl apply -f make/kubernetes/jobservice/jobservice.svc.yaml
$ kubectl apply -f make/kubernetes/mysql/mysql.svc.yaml
$ kubectl apply -f make/kubernetes/registry/registry.svc.yaml
$ kubectl apply -f make/kubernetes/ui/ui.svc.yaml

# create k8s deployment/statefulset
$ kubectl apply -f make/kubernetes/adminserver/adminserver.rc.yaml
$ kubectl apply -f make/kubernetes/registry/registry.rc.yaml
$ kubectl apply -f make/kubernetes/mysql/mysql.rc.yaml
$ kubectl apply -f make/kubernetes/jobservice/jobservice.rc.yaml
$ kubectl apply -f make/kubernetes/ui/ui.rc.yaml

上面的相关yaml 文件执行完成后,我们就可以通过traefik ingress给上面的ui绑定一个域名:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-ops
  namespace: kube-ops
spec:
  rules:
  - host: hub.local
    http:
      paths:
      - path: /
        backend:
          serviceName: ui
          servicePort: 80
      - path: /v2/
        backend:
          serviceName: registry
          servicePort: 5000

注意上面的v2的配置,要在客户端使用docker 命令操作的话就需要配置v2的转发

配置完成后我们就可以在本地使用docker命令进行登录了:

☁  ~  docker login -u admin hub.local
Password:
Login Succeeded

访问上面配置的域名就可以看到Harbor的dashboard 页面了: Harbor Dashboard

欢迎大家加入我们的知识星球:Kubernetes知识星球

微信公众号

扫描下面的二维码关注我们的微信公众帐号,在微信公众帐号中回复◉加群◉即可加入到我们的 kubernetes 讨论群里面共同学习。

wechat-account-qrcode

「真诚赞赏,手留余香」

阳明

请我喝杯咖啡?

使用微信扫描二维码完成支付

相关文章