Docker之分布式仓库Harbor
安装Harbor 下载地址:https://github.com/vmware/harbor/releases
安装要求:4CPU MEM:8GB DISK:160GB
环境准备:
四台主机
两台主机harbor服务器,地址10.0.0.101|102
两台主机harbor客户端上传和下载镜像
一键安装docker、docker-compose、harbor脚本
#!/bin/bash
HARBOR_VERSION=2.6.1
#HARBOR_VERSION=2.6.0
HARBOR_BASE=/apps
HARBOR_NAME=harbor.meng.org
#HARBOR_NAME=`hostname -I|awk '{print $1}'`
DOCKER_VERSION="20.10.10"
#DOCKER_VERSION="19.03.14"
DOCKER_URL="http://mirrors.ustc.edu.cn"
#DOCKER_URL="https://mirrors.tuna.tsinghua.edu.cn"
DOCKER_COMPOSE_VERSION=2.6.1
#DOCKER_COMPOSE_VERSION=1.29.2
DOCKER_COMPOSE_FILE=docker-compose-Linux-x86_64
HARBOR_ADMIN_PASSWORD=123456
HARBOR_IP=`hostname -I|awk '{print $1}'`
COLOR_SUCCESS="echo -e \\033[1;32m"
COLOR_FAILURE="echo -e \\033[1;31m"
END="\033[m"
. /etc/os-release
UBUNTU_DOCKER_VERSION="5:${DOCKER_VERSION}~3-0~${ID}-${UBUNTU_CODENAME}"
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
install_docker(){
if [ $ID = "centos" -o $ID = "rocky" ];then
if [ $VERSION_ID = "7" ];then
cat > /etc/yum.repos.d/docker.repo <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
baseurl=${DOCKER_URL}/docker-ce/linux/centos/7/x86_64/stable/
EOF
else
cat > /etc/yum.repos.d/docker.repo <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/
baseurl=${DOCKER_URL}/docker-ce/linux/centos/8/x86_64/stable/
EOF
fi
yum clean all
${COLOR_FAILURE} "Docker有以下版本"${END}
yum list docker-ce --showduplicates
${COLOR_FAILURE}"5秒后即将安装: docker-"${DOCKER_VERSION}" 版本....."${END}
${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
sleep 5
yum -y install docker-ce-$DOCKER_VERSION docker-ce-cli-$DOCKER_VERSION \
|| { color "Base,Extras的yum源失败,请检查yum源配置" 1;exit; }
else
dpkg -s docker-ce &> /dev/null && $COLOR"Docker已安装,退出" 1 && exit
apt update || { color "更新包索引失败" 1 ; exit 1; }
apt -y install apt-transport-https ca-certificates curl software-properties-common || \
{ color "安装相关包失败" 1 ; exit 2; }
curl -fsSL ${DOCKER_URL}/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] ${DOCKER_URL}/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
apt update
${COLOR_FAILURE} "Docker有以下版本"${END}
apt-cache madison docker-ce
${COLOR_FAILURE}"5秒后即将安装: docker-"${UBUNTU_DOCKER_VERSION}" 版本....."${END}
${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
sleep 5
apt -y install docker-ce=${UBUNTU_DOCKER_VERSION} docker-ce-cli=${UBUNTU_DOCKER_VERSION}
fi
if [ $? -eq 0 ];then
color "安装软件包成功" 0
else
color "安装软件包失败,请检查网络配置" 1
exit
fi
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"],
"insecure-registries": ["harbor.wang.org"]
}
EOF
systemctl daemon-reload
systemctl enable docker
systemctl restart docker
docker version && color "Docker 安装成功" 0 || color "Docker 安装失败" 1
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(){
if [ $ID = "centos" -o $ID = "rocky" ];then
${COLOR_SUCCESS}"开始安装 Docker compose....."${END}
sleep 1
if [ ! -e ${DOCKER_COMPOSE_FILE} ];then
#curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/${DOCKER_COMPOSE_FILE} -o /usr/bin/docker-compose
curl -L https://get.daocloud.io/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose
else
mv ${DOCKER_COMPOSE_FILE} /usr/bin/docker-compose
fi
chmod +x /usr/bin/docker-compose
else
apt -y install docker-compose
fi
if docker-compose --version ;then
${COLOR_SUCCESS}"Docker Compose 安装完成"${END}
else
${COLOR_FAILURE}"Docker compose 安装失败"${END}
exit
fi
}
install_harbor(){
${COLOR_SUCCESS}"开始安装 Harbor....."${END}
sleep 1
if [ ! -e harbor-offline-installer-v${HARBOR_VERSION}.tgz ] ;then
wget https://github.com/goharbor/harbor/releases/download/v${HARBOR_VERSION}/harbor-offline-installer-v${HARBOR_VERSION}.tgz || ${COLOR_FAILURE} "下载失败!" ${END}
fi
[ -d ${HARBOR_BASE} ] || mkdir ${HARBOR_BASE}
tar xvf harbor-offline-installer-v${HARBOR_VERSION}.tgz -C ${HARBOR_BASE}
cd ${HARBOR_BASE}/harbor
cp harbor.yml.tmpl harbor.yml
sed -ri "/^hostname/s/reg.mydomain.com/${HARBOR_NAME}/" harbor.yml
sed -ri "/^https/s/(https:)/#\1/" harbor.yml
sed -ri "s/(port: 443)/#\1/" harbor.yml
sed -ri "/certificate:/s/(.*)/#\1/" harbor.yml
sed -ri "/private_key:/s/(.*)/#\1/" harbor.yml
sed -ri "s/Harbor12345/${HARBOR_ADMIN_PASSWORD}/" harbor.yml
sed -i 's#^data_volume: /data#data_volume: /data/harbor#' harbor.yml
#mkdir -p /data/harbor
${HARBOR_BASE}/harbor/install.sh && ${COLOR_SUCCESS}"Harbor 安装完成"${END} || ${COLOR_FAILURE}"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_BASE}/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f ${HARBOR_BASE}/harbor/docker-compose.yml down
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable harbor &>/dev/null || ${COLOR}"Harbor已配置为开机自动启动"${END}
if [ $? -eq 0 ];then
echo
color "Harbor安装完成!" 0
echo "-------------------------------------------------------------------"
echo -e "请访问链接: \E[32;1mhttp://${HARBOR_IP}/\E[0m"
echo -e "用户和密码: \E[32;1madmin/${HARBOR_ADMIN_PASSWORD}\E[0m"
else
color "Harbor安装失败!" 1
exit
fi
echo "$HARBOR_IP $HARBOR_NAME" >> /etc/hosts
}
docker info &> /dev/null && ${COLOR_FAILURE}"Docker已安装"${END} || install_docker
docker-compose --version &> /dev/null && ${COLOR_FAILURE}"Docker Compose已安装"${END} || install_docker_compose
install_harbor
101、102机器执行脚本 (离线安装或者在线下载安装)
离线安装:提前把需要的harbor版本下载好
[root@ubuntu2004 ~]#ls
harbor-offline-installer-v2.6.1.tgz
执行脚本:
[root@ubuntu2004 ~]#bash install_harbor.sh
Harbor安装完成! [ OK ]
-------------------------------------------------------------------
请访问链接: http://10.0.0.101/
用户和密码: admin/123456
在线下载安装:直接执行脚本即可
脚本执行结束:查看存放路径
[root@ubuntu2004 ~]#ls /data/harbor/
ca_download database job_logs redis registry scandata_exports secret
配置文件harbor.yml存放路径
[root@ubuntu2004 ~]#vim /apps/harbor/harbor.yml
hostname: 10.0.0.101 #这里因为两台机器,为了区别开来,改为各自ip
[root@ubuntu2004 ~]#cd /apps/harbor/
因为配置文件修改,需要将容器关闭重启
[root@ubuntu2004 ~]./prepare
[root@ubuntu2004 harbor]#docker-compose down
[root@ubuntu2004 harbor]#docker-compose up -d
101、102 harbor页面端配置
访问域名或IP进入harbor的web页面
1、项目--新建项目--项目名称:m50--访问级别--公开
2、查看推送命令:项目--镜像仓库--推送命令--docker tag SOURCE_IMAGE[:TAG] harbor.wang.org/m50/REPOSITORY[:TAG]
100 上传镜像
第一步:对镜像打标签
[root@ubuntu2004 ubuntu]#docker tag ubuntu:20.04-v2 10.0.0.101/m50/ubuntu:20.04-v2
查看打过标签的镜像
[root@ubuntu2004 ubuntu]#docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 20.04-v2 e8951fcb2ce1 10 minutes ago 241MB
10.0.0.101/m50/ubuntu 20.04-v2 e8951fcb2ce1 10 minutes ago 241MB
第二步:命令行登录harbor
[root@ubuntu2004 ubuntu]#vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"],
"insecure-registries": ["10.0.0.101","10.0.0.102"]
}
重新启动docker
[root@ubuntu2004 ubuntu]#systemctl restart docker
查看是否加入101、102
[root@ubuntu2004 ubuntu]#docker info
Insecure Registries:
10.0.0.101
10.0.0.102
第三步:登录上传
[root@ubuntu2004 ubuntu]#docker login 10.0.0.101
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@ubuntu2004 ~]#cat .docker/config.json
{
"auths": {
"10.0.0.101": {
"auth": "YWRtaW46MTIzNDU2"
},
"10.0.0.102": {
"auth": "YWRtaW46MTIzNDU2"
}
}
第四步:上传镜像
[root@ubuntu2004 ~]#docker push 10.0.0.101/m50/ubuntu:20.04-v2
第五步:去web101查看项目m50中是否有上传的镜像并在另外一台机器对镜像进行拉取
拉取之前需要修改在8机器修改,允许8机器拉取101,102上面的镜像
[root@ubuntu2004 ubuntu]#vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"],
"insecure-registries": ["10.0.0.101","10.0.0.102"]
}
重新启动docker
[root@ubuntu2004 ubuntu]#systemctl restart docker
查看是否加入101、102
[root@ubuntu2004 ubuntu]#docker info
Insecure Registries:
10.0.0.101
10.0.0.102
在8机器拉取镜像
复制web项目m50的拉取镜像链接,并把链接粘贴到8机器命令行进行拉取镜像
查看镜像:
[root@rocky8 ~]#docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
10.0.0.101/m50/ubuntu <none> e8951fcb2ce1 About an hour ago 241MB
实现harbor高可用
在一个机器创建双向同步(确定哪个项目需要同步)
根据两台harbor主机实现高可用 101、102
参考101第一台haobor服务器项目名称,在102第二台harbor上新建与之同名的项目m50
开始同步
把101机器上的镜像推到102上:
101机器如下操作
第一步:
仓库管理--新建目标--提供者:Harbor
目标名:m50(建议是项目名)
目标URRL:http://10.0.0.102
访问ID:admin
密码:123456
测试连接后确定
第二步:
复制管理--新建规则--名称:10.0.0.102-m50
复制模式:Push-based
目标仓库:m50-http://10.0.0.102
触发模式:事件驱动
选中删除本地资源时同时也删除远程的资源
带宽:-1 保存
第三步:
新上传镜像会发现镜像会同步到102上,但同步之前101就有的镜像需在复制管理中选中项目点击复制
把10.0.0.101同步之前的镜像复制到10.0.0.102上
复制管理--选中项目名称--点击复制--去10.0.0.102上去查看。
第四步:
把102机器上的镜像推到101上:
然后重复101上的操作第一步和第二步,把目标仓库换成10.0.0.101
测试把镜像传到10.0.0.102上,然后去查看10.0.0.101上有没有刚上传的镜像。
配置nginx作为两台harbor的反向代理
nginx反向代理机器10.0.0.8
[root@rocky8 conf.d]#cat /etc/nginx/conf.d/harbor.conf
upstream harbor {
hash $remote_addr
server 10.0.0.101;
server 10.0.0.102;
}
server {
listen 80;
server_name harbor.meng.com;
client_max_body_size 10g; #nginx默认上传大小为1M,超过1M,会返回413响应码
location / {
proxy_pass http://harbor;
}
}
[root@rocky8 conf.d]#nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@rocky8 conf.d]#systemctl enable --now nginx.service
在100客户端做解析并对镜像打标签上传
[root@ubuntu2004 ~]#vim /etc/hosts
10.0.0.8 harbor.meng.com
[root@ubuntu2004 ~]#vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"],
"insecure-registries": ["harbor.meng.com"]
}
[root@ubuntu2004 ~]#systemctl restart docker
[root@ubuntu2004 ~]#docker info
Insecure Registries:
harbor.meng.com
对镜像打标签上传
[root@ubuntu2004 nginx]#docker tag nginx:1.22.0-v3 harbor.meng.com/m50/nginx:1.22.0-v3
[root@ubuntu2004 nginx]#docker login harbor.meng.com
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@ubuntu2004 nginx]#docker push harbor.meng.com/m50/nginx:1.22.0-v3
Harbor安全Https配置
如果nginx作为harbor的反向代理,可把https配置在nginx上
官方文档
https://goharbor.io/docs/2.6.0/install-config/configure-https/
新配置单台barbor服务器,为其配置https,操作如下
用上面脚本安装harbor,通过windows浏览,需要在windows上做解析
10.0.0.103 harbor.wang.org
生成Harbor服务器证书
[root@ubuntu2004 ~]#mkdir /data/harbor/certs
第一步:生成ca的私钥
[root@ubuntu2004 certs]#openssl genrsa -out ca.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
......................................................++++
..................++++
e is 65537 (0x010001)
第二步:生成ca的自签名证书
[root@ubuntu2004 certs]#openssl req -x509 -new -nodes -sha512 -days 3650 \-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=meng.org" \-key ca.key \-out ca.crt
第三步:生成harbor主机的私钥
[root@ubuntu2004 certs]#openssl genrsa -out harbor.meng.org.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
...................................................................++++
............++++
e is 65537 (0x010001)
第四步:生成harbor主机的证书申请
[root@ubuntu2004 certs]#openssl req -sha512 -new \-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.meng.org" \-key harbor.meng.org.key \-out harbor.meng.org.csr
第五步:创建x509 v3 扩展文件(新版新增加的要求)
[root@ubuntu2004 certs]#cat v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=meng.org
DNS.2=meng
DNS.3=harbor.meng.org #此处必须和harbor的网站名称一致
第六步:给harbor主机颁发证书
[root@ubuntu2004 certs]#openssl x509 -req -sha512 -days 3650 \-extfile v3.ext \-CA ca.crt -CAkey ca.key -CAcreateserial \-in harbor.meng.org.csr \-out harbor.meng.org.crt
Signature ok
subject=C = CN, ST = Beijing, L = Beijing, O = example, OU = Personal, CN = harbor.wang.org
Getting CA Private Key
查看当前目录下文件
[root@ubuntu2004 certs]#ls
ca.crt ca.key ca.srl harbor.wang.org.crt harbor.wang.org.csr harbor.wang.org.key v3.ext
第七步:配置 Harbor 服务器使用证书,移走不需要的文件
[root@ubuntu2004 certs]#mkdir bak
[root@ubuntu2004 certs]#mv ca.crt ca.key ca.srl harbor.wang.org.csr v3.ext bak/
[root@ubuntu2004 certs]#ls
bak harbor.wang.org.crt harbor.wang.org.key
修改harbor.yml文件
[root@ubuntu2004 certs]#vim /apps/harbor/harbor.yml
https:
# https port for harbor, default is 443
port: 443
# The path of cert and key files for nginx
certificate: /data/harbor/certs/harbor.wang.org.crt
private_key: /data/harbor/certs/harbor.wang.org.key
第八步:上面的配置生效
[root@ubuntu2004 certs]#cd /apps/harbor/
[root@ubuntu2004 harbor]#./prepare #重新生成配置文件
[root@ubuntu2004 harbor]#docker-compose down
[root@ubuntu2004 harbor]#docker-compose up -d
配置完成,访问域名即可,然后创建项目
但客户端解析服务器域名后登录上传镜像会报错,原因是客户端没有证书
[root@ubuntu2004 ~]#docker login harbor.wang.org
Username: admin
Password:
Error response from daemon: Get "https://harbor.wang.org/v2/":x509:
配置 Docker 客户端使用证书文件
第一步:创建和harbor服务器同名的目录
[root@ubuntu2004 ~]#mkdir -pv /etc/docker/certs.d/harbor.wang.org/#此目录与harbor域名相同
第二步:把服务器上的harbor.wang.org.crt 拷贝到客户端/etc/docker/certs.d/harbor.wang.org/路径下
[root@ubuntu2004 certs]#scp harbor.wang.org.crt 10.0.0.100:/etc/docker/certs.d/harbor.meng.org/
[root@ubuntu2004 harbor.meng.org]#ls
harbor.meng.org.crt
第三步:重启docker服务
[root@ubuntu2004 ~]#systemctl restart docker
然后就可以登录传镜像了
[root@ubuntu2004 ~]#docker login harbor.wang.org
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