Harbor是一个私有的镜像仓库,可以用于存放Docker镜像,在K8S当中部署一个项目需要从镜像仓库拉取镜像,再去构建Pod。
为什么我们要去部署属于自己的私有镜像仓库Harbor?
- 1.K8S集群当中进行项目的构建时,如果从DockerHub进行镜像的拉取,因为墙的原因很容易遇到拉取不到镜像的情况,此时如果我们有私有镜像的话,我们可以将镜像上传到私有仓库,K8S项目的构建(例如Deployment),就可以从私有镜像仓库Harbor进行镜像拉取。
- 2.当我们自己的项目发布时,需要构建自己的Docker镜像,并push到远程仓库,再通过K8S拉取镜像再进行服务的构建,此时Harbor就发挥到它作为镜像仓库的作用。
下面,我们将会使用虚拟机基于Harbor的离线安装包,并基于docker-compose去部署Harbor私有镜像仓库。
1.独立机器部署Harbor私服镜像仓库
1.1 安装本地的Harbor镜像仓库
Harbor安装,下载地址如下:https://github.com/goharbor/harbor/releases/
。
上面是Github页面,可以选择右边的harbor-online-installer-v1.10.19.tgz
在线版本或者是harbor-offline-installer-v1.10.19.tgz
离线版本进行安装。这里推荐使用offline离线版本进行安装,因为Harbor在线版本需要在线下载依赖可能遇到网速问题,离线版本是包当中已经带了所有的Harbor相关的依赖。
下载完成Harbor的离线版本的压缩包之后,我们通过解压并执行安装脚本的方式去安装Harbor。
tar -xvzf harbor-offline-installer-*.tgz
进入到harbor/
目录下,可以看到Harbor的主配置文件harbor.yml
,我们可能需要进行一些自定义的配置才能启动Harbor。
# 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: xxx.xxx.com
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 84
# https related config
# https:
# https port for harbor, default is 443
# port: 444
# The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
# 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
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: Harbor12345
# Harbor DB configuration
database:
# The password for the root user of Harbor DB. Change this before any production use.
password: root123
# The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained.
max_idle_conns: 50
# 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 100 for postgres.
max_open_conns: 100
# The default data volume
data_volume: /data
# Harbor Storage settings by default is using /data dir on local filesystem
# 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:
# # 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:
# maxthreads: 100
# # set disable to true when you want to disable registry redirect
# redirect:
# disabled: false
# Clair configuration
clair:
# The interval of clair updaters, the unit is hour, set to 0 to disable the updaters.
updaters_interval: 12
jobservice:
# Maximum number of job workers in job service
max_job_workers: 10
notification:
# Maximum retry count for webhook job
webhook_job_max_retry: 10
chart:
# 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: /var/log/harbor
# 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
# # The host of external endpoint
# host: localhost
# # Port of external endpoint
# port: 5140
#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY!
_version: 1.10.0
# Uncomment external_database if using external database.
# external_database:
# harbor:
# host: harbor_db_host
# port: harbor_db_port
# db_name: harbor_db_name
# username: harbor_db_username
# password: harbor_db_password
# ssl_mode: disable
# max_idle_conns: 2
# max_open_conns: 0
# clair:
# host: clair_db_host
# port: clair_db_port
# db_name: clair_db_name
# username: clair_db_username
# password: clair_db_password
# ssl_mode: disable
# 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
# external_redis:
# host: redis
# port: 6379
# password:
# # db_index 0 is for core, it's unchangeable
# registry_db_index: 1
# jobservice_db_index: 2
# chartmuseum_db_index: 3
# clair_db_index: 4
# 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 endpoints will appended to 127.0.0.1,localhost,.local,.internal,log,db,redis,nginx,core,portal,postgresql,jobservice,registry,registryctl,clair,chartmuseum,notary-server
no_proxy:
components:
- core
- jobservice
- clair
在Harbor配置当中,我们需要配置Harbor的HTTP和HTTPS的相关配置:
- 在hostname出填写域名配置(如果配置了反向代理则不需要)
- 在
http.port
当中配置HTTP服务启动的端口号。 - (选填,在需要使用Harbor的HTTPS时才需要配置)在
https.port
当中配置HTTPS服务启动的端口号,https.certificate
当中配置HTTPS的证书所在的地址,https.private_key
当中配置HTTPS的私钥所在的地址。
hostname: xxx.xxx.com
http:
port: 84
https:
port: 1443
certificate: /your/certificate/path
private_key: /your/private/key/path
在配置好Harbor配置文件之后,我们通过如下的命令安装脚本install
,去安装好Harbor,并启动Harbor。
./install.sh
如果想要启动/关闭Harbor
,我们可以通过如下的命令去进行操作,
# 启动habor
docker-compose up -d
# 关闭habor
docker-compose down
接着通过docker ps
可以查看运行的容器情况,在这里这里可以找到Harbor
的相关的运行的容器。
root@ecm-4fe6:~/tools/habor/harbor# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc68663a0c75 goharbor/harbor-jobservice:v1.10.19 "/harbor/harbor_jobs…" About a minute ago Up 58 seconds (healthy) harbor-jobservice
294528f398de goharbor/nginx-photon:v1.10.19 "nginx -g 'daemon of…" About a minute ago Up 58 seconds (healthy) 0.0.0.0:84->8080/tcp, [::]:84->8080/tcp nginx
43b3bcdf06cb goharbor/harbor-core:v1.10.19 "/harbor/harbor_core" About a minute ago Up About a minute (healthy) harbor-core
1a7ae4231f1c goharbor/harbor-portal:v1.10.19 "nginx -g 'daemon of…" About a minute ago Up About a minute (healthy) 8080/tcp harbor-portal
9078844124c4 goharbor/harbor-db:v1.10.19 "/docker-entrypoint.…" About a minute ago Up About a minute (healthy) 5432/tcp harbor-db
72f314603d16 goharbor/registry-photon:v1.10.19 "/home/harbor/entryp…" About a minute ago Up About a minute (healthy) 5000/tcp registry
76680fc53a23 goharbor/harbor-registryctl:v1.10.19 "/home/harbor/start.…" About a minute ago Up About a minute (healthy) registryctl
253c363e7abd goharbor/redis-photon:v1.10.19 "redis-server /etc/r…" About a minute ago Up About a minute (healthy) 6379/tcp redis
643df5ccdcb1 goharbor/harbor-log:v1.10.19 "/bin/sh -c /usr/loc…" About a minute ago Up About a minute (healthy) 127.0.0.1:1514->10514/tcp harbor-log
Harbor的HTTP服务,在84端口启动,访问{ip}:84进入Harbor管理如下的Harbor后台页面。
接着使用账号密码登录,账号admin,默认密码在harbor.yml配置文件当中,首次登录需要修改Harbor密码。
1.2 通过已有Nginx服务反向代理Harbor服务请求(可选)
对于Harbor的SSL配置,如果在已有Nginx服务当中配置有HTTPS的SSL证书,我们也可以使用反向代理,将Harbor的84端口通过Nginx进行反向代理暴露到外部,我们添加如下的配置去进行反向代理。编辑Nginx服务器配置,使用命令如下:sudo vim /etc/nginx/sites-available/default
。
server {
listen 188 default_server;
listen [::]:188 default_server;
# SSL configuration
listen 8443 ssl default_server;
listen [::]:8443 ssl default_server;
ssl_certificate /root/ssl/wanna1314y.top_bundle.crt;
# 私钥文件的相对路径或绝对路径
ssl_certificate_key /root/ssl/wanna1314y.top.key;
ssl_session_timeout 5m;
# 配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# 协议配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name wanna1314y.top;
location / {
proxy_pass http://127.0.0.1:84;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
我们想要将Nginx通过1443端口对外HTTPS暴露,代理从而内部的http://127.0.0.1:84
接口(Harbor服务)。(需要修改ssl_certificate和ssl_certificate_key,指定SSL证书所在的位置)
通过如下这样的配置,在防火墙(安全组)当中放开1443端口,接着就可以访问我们的1443端口基于HTTPS协议的方式去访问Harbor啦,地址参考:https://wanna1314y.top:1443
。
1.3 将本地Docker镜像推送到Harbor仓库
我们下面以构建并推送一个nginx镜像举例。我们首先需要拉取(或者构建一个镜像)
docker pull nginx
我们通过docker images
可以查看本地仓库都有哪些镜像,比如我们上面pull了一个nginx镜像,那么这里就可以看到之前我们拉取到的nginx镜像。
root@ecm-4fe6:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f02a7f566928 3 weeks ago 117MB
goharbor/chartmuseum-photon v1.10.19 222e01a0c4f8 6 weeks ago 177MB
goharbor/redis-photon v1.10.19 8abbe7c628db 6 weeks ago 148MB
goharbor/clair-adapter-photon v1.10.19 1f856e990872 6 weeks ago 81.9MB
goharbor/clair-photon v1.10.19 0ccce83decfa 6 weeks ago 181MB
goharbor/notary-server-photon v1.10.19 fe7aae6b169d 6 weeks ago 119MB
goharbor/notary-signer-photon v1.10.19 ca2cfca2baf4 6 weeks ago 116MB
goharbor/harbor-registryctl v1.10.19 fc4186073195 6 weeks ago 109MB
goharbor/registry-photon v1.10.19 b5dc0c94b21e 6 weeks ago 92.1MB
goharbor/nginx-photon v1.10.19 4b6a3a04832e 6 weeks ago 122MB
goharbor/harbor-log v1.10.19 08fa03691200 6 weeks ago 133MB
goharbor/harbor-jobservice v1.10.19 1b5aca7f4143 6 weeks ago 97.8MB
goharbor/harbor-core v1.10.19 85627df50bd9 6 weeks ago 91.6MB
goharbor/harbor-portal v1.10.19 e72ed626ae05 6 weeks ago 130MB
goharbor/harbor-db v1.10.19 c038e2ac8cb3 6 weeks ago 213MB
goharbor/prepare v1.10.19 3abb30b0d645 6 weeks ago 170MB
接着我们需要给镜像打TAG。
# 完整命令格式
# 这里的{repository}/{project}是该镜像在本地的镜像名称,{tag}就是该依赖在本地的版本(默认是latest)
# 这里的{remoteRepository}/{remoteProject}对应的是远程仓库的地址和远程仓库的项目名称, {imageName}是镜像名称(比如nginx),{remoteTag}则是需要推送到远程的版本(默认是latest)
docker tag {repository}/{project}:{tag} {remoteRepository}/{remoteProject}/{imageName}:{remoteTag}
# 我们这里需要将本地的nginx推送到远程仓库(127.0.0.1:84),远程仓库的项目是library(Harbor仓库默认就是library),
# 本地镜像tag为nginx:latest, 远程的镜像tag是127.0.0.1:84/library/nginx:latest
docker tag nginx:latest 127.0.0.1:84/library/nginx:latest
# 如果是版本是latest, 那么可以省略掉, 例如上面的命令可以简写成为下面的
docker tag nginx 127.0.0.1:84/library/nginx
接着使用docker push
尝试推送到本地私服
docker push 127.0.0.1:84/library/nginx
docker push
执行结果如下:
Using default tag: latest
The push refers to repository [127.0.0.1:84/library/nginx]
c13ac49c8f3c: Preparing
5f70bf18a086: Preparing
813c9361c9a1: Preparing
352667057690: Preparing
9f29839ee958: Preparing
8895fa2456bd: Waiting
2ceb45dcc459: Waiting
98b5f35ea9d3: Waiting
denied: requested access to the resource is denied
推送过程中,发现denied: requested access to the resource is denied
,原因在于我们没有权限,我们需要首先使用docker login 127.0.0.1:84
命令,先登录Harbor
账号。
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/#credential-stores
Login Succeeded
中间过程会让提示用户名和密码,看到Login Succeeded
之后,我们重新推送镜像。
root@ecm-4fe6:~# docker push 127.0.0.1:84/library/nginx
Using default tag: latest
The push refers to repository [127.0.0.1:84/library/nginx]
c13ac49c8f3c: Pushed
5f70bf18a086: Pushed
813c9361c9a1: Pushed
352667057690: Pushed
9f29839ee958: Pushed
8895fa2456bd: Pushed
2ceb45dcc459: Pushed
98b5f35ea9d3: Pushed
latest: digest: sha256:6df8098f056f25e26890a11bbe06fa59a6fd035691d1b2747ff192e1a04b4e0b size: 1986
看到上述的提示说明我们已经成功推送到本地Harbor
私服。
2.Harbor相关的配置信息
2.1 修改Harbor的数据存放路径
如果Harbor现在已经有了数据,那么如果需要去进行数据迁移,那么需要先将原来的数据进行迁移,Harbor默认将数据存放到/data
目录下,我们现在将/data
目录下的内容拷贝到/sharedata/data
目录下,使用如下的命令拷贝:
# 安装rsync工具
sudo apt install rsync
# 数据拷贝
rsync -av /data /sharedata
接着找到Harbor的安装目录下的harbor.yaml
配置文件,修改data_valume
配置,将数据卷目录去配置为/sharedata/data
。
# 修改前
data_volume: /data
# 修改后
data_volume: /sharedata/data
接着找到Harbor安装目录下的安装脚本,使用./install.sh
执行Harbor的重新安装,期间会停止之前已经启动的Harbor,重新生成docker-compose.yaml
文件。
需要注意的是:执行install.sh
这里会重新生成docker-compose.yaml
文件,因此会修改所有的数据卷的路径配置!!!
2.2 修改Harbor的外部访问地址(Nginx反向代理Harbor时需要)
在配置了反向代理访问Harbor的情况,需要配置Harbor的外部访问地址。
如果我们通过Nginx反向代理去访问Harbor,那么很可能出现Harbor的启动端口号和Nginx的启动端口号不一致的情况。比如我们的Nginx服务在443端口启动,并且在Nginx上配置了一个域名aaa.xxx.com,但是Harbor仓库在84端口启动,通过Nginx反向代理Harbor的84端口。那么如果Harbor内部存在有页面跳转等情况,Harbor可能会跳转到aaa.xxx.com:84端口,因为对Harbor来说,其实外部访问它的就是84端口,但是aaa.xxx.com:84很可能是一个内部使用的接口(或者Harbor本身是部署在其他的机器上的,根本就不存在这样的接口),对用户来说是无法访问的,用户感知的是443端口,直接进行页面跳转时却跳转到aaa.xxx.com:84端口,属于是页面的错误跳转。
因此如果我们通过Nginx反向代理的Harbor,修改外部访问地址是很有必要的,例如我们对外通过Nginx访问Harbor的接口是https://aaa.xxx.con:443
,那么我们就需要配置Harbor的外部访问地址是https://aaa.xxx.con:443
。
我们找到harbor.yml
配置文件,新增如下的配置项:
external_url: https://aaa.xxx.com:443
如果不修改外部访问地址的话,最典型的影响我们使用的就是Harbor页面上复制的docker pull命令是不对的。
# 不配置external_url
docker pull aaa.xxx.com:84/library/redis:latest
# 配置external_url之后, 自动修正
docker pull aaa.xxx.com:443/library/redis:latest
修改harbor.yml
配置文件之后,我们使用./install.sh
命令去重启Harbor服务,实现重新加载Harbor的配置文件。