Kubernetes 集群仓库 Harbor Helm3 部署
简介
Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有 Registry 服务器,Harbor 提供了更好的性能和安全。提升用户使用 Registry 构建和运行环境传输镜像的效率。
先决条件
-
Kubernetes 1.12+
-
Helm 2.12+ 或 Helm 3.0-beta3 +
-
集群有默认的动态存储可用
-
使用 StorageClass 提供 PV 动态存储
准备环境
系统环境
- kubernetes 版本:1.18.5
- Nginx Ingress 版本:2.2.8
- Harbor Chart 版本:1.4.2
- Harbor 版本:2.0.2
- Helm 版本:3.2.4
- 持久化存储驱动:NFS
核实动态存储
确认默认 StorageClass:
$ kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-storage nfs-nfs-storage Delete WaitForFirstConsumer false 17d
nfs-storage-new (default) nfs-client Delete Immediate false 2d19h
如果不是期望的,可以通过以下命令进行修改:
$ kubectl patch storageclass rook-ceph-block -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
具体参考:https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/
安装 Helm3
在线安装
Helm 现在具有一个安装程序脚本,该脚本将自动获取最新版本的 Helm 并将其本地安装。
$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh
Downloading https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
官方参考:https://helm.sh/docs/intro/quickstart/
下载安装
访问 Helm Github 下载页面 https://github.com/helm/helm/releases 找到最新的客户端,里面有不同系统下的包,这里我们选择 Linux amd64,然后在 Linux 系统中使用 Wget 命令进行下载。
# 下载Helm客户端
wget https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz
# 接下来解压下载的包,然后将客户端放置到 /usr/local/bin/ 目录下:
# 解压 Helm
tar -zxvf helm-v3.2.4-linux-amd64.tar.gz
# 复制客户端执行文件到 bin 目录下,方便在系统下能执行 helm 命令
cp linux-amd64/helm /usr/local/bin/
注意:helm 客户端需要下载到安装了 kubectl 并且能执行能正常通过 kubectl 操作 kubernetes 的服务器上,否则 helm 将不可用。
创建 Namespace
由于 Harbor 组件较多,一般我们会采取新建一个 Namespace 专用于部署 Harbor 相关组件,输入下面命令创建名为 harbor
kubectl create namespace harbor
创建自定义证书
安装 Harbor 我们会默认使用 HTTPS 协议,需要 TLS 证书,如果我们没用自己设定自定义证书文件,那么 Harbor 将自动创建证书文件,不过这个有效期只有一年时间,所以这里我们生成自签名证书,为了避免频繁修改证书,将证书有效期为 10 年,操作如下:
生成证书文件:
下面执行步骤时,需要输入一些证书信息,其中 Common Name 必须要设置为和你要给 Harbor 的域名保持一致,如 Common Name (eg, your name or your server’s hostname) []:hub.7d.com。
# 获得证书
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
# 生成证书签名请求
openssl req -newkey rsa:4096 -nodes -sha256 -keyout tls.key -out tls.csr
# 生成证书
openssl x509 -req -days 3650 -in tls.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt
生成 secret 对象
创建 Kubernetes 的 Secret 资源,且将证书文件导入:
kubectl create secret generic hub-7d-tls --from-file=tls.crt --from-file=tls.key --from-file=ca.crt -n harbor
查看是否创建成功:
kubectl get secret hub-7d-tls -n harbor
可以观察到:
NAME TYPE DATA AGE
hub-7d-tls Opaque 3 52m
设置自定义参数
由于我们需要通过 Helm 安装 Harbor 仓库,需要提前创建 Harbor Chart 的配置清单文件,里面是对要创建的应用 Harbor 进行一系列参数配置,由于参数过多,关于都有 Harbor Chart 都能够配置哪些参数这里就不一一罗列,可以通过访问 Harbor-helm 的 Github 地址 进行了解。
下面描述下,需要的一些配置参数:
values.yaml:
#Ingress 网关入口配置
expose:
type: ingress
tls:
### 是否启用 https 协议
enabled: true
ingress:
hosts:
### 配置 Harbor 的访问域名,需要注意的是配置 notary 域名要和 core 处第一个单词外,其余保持一致
core: hub.7d.com
notary: notary.7d.com
controller: default
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/proxy-body-size: "0"
#### 如果是 traefik ingress,则按下面配置:
# kubernetes.io/ingress.class: "traefik"
# traefik.ingress.kubernetes.io/router.tls: 'true'
# traefik.ingress.kubernetes.io/router.entrypoints: websecure
#### 如果是 nginx ingress,则按下面配置:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.org/client-max-body-size: "0"
## 如果Harbor部署在代理后,将其设置为代理的URL,这个值一般要和上面的 Ingress 配置的地址保存一致
externalURL: https://hub.7d.com
### Harbor 各个组件的持久化配置,并设置各个组件 existingClaim 参数为上面创建的对应 PVC 名称
persistence:
enabled: true
### 存储保留策略,当PVC、PV删除后,是否保留存储数据
resourcePolicy: "keep"
persistentVolumeClaim:
registry:
storageClass: "nfs-storage-new"
size: 20Gi
chartmuseum:
storageClass: "nfs-storage-new"
size: 5Gi
jobservice:
storageClass: "nfs-storage-new"
size: 1Gi
database:
storageClass: "nfs-storage-new"
size: 1Gi
redis:
storageClass: "nfs-storage-new"
size: 1Gi
trivy:
storageClass: "nfs-storage-new"
size: 5Gi
### 默认用户名 admin 的密码配置,注意:密码中一定要包含大小写字母与数字
harborAdminPassword: "admin@123"
### 设置日志级别
logLevel: info
#各个组件 CPU & Memory 资源相关配置
nginx:
resources:
requests:
memory: 256Mi
cpu: 500m
portal:
resources:
requests:
memory: 256Mi
cpu: 500m
core:
resources:
requests:
memory: 256Mi
cpu: 1000m
jobservice:
resources:
requests:
memory: 256Mi
cpu: 500m
registry:
registry:
resources:
requests:
memory: 256Mi
cpu: 500m
controller:
resources:
requests:
memory: 256Mi
cpu: 500m
clair:
clair:
resources:
requests:
memory: 256Mi
cpu: 500m
adapter:
resources:
requests:
memory: 256Mi
cpu: 500m
notary:
server:
resources:
requests:
memory: 256Mi
cpu: 500m
signer:
resources:
requests:
memory: 256Mi
cpu: 500m
database:
internal:
resources:
requests:
memory: 256Mi
cpu: 500m
redis:
internal:
resources:
requests:
memory: 256Mi
cpu: 500m
trivy:
enabled: true
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1024Mi
#开启 chartmuseum,使 Harbor 能够存储 Helm 的 chart
chartmuseum:
enabled: true
resources:
requests:
memory: 256Mi
cpu: 500m
安装 Harbor
添加 Helm 仓库
helm repo add harbor https://helm.goharbor.io
部署 Harbor
helm install harbor harbor/harbor --version 1.4.2 -f values.yaml -n harbor
安装完成后,我们核实下安装情况:
$ kubectl get deployment -n harbor
NAME READY UP-TO-DATE AVAILABLE AGE
harbor-harbor-chartmuseum 1/1 1 1 122m
harbor-harbor-clair 1/1 1 1 122m
harbor-harbor-core 1/1 1 1 122m
harbor-harbor-jobservice 1/1 1 1 122m
harbor-harbor-notary-server 1/1 1 1 122m
harbor-harbor-notary-signer 1/1 1 1 122m
harbor-harbor-portal 1/1 1 1 122m
harbor-harbor-registry 1/1 1 1 122m
查看 ingress:
$ kubectl get ingress -n harbor
NAME CLASS HOSTS ADDRESS PORTS AGE
harbor-harbor-ingress <none> hub.7d.com 80, 443 21h
harbor-harbor-ingress-notary <none> notary.7d.com 80, 443 21h
Host 配置域名
接下来配置 Hosts,客户端想通过域名访问服务,必须要进行 DNS 解析,由于这里没有 DNS 服务器进行域名解析,所以修改 hosts 文件将 Harbor 指定节点的 IP 和自定义 host 绑定。
需要将域名的 DNS 指向任意 node 服务器地址
$ cat /etc/hosts
172.16.106.203 hub.7d.com
访问 harbor
输入地址 https://hub.7d.com 访问 Harbor 仓库。
- 用户:admin
- 密码:admin@123 (在安装配置中自定义的密码)、
进入后可以看到 Harbor 的管理后台:
服务器配置镜像仓库
下载 Harbor 证书
由于 Harbor 是基于 Https 的,故而需要提前配置 tls 证书,进入:Harobr主页->配置管理->系统配置->镜像库根证书
服务器 Docker 中配置 Harbor 证书
然后进入服务器,在服务器上 /etc/docker
目录下创建 certs.d 文件夹,然后在 certs.d 文件夹下创建 Harobr 域名文件夹,可以输入下面命令创建对应文件夹:
mkdir -p /etc/docker/certs.d/hub.7d.com
然后再 /etc/docker/certs.d/hub.mydlq.club 目录下上床上面的 ca 证书文件。
登录 Harbor 仓库
只有登录成功后才能将镜像推送到镜像仓库,所以配置完证书后尝试登录,测试是否能够登录成功:
如果提示 ca 证书错误,则重建检测证书配置是否有误。
docker login -u admin -p admin@123 hub.7d.com
服务器配置 Helm Chart 仓库
配置 Helm 证书
跟配置 Docker 仓库一样,配置 Helm 仓库也得提前配置证书,上传 ca 签名到目录 /etc/pki/ca-trust/source/anchors/
:
$ cat /etc/pki/ca-trust/source/anchors/ca.crt
-----BEGIN CERTIFICATE-----
MIIC9TCCAd2gAwIBAgIRALztT/b8wlhjw50UECEOTR8wDQYJKoZIhvcNAQELBQAw
FDESMBAGA1UEAxMJaGFyYm9yLWNhMB4XDTIwMDIxOTA3NTgwMFoXDTIxMDIxODA3
NTgwMFowFDESMBAGA1UEAxMJaGFyYm9yLWNhMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEArYbsxYmNksU5eQhVIM3OKac4l6MV/5u5belAlWSdpbbQCwMF
G/gAliTSQMgqcmhQ3odYTKImvx+5zrhP5b1CWXCQCVOlOFSLrs3ZLv68ZpKoDLkg
6XhoQFVPLM0v5V+YzWCGAson81LfX3tDhltnOItSpe2KESABVH+5L/2vo25P7Mvw
4bWEWMyY4AS/3toiDZjhwNMrMb2lpICrlH9Sc3dAOzUteyVznA5/WF8IyPI64aKn
tl0gxLOZgUBTkBoxVhPj7dNNZu8lMnqAYXmhWt+oRr7t1HHp2lOtk2u/ndyV0kKL
xufx5FYVJQel2yRBGc/C1QLN18nC1y6u5pITaQIDAQABo0IwQDAOBgNVHQ8BAf8E
BAMCAqQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBACFT92PWBFeCT7By8y8+EkB2TD1QVMZm
NDpBS75q5s2yIumFwJrbY6YsHtRkN1Zx9jc4LiJFHC6r0ES3tbCDapsxocvzn7dW
XLNTtnSx0zPxNXZzgmTsamfunBd4gszdXMshJ+bKsEoTXhJEXVjZq/k0EZS8L4Mp
NZ7ciPqwAI1Tg+mFGp5UOvzxYLyW8nCLPykC73y3ob1tiO6xdyD/orTAbA6pIMc9
7ajTfwYj4Q6JPY/QAmu0S+4hJHs724IrC6hiXUlQNVVRW/d3k+nXbYttnnmPnQXC
RyK2ru7R8H43Zlwj26kQJo6naQoQ0+Xcjcyk5llPqJxCrk3uoHF0r4U=
-----END CERTIFICATE-----
如果下面执行的目录不存在,请用 yum 安装 ca-certificates 包。
执行更新命令,使证书生效:
update-ca-trust extract
添加 Helm 仓库
添加 Helm 仓库:
helm repo add myrepo --username=admin --password=admin@123 https://hub.7d.com/chartrepo/library
-username
:harbor仓库用户名-password
:harbor仓库密码-ca-file
:指向ca.crt证书地址chartrepo
:如果是chart仓库地址,中间必须加 chartrepolibrary
:仓库的项目名称
查看仓库列表:
$ helm repo list
NAME URL
myrepo https://hub.7d.com/chartrepo/library
测试功能
推送与拉取 Docker 镜像
这里为了测试推送镜像,先下载一个用于测试的 helloworld 小镜像,然后推送到 hub.mydlq.club 仓库:
# 拉取 Helloworld 镜像
docker pull hello-world:latest
# 将下载的镜像使用 tag 命令改变镜像名
docker tag hello-world:latest hub.7d.com/library/hello-world:latest
# 推送镜像到镜像仓库
docker push hub.7d.com/library/hello-world:latest
将之前的下载的镜像删除,然后测试从 hub.7d.com
下载镜像进行测试:
# 删除之前镜像
docker rmi hello-world:latest
docker rmi hello-world:latest hub.7d.com/library/hello-world:latest
# 测试从 `hub.7d.com` 下载新镜像
docker pull hub.7d.com/library/hello-world:latest
推送与拉取 Chart
Helm 要想推送 Chart 到 Helm 仓库,需要提前安装上传插件:
helm plugin install https://github.com/chartmuseum/helm-push
# 然后创建一个测试的 Chart 进行推送测试:
helm create hello
# 打包chart,将chart打包成tgz格式
helm package hello
# 推送 chart 进行测试
helm push hello-0.1.0.tgz myrepo
Pushing hello-0.1.0.tgz to myrepo...
遇到的问题
Error response from daemon: Get https://hub.7d.com/v2/: x509: certificate signed by unknown authorit
需要到 docker.service
中修改下参数就可以了
修改 /usr/lib/systemd/system/docker.service
配置:
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
重启docker:
## 守护进程重启
sudo systemctl daemon-reload
## 重启docker服务
sudo systemctl restart docker
413 Request Entity Too Large
$ docker push hub.7d.com/mall_repo/mall-portal:1.0
The push refers to repository [hub.7d.com/mall_repo/mall-portal]
5a8f64cc7f4c: Pushing [==================================================>] 73.98MB/73.98MB
35c20f26d188: Layer already exists
c3fe59dd9556: Preparing
6ed1a81ba5b6: Layer already exists
a3483ce177ce: Layer already exists
ce6c8756685b: Waiting
30339f20ced0: Waiting
0eb22bfb707d: Waiting
a2ae92ffcd29: Waiting
error parsing HTTP 413 response body: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>413 Request Entity Too Large</title></head>\r\n<body>\r\n<center><h1>413 Request Entity Too Large</h1></center>\r\n<hr><center>nginx/1.17.3</center>\r\n</body>\r\n</html>\r\n"
解决办法是自定义参数文件增加:
ingress:
hosts:
### 配置 Harbor 的访问域名,需要注意的是配置 notary 域名要和 core 处第一个单词外,其余保持一致
core: hub.7d.com
notary: notary.7d.com
controller: default
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/proxy-body-size: "0"
#### 如果是 traefik ingress,则按下面配置:
# kubernetes.io/ingress.class: "traefik"
# traefik.ingress.kubernetes.io/router.tls: 'true'
# traefik.ingress.kubernetes.io/router.entrypoints: websecure
#### 如果是 nginx ingress,则按下面配置:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
# 增加 Nignx配置,放开限制:A
nginx.org/client-max-body-size: "0"
示例源码:
- 点赞
- 收藏
- 关注作者
评论(0)