Harbor共享存储高可用 主机拓扑
角色
主机名
ip
系统
资源最低要求
Harbor1 nginx Keepalived1
harbor1
192.168.48.106
OpenEuler22.03LTS
CPU:4核 内存:8G 硬盘:40G
Harbor2 nginx Keepalived2
harbor2
192.168.48.107
OpenEuler22.03LTS
CPU:4核 内存:8G 硬盘:40G
postgresql Redis NFS共享
zujian
192.168.48.108
OpenEuler22.03LTS
CPU:4核 内存:8G 硬盘:40G
高可用ip
192.168.48.100
系统架构图
基本配置 操作节点:[harbor1,harbour2,zujian]
将以下脚本内容添加进去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 if [ $# -eq 2 ];then echo "设置主机名为:$1 " echo "ens160设置IP地址为:192.168.48.$2 " else echo "使用方法:sh $0 主机名 主机位" exit 2 fi echo "--------------------------------------" echo "1.正在设置主机名:$1 " hostnamectl set-hostname $1 echo "2.正在关闭firewalld、dnsmasq、selinux" systemctl disable firewalld &> /dev/null systemctl disable dnsmasq &> /dev/null systemctl stop firewalld systemctl stop dnsmasq sed -i "s#SELINUX=enforcing#SELINUX=disabled#g" /etc/selinux/config setenforce 0 echo "3.正在设置ens160:192.168.48.$2 " cat > /etc/sysconfig/network-scripts/ifcfg-ens160 <<EOFTYPE =EthernetPROXY_METHOD =noneBROWSER_ONLY =no BOOTPROTO =staticDEFROUTE =yes IPV4_FAILURE_FATAL =no IPV6INIT =yes IPV6_AUTOCONF =yes IPV6_DEFROUTE =yes IPV6_FAILURE_FATAL =no NAME =ens160UUID =53b402ff-5865-47dd-a853-7afcd6521738DEVICE =ens160ONBOOT =yes IPADDR =192.168.48.$2GATEWAY =192.168.48.2PREFIX =24DNS1 =192.168.48.2DNS2 =114.114.114.114 nmcli c reload nmcli c up ens 160 echo "4.优化ssh" sed -i "s#\#UseDNS yes#UseDNS no#g" /etc/ssh/sshd_config sed -i "s#GSSAPIAuthentication yes#GSSAPIAuthentication no#g" /etc/ssh/sshd_config systemctl restart sshd echo "5.更改欧拉源为华为云源,速度快一点" sed -i 's/\$basearch/x86_64/g' /etc/yum.repos.d/openEuler.repo sed -i 's/repo.openeuler.org/mirrors.huaweicloud.com\/openeuler/g' /etc/yum.repos.d/openEuler.repo echo "6.更新yum源软件包缓存" yum clean all && yum makecache dnf update -y echo "7.修改history格式及记录数" sed -i "s#HISTSIZE=1000##g" /etc/profile cat >> /etc/profile <<EOF shopt -s histappendUSER_IP =`who -u am i 2>/dev/null | awk '{print $NF}' |sed -e 's/[()]//g' `export HISTFILE =~/.commandline_warriorexport HISTTIMEFORMAT ="%Y-%m-%d %H:%M:%S `whoami`@${USER_IP} : " export HISTSIZE =200000export HISTFILESIZE =1000000export PROMPT_COMMAND ="history -a" EOF source /etc/profile echo "8.添加hosts解析" cat > /etc/hosts <<EOF 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.48.106 harbor1 192.168.48.107 harbor2 192.168.48.108 zujian EOF echo "10.安装chrony服务,并同步时间" dnf install chrony -y systemctl start chronyd systemctl enable chronyd chronyc sources chronyc sources echo "11、安装依赖包" dnf install -y cmake gcc gcc-c++ perl readline readline-devel openssl openssl-devel zlib zlib-devel ncurses-devel readline readline-devel zlib zlib-devel reboot
1 2 3 4 5 6 7 执行脚本命令格式:sh jichu_init.sh 主机名 主机位 [harbor1] sh jichu_init.sh harbor1 106 [harbor2] sh jichu_init.sh harbor2 107 [zujian] sh jichu_init.sh zujian 108
配置ssh免密
操作节点:[harbor1,harbour2,zujian]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 dnf install -y sshpass cat > sshmianmi.sh << "EOF" hosts=("harbor1" "harbor2" "zujian" ) password="Lj201840." ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsafor host in "${hosts[@]} " do sshpass -p "$password " ssh-copy-id -o StrictHostKeyChecking=no "$host " sshpass -p "$password " ssh -o StrictHostKeyChecking=no "$host " "echo '免密登录成功'" done EOF sh sshmianmi.sh
安装高可用组件 操作节点:[harbor1,harbour2]
1 dnf install -y keepalived nginx
安装nginx 操作节点:[harbor1,harbour2]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 cat > /etc/nginx/nginx.conf <<"EOF" user nginx;worker_processes auto;error_log /var/log/nginx/error .log notice ;pid /run/nginx.pid;include /usr/share/nginx/modules/*.conf ;events { worker_connections 1024 ; }stream { log_format main '$remote_addr $upstream_addr - [$time_local ] $status $upstream_bytes_sent ' ; access_log /var/log/nginx/harbor-access.log main; upstream harbor{ server 192.168.48.106:8081 ; server 192.168.48.107:8081 ; } server { listen 80 ; proxy_pass harbor; } }http { log_format main '$remote_addr - $remote_user [$time_local ] "$request " ' '$status $body_bytes_sent "$http_referer " ' '"$http_user_agent " "$http_x_forwarded_for "' ; access_log /var/log/nginx/access.log main; sendfile on ; tcp_nopush on ; keepalive_timeout 65 ; types_hash_max_size 4096 ; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/conf.d/*.conf ; server { listen 8888 default_server; server_name _; location / { } } }EOF systemctl enable --now nginx nginx -s reload
安装安装keepalived 操作节点:[harbor1]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 cat >/ etc/ keepalived/ keepalived.conf << "EOF" ! Configuration File for keepalivedglobal_defs { notification_email { qianyios@ qq.com } router_id harbor1 } vrrp_instance zh { state MASTER interface ens160 mcast_src_ip 192.168 .48 .106 virtual_router_id 107 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168 .48 .100 / 24 } track_script { chk_nginx } } vrrp_script chk_nginx { script "/etc/keepalived/check_nginx.sh" interval 2 weight -20 } EOF
操作节点:[harbor2]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 cat >/ etc/ keepalived/ keepalived.conf << "EOF" ! Configuration File for keepalivedglobal_defs { notification_email { qianyios@ qq.com } router_id harbor2 } vrrp_instance zh { state BACKUP interface ens160 mcast_src_ip 192.168 .48 .107 virtual_router_id 107 priority 99 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168 .48 .100 / 24 } track_script { chk_nginx } } vrrp_script chk_nginx { script "/etc/keepalived/check_nginx.sh" interval 2 weight -20 } EOF
配置检查脚本
操作节点:[harbor1,harbour2]
1 2 3 4 5 6 7 8 9 10 11 12 13 cat >/etc/keepalived/check_nginx.sh <<"EOF" counter=`ps -C nginx --no-header | wc -l`if [ $counter -eq 0 ]; then systemctl start nginx sleep 2 counter=`ps -C nginx --no-header | wc -l` if [ $counter -eq 0 ]; then systemctl stop keepalived fi fi EOF
启动服务
1 2 systemctl enable --now nginx keepalived nginx -s reload
查看VIP虚拟ip
1 2 3 4 5 6 7 8 9 10 11 [root@harbor1 ~] .............2 : ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00 :0 c:29 :af:76 :8 c brd ff:ff:ff:ff:ff:ff inet 192.168 .48.106 /24 brd 192.168 .48.255 scope global noprefixroute ens160 valid_lft forever preferred_lft forever inet 192.168 .48.100 /24 scope global secondary ens160 valid_lft forever preferred_lft forever inet6 fe80::20 c:29 ff:feaf:768 c/64 scope link noprefixroute valid_lft forever preferred_lft forever
安装postgresql 操作节点:[zujian]
安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 useradd postgres passwd postgres wget https:// ftp.postgresql.org/pub/ source/v16.2/ postgresql-16.2 .tar.gz tar zxvf postgresql-16.2 .tar.gz -C /usr/ local/bin/ cd /usr/ local/bin/ postgresql-16.2 / ./configure --prefix=/u sr/local/ postgresql make && make install mkdir -p /data/ postgresql/data mkdir -p /data/ postgresql/log mkdir -p /data/ postgresql/tmp chown -R postgres:postgres /usr/ local/postgresql/ chown -R postgres:postgres /data/ postgresql su - postgres cd cat << "EOF" >> ~/.bash_profile PGHOME=/usr/ local/postgresql export PGHOME PGDATA=/data/ postgresql/data export PGDATA PATH=$PATH :$HOME /bin:$HOME/ .local/bin:$PGHOME/ bin export PATH EOF source ~/.bash_profile psql -V initdb --username=postgres -D /data/ postgresql/data cat > /data/ postgresql/data/ postgresql.conf << "EOF" max_connections = 100 shared_buffers = 128 MB dynamic_shared_memory_type = posix max_wal_size = 1 GB min_wal_size = 80 MB log_timezone = 'Asia/Shanghai' datestyle = 'iso, mdy' timezone = 'Asia/Shanghai' lc_messages = 'en_US.UTF-8' lc_monetary = 'en_US.UTF-8' lc_numeric = 'en_US.UTF-8' lc_time = 'en_US.UTF-8' default_text_search_config = 'pg_catalog.english' listen_addresses = '*' data_directory = '/data/postgresql/data' port = 5432 unix_socket_directories = '/data/postgresql/tmp' unix_socket_group = '' unix_socket_permissions = 0777 logging_collector = on log_directory = '/data/postgresql/log' log_rotation_size = 1 GB log_timezone = 'Asia/Shanghai' log_min_duration_statement = 100 EOF cat >> /data/ postgresql/data/ pg_hba.conf << EOF local all all trust host all all 0.0 .0.0 /0 password host all all ::1 /128 password host all postgres 0.0 .0.0 /0 trust EOF pg_ctl -D /data/ postgresql/data -l logfile start
进入数据库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 psql -h 127.0 .0.1 -p 5432 -U postgres postgres= Enter new password for user "postgres" : Enter it again: postgres= pg_ctl -D /data/ postgresql/data -l / data/postgresql/ data/postgresql.log restart pg_ctl: old server process (PID: 25461 ) seems to be gone starting server anyway waiting for server to start.... done server started psql -h 127.0 .0.1 -p 5432 -U postgres CREATE DATABASE registry; CREATE DATABASE notary_signer; CREATE DATABASE notary_servers; \l create user server with password '123456' ; create user signer with password '123456' ; \du GRANT ALL PRIVILEGES ON DATABASE registry to postgres; GRANT ALL PRIVILEGES ON DATABASE notary_signer to postgres; GRANT ALL PRIVILEGES ON DATABASE notary_servers to postgres; exit
设置启动服务 操作节点[zujian]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #回到root用户下执行 su - root cat >/etc/i nit.d/PG-start.sh<< "EOF" sudo -u postgres /usr/ local/postgresql/ bin/pg_ctl -D / data/postgresql/ data start EOF cat >/etc/i nit.d/PG-stop.sh<< "EOF" sudo -u postgres /usr/ local/postgresql/ bin/pg_ctl -D / data/postgresql/ data stop EOF cat >/etc/i nit.d/PG-restart.sh<<"EOF" sudo -u postgres /usr/ local/postgresql/ bin/pg_ctl -D / data/postgresql/ data restart EOF sudo chmod +x /etc/i nit.d/PG-start.sh sudo chmod +x /etc/i nit.d/PG-stop.sh sudo chmod +x /etc/i nit.d/PG-restart.sh cat >/etc/ systemd/system/ postgresql.service << "EOF" [Unit]Description =postgresql Service [Service] Type=oneshot user=root RemainAfterExit=true ExecStart=/usr/ bin/sudo / etc/init.d/ PG-start.sh ExecStop=/usr/ bin/sudo / etc/init.d/ PG-stop.sh ExecRestart=/usr/ bin/sudo / etc/init.d/ PG-restart.sh [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now postgresql
错误积累
1 2 3 4 5 6 7 8 #每次我启动pgsql的时候就有这个东西2024 -09 -14 14 :34 :03.196 CST [17746 ] HINT: Is another postmaster (PID 16042 ) running in data directory "/data/postgresql/data"? stopped waiting pg_ctl: could not start server #意思是有个pid进程在运行,杀掉它就行了 sudo kill -9 16042
安装redis 操作节点:[zujian]
安装redis 1 2 3 4 5 wget https://download.redis.io/releases/redis-7 .2 .4 .tar.gztar zxvf redis-7 .2 .4 .tar.gz mv redis-7 .2 .4 /usr/local/bin/cd /usr/local/bin/redis-7 .2 .4 make && make install
修改配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 vi /usr/ local/bin/ redis-7.2 .4 /redis.conf daemonize yes requirepass 123456 protected-mode no 以下是一步到位将以上四个命令全部实现 sed -i 's/^bind 127.0.0.1 -::1/#bind 127.0.0.1 -::1/' /usr/ local/bin/ redis-7.2 .4 /redis.conf sed -i 's/^daemonize no/daemonize yes/' /usr/ local/bin/ redis-7.2 .4 /redis.conf echo -e "\nrequirepass 123456" >> /usr/ local/bin/ redis-7.2 .4 /redis.conf sed -i 's/^protected-mode yes/protected-mode no/' /usr/ local/bin/ redis-7.2 .4 /redis.conf
启动服务
1 2 [root@zujian redis-7.2 .4 ]2226 :C 20 Apr 2024 17 : 10 : 45.039
Redis在启动时可能会出现这样的日志:在分析这个问题之前, 首先要弄清楚什么是overcommit? Linux操作系统对大部分申请内存的请求都回复yes
, 以便能运行更多的程序
。 因为申请内存后, 并不会马上使用内存, 这种技术叫做overcommit
。如果Redis在启动时有上面的日志, 说明vm.overcommit_memory=0, Redis提示把它设置为1。 vm.overcommit_memory用来设置内存分配策略, 有三个可选值, 如表:可用内存代表物理内存与swap之和
解决办法:
1 2 3 echo "vm.overcommit_memory=1" >> /etc/sysctl.conf sysctl vm .overcommit_memory=1 redis-server redis.conf
再重新启动就可以查看版本和端口号了
1 2 3 4 5 6 [root@zujian redis-7.2.4]# redis-cli -v redis-cli 7.2.4 [root@zujian redis-7.2.4]# ps aux |grep 6379 root 2227 0.0 0.3 68412 10888 ? Ssl 17:10 0:00 redis-server *:6379 root 5427 0.0 0.0 22096 2300 pts/0 S+ 17:19 0:00 grep --color=auto 6379# redis-server有这个就行
关闭服务(只是普及知识,测试可用,不要随意关闭)
客户端连接redis 操作节点:[zujian]
将redis-cli的工具复制到Harbor1,harbor2
查看redis-cli工具位置
1 2 [root@zujian]/usr/ local/bin/ redis-cli
复制
1 2 3 which redis-cli scp /usr/ local/bin/ redis-cli harbor1:/usr/ local/bin/ scp /usr/ local/bin/ redis-cli harbor2:/usr/ local/bin/
操作节点:[harbor1,harbor2]
1 redis -cli -h 192.168.48.108 -p 6379 -a 123456
到此redis安装成功
设置启动服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 cat >/etc/i nit.d/redis-start.sh<< "EOF" /usr/ local/bin/ redis-server /usr/ local/bin/ redis-7.2 .4 /redis.conf EOF cat >/etc/i nit.d/redis-stop.sh<< "EOF" /usr/ local/bin/ redis-cli -a 123456 shutdown EOF sudo chmod +x /etc/i nit.d/redis-start.sh sudo chmod +x /etc/i nit.d/redis-stop.sh cat >/etc/ systemd/system/ redis.service << "EOF" [Unit]Description =redis Service [Service] Type=oneshot user=root RemainAfterExit=true ExecStart=/usr/ bin/sudo / etc/init.d/ redis-start.sh ExecStop=/usr/ bin/sudo / etc/init.d/ redis-stop.sh [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now redis
NFS共享存储安装 操作节点:[zujian]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 dnf install -y nfs-utils systemctl enable --now nfs mkdir -p /data/ harbor_data cat >> /etc/ exports << "EOF" /data/ harbor_data 192.168 .48.0 /24 (rw,no_root_squash) EOF exportfs -arv [root@zujian ~] Export list for zujian:/data/ harbor_data 192.168 .48.0 /24
操作节点:[harbor1,harbor2]
Harbor1、harbor2机器上安装nfs-utils客户端并挂载共享存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dnf install -y nfs-utils systemctl enable --now nfs mkdir -p /data/ harbor_data cat >>/etc/ fstab<<"EOF" 192.168 .48.108 :/data/ harbor_data /data/ harbor_data nfs defaults 0 0 EOF mount -a df -h | grep harbor [root@harbor1 ~]192.168 .48.108 :/data/ harbor_data 63 G 3.0 G 57 G 6 % /data/ harbor_data [root@harbor2 ~]192.168 .48.108 :/data/ harbor_data 63 G 3.0 G 57 G 6 % /data/ harbor_data
harbor仓库安装 操作节点:[harbor1,harbor2]
安装docker 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 wget https:// download.docker.com/linux/ static/stable/ x86_64/docker-26.0 .1 .tgz tar xf docker-*.tgz cp docker/* /u sr/bin/ cat >/etc/ systemd/system/ containerd.service <<EOF [Unit] Description=containerd container runtime Documentation=https:// containerd.io After=network.target local-fs.target [Service] ExecStartPre=-/sbin/m odprobe overlay ExecStart=/usr/ bin/containerd Type=notify Delegate=yes KillMode=process Restart=always RestartSec=5 LimitNPROC=infinity LimitCORE=infinity LimitNOFILE=1048576 TasksMax=infinity OOMScoreAdjust=-999 [Install] WantedBy=multi-user.target EOF systemctl enable --now containerd.service cat > /etc/ systemd/system/ docker.service <<EOF [Unit] Description=Docker Application Container Engine Documentation=https:// docs.docker.com After=network-online.target firewalld.service containerd.service Wants=network-online.target Requires=docker.socket containerd.service [Service] Type=notify ExecStart=/usr/ bin/dockerd -H fd:/ / --containerd=/ run/containerd/ containerd.sock ExecReload=/bin/ kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always StartLimitBurst=3 StartLimitInterval=60 s LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TasksMax=infinity Delegate=yes KillMode=process OOMScoreAdjust=-500 [Install] WantedBy=multi-user.target EOF cat > /etc/ systemd/system/ docker.socket <<EOF [Unit] Description=Docker Socket for the API [Socket] ListenStream=/var/ run/docker.sock SocketMode=0660 SocketUser=root SocketGroup=docker [Install] WantedBy=sockets.target EOF groupadd docker systemctl enable --now docker.socket && systemctl enable --now docker.service mkdir /etc/ docker cat >/etc/ docker/daemon.json <<EOF { "exec-opts" : ["native.cgroupdriver=systemd" ], "registry-mirrors" : [ "https://docker.mirrors.ustc.edu.cn" , "http://hub-mirror.c.163.com" , "https://pw860av8.mirror.aliyuncs.com" ], "max-concurrent-downloads" : 10 , "log-driver" : "json-file" , "log-level" : "warn" , "log-opts" : { "max-size" : "500m" , "max-file" : "3" }, "data-root" : "/var/lib/docker" } EOF systemctl restart docker docker -v
安装docker-compose 操作节点:[harbor1,harbor2]
1 2 3 4 wget https://gi thub.com/docker/ compose/releases/ download/v2.26.1/ docker-compose-linux-x86_64 mv docker-compose-linux-x86_64 /usr/ local/bin/ docker-compose chmod +x /usr/ local/bin/ docker-compose docker-compose version
配置内核参数并使之生效 操作节点:[harbor1,harbor2]
1 2 3 4 5 6 7 modprobe br_netfilter cat >> /etc/sysctl.conf <<EOF net.bridge .bridge-nf-call-ip6tables = 1 net.bridge .bridge-nf-call-iptables = 1 net.ipv4 .ip_forward = 1 #路由转发 EOF sysctl -p
下载harbor包并配置文件 操作节点:[harbor1,harbor2]
下载离线包offline字样
1 2 3 4 5 6 7 8 9 wget https://gi thub.com/goharbor/ harbor/releases/ download/v2.9.4/ harbor-offline-installer-v2.9.4 .tgz tar zxvf harbor-offline-installer-v2.9.4 .tgz mv harbor /var/ cd /var/ harbor/ [root@harbor1 harbor] common.sh harbor.v2.9.4 .tar.gz harbor.yml.tmpl install.sh LICENSE prepare cp harbor.yml.tmpl harbor.yml
配置harbor文件
操作节点:[harbor1]
1 vi /var/ harbor/harbor.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 hostname: 192.168 .48 .106 http: port: 8081 external_url: https://192.168.48.100 harbor_admin_password: Harbor12345 data_volume: /data/harbor_data _version: 2.9 .0 external_database: harbor: host: 192.168 .48 .108 port: 5432 db_name: registry username: postgres password: 123456 ssl_mode: disable max_idle_conns: 50 max_open_conns: 100 notary_server: host: 192.168 .48 .108 port: 5432 db_name: notary_server username: postgres password: 123456 ssl_mode: disable notary_signer: host: 192.168 .48 .108 port: 5432 db_name: notary_signer username: postgres password: 123456 ssl_mode: disable external_redis: host: 192.168 .48 .108 :6379 password: 123456 registry_db_index: 1 jobservice_db_index: 2 chartmuseum_db_index: 3 trivy_db_index: 5 idle_timeout_seconds: 30 metric: enabled: false port: 9090 path: /metrics trivy: ignore_unfixed: false skip_update: false skip_java_db_update: false offline_scan: false security_check: vuln insecure: false jobservice: max_job_workers: 10 job_loggers: - STD_OUTPUT - FILE logger_sweeper_duration: 1 notification: webhook_job_max_retry: 3 webhook_job_http_client_timeout: 3 log: level: info local: rotate_count: 50 rotate_size: 200M location: /var/log/harbor proxy: http_proxy: https_proxy: no_proxy: components: - core - jobservice - trivy upload_purging: enabled: true age: 168h interval: 24h dryrun: false cache: enabled: false expire_hours: 24
操作节点:[harbor2]
1 vi /var/ harbor/harbor.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 hostname: 192.168 .48 .107 http: port: 8081 external_url: https://192.168.48.100 harbor_admin_password: Harbor12345 data_volume: /data/harbor_data _version: 2.9 .0 external_database: harbor: host: 192.168 .48 .108 port: 5432 db_name: registry username: postgres password: 123456 ssl_mode: disable max_idle_conns: 2 max_open_conns: 0 notary_server: host: 192.168 .48 .108 port: 5432 db_name: notary_server username: postgres password: 123456 ssl_mode: disable notary_signer: host: 192.168 .48 .108 port: 5432 db_name: notary_signer username: postgres password: 123456 ssl_mode: disable external_redis: host: 192.168 .48 .108 :6379 password: 123456 registry_db_index: 1 jobservice_db_index: 2 chartmuseum_db_index: 3 trivy_db_index: 5 idle_timeout_seconds: 30 metric: enabled: false port: 9090 path: /metrics trivy: ignore_unfixed: false skip_update: false skip_java_db_update: false offline_scan: false security_check: vuln insecure: false jobservice: max_job_workers: 10 job_loggers: - STD_OUTPUT - FILE logger_sweeper_duration: 1 notification: webhook_job_max_retry: 3 webhook_job_http_client_timeout: 3 log: level: info local: rotate_count: 50 rotate_size: 200M location: /var/log/harbor proxy: http_proxy: https_proxy: no_proxy: components: - core - jobservice - trivy upload_purging: enabled: true age: 168h interval: 24h dryrun: false cache: enabled: false expire_hours: 24
将配置文件注入到各级件中并安装 先提前下载镜像吧,这里用博主构建的镜像速度会快一点
1 2 docker pull registry.cn-hangzhou.aliyuncs.com/qianyios/prepare:v2.9 .4 docker tag registry.cn-hangzhou.aliyuncs.com/qianyios/prepare:v2.9 .4 goharbor/prepare:v2.9 .4
开始注入
1 2 cd /var/harbor/ ./prepare
开始安装
1 2 cd /var/harbor/ ./install.sh
配置自启动 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cat >/usr/lib/systemd/system/harbor.service << "EOF" [Unit]Description =HarborAfter =docker.service systemd-networkd.service systemd-resolved.service nfs-server.serviceRequires =docker.serviceDocumentation =http://github.com/vmware/harbor [Service]Type =simpleRestart =on-failureRestartSec =5ExecStart =/usr/local/bin/docker-compose -f /var/harbor/docker-compose.yml upExecStop =/usr/local/bin/docker-compose -f /var/harbor/docker-compose.yml down [Install]WantedBy =multi-user.target EOF systemctl daemon-reload systemctl enable harbor --now
大坑来了,之前找了两个星期都没解决的
到此,harbor安装完成,但是你在网页可能会出现不能用admin登入,会显示密码错误
你需要进行下一步安装证书
原因:首先pg数据库在安装harbor时创建的admin是用sha256协议加密的
而在我们harbor页面,我们并没有配置ssl证书,是http方式访问并没有sha256加密协议,意味着harbor再登入的时候,会出现密码错误,就是:网页登入验证===/===
pg数据库验证,配置openssl证书,可以解决此问题,openssl包含sha256协议,这样就可以登入了。
OpenSSL是一个强大的加密库
,广泛应用于互联网的各个角落,用于保护数据传输的安全。它实现了SSL和TLS协议,这些协议是现代网络安全的基石。
配置ssl证书 操作节点:[harbor1,harbor2]
生成ca证书 创建一个放置证书相关的目录,并使用cd进入该目录
1 2 3 4 5 6 7 8 mkdir /var /harbor/cert&& cd /var /harbor/cert ## 1. 生成CA 证书私钥 openssl genrsa -out ca .key 4096 ## 2. 生成CA 证书,可调整 -subj 选项来表明域名名称等信息 openssl req -x509 -new -nodes -sha512 -days 3650 \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=192.168.48.100" \ -key ca .key \ -out ca .crt
生成服务器证书 认证证书通常包含证书请求.csr
文件、签名证书.crt
文件及私钥.key
文件,我这里harbor配置的hostname是192.168.48.100,所以最终需要生成192.168.48.100.crt、192.168.48.100.csr、192.168.48.100.key
三个文件。
key:证书私钥,一般利用rsa等算法生成
csr:证书请求文件,利用证书私钥生成证书请求文件,该文件包含了服务器和地址等信息,申请人将该文件提交给CA机构,CA机构会根据该文件所携带的私钥信息来进行签名生成证书
crt:证书文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 openssl genrsa -out 192 .168 .48 .100 .key 4096 openssl req -sha512 -new \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=192.168.48.100" \ -key 192 .168 .48 .100 .key \ -out 192 .168 .48 .100 .csr cat > v3.ext <<-EOF authorityKeyIdentifier=keyid,issuerbasicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEnciphermentextendedKeyUsage = serverAuthsubjectAltName = @alt_names [alt_names] DNS.1 =192 .168 .48 .100 DNS.2 =127 .0 .0 .1 IP.1 =192 .168 .48 .100 EOF openssl x509 -req -sha512 -days 3650 \ -extfile v3.ext \ -CA ca.crt -CAkey ca.key -CAcreateserial \ -in 192 .168 .48 .100 .csr \ -out 192 .168 .48 .100 .crt
修改harbor配置文件 1 2 3 4 5 6 cat >> /var/harbor/harbor.yml << "EOF" https: port: 443 certificate: /var/harbor/cert/192.168.48.100.crt private_key: /var/harbor/cert/192.168.48.100.key EOF
重新启动
1 2 3 4 cd /var/harbor docker-compose down -v ./prepare docker-compose up -d
镜像上传及拉取测试 操作节点:[harbor1,harbor2,zujian,qianyios(测试客户端)]
找一台客户端装好docker
进行测试
1 2 [root@qianyios ~] Docker version 26.0 .1 , build d260a54
新建私有镜像仓库
客户端免https登陆 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [root@xxxx harbor] 可能会出现以下情况 [root@harbor1 ~] Username: admin Password: Error response from daemon: Get "https://192.168.48.100/v2/" : tls: failed to verify certificate: x509: certificate signed by unknown authority [root@qianyios ~] Username: admin Password: Error response from daemon: Get "https://192.168.48.106:8081/v2/" : http: server gave HTTP response to HTTPS client [root@qianyios ~] [root@qianyios ~] { ................ "registry-mirrors" : [], "insecure-registries" : [ "192.168.48.100" ], ................ } systemctl daemon-reload systemctl restart docker [root@qianyios ~] Containers: 10 Running: 1 Paused: 0 Stopped: 9 Images: 37 ... Experimental: false Insecure Registries: 192.168.48.100 127.0.0.0/8 Registry Mirrors:
进行登入测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 docker login 192.168.48.100 [root@harbor1 ~] 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/ Login Succeeded [root@qianyios ~] 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/ Login Succeeded
上传镜像测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@qianyios ~] Using default tag: latest latest: Pulling from library/nginx a2abf6c4d29d: Pull complete a9edb18cadd1: Pull complete 589b7251471a: Pull complete 186b1aaa4aa6: Pull complete b4df32aa5a72: Pull complete a0bcbecc962e: Pull complete Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest
我们进入当刚刚创建的仓库,点推送指令
1 2 3 docker tag SOURCE_IMAGE [:TAG ] 192.168 .48.100 /qianyios/REPOSITORY[:TAG ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [root@qianyios ~ ]REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 605c77e624dd 2 years ago 141MB [root@qianyios ~ ] [root@qianyios ~ ]REPOSITORY TAG IMAGE ID CREATED SIZE 192.168 .48 .100 /qianyios/nginx V1 605c77e624dd 2 years ago 141MB nginx latest 605c77e624dd 2 years ago 141MB [root@qianyios ~ ]The push refers to repository [192.168 .48 .100 /qianyios/nginx ]d874fd2bc83b: Pushed 32ce5f6a5106: Pushed f1db227348d0: Pushed b8d6e692a25e: Pushed e379e8aedd4d: Pushed 2edcec3590a4: Pushed V1: digest: sha256:ee89b00528ff4f02f2405e4ee221743ebc3f8e8dd0bfd5c4c20a2fa2aaa7ede3 size: 1570
我们去harbor1测试拉取镜像,会发现下载数变成了1
1 2 3 4 5 6 7 8 9 10 11 12 [root@harbor1 ~]V1: Pulling from qianyios/nginx a2abf6c4d29d: Pull complete a9edb18cadd1: Pull complete 589b7251471a: Pull complete 186b1aaa4aa6: Pull complete b4df32aa5a72: Pull complete a0bcbecc962e: Pull complete Digest: sha256:ee89b00528ff4f02f2405e4ee221743ebc3f8e8dd0bfd5c4c20a2fa2aaa7ede3 Status: Downloaded newer image for 192.168.48.100/qianyios/nginx:V1 192.168.48.100/qianyios/nginx:V1 [root@harbor1 ~]
千屹博客旗下的所有文章,是通过本人课堂学习和课外自学所精心整理的知识巨著 难免会有出错的地方 如果细心的你发现了小失误,可以在下方评论区告诉我,或者私信我! 非常感谢大家的热烈支持!