Harbor介绍、整体架构和安装(二)

369 阅读10分钟

4.harbor 安全 https 配置

harbor默认使用http,为了安全,可以使用https。

4.1 主机初始化

参考3.1里面的设置。

4.2 安装docker

[root@rocky9-2 ~]# cat install_docker-binary_v2.sh 
#!/bin/bash
#
#*************************************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2024-01-17
#FileName:      install_docker-binary_v2.sh
#URL:           raymond.blog.csdn.net
#Description:   install_docker-binary for CentOS 7 & CentOS Stream 8/9 & Ubuntu 18.04/20.04/22.04 & Rocky 8/9
#Copyright (C): 2024 All rights reserved
#*************************************************************************************************************
SRC_DIR=/usr/local/src
COLOR="echo -e \033[01;31m"
END='\033[0m'
URL='https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/'
DOCKER_FILE=docker-24.0.7.tgz

os(){
    OS_ID=`sed -rn '/^NAME=/s@.*="([[:alpha:]]+).*"$@\1@p' /etc/os-release`
    OS_RELEASE_VERSION=`sed -rn '/^VERSION_ID=/s@.*="?([0-9]+).?.*"?@\1@p' /etc/os-release`
}

check_file (){
    cd ${SRC_DIR}
    if [ ${OS_ID} == "CentOS" -o ${OS_ID} == "Rocky" ] &> /dev/null;then
        rpm -q wget &> /dev/null || { ${COLOR}"安装wget工具,请稍等..."${END};yum -y install wget &> /dev/null; }
    fi
    if [ ! -e ${DOCKER_FILE} ];then
        ${COLOR}"缺少${DOCKER_FILE}文件,如果是离线包,请把文件放到${SRC_DIR}目录下"${END}
        ${COLOR}'开始下载Docker二进制安装包'${END}
        wget ${URL}${DOCKER_FILE} || { ${COLOR}"Docker二进制安装包下载失败"${END}; exit; } 
    else
        ${COLOR}"相关文件已准备好"${END}
    fi
}

