harbor企业级镜像仓库搭建
harbor镜像仓库搭建
目录
前言
环境:centos 7.9 harbor-offline-installer-v2.4.3.tgz
本篇来讲如何搭建harbor镜像仓库,先从单节点搭建开始讲解,然后开始搭建主从复制架构的harbor仓库,最后使用k8s搭建harbor实现高可用。
下载harbor版本
harbor
的官网:https://goharbor.io/
,点下载按钮其实会跳转到github上,https://github.com/goharbor/harbor/releases/
下载自己所需的版本即可。 也可以直接在虚拟机上wget https://github.com/goharbor/harbor/releases/download/v2.4.3/harbor-offline-installer-v2.4.3.tgz
联网下载。
检查环境并创建证书
查看官方安装文档:https://goharbor.io/docs/2.4.0/
查看安装先决条件:https://goharbor.io/docs/2.4.0/install-config/installation-prereqs/
,需要Docker engine Version 17.06.0-ce+ or higher 、 Docker Compose Version 1.18.0 or higher、Openssl Latest is preferred
。
需要先安装docker、docker-compose
,这里不再体现,默认你已经安装好了docker和docker-compose
,如果不会安装docker
和docker-compose
,请参考https://blog.csdn.net/MssGuo/article/details/122694156
。
#创建一个data目录,用作harbor的数据存储目录
mkdir /data
#创建一个ssl目录用于存放秘钥文件,创建data目录用于存放harbor的数据,创建log存放harbor的日志
mkdir /data/harbor/ssl/ /data/harbor/data /data/harbor/log -p
#默认情况下,harbor如果要使用https登陆,需要有证书,可以自签证书
#进入/data/harbor/ssl/目录创建证书
cd /data/harbor/ssl/
openssl genrsa -out ca.key 4096
#这里的CN=harbor-prod.com写上habbor的域名,没有域名写上ip地址也可以
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor-prod.com" -key ca.key -out ca.crt
#上传安装包到服务器上并解压安装包,默认解压后是harbor目录
cd /data/
tar zxvf harbor-offline-installer-v2.4.3.tgz
#进入到解压后的目录
cd harbor
#将官方的harbor配置文件模板复制一份作为harbor的配置文件
cp harbor.yml.tmpl harbor.yml
harbor配置文件讲解
#编辑harbor.yml,具体修改如下所示
[root@harbor ~]# vim harbor.yml
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: 192.168.118.129 #这里配置ip地址或域名,官方建议不用使用localhost or 127.0.0.1
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 80 #这是http端口,默认80端口,如果https启用,那么http会重定向到https
# https related config
https:
# https port for harbor, default is 443
port: 443 #这是https端口,默认443端口,启动https需要有证书
# The path of cert and key files for nginx
certificate: /data/harbor/ssl/ca.crt #访问harbor的证书,这里要改为上面生成的证书
private_key: /data/harbor/ssl/ca.key #访问harbor的私钥,这里要改为上面生成的证书
# # Uncomment following will enable tls communication between all harbor components
# internal_tls: #是否启用Harbor组件之间的tls通信,默认禁用状态
# # set enabled to true means internal tls is enabled
# enabled: true
# # put your cert and key files on dir
# dir: /etc/harbor/tls/internal
# Uncomment external_url if you want to enable external proxy #是否启用外部代理
# And when it enabled the hostname will no longer used #如果启用,那么主机名将不再使用,默认禁用,值为外部代理的地址
# external_url: https://reg.mydomain.com:8433
# The initial password of Harbor admin #管理员admin的初始密码,默认为Harbor12345
# It only works in first time to install harbor #该初始密码只在第一次安装harbor时起作用
# Remember Change the admin password from UI after launching Harbor.#登录Harbor UI管理界面后,为保证密码安全,强烈建议修改admin密码
harbor_admin_password: Harbor12345
# Harbor DB configuration #harbor数据库配置部分,harbor使用postgresql作为数据库
database:
# The password for the root user of Harbor DB. Change this before any production use.
password: root123 #数据库root用户的密码,生产环境建议修改
# The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained.
max_idle_conns: 100 #空闲连接池中的最大连接数,如果小于等于0,则不保留空闲连接
# The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections.
# Note: the default number of connections is 1024 for postgres of harbor.
max_open_conns: 900 #打开数据库的最大连接数,如果小于等于0,则对打开的连接数没有限制
# The default data volume
data_volume: /data/harbor/data #宿主机上harbor数据存储目录,harbor中的每个组件的数据都存储在该指定路径下的子目录中,这里修改为/data/harbor/data
# Harbor Storage settings by default is using /data dir on local filesystem #Harbor的存储默认在本地文件系统的/data目录
# Uncomment storage_service setting If you want to using external storage #如果需要使用外部存储,则将该部分的注释去掉,生产环境建议使用外部存储
# storage_service:
# # ca_bundle is the path to the custom root ca certificate, which will be injected into the truststore
# # of registry's and chart repository's containers. This is usually needed when the user hosts a internal storage with self signed certificate.
# ca_bundle: #自定义根ca证书的路径,该证书将被注入信任库
# # storage backend, default is filesystem, options include filesystem, azure, gcs, s3, swift and oss
# # for more info about this configuration please refer https://docs.docker.com/registry/configuration/
# filesystem: #存储后端,默认为文件系统,选项包括文件系统、azure、gcs、s3、swift、NFS和oss存储
# maxthreads: 100
# # set disable to true when you want to disable registry redirect
# redirect: #是否启用重定向
# disabled: false
# Trivy configuration
#
# Trivy DB contains vulnerability information from NVD, Red Hat, and many other upstream vulnerability databases.
# It is downloaded by Trivy from the GitHub release page https://github.com/aquasecurity/trivy-db/releases and cached
# in the local file system. In addition, the database contains the update timestamp so Trivy can detect whether it
# should download a newer version from the Internet or use the cached one. Currently, the database is updated every
# 12 hours and published as a new release to GitHub.
trivy:
# ignoreUnfixed The flag to display only fixed vulnerabilities
ignore_unfixed: false
# skipUpdate The flag to enable or disable Trivy DB downloads from GitHub
#
# You might want to enable this flag in test or CI/CD environments to avoid GitHub rate limiting issues.
# If the flag is enabled you have to download the `trivy-offline.tar.gz` archive manually, extract `trivy.db` and
# `metadata.json` files and mount them in the `/home/scanner/.cache/trivy/db` path.
skip_update: false
#
# The offline_scan option prevents Trivy from sending API requests to identify dependencies.
# Scanning JAR files and pom.xml may require Internet access for better detection, but this option tries to avoid it.
# For example, the offline mode will not try to resolve transitive dependencies in pom.xml when the dependency doesn't
# exist in the local repositories. It means a number of detected vulnerabilities might be fewer in offline mode.
# It would work if all the dependencies are in local.
# This option doesn’t affect DB download. You need to specify "skip-update" as well as "offline-scan" in an air-gapped environment.
offline_scan: false
#
# insecure The flag to skip verifying registry certificate
insecure: false
# github_token The GitHub access token to download Trivy DB
#
# Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough
# for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000
# requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult
# https://developer.github.com/v3/#rate-limiting
#
# You can create a GitHub token by following the instructions in
# https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
#
# github_token: xxx
jobservice:
# Maximum number of job workers in job service
max_job_workers: 10 #job服务的最大数量
notification:
# Maximum retry count for webhook job
webhook_job_max_retry: 10 # webhook job的最大重试次数
chart: #harbor不仅可以存储镜像,还可以存Chart,当helm服务器使用
# Change the value of absolute_url to enabled can enable absolute url in chart
absolute_url: disabled #是否启用
# Log configurations
log: #日志相关配置
# options are debug, info, warning, error, fatal
level: info #日志级别
# configs for logs in local storage
local:
# Log files are rotated log_rotate_count times before being removed. If count is 0, old versions are removed rather than rotated.
rotate_count: 50
# Log files are rotated only if they grow bigger than log_rotate_size bytes. If size is followed by k, the size is assumed to be in kilobytes.
# If the M is used, the size is in megabytes, and if G is used, the size is in gigabytes. So size 100, size 100k, size 100M and size 100G
# are all valid.
rotate_size: 200M
# The directory on your host that store log
location: /data/harbor/log #日志存放位置,这里修改为/data/harbor/log
# Uncomment following lines to enable external syslog endpoint. #是否启用外部系统日志
# external_endpoint:
# # protocol used to transmit log to external endpoint, options is tcp or udp
# protocol: tcp #用于将日志传输到外部端点的协议,选项为tcp或udp
# # The host of external endpoint
# host: localhost #外部主机的地址(主机IP)
# # Port of external endpoint
# port: 5140 #外部主机的端口号
#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY!
_version: 2.4.0
# Uncomment external_database if using external database. #是否使用外部数据库,需要使用请取消下面的注释
# external_database: #外部数据库配置
# harbor:
# host: harbor_db_host #外部数据库ip地址
# port: harbor_db_port #外部数据库端口
# db_name: harbor_db_name #数据库名
# username: harbor_db_username #用户名
# password: harbor_db_password #密码
# ssl_mode: disable #是否启用SSL模式
# max_idle_conns: 2 #最大空闲连接数
# max_open_conns: 0 #最大连接数,0表不限制
# notary_signer:
# host: notary_signer_db_host
# port: notary_signer_db_port
# db_name: notary_signer_db_name
# username: notary_signer_db_username
# password: notary_signer_db_password
# ssl_mode: disable
# notary_server:
# host: notary_server_db_host
# port: notary_server_db_port
# db_name: notary_server_db_name
# username: notary_server_db_username
# password: notary_server_db_password
# ssl_mode: disable
# Uncomment external_redis if using external Redis server #启用外部redis缓存服务器则取消下面的注释
# external_redis:
# # support redis, redis+sentinel
# # host for redis: <host_redis>:<port_redis>
# # host for redis+sentinel:
# # <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3>
# host: redis:6379 # redis的地址:端口
# password: # 连接外部redis服务的密码
# # sentinel_master_set must be set to support redis+sentinel
# #sentinel_master_set:
# # db_index 0 is for core, it's unchangeable
# registry_db_index: 1
# jobservice_db_index: 2
# chartmuseum_db_index: 3
# trivy_db_index: 5
# idle_timeout_seconds: 30
# Uncomment uaa for trusting the certificate of uaa instance that is hosted via self-signed cert.
# uaa:
# ca_file: /path/to/ca
# Global proxy
# Config http proxy for components, e.g. http://my.proxy.com:3128
# Components doesn't need to connect to each others via http proxy.
# Remove component from `components` array if want disable proxy
# for it. If you want use proxy for replication, MUST enable proxy
# for core and jobservice, and set `http_proxy` and `https_proxy`.
# Add domain to the `no_proxy` field, when you want disable proxy
# for some special registry.
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- trivy
# metric:
# enabled: false
# port: 9090
# path: /metrics
# Trace related config
# only can enable one trace provider(jaeger or otel) at the same time,
# and when using jaeger as provider, can only enable it with agent mode or collector mode.
# if using jaeger collector mode, uncomment endpoint and uncomment username, password if needed
# if using jaeger agetn mode uncomment agent_host and agent_port
# trace:
# enabled: true
# # set sample_rate to 1 if you wanna sampling 100% of trace data; set 0.5 if you wanna sampling 50% of trace data, and so forth
# sample_rate: 1
# # # namespace used to differenciate different harbor services
# # namespace:
# # # attributes is a key value dict contains user defined attributes used to initialize trace provider
# # attributes:
# # application: harbor
# # # jaeger should be 1.26 or newer.
# # jaeger:
# # endpoint: http://hostname:14268/api/traces
# # username:
# # password:
# # agent_host: hostname
# # # export trace data by jaeger.thrift in compact mode
# # agent_port: 6831
# # otel:
# # endpoint: hostname:4318
# # url_path: /v1/traces
# # compression: false
# # insecure: true
# # timeout: 10s
安装harbor
配置文件修改完成,我们开始安装harbor,如下所示:
cd /data/harbor
#先执行./prepare检查一下,看看有没有报错,有报错就解决
./prepare
#上面检查没有报错,就开始开始安装,同时安装trivy镜像漏洞扫描器
./install.sh --with-trivy
安装过程报错
如果在安装过程中出现下面的报错:
解决办法为:
vim /etc/rsyslog.conf
$ModLoad imtcp #取消注释
$InputTCPServerRun 1514 #取消注释并修改为1514
systemctl restart rsyslog.service #重启rsyslog
继续执行安装harbor即可
网页登录
网页输入https://ip地址
,选择下面的继续前往,
注意:前面配置文件说过,如果启用了https
,那么即使输入http://192.168.44.133:80
也会重定向到https://192.168.44.133:443
。
输入账号密码即可登录,账号是admin
,密码是harbor.yml
文件里配置的初始密码
强烈建议立即修改默认密码,不然容易受到攻击
docker的组件
harbor是使用docker容器启动的,每一个容器都是harbor的一个组件,如何所示:
[root@dev-node02 harbor]# cd /data/harbor/
[root@dev-node02 harbor]# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
harbor-core "/harbor/entrypoint.…" core running (healthy)
harbor-db "/docker-entrypoint.…" postgresql running (healthy)
harbor-jobservice "/harbor/entrypoint.…" jobservice running (healthy)
harbor-log "/bin/sh -c /usr/loc…" log running (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal "nginx -g 'daemon of…" portal running (healthy)
nginx "nginx -g 'daemon of…" proxy running (healthy) 0.0.0.0:880->8080/tcp, :::880->8080/tcp, 0.0.0.0:443->8443/tcp, :::443->8443/tcp
redis "redis-server /etc/r…" redis running (healthy)
registry "/home/harbor/entryp…" registry running (healthy)
registryctl "/home/harbor/start.…" registryctl running (healthy)
trivy-adapter "/home/scanner/entry…" trivy-adapter running (healthy)
[root@dev-node02 harbor]#
Harbor是一个企业级的Docker Registry服务器,它提供了安全、可靠且高效的镜像管理解决方案。下面是Harbor各个组件的作用:
1. harbor-core:核心组件,负责处理Harbor的核心业务逻辑,包括用户认证、权限控制、镜像复制等。
2. harbor-db:数据库组件,使用PostgreSQL作为后端存储,用于存储Harbor的元数据信息,如用户信息、镜像信息等。
3. harbor-jobservice:异步任务组件,负责处理耗时较长的任务,如镜像扫描、垃圾回收等。
4. harbor-log:日志组件,负责收集和存储Harbor的日志信息。
5. harbor-portal:前端门户组件,使用Nginx作为Web服务器,提供用户界面,让用户可以通过Web界面访问Harbor。
6. nginx:反向代理组件,用于将客户端请求转发到相应的后端服务,同时提供SSL加密和负载均衡等功能。
7. redis:缓存组件,用于存储Harbor的缓存数据,提高系统性能。
8. registry:镜像仓库组件,负责存储和管理Docker镜像。
9. registryctl:注册表控制器组件,负责监控和管理Harbor的各个组件。
10. trivy-adapter:Trivy适配器组件,用于集成Trivy(一个开源的容器安全扫描工具)到Harbor中,实现容器安全扫描功能。
启动、停止harbor
#停止harbor
#进入到harbor的安装目录才能启动停止,有一个docker-compose.yml文件
cd /root/harbor
#停止harbor
docker-compose down -v
#启动harbor
#进入到harbor的安装目录才能启动停止,有一个docker-compose.yml文件
cd /root/harbor
#启动harbor
docker-compose up -d
docker推送镜像到harbor镜像仓库、docker从harbor镜像仓库下载镜像
下面来验证docker
推送镜像到harbor
镜像仓库、docker
从harbor
镜像仓库下载镜像,如下:
首先在页面创建一个我们自己的私有仓库(默认有一个library公开仓库),这里创建了一个叫my_harbor
的私有仓库。
1、添加仓库地址、重启docker
在一台需要上传镜像到镜像仓库或要从镜像仓库下载镜像的服务器上做下面的操作,这台服务器也是要安装有docker的。
#在/etc/docker/daemon.json文件添加镜像仓库地址
[root@master ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["192.168.44.133:443"] #添加这一句,把镜像仓库地址端口添加到docker daemon
}
#注意:如果使用的是域名,那么可以这样写 "insecure-registries": ["harbor-prod.com"],当然这个域名要能解析到harbor服务器ip地址,这里
#直接写域名,默认的是http的80端口,前面我们也说过,会重定向到https的;如果没有DNS解析,那可以做本地域名解析 echo '192.168.44.133
# harbor-prod.com' >> /etc/hosts
# 注意:不管harbor是使用https协议还是http协议,daemon.json文件都要设置这个参数"insecure-registries": ["192.168.44.133:443"],同时不要写https://这样的前缀,不然docker会报错。
#重启docker服务
systemctl daemon-reload && systemctl restart docker
2、登录镜像仓库、退出镜像仓库
#使用docker login命令登录镜像仓库,指定仓库地址端口,如果是域名的话,直接使用域名登录即可docker login -u admin xiaoming.com
#使用docker login命令登录镜像仓库,指定仓库地址端口
docker login -u admin 192.168.44.133:443
#账号密码被保存在 ~/.docker/config.json下
cat ~/.docker/config.json
{
"auths": {
"192.168.44.133:443": { #这就是我们的仓库地址账号密码,这种加密方式其实是使用base64加密的,不安全
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
}
}
#使用base64解密就能清晰的看到账号密码
echo "YWRtaW46SGFyYm9yMTIzNDU=" | base64 -d
#为了安全,我们要及时退出登录
docker logout 192.168.44.133:443
#查看/root/.docker/config.json,已经没了登录信息
cat /root/.docker/config.json
{
"auths": {}
}
3、推送镜像到远程harbor仓库
#这台机器上有一个busybox:latest的镜像,我们要把它推送到我们的harbor镜像仓库
#首先我们要给镜像打一个标签,标签格式为:镜像仓库域名/仓库名/镜像:tag ,这种格式是固定的,因为后面我们使用docker push的时候默认就是推
# 送到这样的仓库地址上去的
#如果使用域名的话,直接打标签即可docker tag nginx:1.7.9 xiaoming.com/my_harbor/nginx:1.0.0
#为镜像打标签
docker tag busybox:latest 192.168.44.133:443/my_harbor/busybox:1.0.2
#推送镜像到harbor镜像仓库,前提是已经登录了镜像仓库
#如果使用域名的话,直接推送即可docker push xiaoming.com/my_harbor/nginx:1.0.0
docker push 192.168.44.133:443/my_harbor/busybox:1.0.2
4、下载镜像,从harbor远程镜像仓库下载镜像
#先删除busybox:1.0.2镜像
docker rmi 192.168.44.133:443/my_harbor/busybox:1.0.2
#下载busybox:1.0.2镜像,已经成功下载了
docker pull 192.168.44.133:443/my_harbor/busybox:1.0.2
#已经成功下载了busybox:1.0.2镜像
docker images 192.168.44.133:443/my_harbor/busybox:1.0.2
配置harbor镜像复制
harbor可以配置镜像复制,还可以配置彼此之间相互复制,意思就是说得存在两个harbor,然后在harbor1上配置当触发推送或删除镜像时自动同步到harbor2仓库上。此时还可以使用nginx做反向代理,代理到后端的两个harbor镜像库,从而实现负载均衡。(有条件的还可以将nginx做高可用,即部署两个nginx,两个nginx服务器之间搭建keepalived,对外暴露vip提供harbor访问即可)
1、准备3台服务器,192.168.44.20 nginx服务器、192.168.44.21 harbor1服务器、192.168.44.22 harbor服务器;
注意: 如果harbor启用https自签证书,则harbor1和harbor2都应该使用相同的自签证书,可在harbor1上生成
ca.crt、cat.key文件,然后scp给harbor2即可;(这里我们启用https协议)
2、参照上面的安装方法,在192.168.44.21上安装harbor1,然后配置docker.;
3、参照上面的安装方法,在192.168.44.22上安装harbor2,然后配置docker;
登录harbor1页面,创建一个ruoyi项目库。
然后系统管理-仓库管理-创建目标:如下:
复制管理:
最后,我们在harbor1上创建几个项目,ruoyi-prod、ruoyi-dev;
然后在harbor1服务器上配置镜像仓库:
cat /etc/docker/daemon.json
{
"insecure-registries": ["192.168.44.21:443"], # 配置harbor1的镜像仓库
.......
}
systemctl restart docker;
docker login -u admin -p 123456 192.168.44.21:443
docker tag redis:6.2.6-alpine 192.168.44.21:443/ruoyi-dev/redis:6.2.6-alpine
docker push 192.168.44.21:443/ruoyi-dev/redis:6.2.6-alpine
docker tag redis:6.2.6-alpine 192.168.44.21:443/ruoyi-prod/redis:6.2.6-alpine
docker push 192.168.44.21:443/ruoyi-prod/redis:6.2.6-alpine
这时在harbor1上查看,ruoyi-prod、ruoyi-dev镜像仓库已经存在redis镜像了,harbor2也同步过来了。说明同步是成功的。在harbor1的系统管理-复制管理-选中规则也可以看到复制任务记录。
同理,在harbor1上删除ruoyi-prod、ruoyi-dev镜像仓库里的redis镜像,harbor2上的redis也被删除了,因为我们在复制管理创建规则shi时够选择了"删除本地资源时同时也删除远程的资源"按钮。
现在,我们同理,在harbor2上也创建规则,让上传到harbor2的镜像也同步到harbor1上:
1、按照上面的方式在harbor2上创建仓库管理规则、复制管理规则,测试目标是harbor1的地址url;
2、在harbor2上配置:
vim /etc/docker/daemon.json
......
"insecure-registries": ["https://192.168.44.22:4443"],
.....
docker tag ruoyi-auth:dev-124 192.168.44.22:4443/ruoyi-dev/ruoyi-auth:dev-125
docker login -u admin -p 123456 192.168.44.22:4443
docker push 192.168.44.22:4443/ruoyi-dev/ruoyi-auth:dev-125
# 查看harbor2上已经有镜像了,harbor1里也有了,说明配置成功。
至此,harbor1和harbor2 彼此之间镜像实现了两两同步的。
配置nginx反向代理到harbor镜像仓库
在192.168.44.20上安装nginx,可以参考https://blog.csdn.net/MssGuo/article/details/114285260
,这里直接使用yum安装nginx1.24版本:
cat > /etc/yum.repos.d/nginx.repo <<'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
yum install nginx -y
mkdir /etc/nginx/harbor/
# 把harbor上的自签证书复制过来,因为我们harbor使用https协议并且创建了自签证书,所以nginx也要使用相同的自签证书
scp -r root@harbor1:/data/harbor/ssl /etc/nginx/harbor/
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/harbor.conf
# 编辑配置文件,内容如下
vim /etc/nginx/conf.d/harbor.conf
upstream harbor_server{ # 配置后端harbor
ip_hash; # 这里使用ip_hash,让同一个客户端请求同一个后端
server 192.168.44.21:443; # 指定harbor1的IP和端口,https端口是443
server 192.168.44.22:4443; # 指定harbor1的IP和端口,https端口是4443
}
server {
listen 443 ssl; # nginx我们启用443端口,ssl协议
server_name localhost;
access_log /var/log/nginx/host.access.log main;
ssl_certificate /etc/nginx/harbor/ssl/ca.crt; # 指定自签证书
ssl_certificate_key /etc/nginx/harbor/ssl/ca.key; # 指定自签证书
location / {
proxy_pass https://harbor_server; # 配置反向代理,这里设置的https协议
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 80; # nginx的80端口
server_name localhost;
access_log /var/log/nginx/host.access.log main;
rewrite ^(.*)$ https://$host$1 permanent; # 设置80端口重定向到443端口
}
# 启动nginx
systemctl start nginx
# 浏览器访问可以正常登录
#通过注释掉upstream harbor_server的后端harbor,来单独测试登录harbor1、harbor2,发现都可以正常登录
https://192.168.44.20:443
# 至此,只需要在docker配置nginx的镜像仓库地址即可
vim /etc/docker/daemon.json
....
"insecure-registries": ["192.168.44.20:443"],
.....
# 以上,insecure-registries参数,注意不要写https://协议,否则docker报错,不管harbor使用啥协议,都要配置这个insecure-registries参数
小节
以上我们的总体思路是:
1、安装两个harbor镜像仓库,harbor1和harbor2,由于这两个harbor镜像仓库安装在不同的宿主机上,所以他们具有各自的数据,如pgsql数据库redis数据库等,并且,如果harbor启用https自签证书的话,则harbor1、harbor2都需要使用相同的证书,账号密码也要一样(因为我们后面要使用nginx做负载),只需要将harbor1的自签证书复制给harbor2即可;
2、harbor1和harbor2的登录用户账号密码都保持相同;
3、在harbor1上创建项目,然后系统管理-仓库管理-创建一个目标,这个目标记录其实就是填写要推送镜像给目标harbor2仓库的一些信息,比如harbor2的url,账号密码等信息;
4、在harbor1上,系统管理-复制管理-新建规则,这个规则就是定义要如何同步资源给harbor2仓库;
5、最后,在harbor1上配置/etc/docker/daemon.json 文件后,登录harbor1,推送镜像给harbor1镜像仓库,检查harbor2已经同步了镜像,现在harbor1已经实现当有推送镜像发生时主动推送镜像给harbor2;
6、同理,在harbor2上配置,系统管理-仓库管理-创建一个目标、系统管理-复制管理-新建规则,也配置当有用户推送镜像给harbor2时,自动推送给harbor1;
7、现在,harbor1和harbor2 都能彼此自动推送镜像给对方;
8、配置nginx反向代理,如果harbor使用了https协议,则需要自签证书也放在nginx服务器上,nginx配置文件定义反向代理,指定自签证书,这样就能正确的实现nginx反向代理到harbor镜像仓库了。
9、最后,全部的docker节点/etc/docker/daemon.json 文件里面insecure-registries参数只需要指定nginx的地址即可。
10、注意:如果harbor1并非新部署,也就是说已经存在harbor1仓库并且存在很多镜像了,此时需要新添加部署harbor2实现主从复制,那么这时在harbor1上旧的镜像并不是主动推送到harbor2上。
以上,我们介绍了两个harbor相互同步镜像,这种方法其实是存在弊端的,比如在harbor1的创建的账号无法同步到harbor2上,当harbor1故障后,测试客户端仍有镜像上传,镜像就会上传到harbor2上,当harbor1解决故障后并不会同步得到故障期间的镜像。
其他高可用架构
B站上kubesphere官方提供了另外一种harbor高可用,地址: https://b23.tv/UK1hJKy
,可了解参考。
在k8s上安装harbor
既然harbor是使用docker容器部署,那么我们就可以利用k8s的自动恢复功能来部署harbor高可用。
参考官方文档:https://goharbor.io/docs/2.10.0/install-config/harbor-ha-helm/
要求:
Kubernetes集群1.10+
Helm 2.8.0+高可用的入口控制器(Harbor不管理外部端点)
高可用的PostgreSQL (Harbor不处理数据库HA的部署)
高可用的Redis (Harbor不处理Redis HA的部署)
PVC可以跨节点或外部对象存储共享
# 下载chart并安装
helm repo add harbor https://helm.goharbor.io
helm fetch harbor/harbor --untar
ls harbor-1.14.2.tgz
tar xf harbor-1.14.2.tgz
cd harbor/
vim values.yaml
# 设置存储类自动分配pv
persistence.persistentVolumeClaim.registry.storageClass: "nfs-storageclass"
persistence.persistentVolumeClaim.jobservice.storageClass: "nfs-storageclass"
persistence.persistentVolumeClaim.database.storageClass: "nfs-storageclass"
persistence.persistentVolumeClaim.redis.storageClass: "nfs-storageclass"
persistence.persistentVolumeClaim.trivy.storageClass: "nfs-storageclass"
# 如果使用了存储类,修改pvc的访问模式是ReadWriteMany,以允许pod跨节点共享
persistence.persistentVolumeClaim.registry.accessMode: "ReadWriteMany"
persistence.persistentVolumeClaim.jobservice.accessMode: "ReadWriteMany"
persistence.persistentVolumeClaim.database.accessMode: "ReadWriteMany"
persistence.persistentVolumeClaim.redis.accessMode: "ReadWriteMany"
persistence.persistentVolumeClaim.trivy.accessMode: "ReadWriteMany"
# size可以根据自己的设置改大一点
persistence.persistentVolumeClaim.registry.size: 50Gi
persistence.persistentVolumeClaim.jobservice.size: 10Gi
persistence.persistentVolumeClaim.database.size: 10Gi
persistence.persistentVolumeClaim.redis.size: 10Gi
persistence.persistentVolumeClaim.trivy.size: 10Gi
#设置 portal.replicas, core.replicas, jobservice.replicas, registry.replicas, chartmuseum.replicas副本数为n(n>=2)
portal.replicas: 2
core.replicas: 2
jobservice.replicas: 2
registry.replicas: 2
trivy.replicas: 2
#部署harbor
cd ../
helm install harbor-prod harbor/
# 发现了如下报错
[root@dev-master k8s]# helm template harbor-repo harbor/
Error: template: harbor/templates/registry/registry-secret.yaml:11:62: executing "harbor/templates/registry/registry-secret.yaml" at <include "harbor.secretKeyHelper" (dict "key" "REGISTRY_HTTP_SECRET" "data" $existingSecret.data)>: error calling include: template: harbor/templates/_helpers.tpl:44:41: executing "harbor.secretKeyHelper" at <.data>: wrong type for value; expected map[string]interface {}; got interface {}
Use --debug flag to render out invalid YAML
[root@dev-master k8s]# 这个可能是官方的bug。决定使用bitnami的harbor,反正harbor的版本都一样
[root@dev-master k8s]# helm search repo harbor
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/harbor 21.1.1 2.10.2 Harbor is an open source trusted cloud-native r...
harbor/harbor 1.14.2 2.10.2 An open source trusted cloud native registry th...
[root@dev-master k8s]# helm pull bitnami/harbor --version=21.1.1
tar xf harbor-21.1.1.tgz
cd harbor
vim values.yaml
adminPassword: "123456"
externalURL: https://harbor-prod.com
未完。。。。。。。。。
总结
1、前提条件:安装好docker、docker-compose
[root@harbor ~]# mkdir /data #创建一个data目录,用作harbor的数据存储目录
[root@harbor ~]# mkdir /data/harbor/ssl/ -p #在data目录下创建一个ssl目录,用于存放秘钥文件
#默认情况下,harbor如果要使用https登陆,需要有证书,可以自签证书
[root@harbor ~]# cd /data/harbor/ssl/ #切换目录
[root@harbor ssl]# openssl genrsa -out ca.key 4096
[root@harbor ssl]# openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=xiaoming.com" \ #这里的xiaoming.com写上你的域名,没有域名写上ip地址也可以
-key ca.key \
-out ca.crt
[root@harbor ~]# tar zxvf harbor-offline-installer-v2.4.3.tgz #上传安装包到服务器上并解压安装包
[root@harbor ~]# cd harbor #进入到解压后的目录
[root@harbor harbor]# cp harbor.yml.tmpl harbor.yml #将官方的harbor配置文件模板复制一份作为harbor的配置文件
2、编辑harbor.yml配置文件
# 主要修改以下节点即可,其它参数根据实际情况修改:
hostname: 192.168.118.129 #这里配置ip地址或域名,官方建议不用使用localhost or 127.0.0.1
certificate: /data/harbor/ssl/ca.crt #访问harbor的证书,这里要改为上面生成的证书
private_key: /data/harbor/ssl/ca.key #访问harbor的私钥,这里要改为上面生成的证书
3、安装harbor
[root@harbor ~]# cd harbor #进入到解压后的harbor目录
[root@harbor harbor]# ./prepare #先执行./prepare检查一下,看看有没有报错,有报错就解决
[root@harbor harbor]# ./install.sh #上面检查没有报错,就开始开始安装
4、网页登录
网页输入https://ip地址,默认账目为admin,初始密码是harbor.yml文件里面设置的初始密码
创建自己的私有镜像仓库
5、启动、停止harbor
#harbor也是使用容器启动的,如下所示,查看harbor的容器
[root@harbor ~]# docker ps -a #查看harbor的容器,显示启动了9个容器
#启动停止harbor都要进入到harbor的安装目录,因为里面有一个docker-compose.yml文件
#停止harbor
[root@harbor ~]# cd /root/harbor
[root@harbor harbor]# docker-compose down -v #停止harbor
#启动harbor
[root@harbor ~]# cd /root/harbor
[root@harbor harbor]# docker-compose up -d #启动harbor
6、推送镜像到harbor远程仓库、从harbor远程镜像仓库下载镜像
(1)、添加仓库地址、重启docker
在一台需要上传镜像到镜像仓库或要从镜像仓库下载镜像的服务器上做下面的操作,这台服务器也是要安装有docker的
#在/etc/docker/daemon.json文件添加镜像仓库地址
[root@master ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["192.168.44.133:443"] #添加这一句,把镜像仓库地址端口添加到docker daemon
}
[root@master ~]# systemctl restart docker #要重启docker服务
(2)、登录镜像仓库、退出镜像仓库
[root@master ~]# docker login -u admin 192.168.44.133:443 #使用docker login命令登录创建查看,指定仓库地址端口
[root@master ~]# docker logout 192.168.44.133:443 #退出登录我们的镜像仓库
(3)、推送镜像到远程harbor仓库
#这台机器上有一个busybox:latest的镜像,我们要把它推送到我们的harbor镜像仓库
#首先我们要给镜像打一个标签,标签格式为:镜像仓库域名/仓库名/镜像:tag ,这种格式是固定的,因为后面我们使用docker push的时候默认就是推
# 送到这样的仓库地址上去的
[root@master ~]# docker tag busybox:latest 192.168.44.133:443/my_harbor/busybox:1.0.2 #为镜像打标签
#推送镜像到harbor镜像仓库,前提是已经登录了镜像仓库
[root@master ~]# docker push 192.168.44.133:443/my_harbor/busybox:1.0.2 #推送镜像到harbor镜像仓库
The push refers to repository [192.168.44.133:443/my_harbor/busybox]
01fd6df81c8e: Pushed
1.0.2: digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee size: 527
(4)、下载镜像,从harbor远程镜像仓库下载镜像
[root@master ~]# docker pull 192.168.44.133:443/my_harbor/busybox:1.0.2 #下载busybox:1.0.2镜像,已经成功下载了
1.0.2: Pulling from my_harbor/busybox
Digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee
Status: Downloaded newer image for 192.168.44.133:443/my_harbor/busybox:1.0.2
192.168.44.133:443/my_harbor/busybox:1.0.2
7、使用域名配置镜像仓库地址
使用域名和使用ip地址配置没有什么不同,因为harbor.yml配置文件中已经说明了如果启用了https,那么http访问还是会重定向到https。所以,直接使用域名配置harbor镜像仓库地址其实会重定向到https。
[root@master ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["xiaoming.com"] #使用域名配置,相当于http://xiaoming.com:80
}
[root@master ~]# echo '192.168.44.133 xiaoming.com' >>/etc/hosts #设置本地域名解析
[root@master ~]# systemctl daemon-reload #重新加载系统配置
[root@master ~]# systemctl restart docker #要重启docker服务
[root@master ~]# docker login -u admin xiaoming.com #登录
[root@master ~]# docker tag nginx:1.7.9 xiaoming.com/my_harbor/nginx:1.0.0 #给镜像打tag
[root@master ~]# docker push xiaoming.com/my_harbor/nginx:1.0.0 #推送镜像
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)