• 1.在 Kubernetes 在快速安装 Harbor


    网址:https://www.qikqiak.com/post/harbor-quick-install/

    安装 Harbor

    Harbor 支持多种安装方式,源码目录下面默认有一个安装脚本(make/install.sh),采用 docker-compose 的形式运行 Harbor 各个组件,和前面的课程一样,我们这里依然还是将 Harbor 安装到 Kubernetes 集群中,如果我们对 Harbor 的各个组件之间的运行关系非常熟悉,同样的,我们可以自己手动编写资源清单文件进行部署,不过 Harbor 源码目录中也为我们提供了生成这些资源清单的脚本文件了(make/kubernetes/k8s-prepare),我们只需要执行下面的命令即可为我们生成所需要用到的 YAML 文件了:

    $ python make/kubernetes/k8s-prepare
    

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

    不过我们这里给大家介绍另外一种简单的安装方法:Helm,Harbor 官方提供了对应的 Helm Chart 包,所以我们可以很容易安装。

    首先下载 Harbor Chart 包到要安装的集群上:

    $ git clone https://github.com/goharbor/harbor-helm
    

    切换到我们需要安装的分支,比如我们这里使用 1.0.0分支:

    $ cd harbor-helm
    $ git checkout 1.0.0
    

    安装 Helm Chart 包最重要的当然是values.yaml文件了,我们可以通过覆盖该文件中的属性来改变配置:

    expose:
      # 设置暴露服务的方式。将类型设置为 ingress、clusterIP或nodePort并补充对应部分的信息。
      type: ingress
      tls:
        # 是否开启 tls,注意:如果类型是 ingress 并且tls被禁用,则在pull/push镜像时,则必须包含端口。详细查看文档:https://github.com/goharbor/harbor/issues/5291。
        enabled: true
        # 如果你想使用自己的 TLS 证书和私钥,请填写这个 secret 的名称,这个 secret 必须包含名为 tls.crt 和 tls.key 的证书和私钥文件,如果没有设置则会自动生成证书和私钥文件。
        secretName: ""
        # 默认 Notary 服务会使用上面相同的证书和私钥文件,如果你想用一个独立的则填充下面的字段,注意只有类型是 ingress 的时候才需要。
        notarySecretName: ""
        # common name 是用于生成证书的,当类型是 clusterIP 或者 nodePort 并且 secretName 为空的时候才需要
        commonName: ""
      ingress:
        hosts:
          core: core.harbor.domain
          notary: notary.harbor.domain
        annotations:
          ingress.kubernetes.io/ssl-redirect: "true"
          nginx.ingress.kubernetes.io/ssl-redirect: "true"
          ingress.kubernetes.io/proxy-body-size: "0"
          nginx.ingress.kubernetes.io/proxy-body-size: "0"
      clusterIP:
        # ClusterIP 服务的名称
        name: harbor
        ports:
          httpPort: 80
          httpsPort: 443
          # Notary 服务监听端口,只有当 notary.enabled 设置为 true 的时候有效
          notaryPort: 4443
      nodePort:
        # NodePort 服务名称
        name: harbor
        ports:
          http:
            port: 80
            nodePort: 30002
          https:
            port: 443
            nodePort: 30003
          notary:
            port: 4443
            nodePort: 30004
    
    # Harbor 核心服务外部访问 URL。主要用于:
    # 1) 补全 portal 页面上面显示的 docker/helm 命令
    # 2) 补全返回给 docker/notary 客户端的 token 服务 URL
    
    # 格式:protocol://domain[:port]。
    # 1) 如果 expose.type=ingress,"domain"的值就是 expose.ingress.hosts.core 的值
    # 2) 如果 expose.type=clusterIP,"domain"的值就是 expose.clusterIP.name 的值
    # 3) 如果 expose.type=nodePort,"domain"的值就是 k8s 节点的 IP 地址
    
    # 如果在代理后面部署 Harbor,请将其设置为代理的 URL
    externalURL: https://core.harbor.domain
    
    # 默认情况下开启数据持久化,在k8s集群中需要动态的挂载卷默认需要一个StorageClass对象。
    # 如果你有已经存在可以使用的持久卷,需要在"storageClass"中指定你的 storageClass 或者设置 "existingClaim"。
    #
    # 对于存储 docker 镜像和 Helm charts 包,你也可以用 "azure"、"gcs"、"s3"、"swift" 或者 "oss",直接在 "imageChartStorage" 区域设置即可
    persistence:
      enabled: true
      # 设置成"keep"避免在执行 helm 删除操作期间移除 PVC,留空则在 chart 被删除后删除 PVC
      resourcePolicy: "keep"
      persistentVolumeClaim:
        registry:
          # 使用一个存在的 PVC(必须在绑定前先手动创建)
          existingClaim: ""
          # 指定"storageClass",或者使用默认的 StorageClass 对象,设置成"-"禁用动态分配挂载卷
          storageClass: ""
          subPath: ""
          accessMode: ReadWriteOnce
          size: 5Gi
        chartmuseum:
          existingClaim: ""
          storageClass: ""
          subPath: ""
          accessMode: ReadWriteOnce
          size: 5Gi
        jobservice:
          existingClaim: ""
          storageClass: ""
          subPath: ""
          accessMode: ReadWriteOnce
          size: 1Gi
        # 如果使用外部的数据库服务,下面的设置将会被忽略
        database:
          existingClaim: ""
          storageClass: ""
          subPath: ""
          accessMode: ReadWriteOnce
          size: 1Gi
        # 如果使用外部的 Redis 服务,下面的设置将会被忽略
        redis:
          existingClaim: ""
          storageClass: ""
          subPath: ""
          accessMode: ReadWriteOnce
          size: 1Gi
      # 定义使用什么存储后端来存储镜像和 charts 包,详细文档地址:https://github.com/docker/distribution/blob/master/docs/configuration.md#storage
      imageChartStorage:
        # 正对镜像和chart存储是否禁用跳转,对于一些不支持的后端(例如对于使用minio的`s3`存储),需要禁用它。为了禁止跳转,只需要设置`disableredirect=true`即可,详细文档地址:https://github.com/docker/distribution/blob/master/docs/configuration.md#redirect
        disableredirect: false
        # 指定存储类型:"filesystem", "azure", "gcs", "s3", "swift", "oss",在相应的区域填上对应的信息。
        # 如果你想使用 pv 则必须设置成"filesystem"类型
        type: filesystem
        filesystem:
          rootdirectory: /storage
          #maxthreads: 100
        azure:
          accountname: accountname
          accountkey: base64encodedaccountkey
          container: containername
          #realm: core.windows.net
        gcs:
          bucket: bucketname
          # The base64 encoded json file which contains the key
          encodedkey: base64-encoded-json-key-file
          #rootdirectory: /gcs/object/name/prefix
          #chunksize: "5242880"
        s3:
          region: us-west-1
          bucket: bucketname
          #accesskey: awsaccesskey
          #secretkey: awssecretkey
          #regionendpoint: http://myobjects.local
          #encrypt: false
          #keyid: mykeyid
          #secure: true
          #v4auth: true
          #chunksize: "5242880"
          #rootdirectory: /s3/object/name/prefix
          #storageclass: STANDARD
        swift:
          authurl: https://storage.myprovider.com/v3/auth
          username: username
          password: password
          container: containername
          #region: fr
          #tenant: tenantname
          #tenantid: tenantid
          #domain: domainname
          #domainid: domainid
          #trustid: trustid
          #insecureskipverify: false
          #chunksize: 5M
          #prefix:
          #secretkey: secretkey
          #accesskey: accesskey
          #authversion: 3
          #endpointtype: public
          #tempurlcontainerkey: false
          #tempurlmethods:
        oss:
          accesskeyid: accesskeyid
          accesskeysecret: accesskeysecret
          region: regionname
          bucket: bucketname
          #endpoint: endpoint
          #internal: false
          #encrypt: false
          #secure: true
          #chunksize: 10M
          #rootdirectory: rootdirectory
    
    imagePullPolicy: IfNotPresent
    
    logLevel: debug
    # Harbor admin 初始密码,Harbor 启动后通过 Portal 修改该密码
    harborAdminPassword: "Harbor12345"
    # 用于加密的一个 secret key,必须是一个16位的字符串
    secretKey: "not-a-secure-key"
    
    # 如果你通过"ingress"保留服务,则下面的Nginx不会被使用
    nginx:
      image:
        repository: goharbor/nginx-photon
        tag: v1.7.0
      replicas: 1
      # resources:
      #  requests:
      #    memory: 256Mi
      #    cpu: 100m
      nodeSelector: {}
      tolerations: []
      affinity: {}
      ## 额外的 Deployment 的一些 annotations
      podAnnotations: {}
    
    portal:
      image:
        repository: goharbor/harbor-portal
        tag: v1.7.0
      replicas: 1
    # resources:
    #  requests:
    #    memory: 256Mi
    #    cpu: 100m
      nodeSelector: {}
      tolerations: []
      affinity: {}
      podAnnotations: {}
    
    core:
      image:
        repository: goharbor/harbor-core
        tag: v1.7.0
      replicas: 1
    # resources:
    #  requests:
    #    memory: 256Mi
    #    cpu: 100m
      nodeSelector: {}
      tolerations: []
      affinity: {}
      podAnnotations: {}
    
    adminserver:
      image:
        repository: goharbor/harbor-adminserver
        tag: v1.7.0
      replicas: 1
      # resources:
      #  requests:
      #    memory: 256Mi
      #    cpu: 100m
      nodeSelector: {}
      tolerations: []
      affinity: {}
      podAnnotations: {}
    
    jobservice:
      image:
        repository: goharbor/harbor-jobservice
        tag: v1.7.0
      replicas: 1
      maxJobWorkers: 10
      # jobs 的日志收集器:"file", "database" or "stdout"
      jobLogger: file
    # resources:
    #   requests:
    #     memory: 256Mi
    #     cpu: 100m
      nodeSelector: {}
      tolerations: []
      affinity: {}
      podAnnotations: {}
    
    registry:
      registry:
        image:
          repository: goharbor/registry-photon
          tag: v2.6.2-v1.7.0
      controller:
        image:
          repository: goharbor/harbor-registryctl
          tag: v1.7.0
      replicas: 1
      nodeSelector: {}
      tolerations: []
      affinity: {}
      podAnnotations: {}
    
    chartmuseum:
      enabled: true
      image:
        repository: goharbor/chartmuseum-photon
        tag: v0.7.1-v1.7.0
      replicas: 1
      # resources:
      #  requests:
      #    memory: 256Mi
      #    cpu: 100m
      nodeSelector: {}
      tolerations: []
      affinity: {}
      podAnnotations: {}
    
    clair:
      enabled: true
      image:
        repository: goharbor/clair-photon
        tag: v2.0.7-v1.7.0
      replicas: 1
      # 用于从 Internet 更新漏洞数据库的http(s)代理
      httpProxy:
      httpsProxy:
      # clair 更新程序的间隔,单位为小时,设置为0来禁用
      updatersInterval: 12
      # resources:
      #  requests:
      #    memory: 256Mi
      #    cpu: 100m
      nodeSelector: {}
      tolerations: []
      affinity: {}
      podAnnotations: {}
    
    notary:
      enabled: true
      server:
        image:
          repository: goharbor/notary-server-photon
          tag: v0.6.1-v1.7.0
        replicas: 1
        # resources:
        #  requests:
        #    memory: 256Mi
        #    cpu: 100m
      signer:
        image:
          repository: goharbor/notary-signer-photon
          tag: v0.6.1-v1.7.0
        replicas: 1
        # resources:
        #  requests:
        #    memory: 256Mi
        #    cpu: 100m
      nodeSelector: {}
      tolerations: []
      affinity: {}
      podAnnotations: {}
    
    database:
      # 如果使用外部的数据库,则设置 type=external,然后填写 external 区域的一些连接信息
      type: internal
      internal:
        image:
          repository: goharbor/harbor-db
          tag: v1.7.0
        # 内部的数据库的初始化超级用户的密码
        password: "changeit"
        # resources:
        #  requests:
        #    memory: 256Mi
        #    cpu: 100m
        nodeSelector: {}
        tolerations: []
        affinity: {}
      external:
        host: "192.168.0.1"
        port: "5432"
        username: "user"
        password: "password"
        coreDatabase: "registry"
        clairDatabase: "clair"
        notaryServerDatabase: "notary_server"
        notarySignerDatabase: "notary_signer"
        sslmode: "disable"
      podAnnotations: {}
    
    redis:
      # 如果使用外部的 Redis 服务,设置 type=external,然后补充 external 部分的连接信息。
      type: internal
      internal:
        image:
          repository: goharbor/redis-photon
          tag: v1.7.0
        # resources:
        #  requests:
        #    memory: 256Mi
        #    cpu: 100m
        nodeSelector: {}
        tolerations: []
        affinity: {}
      external:
        host: "192.168.0.2"
        port: "6379"
        # coreDatabaseIndex 必须设置为0
        coreDatabaseIndex: "0"
        jobserviceDatabaseIndex: "1"
        registryDatabaseIndex: "2"
        chartmuseumDatabaseIndex: "3"
        password: ""
      podAnnotations: {}
    

    有了上面的配置说明,则我们可以根据自己的需求来覆盖上面的值,比如我们这里新建一个 qikqiak-values.yaml 的文件,文件内容如下:

    expose:
      type: ingress
      tls:
        enabled: true
      ingress:
        hosts:
          core: registry.qikqiak.com
          notary: notary.qikqiak.com
        annotations:
          kubernetes.io/ingress.class: "traefik"
          ingress.kubernetes.io/ssl-redirect: "true"
          ingress.kubernetes.io/proxy-body-size: "0"
    
    externalURL: https://registry.qikqiak.com
    
    persistence:
      enabled: true
      resourcePolicy: "keep"
      persistentVolumeClaim:
        registry:
          storageClass: "harbor-data"
        chartmuseum:
          storageClass: "harbor-data"
        jobservice:
          storageClass: "harbor-data"
        database:
          storageClass: "harbor-data"
        redis:
          storageClass: "harbor-data"
    

    其中需要我们定制的部分很少,我们将域名替换成我们自己的,使用默认的 Ingress 方式暴露服务,其他需要我们手动配置的部分就是数据持久化的部分,我们需要提前为上面的这些服务创建好可用的 PVC 或者 StorageClass 对象,比如我们这里使用一个名为 harbor-data 的 StorageClass 资源对象,当然也可以根据我们实际的需求修改 accessMode 或者存储容量:(harbor-data-sc.yaml)

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: harbor-data
    provisioner: fuseim.pri/ifs
    

    先新建上面的 StorageClass 资源对象:

    $ kubectl create -f harbor-data-sc.yaml
    storageclass.storage.k8s.io "harbor-data" created
    

    创建完成后,使用上面自定义的 values 文件安装:

    $ helm install --name harbor -f qikqiak-values.yaml . --namespace kube-ops
    NAME:   harbor
    LAST DEPLOYED: Fri Feb 22 22:39:22 2019
    NAMESPACE: kube-ops
    STATUS: DEPLOYED
    
    RESOURCES:
    ==> v1/StatefulSet
    NAME                    DESIRED  CURRENT  AGE
    harbor-harbor-database  1        1        0s
    harbor-harbor-redis     1        1        0s
    
    ==> v1beta1/Ingress
    NAME                   HOSTS                                    ADDRESS  PORTS  AGE
    harbor-harbor-ingress  registry.qikqiak.com,notary.qikqiak.com  80, 443  0s
    
    ==> v1/Pod(related)
    NAME                                          READY  STATUS             RESTARTS  AGE
    harbor-harbor-adminserver-58c855568c-jnpvq    0/1    ContainerCreating  0         0s
    harbor-harbor-chartmuseum-58d6c9b898-4csmd    0/1    Pending            0         0s
    harbor-harbor-clair-5c7689585-hd2br           0/1    ContainerCreating  0         0s
    harbor-harbor-core-6f56879469-rbthd           0/1    ContainerCreating  0         0s
    harbor-harbor-jobservice-74d7795cdb-bhzdm     0/1    ContainerCreating  0         0s
    harbor-harbor-notary-server-69cdbdfb56-ggc49  0/1    Pending            0         0s
    harbor-harbor-notary-signer-8499dc4db7-f78cd  0/1    Pending            0         0s
    harbor-harbor-portal-55c45c558d-dmj48         0/1    Pending            0         0s
    harbor-harbor-registry-5569fcbf78-5grds       0/2    Pending            0         0s
    harbor-harbor-database-0                      0/1    Pending            0         0s
    harbor-harbor-redis-0                         0/1    Pending            0         0s
    
    ==> v1/Secret
    NAME                       TYPE               DATA  AGE
    harbor-harbor-adminserver  Opaque             4     1s
    harbor-harbor-chartmuseum  Opaque             1     1s
    harbor-harbor-core         Opaque             4     1s
    harbor-harbor-database     Opaque             1     1s
    harbor-harbor-ingress      kubernetes.io/tls  3     1s
    harbor-harbor-jobservice   Opaque             1     1s
    harbor-harbor-registry     Opaque             1     1s
    
    ==> v1/ConfigMap
    NAME                         DATA  AGE
    harbor-harbor-adminserver    39    1s
    harbor-harbor-chartmuseum    24    1s
    harbor-harbor-clair          1     1s
    harbor-harbor-core           1     1s
    harbor-harbor-jobservice     1     1s
    harbor-harbor-notary-server  5     1s
    harbor-harbor-registry       2     1s
    
    ==> v1/PersistentVolumeClaim
    NAME                       STATUS   VOLUME                                    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
    harbor-harbor-chartmuseum  Pending  harbor-data                               1s
    harbor-harbor-jobservice   Bound    pvc-a8a35d0e-36af-11e9-bcd8-525400db4df7  1Gi  RWO  harbor-data  1s
    harbor-harbor-registry     Bound    pvc-a8a466e9-36af-11e9-bcd8-525400db4df7  5Gi  RWO  harbor-data  1s
    
    ==> v1/Service
    NAME                         TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)            AGE
    harbor-harbor-adminserver    ClusterIP  10.108.3.242    <none>       80/TCP             1s
    harbor-harbor-chartmuseum    ClusterIP  10.101.49.103   <none>       80/TCP             1s
    harbor-harbor-clair          ClusterIP  10.110.173.153  <none>       6060/TCP           1s
    harbor-harbor-core           ClusterIP  10.105.178.198  <none>       80/TCP             1s
    harbor-harbor-database       ClusterIP  10.102.101.155  <none>       5432/TCP           0s
    harbor-harbor-jobservice     ClusterIP  10.100.127.32   <none>       80/TCP             0s
    harbor-harbor-notary-server  ClusterIP  10.105.25.64    <none>       4443/TCP           0s
    harbor-harbor-notary-signer  ClusterIP  10.108.92.82    <none>       7899/TCP           0s
    harbor-harbor-portal         ClusterIP  10.103.111.161  <none>       80/TCP             0s
    harbor-harbor-redis          ClusterIP  10.107.205.3    <none>       6379/TCP           0s
    harbor-harbor-registry       ClusterIP  10.100.87.29    <none>       5000/TCP,8080/TCP  0s
    
    ==> v1/Deployment
    NAME                         DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
    harbor-harbor-adminserver    1        1        1           0          0s
    harbor-harbor-chartmuseum    1        1        1           0          0s
    harbor-harbor-clair          1        1        1           0          0s
    harbor-harbor-core           1        1        1           0          0s
    harbor-harbor-jobservice     1        1        1           0          0s
    harbor-harbor-notary-server  1        1        1           0          0s
    harbor-harbor-notary-signer  1        1        1           0          0s
    harbor-harbor-portal         1        1        1           0          0s
    harbor-harbor-registry       1        0        0           0          0s
    
    
    NOTES:
    Please wait for several minutes for Harbor deployment to complete.
    Then you should be able to visit the Harbor portal at https://registry.qikqiak.com.
    For more details, please visit https://github.com/goharbor/harbor.
    

    上面是我们通过 Helm 安装所有涉及到的一些资源对象,稍微等一会儿,就可以安装成功了,查看对应的 Pod 状态:

    $ kubectl get pods -n kube-ops
    NAME                                           READY     STATUS    RESTARTS   AGE
    harbor-harbor-adminserver-58c855568c-7dqqb     1/1       Running   0          37m
    harbor-harbor-chartmuseum-58d6c9b898-4csmd     1/1       Running   0          49m
    harbor-harbor-clair-5c7689585-hd2br            1/1       Running   0          49m
    harbor-harbor-core-6f56879469-rbthd            1/1       Running   8          49m
    harbor-harbor-database-0                       1/1       Running   0          49m
    harbor-harbor-jobservice-74d7795cdb-bhzdm      1/1       Running   7          49m
    harbor-harbor-notary-server-69cdbdfb56-vklbt   1/1       Running   0          20m
    harbor-harbor-notary-signer-8499dc4db7-f78cd   1/1       Running   0          49m
    harbor-harbor-portal-55c45c558d-dmj48          1/1       Running   0          49m
    harbor-harbor-redis-0                          1/1       Running   0          49m
    harbor-harbor-registry-5569fcbf78-5grds        2/2       Running   0          49m
    

    现在都是Running状态了,都成功运行起来了,查看下对应的 Ingress 对象:

    $ kubectl get ingress -n kube-ops
    NAME                    HOSTS                                     ADDRESS   PORTS     AGE
    harbor-harbor-ingress   registry.qikqiak.com,notary.qikqiak.com             80, 443   50m
    

    如果你有自己的真正的域名,则将上面的两个域名解析到你的任意一个 Ingress Controller 的 Pod 所在的节点即可,我们这里为了演示方便,还是自己在本地的/etc/hosts里面添加上registry.qikqiak.comnotary.qikqiak.com的映射。

    在第一次安装的时候比较顺畅,后面安装总是不成功,查看数据库的 Pod 日志出现database “registry” does not exist()的错误信息,如果 registry 数据库没有自动创建,我们可以进入数据库 Pod 中手动创建:

    # 1. 进入数据库 Pod
    $ kubectl exec -it harbor-harbor-database-0 -n kube-ops /bin/bash
    # 2. 连接数据库
    root [ / ]# psql --username postgres
    psql (9.6.10)
    Type "help" for help.
    # 3. 创建 registry 数据库
    postgres=# CREATE DATABASE registry ENCODING 'UTF8';
    CREATE DATABASE
    postgres=# c registry;
    You are now connected to database "registry" as user "postgres".
    registry=# CREATE TABLE schema_migrations(version bigint not null primary key, dirty boolean not null);
    CREATE TABLE
    registry-# quit
    
  • 相关阅读:
    leetcode 576. Out of Boundary Paths 、688. Knight Probability in Chessboard
    leetcode 129. Sum Root to Leaf Numbers
    leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings
    leetcode 402. Remove K Digits 、321. Create Maximum Number
    leetcode 139. Word Break 、140. Word Break II
    leetcode 329. Longest Increasing Path in a Matrix
    leetcode 334. Increasing Triplet Subsequence
    leetcode 403. Frog Jump
    android中webView加载H5,JS不能调用问题的解决
    通过nginx中转获取不到IP的问题解决
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/13853644.html
Copyright © 2020-2023  润新知