install(){ 
    [ -f /usr/bin/docker ] && { ${COLOR}"Docker已存在,安装失败"${END};exit; }
    ${COLOR}"开始安装Docker,请稍等..."${END}
    if [ ${OS_ID} == "CentOS" -o ${OS_ID} == "Rocky" ] &> /dev/null;then
        rpm -q tar &> /dev/null || { ${COLOR}"安装tar工具,请稍等..."${END};yum -y install tar &> /dev/null; }
    fi
    tar xf ${DOCKER_FILE} 
    mv docker/* /usr/bin/
    cat > /lib/systemd/system/docker.service <<-EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H unix://var/run/docker.sock
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
EOF
    mkdir -p /etc/docker
    cat > /etc/docker/daemon.json <<-EOF
{
    "registry-mirrors": [
        "https://registry.docker-cn.com",
        "https://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn"
    ],
    "data-root": "/data/docker",
    "exec-opts": ["native.cgroupdriver=systemd"],
    "max-concurrent-downloads": 10,
    "max-concurrent-uploads": 5,
    "log-opts": {
        "max-size": "300m",
        "max-file": "2"  
    },
    "live-restore": true
}
EOF
    echo 'alias rmi="docker images -qa|xargs docker rmi -f"' >> ~/.bashrc
    echo 'alias rmc="docker ps -qa|xargs docker rm -f"' >> ~/.bashrc
    systemctl daemon-reload
    systemctl enable --now docker &> /dev/null
    systemctl is-active docker &> /dev/null && ${COLOR}"Docker 服务启动成功"${END} || { ${COLOR}"Docker 启动失败"${END};exit; }
    docker version && ${COLOR}"Docker 安装成功"${END} || ${COLOR}"Docker 安装失败"${END}
}

set_swap_limit(){
    if [ ${OS_RELEASE_VERSION} == "18" -o ${OS_RELEASE_VERSION} == "20" ];then
        grep -q "swapaccount=1" /etc/default/grub && { ${COLOR}'"WARNING: No swap limit support"警告,已设置'${END};exit; }
        ${COLOR}'设置Docker的"WARNING: No swap limit support"警告'${END}
        sed -ri '/^GRUB_CMDLINE_LINUX=/s@"$@ swapaccount=1"@' /etc/default/grub
        update-grub &> /dev/null
        ${COLOR}"10秒后,机器会自动重启!"${END}
        sleep 10
        reboot
    fi
}

main(){
    os
    check_file
    install
    set_swap_limit
}

main

[root@rocky9-2 ~]# bash install_docker-binary_v2.sh

[root@rocky9-2 ~]# docker version
Client:
 Version:           24.0.7
 API version:       1.43
 Go version:        go1.20.10
 Git commit:        afdd53b
 Built:             Thu Oct 26 09:04:00 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.10
  Git commit:       311b9ff
  Built:            Thu Oct 26 09:05:28 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.7.6
  GitCommit:        091922f03c2762540fd057fba91260237ff86acb
 runc:
  Version:          1.1.9
  GitCommit:        v1.1.9-0-gccaecfc
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

4.3 安装docker compose

[root@rocky9-2 ~]# wget https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-x86_64

[root@rocky9-2 ~]# mv docker-compose-linux-x86_64 /usr/bin/docker-compose
[root@rocky9-2 ~]# chmod +x /usr/bin/docker-compose

[root@rocky9-2 ~]# docker-compose -v
Docker Compose version v2.23.3

4.4 下载Harbor安装包并解压缩

[root@rocky9-2 ~]# wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz

[root@rocky9-2 ~]# mkdir /apps

[root@rocky9-2 ~]# tar xvf harbor-offline-installer-v2.10.0.tgz -C /apps/
harbor/harbor.v2.10.0.tar.gz
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl

4.5 生成私钥和证书

最新文档: goharbor.io/docs/2.10.0…

[root@rocky9-2 ~]# touch /root/.rnd
[root@rocky9-2 ~]# mkdir /apps/harbor/certs/
[root@rocky9-2 ~]# cd /apps/harbor/certs/

# 1.生成证书颁发机构证书
# 生成CA证书私钥
[root@rocky9-2 certs]# openssl genrsa -out ca.key 4096

# 生成CA证书,请把下面的变量DOMAIN值改成自己的域名
[root@rocky9-2 certs]# DOMAIN=raymonds.cc

[root@rocky9-2 certs]# openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=ca.${DOMAIN}" -key ca.key -out ca.crt

# 2.生成服务器证书
# 生成私人密钥
[root@rocky9-2 certs]# openssl genrsa -out harbor.${DOMAIN}.key 4096

# 生成证书签名请求(CSR)
[root@rocky9-2 certs]# openssl req -sha512 -new -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.${DOMAIN}" -key harbor.${DOMAIN}.key -out harbor.${DOMAIN}.csr

# 生成 x509 v3 扩展文件
[root@rocky9-2 certs]# cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=${DOMAIN}
DNS.2=ca.${DOMAIN}
DNS.3=harbor.${DOMAIN}
EOF

# 使用 v3.ext 文件为 Harbor 主机生成证书
[root@rocky9-2 certs]# openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in harbor.${DOMAIN}.csr -out harbor.${DOMAIN}.crt

# 转换crt为cert,供Docker使用,Docker守护程序将.crt文件解释为CA证书,并将.cert文件解释为客户端证书
[root@rocky9-2 certs]# openssl x509 -inform PEM -in harbor.${DOMAIN}.crt -out harbor.${DOMAIN}.cert

[root@rocky9-2 certs]# tree
-bash: tree: command not found
# 没有tree命令

# 安装tree
[root@Rocky9-2 certs]# dnf -y install tree

[root@rocky9-2 certs]# tree
.
├── ca.crt
├── ca.key
├── ca.srl
├── harbor.raymonds.cc.cert
├── harbor.raymonds.cc.crt
├── harbor.raymonds.cc.csr
├── harbor.raymonds.cc.key
└── v3.ext

0 directories, 8 files

4.6 编辑配置文件 harbor.cfg

[root@Rocky9-2 certs]# cd ..
[root@Rocky9-2 harbor]# ls
certs  common.sh  harbor.v2.10.0.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@Rocky9-2 harbor]# mv harbor.yml.tmpl harbor.yml

[root@Rocky9-2 harbor]# vim harbor.yml
-bash: vim: command not found
# Rocky和CentOS默认没有安装vim。

[root@Rocky9-2 harbor]# dnf -y install vim

[root@Rocky9-2 harbor]# vim harbor.yml
hostname: harbor.raymonds.cc

https:
  port: 443
  certificate: /apps/harbor/certs/harbor.raymonds.cc.crt
  private_key: /apps/harbor/certs/harbor.raymonds.cc.key

harbor_admin_password: 123456

# 使用下面命令直接替换
HARBOR_INSTALL_DIR=/apps
HARBOR_ADMIN_PASSWORD=123456

sed -ri.bak -e 's/^(hostname:) .*/\1 harbor.'''${DOMAIN}'''/' -e 's@  (certificate:) .*@  \1 '''${HARBOR_INSTALL_DIR}'''/harbor/certs/harbor.'''${DOMAIN}'''.crt@' -e 's@  (private_key:) .*@  \1 '''${HARBOR_INSTALL_DIR}'''/harbor/certs/harbor.'''${DOMAIN}'''.key@' -e 's/^(harbor_admin_password:) .*/\1 '''${HARBOR_ADMIN_PASSWORD}'''/' ${HARBOR_INSTALL_DIR}/harbor/harbor.yml

4.7 运行 harbor 安装脚本

# 先安装python
# rocky和CentOS
yum -y install python3

# Ubuntu
apt -y install python3

# --with-trivy:选择安装镜像扫描组件Trivy。
[root@rocky9-2 harbor]# ./install.sh --with-trivy

[Step 0]: checking if docker is installed ...

Note: docker version: 24.0.7

[Step 1]: checking docker-compose is installed ...

Note: docker-compose version: 2.23.3

[Step 2]: loading Harbor images ...
ad00c0c1d948: Loading layer [==================================================>]  40.11MB/40.11MB
7570a78aea36: Loading layer [==================================================>]   9.08MB/9.08MB
04774e0e84f2: Loading layer [==================================================>]  4.096kB/4.096kB
8a42710a9f5a: Loading layer [==================================================>]  3.072kB/3.072kB
f1990e77f8e5: Loading layer [==================================================>]    197MB/197MB
172f5af926be: Loading layer [==================================================>]   17.6MB/17.6MB
2bef5dd17a10: Loading layer [==================================================>]  215.4MB/215.4MB
Loaded image: goharbor/trivy-adapter-photon:v2.10.0
8c10ac3a40a9: Loading layer [==================================================>]  89.84MB/89.84MB
cc741ba6af65: Loading layer [==================================================>]  65.11MB/65.11MB
7877ea7046dd: Loading layer [==================================================>]   13.2MB/13.2MB
3de91a0984fe: Loading layer [==================================================>]  65.54kB/65.54kB
4d2cda613456: Loading layer [==================================================>]   2.56kB/2.56kB
625b81c9e514: Loading layer [==================================================>]  1.536kB/1.536kB
6496ec4ce84e: Loading layer [==================================================>]  12.29kB/12.29kB
2b332fb0075b: Loading layer [==================================================>]  5.322MB/5.322MB
f8976ae46d77: Loading layer [==================================================>]  457.7kB/457.7kB
Loaded image: goharbor/prepare:v2.10.0
a36cb8a4e510: Loading layer [==================================================>]  126.1MB/126.1MB
fd72ef63aacc: Loading layer [==================================================>]  3.584kB/3.584kB
162d9960a2b9: Loading layer [==================================================>]  3.072kB/3.072kB
b71508b0d586: Loading layer [==================================================>]   2.56kB/2.56kB
18c685e189cb: Loading layer [==================================================>]  3.072kB/3.072kB
84690af2e82b: Loading layer [==================================================>]  3.584kB/3.584kB
8d7eb73e8207: Loading layer [==================================================>]  20.48kB/20.48kB
Loaded image: goharbor/harbor-log:v2.10.0
001da4979db8: Loading layer [==================================================>]  8.562MB/8.562MB
275281f671bf: Loading layer [==================================================>]  4.096kB/4.096kB
f6856e2d539f: Loading layer [==================================================>]   17.4MB/17.4MB
557317f3c1c5: Loading layer [==================================================>]  3.072kB/3.072kB
942b8c3060c6: Loading layer [==================================================>]  32.81MB/32.81MB
b2bc30e737e7: Loading layer [==================================================>]     51MB/51MB
Loaded image: goharbor/harbor-registryctl:v2.10.0
d5e5478da184: Loading layer [==================================================>]  116.8MB/116.8MB
Loaded image: goharbor/nginx-photon:v2.10.0
74a7f6a8de8c: Loading layer [==================================================>]  11.58MB/11.58MB
46523ccaf371: Loading layer [==================================================>]   27.6MB/27.6MB
3cea6b428022: Loading layer [==================================================>]  4.608kB/4.608kB
9815d4ae0f06: Loading layer [==================================================>]  28.39MB/28.39MB
Loaded image: goharbor/harbor-exporter:v2.10.0
7d7e15ae8ca1: Loading layer [==================================================>]  15.93MB/15.93MB
e13b0ff80947: Loading layer [==================================================>]  111.8MB/111.8MB
da74a4230588: Loading layer [==================================================>]  3.072kB/3.072kB
89240f6f343b: Loading layer [==================================================>]   59.9kB/59.9kB
7b00214da46a: Loading layer [==================================================>]  61.95kB/61.95kB
Loaded image: goharbor/redis-photon:v2.10.0
345fdbd05997: Loading layer [==================================================>]  8.562MB/8.562MB
5c4443929555: Loading layer [==================================================>]  4.096kB/4.096kB
605c9788ef17: Loading layer [==================================================>]  3.072kB/3.072kB
b2ab56de0e45: Loading layer [==================================================>]   17.4MB/17.4MB
950eb2734789: Loading layer [==================================================>]  18.19MB/18.19MB
Loaded image: goharbor/registry-photon:v2.10.0
7693164e30e0: Loading layer [==================================================>]  116.8MB/116.8MB
6b50b5d516aa: Loading layer [==================================================>]  6.531MB/6.531MB
5aea217650ad: Loading layer [==================================================>]  246.8kB/246.8kB
0b3de92ff70b: Loading layer [==================================================>]  1.477MB/1.477MB
Loaded image: goharbor/harbor-portal:v2.10.0
b79ac58f353c: Loading layer [==================================================>]  11.58MB/11.58MB
18c4c015e339: Loading layer [==================================================>]  3.584kB/3.584kB
c6eef6a39935: Loading layer [==================================================>]   2.56kB/2.56kB
03db56130352: Loading layer [==================================================>]  58.57MB/58.57MB
78c9748f2d29: Loading layer [==================================================>]  5.632kB/5.632kB
e1732f90232a: Loading layer [==================================================>]  123.4kB/123.4kB
6b733e4833c8: Loading layer [==================================================>]  80.38kB/80.38kB
fe6828cc147a: Loading layer [==================================================>]  59.56MB/59.56MB
8e1349c44768: Loading layer [==================================================>]   2.56kB/2.56kB
Loaded image: goharbor/harbor-core:v2.10.0
02b0385778eb: Loading layer [==================================================>]  15.93MB/15.93MB
ac2be26232ee: Loading layer [==================================================>]    175MB/175MB
1e3e9dba5eaa: Loading layer [==================================================>]  25.47MB/25.47MB
c7fa85d79c1c: Loading layer [==================================================>]  18.14MB/18.14MB
f9ef6596c7ce: Loading layer [==================================================>]   5.12kB/5.12kB
e35036cc139f: Loading layer [==================================================>]  6.144kB/6.144kB
0cb7ded8041a: Loading layer [==================================================>]  3.072kB/3.072kB
5d178abacde0: Loading layer [==================================================>]  2.048kB/2.048kB
67fe09fd709b: Loading layer [==================================================>]   2.56kB/2.56kB
d0b4aac335c4: Loading layer [==================================================>]   7.68kB/7.68kB
Loaded image: goharbor/harbor-db:v2.10.0
fced8697b2c7: Loading layer [==================================================>]  11.58MB/11.58MB
af968b902c26: Loading layer [==================================================>]  3.584kB/3.584kB
7caaebde63bc: Loading layer [==================================================>]   2.56kB/2.56kB
d6e3c7a6ef36: Loading layer [==================================================>]  44.96MB/44.96MB
bc8a8ef654ea: Loading layer [==================================================>]  45.75MB/45.75MB
Loaded image: goharbor/harbor-jobservice:v2.10.0


[Step 3]: preparing environment ...

[Step 4]: preparing harbor configs ...
prepare base dir is set to /apps/harbor
Generated configuration file: /config/portal/nginx.conf
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/registryctl/config.yml
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
Generated and saved secret to file: /data/secret/keys/secretkey
Successfully called func: create_root_cert
Generated configuration file: /config/trivy-adapter/env
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir


Note: stopping existing Harbor instance ...


[Step 5]: starting Harbor ...
[+] Running 11/11
  Network harbor_harbor        Created                                                                            0.1s 
  Container harbor-log         Started                                                                            0.0s 
  Container harbor-db          Started                                                                            0.1s 
  Container redis              Started                                                                            0.1s 
  Container registry           Started                                                                            0.1s 
  Container registryctl        Started                                                                            0.0s 
  Container harbor-portal      Started                                                                            0.1s 
  Container trivy-adapter      Started                                                                            0.0s 
  Container harbor-core        Started                                                                            0.0s 
  Container nginx              Started                                                                            0.0s 
  Container harbor-jobservice  Started                                                                            0.0s 
 ----Harbor has been installed and started successfully.----

 ----Harbor has been installed and started successfully.----
# 出现“Harbor has been installed and started successfully”提示表示安装成功。

[root@rocky9 harbor]# docker-compose ps
NAME                IMAGE                                   COMMAND                  SERVICE         CREATED              STATUS                        PORTS
harbor-core         goharbor/harbor-core:v2.10.0            "/harbor/entrypoint.…"   core            About a minute ago   Up About a minute (healthy)   
harbor-db           goharbor/harbor-db:v2.10.0              "/docker-entrypoint.…"   postgresql      About a minute ago   Up About a minute (healthy)   
harbor-jobservice   goharbor/harbor-jobservice:v2.10.0      "/harbor/entrypoint.…"   jobservice      About a minute ago   Up About a minute (healthy)   
harbor-log          goharbor/harbor-log:v2.10.0             "/bin/sh -c /usr/loc…"   log             About a minute ago   Up About a minute (healthy)   127.0.0.1:1514->10514/tcp
harbor-portal       goharbor/harbor-portal:v2.10.0          "nginx -g 'daemon of…"   portal          About a minute ago   Up About a minute (healthy)   
nginx               goharbor/nginx-photon:v2.10.0           "nginx -g 'daemon of…"   proxy           About a minute ago   Up About a minute (healthy)   0.0.0.0:80->8080/tcp, :::80->8080/tcp, 0.0.0.0:443->8443/tcp, :::443->8443/tcp
redis               goharbor/redis-photon:v2.10.0           "redis-server /etc/r…"   redis           About a minute ago   Up About a minute (healthy)   
registry            goharbor/registry-photon:v2.10.0        "/home/harbor/entryp…"   registry        About a minute ago   Up About a minute (healthy)   
registryctl         goharbor/harbor-registryctl:v2.10.0     "/home/harbor/start.…"   registryctl     About a minute ago   Up About a minute (healthy)   
trivy-adapter       goharbor/trivy-adapter-photon:v2.10.0   "/home/scanner/entry…"   trivy-adapter   About a minute ago   Up About a minute (healthy) 

4.8 实现开机自动启动 harbor

[root@rocky9-2 harbor]# cat > /lib/systemd/system/harbor.service <<-EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target
EOF

[root@rocky9-2 harbor]# systemctl daemon-reload && systemctl enable harbor

4.9 用https方式访问harbor网站

在windows系统C:\Windows\System32\drivers\etc\hosts文件里,添加下面内容

172.31.0.19 harbor.raymonds.cc

在浏览器输入“harbor.raymonds.cc”,然后选择“高级”。

t1-10

图1-10 访问harbor

选择下面的“继续访问harbor.raymonds.cc”。

t1-11

图1-11 访问harbor2

输入用户名和密码,选择“登陆”。

t1-12

图1-12 登陆harbor

图1-13就是harbor登陆后的界面。

t1-13

图1-13 harbor登陆后的界面

图1-14就是harbor.raymonds.cc网址的证书。

t1-14

图1-14 harbor网址证书

4.10 使用 harbor

4.10.1 建立项目

harbor上必须先建立项目,才能上传镜像

在“项目”菜单下面选择“新建项目”。

t1-15

图1-15 新建项目

在“新建项目”窗口,设置“项目名称”为linux,勾选“访问级别”后面的“公开”选项,然后点“确定”。

t1-16

图1-16 新建项目

可以看到下图已经新建了项目linux。

t1-17

图1-17 创建完项目后的界面

4.10.2 在客户端下载CA的证书

直接上传镜像会报错

[root@rocky9-2 harbor]# cat >> /etc/hosts <<-EOF
172.31.0.19 harbor.raymonds.cc
EOF

# 没有证书验证,直接登录失败
[root@rocky9-2 harbor]# docker login harbor.raymonds.cc
Username: admin
Password: 
.Error response from daemon: Get "https://harbor.raymonds.cc/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority

在客户端下载ca的证书

[root@rocky9-2 harbor]# mkdir -pv /etc/docker/certs.d/harbor.${DOMAIN}
mkdir: created directory '/etc/docker/certs.d'
mkdir: created directory '/etc/docker/certs.d/harbor.raymonds.cc'

[root@rocky9-2 harbor]# scp -r /apps/harbor/certs/{harbor.${DOMAIN}.cert,harbor.${DOMAIN}.key,ca.crt} /etc/docker/certs.d/harbor.${DOMAIN}

[root@rocky9 certs]# tree /etc/docker/certs.d/harbor.${DOMAIN}
/etc/docker/certs.d/harbor.raymonds.cc/
├── ca.crt
├── harbor.raymonds.cc.cert
└── harbor.raymonds.cc.key

0 directories, 3 files

4.10.3 从客户端上传镜像

# 先登录系统
[root@rocky9 certs]# docker login harbor.raymonds.cc
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

[root@rocky9-2 harbor]# cat ~/.docker/config.json
{
	"auths": {
		"harbor.raymonds.cc": {
			"auth": "YWRtaW46MTIzNDU2"
		}
	}
}

4.10.4 给本地镜像打标签并上传到harbor

修改 images 的名称,不修改成指定格式无法将镜像上传到 harbor 仓库

[root@Rocky9-2 harbor]# docker pull alpine

[root@Rocky9-2 harbor]# docker images |grep "alpine"
alpine                          latest    f8c20f8bbcb6   5 weeks ago   7.38MB

[root@Rocky9-2 harbor]# docker tag alpine harbor.raymonds.cc/linux/alpine
[root@Rocky9-2 harbor]# docker images |grep "alpine"
alpine                            latest    f8c20f8bbcb6   5 weeks ago   7.38MB
harbor.raymonds.cc/linux/alpine   latest    f8c20f8bbcb6   5 weeks ago   7.38MB

[root@rocky9-2 harbor]# docker push harbor.raymonds.cc/linux/alpine
Using default tag: latest
The push refers to repository [harbor.raymonds.cc/linux/alpine]
5af4f8f59b76: Pushed 
latest: digest: sha256:13b7e62e8df80264dbb747995705a986aa530415763a6c58f84a3ca8af9a5bcd size: 528

访问harbor网站验证上传镜像成功

t1-18

图1-18 查看上传的镜像

4.10.5 下载harbor的镜像

在172.31.0.8的Rocky 8的主机上无需登录,即可下载镜像

首先要主机初始化和安装docker,安装方法参考4.1和4.2。

[root@rocky8 ~]# cat >> /etc/hosts <<-EOF
172.31.0.19 harbor.raymonds.cc
EOF

[root@rocky8 ~]# docker pull harbor.raymonds.cc/linux/alpine
Using default tag: latest
Error response from daemon: Get "https://harbor.raymonds.cc/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority
# 没有证书不能推送镜像。

[root@rocky8 ~]# DOMAIN=raymonds.cc
[root@rocky8 ~]# mkdir -pv /etc/docker/certs.d/harbor.${DOMAIN}
mkdir: created directory '/etc/docker/certs.d'
mkdir: created directory '/etc/docker/certs.d/harbor.raymonds.cc'

[root@Rocky9-2 harbor]# scp -r /apps/harbor/certs/{harbor.${DOMAIN}.cert,harbor.${DOMAIN}.key,ca.crt} 172.31.0.8:/etc/docker/certs.d/harbor.${DOMAIN}/

[root@rocky8 ~]# tree /etc/docker/certs.d/harbor.${DOMAIN}/
-bash: tree: command not found
[root@rocky8 ~]# dnf -y install tree

[root@rocky8 ~]# tree /etc/docker/certs.d/harbor.${DOMAIN}/
/etc/docker/certs.d/harbor.raymonds.cc/
├── ca.crt
├── harbor.raymonds.cc.cert
└── harbor.raymonds.cc.key

0 directories, 3 files

[root@rocky8 ~]# docker pull harbor.raymonds.cc/linux/alpine
Using default tag: latest
latest: Pulling from linux/alpine
661ff4d9561e: Pull complete 
Digest: sha256:13b7e62e8df80264dbb747995705a986aa530415763a6c58f84a3ca8af9a5bcd
Status: Downloaded newer image for harbor.raymonds.cc/linux/alpine:latest
harbor.raymonds.cc/linux/alpine:latest

[root@rocky8 ~]# docker images
REPOSITORY                        TAG       IMAGE ID       CREATED       SIZE
harbor.raymonds.cc/linux/alpine   latest    f8c20f8bbcb6   5 weeks ago   7.38MB

4.11一键安装harbor脚本https方式

Shell脚本源码地址:

Gitee:gitee.com/raymond9/sh…

Github:github.com/raymond9999…

可以去上面的Gitee或Github代码仓库拉取脚本。

4.11.1 基于docker二进制包一键安装Harbor脚本https方式

[root@rocky9-2 ~]# cat install_harbor_https_v2_1.sh
#!/bin/bash
#
#******************************************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2024-01-26
#FileName:      install_harbor_https_v2_1.sh
#URL:           raymond.blog.csdn.net
#Description:   install_harbor_https for CentOS 7 & CentOS Stream 8/9 & Ubuntu 18.04/20.04/22.04 & Rocky 8/9
#Copyright (C): 2024 All rights reserved
#******************************************************************************************************************
SRC_DIR=/usr/local/src
COLOR="echo -e \033[01;31m"
END='\033[0m'

URL='https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/'
DOCKER_FILE=docker-24.0.7.tgz

# Docker Compose下载地址:“https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-x86_64”,请提前下载。
DOCKER_COMPOSE_FILE=docker-compose-linux-x86_64

# Harbor下载地址:“https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz”,请提前下载。
HARBOR_FILE=harbor-offline-installer-v
HARBOR_VERSION=2.10.0
TAR=.tgz
HARBOR_INSTALL_DIR=/apps
DOMAIN=raymonds.cc
HARBOR_ADMIN_PASSWORD=123456

os(){
    OS_ID=`sed -rn '/^NAME=/s@.*="([[:alpha:]]+).*"$@\1@p' /etc/os-release`
    OS_RELEASE_VERSION=`sed -rn '/^VERSION_ID=/s@.*="?([0-9]+).?.*"?@\1@p' /etc/os-release`
}

check_file (){
    cd ${SRC_DIR}
    if [ ${OS_ID} == "CentOS" -o ${OS_ID} == "Rocky" ] &> /dev/null;then
        rpm -q wget &> /dev/null || { ${COLOR}"安装wget工具,请稍等..."${END};yum -y install wget &> /dev/null; }
    fi
    if [ ! -e ${DOCKER_FILE} ];then
        ${COLOR}"缺少${DOCKER_FILE}文件,如果是离线包,请把文件放到${SRC_DIR}目录下"${END}
        ${COLOR}'开始下载DOCKER二进制源码包'${END}
        wget ${URL}${DOCKER_FILE} || { ${COLOR}"DOCKER二进制安装包下载失败"${END}; exit; }
    elif [ ! -e ${DOCKER_COMPOSE_FILE} ];then
        ${COLOR}"缺少${DOCKER_COMPOSE_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}
        exit
    elif [ ! -e ${HARBOR_FILE}${HARBOR_VERSION}${TAR} ];then
        ${COLOR}"缺少${HARBOR_FILE}${HARBOR_VERSION}${TAR}文件,请把文件放到${SRC_DIR}目录下"${END}
        exit
    else
        ${COLOR}"相关文件已准备好"${END}
    fi
}

install_docker(){ 
    ${COLOR}"开始安装Docker,请稍等..."${END}
    tar xf ${DOCKER_FILE}
    mv docker/* /usr/bin/
    cat > /lib/systemd/system/docker.service <<-EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H unix://var/run/docker.sock
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
EOF
    mkdir -p /etc/docker
    cat > /etc/docker/daemon.json <<-EOF
{
    "registry-mirrors": [
        "https://registry.docker-cn.com",
        "https://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn"
    ],
    "data-root": "/data/docker",
    "exec-opts": ["native.cgroupdriver=systemd"],
    "max-concurrent-downloads": 10,
    "max-concurrent-uploads": 5,
    "log-opts": {
        "max-size": "300m",
        "max-file": "2"  
    },
    "live-restore": true
}
EOF
    echo 'alias rmi="docker images -qa|xargs docker rmi -f"' >> ~/.bashrc
    echo 'alias rmc="docker ps -qa|xargs docker rm -f"' >> ~/.bashrc
    systemctl daemon-reload
    systemctl enable --now docker &> /dev/null
    systemctl is-active docker &> /dev/null && ${COLOR}"Docker 服务启动成功"${END} || { ${COLOR}"Docker 启动失败"${END};exit; }
    docker version && ${COLOR}"Docker 安装成功"${END} || ${COLOR}"Docker 安装失败"${END}
}

install_docker_compose(){
    ${COLOR}"开始安装Docker Compose,请稍等..."${END}
    mv ${SRC_DIR}/${DOCKER_COMPOSE_FILE} /usr/bin/docker-compose
    chmod +x /usr/bin/docker-compose
    docker-compose --version &&  ${COLOR}"Docker Compose 安装完成"${END} || ${COLOR}"Docker compose 安装失败"${END}
}

install_harbor(){
    ${COLOR}"开始安装Harbor,请稍等..."${END}
    [ -d ${HARBOR_INSTALL_DIR} ] || mkdir ${HARBOR_INSTALL_DIR}
    tar xf ${SRC_DIR}/${HARBOR_FILE}${HARBOR_VERSION}${TAR} -C ${HARBOR_INSTALL_DIR}/

    # 生成私钥和证书
	touch /root/.rnd
    mkdir /apps/harbor/certs/
    cd /apps/harbor/certs/
    openssl genrsa -out ca.key 4096
    openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=ca.${DOMAIN}" -key ca.key -out ca.crt
    openssl genrsa -out harbor.${DOMAIN}.key 4096
    openssl req -sha512 -new -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.${DOMAIN}" -key harbor.${DOMAIN}.key -out harbor.${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=${DOMAIN}
DNS.2=ca.${DOMAIN}
DNS.3=harbor.${DOMAIN}
EOF
    openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in harbor.${DOMAIN}.csr -out harbor.${DOMAIN}.crt
    openssl x509 -inform PEM -in harbor.${DOMAIN}.crt -out harbor.${DOMAIN}.cert
	
    mv ${HARBOR_INSTALL_DIR}/harbor/harbor.yml.tmpl ${HARBOR_INSTALL_DIR}/harbor/harbor.yml
    sed -ri.bak -e 's/^(hostname:) .*/\1 harbor.'''${DOMAIN}'''/' -e 's@  (certificate:) .*@  \1 '''${HARBOR_INSTALL_DIR}'''/harbor/certs/harbor.'''${DOMAIN}'''.crt@' -e 's@  (private_key:) .*@  \1 '''${HARBOR_INSTALL_DIR}'''/harbor/certs/harbor.'''${DOMAIN}'''.key@' -e 's/^(harbor_admin_password:) .*/\1 '''${HARBOR_ADMIN_PASSWORD}'''/' ${HARBOR_INSTALL_DIR}/harbor/harbor.yml
    if [ ${OS_ID} == "CentOS" -o ${OS_ID} == "Rocky" ] &> /dev/null;then
        rpm -q python3 &> /dev/null || { ${COLOR}"安装python3,请稍等..."${END};yum -y install python3 &> /dev/null; }
    else
        dpkg -s python3 &>/dev/null || { ${COLOR}"安装python3,请稍等..."${END};apt -y install python3 &> /dev/null; }
    fi
    ${HARBOR_INSTALL_DIR}/harbor/install.sh --with-trivy && ${COLOR}"Harbor 安装完成"${END} ||  ${COLOR}"Harbor 安装失败"${END}
    cat > /lib/systemd/system/harbor.service <<-EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f ${HARBOR_INSTALL_DIR}/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f ${HARBOR_INSTALL_DIR}/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload 
    systemctl enable harbor &>/dev/null && ${COLOR}"Harbor已配置为开机自动启动"${END}
}

set_swap_limit(){
    if [ ${OS_RELEASE_VERSION} == "18" -o ${OS_RELEASE_VERSION} == "20" ];then
        grep -q "swapaccount=1" /etc/default/grub && { ${COLOR}'"WARNING: No swap limit support"警告,已设置'${END};exit; }
        ${COLOR}'设置Docker的"WARNING: No swap limit support"警告'${END}
        sed -ri '/^GRUB_CMDLINE_LINUX=/s@"$@ swapaccount=1"@' /etc/default/grub
        update-grub &> /dev/null
        ${COLOR}"10秒后,机器会自动重启"${END}
        sleep 10
        reboot
    fi
}

main(){
    os
    check_file
    [ -f /usr/bin/docker ] && ${COLOR}"Docker已安装"${END} || install_docker
    [ -f /usr/bin/docker-compose ] && ${COLOR}"Docker Compose已安装"${END} || install_docker_compose
    systemctl is-active harbor &> /dev/null && ${COLOR}"Harbor已安装"${END} || install_harbor
    set_swap_limit
}

main

4.11.2 基于docker镜像仓库一键安装Harbor脚本https方式

[root@rocky9-2 ~]# cat install_harbor_https_v2_2.sh
#!/bin/bash
#
#******************************************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2024-01-26
#FileName:      install_harbor_https_v2_2.sh
#URL:           raymond.blog.csdn.net
#Description:   install_harbor_https for CentOS 7 & CentOS Stream 8/9 & Ubuntu 18.04/20.04/22.04 & Rocky 8/9
#Copyright (C): 2024 All rights reserved
#******************************************************************************************************************
SRC_DIR=/usr/local/src
COLOR="echo -e \033[01;31m"
END='\033[0m'

DOCKER_VERSION=24.0.7
DOCKER_MAIN_VERSION=`echo ${DOCKER_VERSION} | awk -F'.' '{print $1}'`
URL='mirrors.aliyun.com'

# Docker Compose下载地址:“https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-x86_64”,请提前下载。
DOCKER_COMPOSE_FILE=docker-compose-linux-x86_64

# Harbor下载地址:“https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz”,请提前下载。
HARBOR_FILE=harbor-offline-installer-v
HARBOR_VERSION=2.10.0
TAR=.tgz
HARBOR_INSTALL_DIR=/apps
DOMAIN=raymonds.cc
HARBOR_ADMIN_PASSWORD=123456

os(){
    OS_ID=`sed -rn '/^NAME=/s@.*="([[:alpha:]]+).*"$@\1@p' /etc/os-release`
    OS_RELEASE_VERSION=`sed -rn '/^VERSION_ID=/s@.*="?([0-9]+).?.*"?@\1@p' /etc/os-release`
}

check_file (){
    cd ${SRC_DIR}
    if [ ! -e ${DOCKER_COMPOSE_FILE} ];then
        ${COLOR}"缺少${DOCKER_COMPOSE_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}
        exit
    elif [ ! -e ${HARBOR_FILE}${HARBOR_VERSION}${TAR} ];then
        ${COLOR}"缺少${HARBOR_FILE}${HARBOR_VERSION}${TAR}文件,请把文件放到${SRC_DIR}目录下"${END}
        exit
    else
        ${COLOR}"相关文件已准备好"${END}
    fi
}

ubuntu_install_docker(){
    ${COLOR}"开始安装Docker依赖包,请稍等..."${END}
    apt update &> /dev/null
    apt -y install apt-transport-https ca-certificates curl software-properties-common &> /dev/null
    curl -fsSL https://${URL}/docker-ce/linux/ubuntu/gpg | sudo apt-key add - &> /dev/null
    add-apt-repository -y "deb [arch=amd64] https://${URL}/docker-ce/linux/ubuntu  $(lsb_release -cs) stable" &> /dev/null 
    apt update &> /dev/null

    ${COLOR}"Docker有以下版本"${END}
    apt-cache madison docker-ce
    ${COLOR}"10秒后即将安装:Docker-"${DOCKER_VERSION}"版本......"${END}
    ${COLOR}"如果想安装其它Docker版本,请按Ctrl+c键退出,修改版本再执行"${END}
    sleep 10

    ${COLOR}"开始安装Docker,请稍等..."${END}
    if [ ${DOCKER_MAIN_VERSION} == "18" -o ${DOCKER_MAIN_VERSION} == "19" -o ${DOCKER_MAIN_VERSION} == "20" ];then
        apt -y install docker-ce=5:${DOCKER_VERSION}~3-0~ubuntu-$(lsb_release -cs) docker-ce-cli=5:${DOCKER_VERSION}~3-0~ubuntu-$(lsb_release -cs) &> /dev/null || { ${COLOR}"apt源失败,请检查apt配置"${END};exit; }
    else
        apt -y install docker-ce=5:${DOCKER_VERSION}-1~ubuntu.$(lsb_release -rs)~$(lsb_release -cs) docker-ce-cli=5:${DOCKER_VERSION}-1~ubuntu.$(lsb_release -rs)~$(lsb_release -cs) &> /dev/null || { ${COLOR}"apt源失败,请检查apt配置"${END};exit; }
    fi
}

centos_install_docker(){
    ${COLOR}"开始安装Docker依赖包,请稍等..."${END}
    yum -y install yum-utils &> /dev/null
    yum-config-manager --add-repo https://${URL}/docker-ce/linux/centos/docker-ce.repo &> /dev/null
    yum clean all &> /dev/null
	yum makecache &> /dev/null

    ${COLOR}"Docker有以下版本"${END}
    yum list docker-ce.x86_64 --showduplicates
    ${COLOR}"10秒后即将安装:Docker-"${DOCKER_VERSION}"版本......"${END}
    ${COLOR}"如果想安装其它Docker版本,请按Ctrl+c键退出,修改版本再执行"${END}
    sleep 10

    ${COLOR}"开始安装Docker,请稍等..."${END}
    yum -y install docker-ce-${DOCKER_VERSION} docker-ce-cli-${DOCKER_VERSION} &> /dev/null || { ${COLOR}"yum源失败,请检查yum配置"${END};exit; }
}

mirror_accelerator(){
    mkdir -p /etc/docker
    cat > /etc/docker/daemon.json <<-EOF
{
    "registry-mirrors": [
        "https://registry.docker-cn.com",
        "https://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn"
    ],
    "data-root": "/data/docker",
    "exec-opts": ["native.cgroupdriver=systemd"],
    "max-concurrent-downloads": 10,
    "max-concurrent-uploads": 5,
    "log-opts": {
        "max-size": "300m",
        "max-file": "2"  
    },
    "live-restore": true
}
EOF
    systemctl daemon-reload
    systemctl enable --now docker
    systemctl is-active docker &> /dev/null && ${COLOR}"Docker 服务启动成功"${END} || { ${COLOR}"Docker 启动失败"${END};exit; }
    docker version &&  ${COLOR}"Docker 安装成功"${END} || ${COLOR}"Docker 安装失败"${END}
}

set_alias(){
    echo 'alias rmi="docker images -qa|xargs docker rmi -f"' >> ~/.bashrc
    echo 'alias rmc="docker ps -qa|xargs docker rm -f"' >> ~/.bashrc
}

install_docker_compose(){
    ${COLOR}"开始安装Docker Compose,请稍等..."${END}
    mv ${SRC_DIR}/${DOCKER_COMPOSE_FILE} /usr/bin/docker-compose
    chmod +x /usr/bin/docker-compose
    docker-compose --version &&  ${COLOR}"Docker Compose 安装完成"${END} || ${COLOR}"Docker compose 安装失败"${END}
}

install_harbor(){
    ${COLOR}"开始安装Harbor,请稍等..."${END}
    [ -d ${HARBOR_INSTALL_DIR} ] || mkdir ${HARBOR_INSTALL_DIR}
    tar xf ${SRC_DIR}/${HARBOR_FILE}${HARBOR_VERSION}${TAR} -C ${HARBOR_INSTALL_DIR}/

    # 生成私钥和证书
	touch /root/.rnd
    mkdir /apps/harbor/certs/
    cd /apps/harbor/certs/
    openssl genrsa -out ca.key 4096
    openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=ca.${DOMAIN}" -key ca.key -out ca.crt
    openssl genrsa -out harbor.${DOMAIN}.key 4096
    openssl req -sha512 -new -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.${DOMAIN}" -key harbor.${DOMAIN}.key -out harbor.${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=${DOMAIN}
DNS.2=ca.${DOMAIN}
DNS.3=harbor.${DOMAIN}
EOF
    openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in harbor.${DOMAIN}.csr -out harbor.${DOMAIN}.crt
    openssl x509 -inform PEM -in harbor.${DOMAIN}.crt -out harbor.${DOMAIN}.cert

    mv ${HARBOR_INSTALL_DIR}/harbor/harbor.yml.tmpl ${HARBOR_INSTALL_DIR}/harbor/harbor.yml
    sed -ri.bak -e 's/^(hostname:) .*/\1 harbor.'''${DOMAIN}'''/' -e 's@  (certificate:) .*@  \1 '''${HARBOR_INSTALL_DIR}'''/harbor/certs/harbor.'''${DOMAIN}'''.crt@' -e 's@  (private_key:) .*@  \1 '''${HARBOR_INSTALL_DIR}'''/harbor/certs/harbor.'''${DOMAIN}'''.key@' -e 's/^(harbor_admin_password:) .*/\1 '''${HARBOR_ADMIN_PASSWORD}'''/' ${HARBOR_INSTALL_DIR}/harbor/harbor.yml
    if [ ${OS_ID} == "CentOS" -o ${OS_ID} == "Rocky" ] &> /dev/null;then
        rpm -q python3 &> /dev/null || { ${COLOR}"安装python3,请稍等..."${END};yum -y install python3 &> /dev/null; }
    else
        dpkg -s python3 &>/dev/null || { ${COLOR}"安装python3,请稍等..."${END};apt -y install python3 &> /dev/null; }
    fi
    ${HARBOR_INSTALL_DIR}/harbor/install.sh --with-trivy && ${COLOR}"Harbor 安装完成"${END} ||  ${COLOR}"Harbor 安装失败"${END}
    cat > /lib/systemd/system/harbor.service <<-EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f ${HARBOR_INSTALL_DIR}/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f ${HARBOR_INSTALL_DIR}/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload 
    systemctl enable harbor &>/dev/null && ${COLOR}"Harbor已配置为开机自动启动"${END}
}

set_swap_limit(){
    if [ ${OS_RELEASE_VERSION} == "18" -o ${OS_RELEASE_VERSION} == "20" ];then
        grep -q "swapaccount=1" /etc/default/grub && { ${COLOR}'"WARNING: No swap limit support"警告,已设置'${END};exit; }
        ${COLOR}'设置Docker的"WARNING: No swap limit support"警告'${END}
        sed -ri '/^GRUB_CMDLINE_LINUX=/s@"$@ swapaccount=1"@' /etc/default/grub
        update-grub &> /dev/null
        ${COLOR}"10秒后,机器会自动重启"${END}
        sleep 10
        reboot
    fi
}

main(){
    os
    check_file
    if [ ${OS_ID} == "CentOS" -o ${OS_ID} == "Rocky" ] &> /dev/null;then
        rpm -q docker-ce &> /dev/null && ${COLOR}"Docker已安装"${END} || centos_install_docker
    else
        dpkg -s docker-ce &>/dev/null && ${COLOR}"Docker已安装"${END} || ubuntu_install_docker
    fi
    [ -f /etc/docker/daemon.json ] &>/dev/null && ${COLOR}"Docker镜像加速器已设置"${END} || mirror_accelerator
    grep -Eqoi "(.*rmi=|.*rmc=)" ~/.bashrc && ${COLOR}"Docker别名已设置"${END} || set_alias
    [ -f /usr/bin/docker-compose ] && ${COLOR}"Docker Compose已安装"${END} || install_docker_compose
    systemctl is-active harbor &> /dev/null && ${COLOR}"Harbor已安装"${END} || install_harbor
    set_swap_limit
}

main