前言
通过 Harbor 项目地址 找到最新的 Release 版本
因为Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器。在使用的过程中,发现与containerd不能很好地兼容。所以我这边启用了原来的一套基于docker-cri 的K8S高可用服务(3台AlmaLinux 的 master节点,使用IP漂移)来做测试
1. harbor的主要功能
- 镜像存储:提供安全可靠的容器镜像存储服务,支持多种容器格式,如 Docker 镜像。
- 访问控制:可以对用户和用户组进行精细的访问权限控制,确保只有授权用户能够访问特定的镜像资源。
- 镜像复制:支持在不同的 Harbor 实例之间进行镜像复制,方便跨数据中心或不同环境的镜像分发。
- 漏洞扫描:能够对上传的镜像进行漏洞扫描,及时发现潜在的安全风险。
- 签名验证:支持对镜像进行数字签名,确保镜像的完整性和来源可信。
2. 优势特点
- 企业级特性:专为企业环境设计,满足企业对容器镜像管理的高要求,如安全性、可扩展性和高可用性。
- 安全保障:通过多种安全机制,如访问控制、漏洞扫描和签名验证,保障容器镜像的安全性。
- 易于部署和管理:提供简单易用的安装和管理界面,方便管理员进行配置和维护。
- 与容器生态系统集成:与常见的容器编排工具(如 Kubernetes)和持续集成 / 持续部署(CI/CD)工具无缝集成。
3. 应用场景
- 企业内部容器化应用部署:为企业内部的容器化应用提供统一的镜像存储和管理平台。
- 多云环境下的镜像分发:方便在不同的云平台之间分发容器镜像。
- 软件开发和交付流程:在持续集成 / 持续部署流程中,作为可靠的镜像仓库,确保镜像的质量和安全性。
总之,Harbor 是一个功能强大、安全可靠的容器镜像仓库,为企业的容器化应用提供了重要的基础设施支持。
官网地址:https://github.com/goharbor/harbor
安装
方法1
这里单独用一台服务器来部署的 harbor
我目前使用的方法1
1. 先安装 docker 及相关组件
docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
这里直接略过了,这里不讲docker的安装和使用
2. 添加docker镜像配置
这里主要把我们的私有仓库地址配置进去 - insecure-registries
{"registry-mirrors":["https://registry.docker-cn.com","https://rsbud4vc.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com","http://qtid6917.mirror.aliyuncs.com","https://rncxm540.mirror.aliyuncs.com"],"exec-opts": ["native.cgroupdriver=systemd"],"log-opts": {"max-size": "100m"},"insecure-registries": ["192.168.86.100"]
}
配置完成后重启一下
systemctl daemon-reload
systemctl restart docker.service
3. Docker-compose安装
sudo curl -L "https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#授权
sudo chmod +x /usr/local/bin/docker-compose
#检查
docker-compose --version
#检查 - 提示信息如下
Docker Compose version v2.21.0#如果你的系统提示找不到 docker-compose,你可以创建一个符号链接
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
4. 签发证书
我这里就把这个步骤省了(因为这里是第二次操作了)
考虑 harbor 一般都会部署在内网,感觉意义不大
如果上生产的话,我肯定会考虑使用 阿里云 或 Docker Registry 之类的
mkdir /data/ssl -p
cd /data/ssl/#生成私钥
openssl genrsa -out ca.key 2048#生成证书
openssl req -new -x509 -days 3650 -key ca.key -out ca.pem#生成域名私钥
openssl genrsa -out weiheng-basic-sevice.key 2048
#生成证书请求 - Common Name 填写主机名
openssl req -new -key weiheng-basic-sevice.key -out weiheng-basic-sevice.csr
#签发证书
openssl x509 -req -in weiheng-basic-sevice.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out weiheng-basic-sevice.pem -days 3650
5. Harbor脚本功能
Harbor安装包文件作用解释:
● prepare - 环境准备
● common.sh - 环境检测脚本,在安装过程中会运行该脚本来检测docker、docker-compose、golang等是否符合要求
● harbor.yml.tmpl - harbor的配置文件模板,可根据该文件生成Harbor的配置文件,譬如密码,持久化位置
● install.sh - 安装脚本
6. 安装
#下载最新的 harbor
#从这个地址去找 https://github.com/goharbor/harbor/releases
wget https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgztar zxvf harbor-offline-installer-v2.11.1.tgz cd harbor
cp harbor.yml.tmpl harbor.yml
vim harbor.yml#修改配置文件:
hostname: weiheng-basic-sevice
#修改 hostname,跟上面签发的证书域名保持一致
#协议用 https - 我这里直接把 https 相关的直接注释掉了,直接使用 http 访问
certificate: /data/ssl/weiheng-basic-sevice.pem
private_key: /data/ssl/weiheng-basic-sevice.key#邮件和 ldap 不需要配置,在 harbor 的 web 界面可以配置, 其他配置采用默认即可
#修改之后保存退出
#harbor 默认的账号密码:admin/Harbor12345#安装
./install.sh#停止 & 重启容器
docker compose down && docker compose up -d
harbor 安装完成
上面的https 是之前的一个截图
下面的是 http 直接访问的,可以看到都是OK的
7. 上传镜像到Harbor
docker login 192.168.86.100
#账户/密码:admin/Harbor12345#给Tomcat镜像打标签
docker tag tomcat:latest 192.168.86.100/test/tomcat:v1#推送到harbor
docker push 192.168.86.100/test/tomcat:v1#删除镜像
docker rmi 192.168.86.100/test/tomcat:v1#从harbor拉取镜像
docker pull 192.168.86.100/test/tomcat:v1
到这一步,如果先拉用docker pull 从harbor 拉取镜像,再通过K8S使用相同的镜像创建资源对象,已经可以成功使用harbor镜像了
但是如果 docker images 里没有该镜像, 直接 k run --image 会出现镜像拉取失败
8. 配置K8S从harbor拉取镜像
参考官方文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/pull-image-private-registry/
[root@weihengmaster1 ~]# docker login -u admin -p Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
^C[root@weihengmaster1 ~]# docker login -u admin -p Harbor12345 192.168.86.100
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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/#credential-storesLogin Succeeded
[root@weihengmaster1 ~]# kubectl -n harbor create secret generic harbor \--from-file=.dockerconfigjson=/root/.docker/config.json \--type=kubernetes.io/dockerconfigjson#创建私有仓库仓库访问凭据
kubectl -n harbor create secret docker-registry harbor-regcred \--docker-server=192.168.86.100 \--docker-username=admin \--docker-password=Harbor12345 \--docker-email=<email>#检查
kubectl -n harbor get secret harbor-regcred --output=yaml
#查看 dockerconfigjson 明文
kubectl -n harbor get secret harbor-regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode#要了解 auth 字段中的内容,请将 base64 编码过的数据转换为可读格式:
echo "c3R...zE2" | base64 --decode#创建使用私有仓库的po
apiVersion: v1
kind: Pod
metadata:name: private-reg
spec:containers:- name: private-reg-containerimage: 192.168.86.100/test/tomcat:v1imagePullSecrets:- name: harbor-regcrednamespace: harbork create -f private-reg.yaml
这里可以看到,镜像直接由K8S拉取的,没有存储到本地的 docker images 里
9. 测试
这里给刚才新建的pod expose 一个类型为 NodePort 的 service 然后进行访问尝试
可以看到是可以正常访问到tomcat的,只不过这里没有找到欢迎页面
那么我进入这个pod手动写入一个 index.jsp
k exec -it private-reg -- /bin/bash
刷新后可以看到
这里因为使用了IP漂移,所以通过VIP - 192168.86.199 也是可以正常访问的
到这里我想整个流程已经形成闭环了
harbor安装 -> image上传 -> K8S拉取 harbor 镜像发布成pod
方法2
这是之前安装的,后来舍弃的一个方法,因为当时用的containerd,感觉很不方便
主要体现在harbor 是基于docker的,K8S是基于 containerd 的,镜像间的推送拉取感觉很不方便,欢迎大佬留言赐教
下面是之前本地的一些笔记,现在贴出来做个记录吧
1. 新建一个 Namespace
kubectl create namespace harbor
2. 生成私钥和证书
这一步可以跳过,如果没有设置,harbor会自动生成私钥和证书文件
openssl genrsa -out harbor.key 2048
openssl req -new -x509 -days 3650 -key harbor.key -out harbor.pem
3. 创建一个 TLS 类型的 Secret 存放证书
kubectl -n harbor create secret tls harbor-tls
–cert=harbor.pem --key=harbor.key
4. 安装NFS
#在主机节点安装nfs服务
sudo apt-get update && sudo apt-get install -y nfs-kernel-server#指定文件共享目录
sudo mkdir /opt/nfs
#创建目录,只允许创建者删除该目录
sudo chmod 1777 /opt/nfs/
sudo bash -c 'echo software > /opt/nfs/hello.txt'#创建共享目录
sudo vim /etc/exports
#添加如下内容 - 权限调整
/opt/nfs/ *(rw,sync,no_root_squash,subtree_check)
/var/nfs/harbor 10.0.0.0/8(rw,sync,no_root_squash,no_subtree_check)#使 /etc/exports 文件重新读取
sudo exportfs -ra#在第二个节点进行测试
#weiheng@weihengworker:~$ sudo apt-get -y install nfs-common
#weiheng@weihengworker:~$ showmount -e weihengcp
#Export list for weihengcp:
#/opt/nfs *
#weiheng@weihengworker:~$ #将远程 /opt/nfs 共享目录挂载到本地 /nfs 目录
#weiheng@weihengworker:~$ sudo mount weihengcp:/opt/nfs /opt/nfs
#weiheng@weihengworker:~$ ls -l /opt/nfs
#total 4
#-rw-r--r-- 1 root root 9 Oct 11 03:41 hello.txt
#weiheng@weihengworker:~$
5. 创建PV、PVC
这里只会检查语法,名称或目录不正确不会产生错误,但使用该资源的 Pod 将无法启动
accessModes 目前不会影响实际访问,通常只是作为标签使用
创建PV
vim harbor-pv.yaml
#内容如下
apiVersion: v1
kind: PersistentVolume
metadata:name: harbor-pv
spec:capacity:storage: 13GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retainnfs:path: /opt/nfsserver: weihengcp #修改成自己的readOnly: falsekubectl create -f harbor-pv.yamlkubectl get pv
创建PVC
vim harbor-pvc.yaml
#内容如下 - 创建并验证新的 PVC 是否已绑定。
#这里是自动完成PVC和PV的绑定的,K8S控制器会寻找一个符合条件的PV并将其绑定到PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: harbor-pvcnamespace: harbor
spec:accessModes:- ReadWriteManyresources:requests:storage: 13Gi#创建PVC
kubectl create -f harbor-pvc.yaml#查看PVC
weiheng@weihengcp:/data/work$ k -n harbor get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
harbor-pvc Bound harbor-pv 13Gi RWX <unset> 19s
weiheng@weihengcp:/data/work$ #查看PV,是否有被自动绑定上 - 看 CLAIM 字段
weiheng@weihengcp:/data/work$ k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
harbor-pv 13Gi RWX Retain Bound harbor/harbor-pvc <unset> 24s
weiheng@weihengcp:/data/work$
6. 安装Harbor
我在Harbor官网上找了一下:https://goharbor.io/docs/2.11.0/install-config/harbor-ha-helm/
#添加仓库
helm repo add harbor https://helm.goharbor.io
#更新
helm repo update
#下载harbor
helm fetch harbor/harbor --untar #编辑修改 values.yaml
weiheng@weihengcp:~/.cache/helm/repository/harbor$ vim values.yaml
#内容如下,就改了几个地方,其他都是用的默认值
expose:type: nodePorttls:enabled: truecertSource: secretauto:commonName: ""secret:#用的自定义的secretsecretName: "harbor-tls"ingress:hosts:core: core.harbor.comkubeVersionOverride: ""className: ""annotations:ingress.kubernetes.io/ssl-redirect: "true"ingress.kubernetes.io/proxy-body-size: "0"nginx.ingress.kubernetes.io/ssl-redirect: "true"nginx.ingress.kubernetes.io/proxy-body-size: "0"labels: {}#这里配的自己 节点名称,因为我这里使用的 expose 类型是 nodePort
externalURL: https://weihengcppersistence:enabled: trueresourcePolicy: "keep"persistentVolumeClaim:registry:#用的自己之前创建的PVCexistingClaim: "harbor-pvc" #<-- editstorageClass: ""subPath: "registry"accessMode: ReadWriteManysize: 5Giannotations: {}jobservice:jobLog:existingClaim: "harbor-pvc" #<-- editstorageClass: ""subPath: "jobservice"accessMode: ReadWriteManysize: 1Giannotations: {}database:existingClaim: "harbor-pvc" #<-- editstorageClass: ""subPath: "database"accessMode: ReadWriteManysize: 1Giannotations: {}redis:existingClaim: "harbor-pvc" #<-- editstorageClass: ""subPath: "redis"accessMode: ReadWriteManysize: 1Giannotations: {}trivy:existingClaim: "harbor-pvc" #<-- editstorageClass: ""subPath: "trivy"accessMode: ReadWriteManysize: 5Giannotations: {}#使用 values.yaml 安装这个chart,查看输出以确保正常运行
weiheng@weihengcp:~/.cache/helm/repository/harbor$ helm --namespace harbor install harbor .
NAME: harbor
LAST DEPLOYED: Fri Oct 11 06:54:03 2024
NAMESPACE: harbor
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Please wait for several minutes for Harbor deployment to complete.
Then you should be able to visit the Harbor portal at https://core.harbor.com
For more details, please visit https://github.com/goharbor/harbor
weiheng@weihengcp:~/.cache/helm/repository/harbor$#如果安装后发现 Values 中有些配置需要修改,可以在修改完配置后以升级的方式使配置生效
helm --namespace harbor upgrade harbor .#删除测试的资源
#helm uninstall harbor --namespace harbor
到这里就安装完了