比如这里我们将主域名配置为 harbor.k8s.local,通过一个 nfs-client的 StorageClass 来提供存储,又因为前面我们在安装 GitLab 的时候就已经单独安装了 postgresql 和 reids 两个数据库,所以我们也可以配置 Harbor 使用这两个外置的数据库,这样可以降低资源的使用(我们可以认为这两个数据库都是 HA 模式)。但是使用外置的数据库我们需要提前手动创建数据库,比如我们这里使用的 GitLab 提供的数据库,则进入该 Pod 创建 harbor、notary_server、notary_signer这3个数据库:
$kubectlgetpods-nkube-ops-lname=postgresqlNAMEREADYSTATUSRESTARTSAGEpostgresql-75b8447fb5-th6bw1/1Running12d$kubectlexec-itpostgresql-75b8447fb5-th6bw/bin/bash-nkube-opskubectlexec[POD][COMMAND]isDEPRECATEDandwillberemovedinafutureversion.Usekubectlexec[POD]--[COMMAND]instead.root@postgresql-75b8447fb5-th6bw:/var/lib/postgresql#sudosu-postgrespostgres@postgresql-75b8447fb5-th6bw:~$psqlpsql(12.3(Ubuntu12.3-1.pgdg18.04+1))Type"help"forhelp.postgres=#CREATEDATABASEharborOWNERpostgres;CREATEDATABASEpostgres=#GRANTALLPRIVILEGESONDATABASEharbortopostgres;GRANTpostgres=#GRANTALLPRIVILEGESONDATABASEharbortogitlab;GRANT#Todo:用同样的方式创建其他两个数据库:notary_server、notary_signer......postgres-#\q#退出
数据库准备过后,就可以使用我们自己定制的 values 文件来进行安装了,完整的定制的 values 文件如下所示:
#values-prod.yamlexternalURL:https://harbor.k8s.localharborAdminPassword:Harbor12345logLevel:debugexpose:type:ingresstls:enabled:trueingress:className:nginx#指定ingressclasshosts:core:harbor.k8s.localnotary:notary.k8s.localpersistence:enabled:trueresourcePolicy:"keep"persistentVolumeClaim:registry:#如果需要做高可用,多个副本的组件则需要使用支持ReadWriteMany的后端#这里我们使用nfs,生产环境不建议使用nfsstorageClass:"nfs-client"#如果是高可用的,多个副本组件需要使用ReadWriteMany,默认为ReadWriteOnceaccessMode:ReadWriteManysize:5Gichartmuseum:storageClass:"nfs-client"accessMode:ReadWriteManysize:5Gijobservice:storageClass:"nfs-client"accessMode:ReadWriteManysize:1Gitrivy:storageClass:"nfs-client"accessMode:ReadWriteManysize:2Gidatabase:type:externalexternal:host:"postgresql.kube-ops.svc.cluster.local"port:"5432"username:"gitlab"password:"passw0rd"coreDatabase:"harbor"notaryServerDatabase:"notary_server"notarySignerDatabase:"notary_signer"redis:type:externalexternal:addr:"redis.kube-ops.svc.cluster.local:6379"#默认为一个副本,如果要做高可用,只需要设置为replicas>=2即可portal:replicas:1core:replicas:1jobservice:replicas:1registry:replicas:1chartmuseum:replicas:1trivy:replicas:1notary:server:replicas:1signer:replicas:1
这些配置信息都是根据 Harbor 的 Chart 包默认的 values 值进行覆盖的,现在我们直接安装即可:
$cdharbor$helmupgrade--installharbor.-fvalues-prod.yaml-nkube-opsRelease"harbor"doesnotexist.Installingitnow.NAME:harborLASTDEPLOYED:ThuJul717:31:432022NAMESPACE:kube-opsSTATUS:deployedREVISION:1TESTSUITE:NoneNOTES:PleasewaitforseveralminutesforHarbordeploymenttocomplete.ThenyoushouldbeabletovisittheHarborportalathttps://harbor.k8s.localFormoredetails,pleasevisithttps://github.com/goharbor/harbor
正常情况下隔一会儿就可以安装成功了:
$helmls-nkube-opsNAMENAMESPACEREVISIONUPDATEDSTATUSCHARTAPPVERSIONharborkube-ops12022-07-0717:31:43.083547+0800CSTdeployedharbor-1.9.22.5.2$kubectlgetpods-nkube-ops-lapp=harborNAMEREADYSTATUSRESTARTSAGEharbor-chartmuseum-544ddbcb64-nvk7w1/1Running030mharbor-core-7fd9964685-lqqw21/1Running030mharbor-jobservice-6dbd89c59-vvzx51/1Running030mharbor-notary-server-764b8859bf-82f5q1/1Running030mharbor-notary-signer-869d9bf585-kbwwg1/1Running030mharbor-portal-74db6bb688-2w79p1/1Running035mharbor-registry-695db89bfd-v9wwt2/2Running030mharbor-trivy-01/1Running035m
安装完成后,我们就可以将域名 harbor.k8s.local解析到 Ingress Controller 流量入口点,然后就可以通过该域名在浏览器中访问了:
$kubectlgetingress-nkube-opsNAMECLASSHOSTSADDRESSPORTSAGEharbor-ingressnginxharbor.k8s.local80,44312sharbor-ingress-notarynginxnotary.k8s.local80,44312s
用户名使用默认的 admin,密码则是上面配置的默认 Harbor12345,需要注意的是要使用 https 进行访问(默认也会跳转到 https),否则登录可能提示用户名或密码错误:
登录过后即可进入 Harbor 的 Dashboard 页面:
我们可以看到有很多功能,默认情况下会有一个名叫 library的项目,该项目默认是公开访问权限的,进入项目可以看到里面还有 Helm Chart包的管理,可以手动在这里上传,也可以对该项目里面的镜像进行一些其他配置。
推送镜像接下来我们来测试下如何在 containerd 中使用 Harbor 镜像仓库。
首先我们需要将私有镜像仓库配置到 containerd 中去,修改 containerd 的配置文件 /etc/containerd/config.toml:
[plugins."io.containerd.grpc.v1.cri".registry] [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] endpoint = ["https://bqr1dr1n.mirror.aliyuncs.com"] [plugins."io.containerd.grpc.v1.cri".registry.configs] [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.k8s.local".tls] insecure_skip_verify = true [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.k8s.local".auth] username = "admin" password = "Harbor12345"
在 plugins."io.containerd.grpc.v1.cri".registry.configs下面添加对应 harbor.k8s.local的配置信息,insecure_skip_verify = true表示跳过安全校验,然后通过 plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.k8s.local".auth配置 Harbor 镜像仓库的用户名和密码。
配置完成后重启 containerd:
$systemctlrestartcontainerd
现在我们使用 nerdctl来进行登录:
$nerdctllogin-uadminharbor.k8s.localEnterPassword:ERRO[0004]failedtocalltryLoginWithRegHosterror="failedtocallrh.Client.Do:Get\"https://harbor.k8s.local/v2/\":x509:certificatesignedbyunknownauthority"i=0FATA[0004]failedtocallrh.Client.Do:Get"https://harbor.k8s.local/v2/":x509:certificatesignedbyunknownauthority[root@master1~]#
可以看到还是会报证书相关的错误,只需要添加一个 --insecure-registry参数即可解决该问题:
$nerdctllogin-uadmin--insecure-registryharbor.k8s.localEnterPassword:WARN[0004]skippingverifyingHTTPScertsfor"harbor.k8s.local"WARNING:Yourpasswordwillbestoredunencryptedin/root/.docker/config.json.Configureacredentialhelpertoremovethiswarning.Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLoginSucceeded
然后我们先随便拉一个镜像:
$nerdctlpullbusybox:1.35.0docker.io/library/busybox:1.35.0:resolved|++++++++++++++++++++++++++++++++++++++|index-sha256:8c40df61d40166f5791f44b3d90b77b4c7f59ed39a992fd9046886d3126ffa68:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:8cde9b8065696b65d7b7ffaefbab0262d47a5a9852bfd849799559d296d2e0cd:done|++++++++++++++++++++++++++++++++++++++|config-sha256:d8c0f97fc6a6ac400e43342e67d06222b27cecdb076cbf8a87f3a2a25effe81c:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:fc0cda0e09ab32c72c61d272bb409da4e2f73165c7bf584226880c9b85438e63:done|++++++++++++++++++++++++++++++++++++++|elapsed:83.7s
然后将该镜像重新 tag 成 Harbor 上的镜像地址:
$nerdctltagbusybox:1.35.0harbor.k8s.local/library/busybox:1.35.0
再执行 push 命令即可将镜像推送到 Harbor 上:
$nerdctlpush--insecure-registryharbor.k8s.local/library/busybox:1.35.0INFO[0000]pushingasareduced-platformimage(application/vnd.docker.distribution.manifest.list.v2+json,sha256:29fe0126b13c3ea2641ca42c450fa69583d212dbd9b7b623814977b5b0945726)WARN[0000]skippingverifyingHTTPScertsfor"harbor.k8s.local"index-sha256:29fe0126b13c3ea2641ca42c450fa69583d212dbd9b7b623814977b5b0945726:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:8cde9b8065696b65d7b7ffaefbab0262d47a5a9852bfd849799559d296d2e0cd:done|++++++++++++++++++++++++++++++++++++++|config-sha256:d8c0f97fc6a6ac400e43342e67d06222b27cecdb076cbf8a87f3a2a25effe81c:done|++++++++++++++++++++++++++++++++++++++|elapsed:6.9stotal:2.2Ki(333.0B/s)
推送完成后,我们就可以在 Portal 页面上看到这个镜像的信息了:
镜像 push 成功,同样可以测试下 pull:
$nerdctlrmiharbor.k8s.local/library/busybox:1.35.0Untagged:harbor.k8s.local/library/busybox:1.35.0@sha256:8c40df61d40166f5791f44b3d90b77b4c7f59ed39a992fd9046886d3126ffa68Deleted:sha256:cf4ac4fc01444f1324571ceb0d4f175604a8341119d9bb42bc4b2cb431a7f3a5$nerdctlrmibusybox:1.35.0Untagged:docker.io/library/busybox:1.35.0@sha256:8c40df61d40166f5791f44b3d90b77b4c7f59ed39a992fd9046886d3126ffa68Deleted:sha256:cf4ac4fc01444f1324571ceb0d4f175604a8341119d9bb42bc4b2cb431a7f3a5$nerdctlpull--insecure-registryharbor.k8s.local/library/busybox:1.35.0WARN[0000]skippingverifyingHTTPScertsfor"harbor.k8s.local"harbor.k8s.local/library/busybox:1.35.0:resolved|++++++++++++++++++++++++++++++++++++++|index-sha256:29fe0126b13c3ea2641ca42c450fa69583d212dbd9b7b623814977b5b0945726:done|++++++++++++++++++++++++++++++++++++++|manifest-sha256:8cde9b8065696b65d7b7ffaefbab0262d47a5a9852bfd849799559d296d2e0cd:done|++++++++++++++++++++++++++++++++++++++|config-sha256:d8c0f97fc6a6ac400e43342e67d06222b27cecdb076cbf8a87f3a2a25effe81c:done|++++++++++++++++++++++++++++++++++++++|layer-sha256:fc0cda0e09ab32c72c61d272bb409da4e2f73165c7bf584226880c9b85438e63:done|++++++++++++++++++++++++++++++++++++++|elapsed:0.7stotal:2.2Ki(3.2KiB/s)$nerdctlimagesREPOSITORYTAGIMAGEIDCREATEDPLATFORMSIZEBLOBSIZEharbor.k8s.local/library/busybox1.35.029fe0126b13c17secondsagolinux/amd641.2MiB757.7KiB
但是上面我们也可以看到单独使用 containerd 比如通过 nerdctl 或者 ctr 命令访问 Harbor 镜像仓库的时候即使跳过证书校验或者配置上 CA 证书也是会出现证书错误的,这个时候我们需要去跳过证书校验或者指定证书路径才行。
#解决办法1.指定-k 参数跳过证书校验。$ctrimagespull--useradmin:Harbor12345-kharbor.k8s.local/library/busybox:1.35.0#解决办法2.指定CA证书、Harbor 相关证书文件路径。$ctrimagespull--useradmin:Harbor12345--tlscacertca.crtharbor.k8s.local/library/busybox:1.35.0
但是如果直接使用 ctrctl则是有效的:
$crictlpullharbor.k8s.local/library/busybox@sha256:29fe0126b13c3ea2641ca42c450fa69583d212dbd9b7b623814977b5b0945726Imageisuptodateforsha256:d8c0f97fc6a6ac400e43342e67d06222b27cecdb076cbf8a87f3a2a25effe81c
如果想要在 Kubernetes 中去使用那么就需要将 Harbor 的认证信息以 Secret 的形式添加到集群中去:
$kubectlcreatesecretdocker-registryharbor-auth--docker-server=https://harbor.k8s.local--docker-username=admin--docker-password=Harbor12345--docker-email=info@ydzs.io-ndefault
然后我们使用上面的私有镜像仓库来创建一个 Pod:
#test-harbor.yamlapiVersion:v1kind:Podmetadata:name:harbor-registry-testspec:containers:-name:testimage:harbor.k8s.local/library/busybox:1.35.0args:-sleep-"3600"imagePullSecrets:-name:harbor-auth
创建后可以查看该 Pod 是否能正常获取镜像:
$kubectldescribepodharbor-registry-testName:harbor-registry-testNamespace:defaultPriority:0Node:node1/192.168.0.107StartTime:Thu,07Jul202218:52:39+0800#......Events:TypeReasonAgeFromMessage-------------------------NormalScheduled10sdefault-schedulerSuccessfullyassigneddefault/harbor-registry-testtonode1NormalPulling10skubeletPullingimage"harbor.k8s.local/library/busybox:1.35.0"NormalPulled5skubeletSuccessfullypulledimage"harbor.k8s.local/library/busybox:1.35.0"in4.670528883sNormalCreated5skubeletCreatedcontainertestNormalStarted5skubeletStartedcontainertest
到这里证明上面我们的私有镜像仓库搭建成功了,大家可以尝试去创建一个私有的项目,然后创建一个新的用户,使用这个用户来进行 pull/push 镜像,Harbor 还具有其他的一些功能,比如镜像复制,Helm Chart 包托管等等,大家可以自行测试,感受下 Harbor 和官方自带的 registry 仓库的差别。
关键词: 认证服务 我们需要 配置文件