在早先,容器仓库有Portus和harbor最为瞩目,harbor是vmware的产品,而前者则是由suse团队维护,但在2019portus提供了最后一个版本。但随着时间的推移,harbor提供了更多与时俱进的功能服务,这也导致harbor愈发的收到关注和使用。并且harbor是由vmware中国区成员参与,众所周知,一款提供中文界面且有优秀的产品,往往都是更受欢迎的。
harbor不仅可以存放容器镜像,还可以提供helm的仓库,简单列出他具备的功能
- 云原生注册表:支持容器镜像和Helm图表,Harbor 充当云原生环境(如容器运行时和编排平台)的注册表。
- 基于角色的访问控制:用户通过“项目”访问不同的存储库,并且用户可以对项目下的图像或 Helm 图表具有不同的权限。
- 基于策略的复制:可以使用过滤器(存储库、标签和标签)基于策略在多个注册表实例之间复制(同步)图像和图表。如果遇到任何错误,Harbor 会自动重试复制。这可用于辅助负载平衡、实现高可用性以及促进混合和多云场景中的多数据中心部署。
- 漏洞扫描:Harbor 定期扫描映像以查找漏洞,并进行策略检查以防止部署易受攻击的映像。
- LDAP/AD 支持:Harbor 与现有的企业 LDAP/AD 集成以进行用户身份验证和管理,并支持将 LDAP 组导入 Harbor,然后可以授予特定项目的权限。
- OIDC 支持:Harbor 利用 OpenID Connect (OIDC) 来验证由外部授权服务器或身份提供者认证的用户的身份。可以启用单点登录以登录到 Harbor 门户。
- 图像删除和垃圾收集:系统管理员可以运行垃圾收集作业,以便可以删除图像(悬空清单和未引用的 blob)并定期释放它们的空间。
- Notary:支持使用 Docker Content Trust(利用 Notary)对容器镜像进行签名,以保证真实性和出处。此外,还可以激活防止部署未签名映像的策略。
- 图形用户门户:用户可以轻松浏览、搜索存储库和管理项目。
- 审计:通过日志跟踪对存储库的所有操作。
- RESTful API:提供 RESTful API 是为了方便管理操作,并且易于用于与外部系统集成。嵌入式 Swagger UI 可用于探索和测试 API。
- 易于部署:Harbor 可以通过 Docker compose 以及 Helm Chart 进行部署,最近还添加了一个 Harbor Operator。
以上内容特征从github获取,
阅读本章,你将了解如何利用harbor配置基本的docker容器仓库和helm仓库的使用
harbor
如果你是nginx,则可以直接使用如下命令创建。
openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout linuxea.key -out linuxea.crt -subj /C=CH/ST=ShangHai/L=Xian/O=Devops/CN=linuxea.test.com
1.准备证书
我们按照官方文档进行创建ssl证书
与之不同的是我们尽可能的将证书配置的旧一些。
因为无论在什么环境,证书最大的问题就是会过期,后期替换的时候会波及到正常使用。
- 域名:harbor.local.com
- 创建的证书目录:/data/cert-
date +%F
复制下面的命令在sh脚本中修改${YOU_DOMAIN}
和${CERT_PATH}
后执行即可
CERT_PATH=/data/cert-`date +%F`/
YOU_DOMAIN=harbor.local.com
mkdir -p ${CERT_PATH}
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 365000
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=${YOU_DOMAIN}"
-key ca.key
-out ca.crt
openssl genrsa -out ${YOU_DOMAIN}.key 4096
openssl req -sha512 -new
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=${YOU_DOMAIN}"
-key ${YOU_DOMAIN}.key
-out ${YOU_DOMAIN}.csr
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=${YOU_DOMAIN}
DNS.2=yourdomain
DNS.3=hostname
EOF
openssl x509 -req -sha512 -days 365000
-extfile v3.ext
-CA ca.crt -CAkey ca.key -CAcreateserial
-in ${YOU_DOMAIN}.csr
-out ${YOU_DOMAIN}.crt
cp ${YOU_DOMAIN}.crt ${YOU_DOMAIN}.key ${CERT_PATH}
2.harbor和docker
接着将证书复制到harbor和docker的目录,使其生效
1.复制crt和key 到harbor的证书目录
cp ${YOU_DOMAIN}.crt ${YOU_DOMAIN}.key ${CERT_PATH}
2.转换yourdomain.com.crt为yourdomain.com.cert, 供 Docker 使用
openssl x509 -inform PEM -in harbor.local.com.crt -out harbor.local.com.cert
本机
mkdir -p /etc/docker/certs.d/harbor.local.com/
cp harbor.local.com.cert /etc/docker/certs.d/harbor.local.com/
cp harbor.local.com.key /etc/docker/certs.d/harbor.local.com/
cp ca.crt /etc/docker/certs.d/harbor.local.com/
systemctl reload docker
其他节点
scp harbor.local.com.cert harbor.local.com.key ca.crt 172.16.15.136:/etc/docker/certs.d/harbor.local.com/
systemctl reload docker
- 如果不是80端口
请创建文件夹/etc/docker/certs.d/yourdomain.com:port或/etc/docker/certs.d/harbor_IP:port.
3.harbor.yml
经过过滤得到如下配置
[root@b.linuxea.com harbor]# egrep -v "^$|^#|^ #|^ #" harbor.yml
hostname: reg.mydomain.com
http:
port: 80
https:
port: 443
certificate: /your/certificate/path
private_key: /your/private/key/path
harbor_admin_password: Harbor12345
database:
password: root123
max_idle_conns: 100
max_open_conns: 900
data_volume: /data
trivy:
ignore_unfixed: false
skip_update: false
offline_scan: false
insecure: false
jobservice:
max_job_workers: 10
notification:
webhook_job_max_retry: 10
chart:
absolute_url: disabled
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
_version: 2.5.0
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- trivy
upload_purging:
enabled: true
age: 168h
interval: 24h
dryrun: false
3.1.将服务器证书和密钥复制到 Harbor 主机上的 certficates 文件夹中。创建一个存储目录:
mkdir /data/harbor/data
配置文件。进行sed替换即可,主要修改如下:
- hostname:域名
- certificate: cert目录地址
- private_key: key目录地址
- harbor_admin_password: 登录密码
- data_volume: docker-compose的所有挂载目录
sed -i 's@hostname: reg.mydomain.com@hostname: harbor.local.com@g' harbor.yml
sed -i 's@certificate: /your/certificate/path@certificate: /data/cert-2022-06-28/harbor.local.com.crt@g' harbor.yml
sed -i 's@private_key: /your/private/key/path@private_key: /data/cert-2022-06-28/harbor.local.com.key@g' harbor.yml
sed -i 's@harbor_admin_password: Harbor12345@harbor_admin_password: admin@g' harbor.yml
sed -i 's@data_volume: /data@data_volume: /data/harbor/data@g' harbor.yml
4.安装harbor
一切准备妥当,执行./install.sh脚本自动安装
[root@b.linuxea.com harbor]# ./install.sh
[Step 0]: checking if docker is installed ...
Note: docker version: 19.03.6
[Step 1]: checking docker-compose is installed ...
.......
[Step 5]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating harbor-db ... done
Creating registry ... done
Creating redis ... done
Creating harbor-portal ... done
Creating registryctl ... done
Creating harbor-core ... done
Creating harbor-jobservice ... done
Creating nginx ... done
✔ ----Harbor has been installed and started successfully.----
5.测试容器仓库
回到其他节点测试docker的应有配置目录结构如下
[root@a.linuxea.com ~]# tree /etc/docker/
/etc/docker/
├── certs.d
│ └── harbor.local.com
│ ├── ca.crt
│ ├── harbor.local.com.cert
│ └── harbor.local.com.key
├── daemon.json
└── key.json
2 directories, 5 files
(base) [root@a.linuxea.com ~]# cat /etc/docker/daemon.json
{"insecure-registries":["172.16.100.150:8443",harbor.local.com]}
登录测试
[root@a.linuxea.com ~]# docker login harbor.local.com
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
上传镜像测试
创建一个仓库
harbor提供的命令如下
docker push harbor.local.com/base/REPOSITORY[:TAG]
测试
[root@a.linuxea.com ~]# docker tag mysql:8.0.16 harbor.local.com/base/mysql:8.0.16
[root@a.linuxea.com ~]# docker push harbor.local.com/base/mysql:8.0.16
The push refers to repository [harbor.local.com/base/mysql]
605d208195c7: Pushed
9d87c3455758: Pushed
80f1020054a4: Pushed
b0425df45fae: Pushed
680666c6bf72: Pushed
7e7fffcdabb3: Pushed
77737de99484: Pushed
2f1b41b24201: Pushed
007a7f930352: Pushed
c6926fcee191: Pushed
b78ec9586b34: Pushed
d56055da3352: Pushed
8.0.16: digest: sha256:036b8908469edac85afba3b672eb7cbc58d6d6b90c70df0bb3fe2ab4fd939b22 size: 2828
docker没有问题后配置helm仓库
helm3
1.helm3安装
在官网下载一个helm,解压后并将可执行文件放置sbin下
wget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz
tar xf helm-v3.8.2-linux-amd64.tar.gz
cp linux-amd64/helm /usr/local/sbin
安装完成
[root@a.linuxea.com ~]# helm version
version.BuildInfo{Version:"v3.8.2", GitCommit:"5cb9af4b1b271d11d7a97a71df3ac337dd94ad37", GitTreeState:"clean", GoVersion:"go1.17.5"}
2.添加helm源
添加一个azure源,并将其更新
helm repo add stable http://mirror.azure.cn/kubernetes/charts/
helm repo list
helm repo update
helm search repo stable
3.登录helm
[root@a.linuxea.com ~]# helm registry login harbor.local.com
Username: admin
Password:
Login Succeeded
我们还需要让系统信任这个ca,于是我们将 /etc/docker/certs.d/harbor.local.com/ca.crt的内容追加到如/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem文件中,并复制ca.crt到/etc/pki/ca-trust/source/anchors/
cp /etc/docker/certs.d/harbor.local.com/ca.crt /etc/pki/ca-trust/source/anchors/
3.中转charts
我们一个共有的mirros的包中转到私有的仓库上。
在中转之前,需要添加一个源来提供现有的charts
下载redis
helm fetch stable/redis
[root@a.linuxea.com ~]# ls redis-10.5.7.tgz
redis-10.5.7.tgz
推送到harbor.local.com
推送 chart 到当前项目
helm push redis-10.5.7.tgz oci://harbor.local.com/redis
登录harbor查看
点进这个Artifacts内,就能看到更多的信息
4.上传本地charts
现在在本地创建一个charts用作测试,上传到harbor中
[root@a.linuxea.com data]# helm create test
Creating test
[root@a.linuxea.com data]# ls test/
charts Chart.yaml templates values.yaml
打包推送
[root@a.linuxea.com data]# helm package test
Successfully packaged chart and saved it to: /data/test-0.1.0.tgz
推送到helm服务器
[root@a.linuxea.com data]# helm push test-0.1.0.tgz oci://harbor.local.com/redis
Pushed: harbor.local.com/redis/test:0.1.0
Digest: sha256:1a86bc2ae87a8760398099a9c0966ce41141eacc7270673d03dfc4005bc349db
5.使用私有charts
回到仓库里面,鼠标放在拉取按钮上将会显示拉取的命令
如下
helm pull oci://harbor.local.com/redis/redis --version 10.5.7
拉到本地
[root@a.linuxea.com opt]# helm pull oci://harbor.local.com/redis/redis --version 10.5.7
Pulled: harbor.local.com/redis/redis:10.5.7
Digest: sha256:41643fa64d23797d0a874a2b264c9fc1f7323b08b9a02fb3010d72805b54bc3a
[root@a.linuxea.com opt]# ls
redis-10.5.7.tgz
解压后使用template可以看到模板的配置清单信息
[root@a.linuxea.com opt]# tar xf redis-10.5.7.tgz
[root@a.linuxea.com redis]# helm template test ./
安装测试
helm upgrade --install -f values.yaml test-redis stable/redis --namespace redis --create-namespace
- --create-namespace: 如果名称空间不存在就创建
- upgrade: 如果存在就更新,不存在就创建
[root@a.linuxea.com redis]# helm install -f values.yaml test-redis stable/redis --namespace redis --create-namespace
WARNING: This chart is deprecated
NAME: test-redis
LAST DEPLOYED: Tue Jun 28 14:50:56 2022
NAMESPACE: redis
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
This Helm chart is deprecated
Given the `stable` deprecation timeline (https://github.com/helm/charts#deprecation-timeline), the Bitnami maintained Redis Helm chart is now located at bitnami/charts (https://github.com/bitnami/charts/).
The Bitnami repository is already included in the Hubs and we will continue providing the same cadence of updates, support, etc that we've been keepinghere these years. Installation instructions are very similar, just adding the _bitnami_ repo and using it during the installation (`bitnami/<chart>` instead of `stable/<chart>`)
```bash
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install my-release bitnami/<chart> # Helm 3
$ helm install --name my-release bitnami/<chart> # Helm 2
```
To update an exisiting _stable_ deployment with a chart hosted in the bitnami repository you can execute
```bash $ helm
repo add bitnami https://charts.bitnami.com/bitnami
$ helm upgrade my-release bitnami/<chart>
```
Issues and PRs related to the chart itself will be redirected to `bitnami/charts` GitHub repository. In the same way, we'll be happy to answer questions related to this migration process in this issue (https://github.com/helm/charts/issues/20969) created as a common place for discussion.
** Please be patient while the chart is being deployed **
Redis can be accessed via port 6379 on the following DNS name from within your cluster:
test-redis-master.redis.svc.cluster.local
To get your password run:
export REDIS_PASSWORD=$(kubectl get secret --namespace redis test-redis -o jsonpath="{.data.redis-password}" | base64 --decode)
To connect to your Redis server:
1. Run a Redis pod that you can use as a client:
kubectl run --namespace redis test-redis-client --rm --tty -i --restart='Never'
--env REDIS_PASSWORD=$REDIS_PASSWORD
--image docker.io/bitnami/redis:5.0.7-debian-10-r32 -- bash
2. Connect using the Redis CLI:
redis-cli -h test-redis-master -a $REDIS_PASSWORD
To connect to your database from outside the cluster execute the following commands:
kubectl port-forward --namespace redis svc/test-redis-master 6379:6379 &
redis-cli -h 127.0.0.1 -p 6379 -a $REDIS_PASSWORD
查看密码
[root@a.linuxea.com redis]# kubectl get secret --namespace redis test-redis -o jsonpath="{.data.redis-password}" | base64 --decode
VeiervwDUG
查看运行状态
由于一些配置没有准备,此时redis是pending的,但是helm安装是成功的。我们的目的达到了
[root@k8s-02 ~]# kubectl -n redis get all
NAME READY STATUS RESTARTS AGE
pod/test-redis-master-0 0/1 Pending 0 2m53s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/test-redis-headless ClusterIP None <none> 6379/TCP 2m53s
service/test-redis-master ClusterIP 10.101.161.177 <none> 6379/TCP 2m53s
NAME READY AGE
statefulset.apps/test-redis-master 0/1 2m53s
已经测试完成,现在卸载掉即可
([root@a.linuxea.com redis]# helm -n redis ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
test-redis redis 1 2022-06-28 14:50:56.56116374 +0800 CST deployed redis-10.5.7 5.0.7
[root@a.linuxea.com redis]# helm -n redis uninstall test-redis
release "test-redis" uninstalled
[root@a.linuxea.com redis]# helm -n redis ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
基于ip的helm
在很多场景中,我们需要把一个http的改成https并且还要他支持https,并且还是ip,这在harbor官网已经有说明,老话重提的。
1.准备证书
与此前不同的是,我们需要将subjectAltName = @alt_names的值也改成ip地址
subjectAltName = IP:IPADDRESS
如下
CERT_PATH=/data/cert-`date +%F`/
YOU_DOMAIN=harbor.local.com
mkdir -p ${CERT_PATH}
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 365000
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=${YOU_DOMAIN}"
-key ca.key
-out ca.crt
openssl genrsa -out ${YOU_DOMAIN}.key 4096
openssl req -sha512 -new
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=${YOU_DOMAIN}"
-key ${YOU_DOMAIN}.key
-out ${YOU_DOMAIN}.csr
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=${YOU_DOMAIN}
DNS.2=yourdomain
DNS.3=hostname
EOF
openssl x509 -req -sha512 -days 365000
-extfile v3.ext
-CA ca.crt -CAkey ca.key -CAcreateserial
-in ${YOU_DOMAIN}.csr
-out ${YOU_DOMAIN}.crt
cp ${YOU_DOMAIN}.crt ${YOU_DOMAIN}.key ${CERT_PATH}
以172.16.100.150为例
CERT_PATH=/data/cert-`date +%F`/
YOU_DOMAIN=172.16.100.150:8443
mkdir -p ${CERT_PATH}
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 365000
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=${YOU_DOMAIN}"
-key ca.key
-out ca.crt
openssl genrsa -out ${YOU_DOMAIN}.key 4096
openssl req -sha512 -new
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=${YOU_DOMAIN}"
-key ${YOU_DOMAIN}.key
-out ${YOU_DOMAIN}.csr
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP:172.16.100.150
[alt_names]
DNS.1=${YOU_DOMAIN}
DNS.2=yourdomain
DNS.3=hostname
EOF
openssl x509 -req -sha512 -days 365000
-extfile v3.ext
-CA ca.crt -CAkey ca.key -CAcreateserial
-in ${YOU_DOMAIN}.csr
-out ${YOU_DOMAIN}.crt
cp ${YOU_DOMAIN}.crt ${YOU_DOMAIN}.key ${CERT_PATH}
2.harbor.yaml配置
harbor.yaml部分配置
hostname: 172.16.100.150
http:
port: 8080
https:
port: 8443
certificate: /etc/ssl/certs/172.16.100.150:8443.crt
private_key: /etc/ssl/certs/172.16.100.150:8443.key
配置完成后需要执行./prepare
并且重启
3.docker和ca
仍然进行证书拷贝
首先拷贝当前节点的
cp 172.16.100.150:8443.* /etc/docker/certs.d/172.16.100.150:8443/
在将当前的证书打包拷贝到其他需要使用helm上传下载的节点
tar -zcf 8443.tar 172.16.100.150:8443
scp 8443.tar 172.16.15.136:/etc/docker/certs.d/
目录结构如下
[root@docker-156 certs.d]# tree /etc/docker/certs.d/
/etc/docker/certs.d/
├── 172.16.100.150:8443
│ ├── 172.16.100.150:8443.cert
│ ├── 172.16.100.150:8443.crt
│ ├── 172.16.100.150:8443.csr
│ ├── 172.16.100.150:8443.key
│ └── ca.crt
仍然需要让系统信任这个ca,于是我们将 ca.crt的内容追加到如/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem文件中,并复制ca.crt到/etc/pki/ca-trust/source/anchors/
cp /etc/docker/certs.d/harbor.local.com/ca.crt /etc/pki/ca-trust/source/anchors/
而后就可以正常推送和下载了