一、harbor介紹
Docker容器應用的開發和運行離不開可靠的鏡像管理,雖然Docker官方也提供了公共的鏡像倉庫,但是從安全和效率等方面考慮,部署我們私有環境內的Registry也是非常必要的。Harbor是由VMware公司開源的企業級的Docker Registry管理項目,它包括權限管理(RBAC)、LDAP、日志審核、管理界面、自我注冊、鏡像復制和中文支持等功能。
二、harbor安裝
准備工作
docker-ce的安裝
docker的安裝有兩個方法:
-
yum安裝
yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repohttps://download.docker.com/linux/centos/docker-ce.repo yum -y install docker-ce; systemctl start docker -
curl安裝
curl -fsSL https://get.docker.com/ | sh
安裝docker-compose
docker-compose的安裝也有種方法:
-
curl直接下載
curl -L https://github.com/docker/compose/releases/download/1.25.0-rc1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
開始安裝
下載harbor
選擇你需要的版本,Offine是離線安裝包,Online是在線安裝包。在線的安裝方式比較簡單,這里我使用的離線安裝,包自然會比Online的大一些。本文使用的版本是1.8.1
wget https://storage.googleapis.com/harbor-releases/release-1.8.0/harbor-online-installer-v1.8.1.tgz
tar xvf harbor-online-installer-v1.8.1.tgz
修改配置文件
vim harbor.yml
修改hostname:填服務IP不用使用127.0.0.1
關閉默認的http配置:如果不需要證書的話,就開啟,部署起來省事兒
打開https配置:這個需要證書,證書的只做參看下一小節。
填寫證書的完整路徑
制作證書
1、創建ca證書
cd /data/cert #該目錄是harbor中配置的目錄
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt
其中:(req:申請證書簽署請求;-newkey 新密鑰 ;-x509:可以用來顯示證書的內容,轉換其格式,給CSR簽名等X.509證書的管理工作,這里用來自簽名。)
一路回車出現Common Name 輸入IP或域名
Common Name (eg, your name or your server's hostname) []:47.52.25.8
2、生成證書簽名請求
openssl req -newkey rsa:4096 -nodes -sha256 -keyout 47.52.25.80.key -out 47.52.25.80.csr
一路回車出現Common Name 輸入IP或域名
Common Name (eg, your name or your server's hostname) []:47.52.25.8
3、生成證書
echo subjectAltName = IP:47.52.25.8 > extfile.cnf
openssl x509 -req -days 365 -in 47.52.25.80.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.cnf -out 47.52.25.80.crt

執行安裝
./prepare 更新配置文件

./install.sh

Docker-compose管理命令

執行命令必須進入harbor安裝目錄,可能因為需要讀取docker-compose.yml,docker-compose.yml是安裝完成后生成的。
docker-compose ps
docker-compose down
docker-compose down -v 停止並刪除容器
docker-compose start 啟動容器,容器不存在就無法啟動
docker-compose stop 停止容器
docker-compose up -d 后台啟動,如果容器不存在根據鏡像自動創建
查看日志

cat docker-compose.yml |grep log
cd /var/log/harbor/
分發證書
本機執行
mkdir -p /etc/docker/certs.d/192.168.2.22
cd /data/cert/
cp 192.168.2.22.crt ca.crt /etc/docker/certs.d/192.168.2.22/
cd /etc/docker/certs.d/192.168.2.22
Ls
拷貝證書到所有節點
scp -r 192.168.2.22/ 192.168.2.23:/etc/docker/certs.d/192.168.2.22
systemctl restart docker ##測試感覺可以不重啟
三、Harbor主從同步鏡像
注意:不同版本的harbor無法使用主從同步

按要求配置連接,測試成功后,點開具體的項目,配置復制

四、使用google瀏覽器訪問不是私密連接問題
使用IP創建的證書后,使用谷歌瀏覽器打開管理UI會報錯,不是私密連接,可以使用自簽名證書解決,參考文檔
自簽名證書制作,解決google瀏覽器私密連接問題
hub.ict.ac.cn
設置自簽名機構
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=hub.ict.ac.cn" -key ca.key -out ca.crt
openssl genrsa -out hub.ict.ac.cn.key 4096
openssl req -sha512 -new -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=hub.ict.ac.cn" -key hub.ict.ac.cn.key -out hub.ict.ac.cn.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=hub.ict.ac.cn
DNS.2=harbor
DNS.3=ks-allinone
EOF
制作證書
openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in hub.ict.ac.cn.csr -out hub.ict.ac.cn.crt
openssl x509 -inform PEM -in hub.ict.ac.cn.crt -out hub.ict.ac.cn.cert
分發證書
cp hub.ict.ac.cn.crt /etc/pki/ca-trust/source/anchors/hub.ict.ac.cn.crt
update-ca-trust
mkdir -p /etc/docker/certs.d/hub.ict.ac.cn
cp hub.ict.ac.cn.cert /etc/docker/certs.d/hub.ict.ac.cn/
cp hub.ict.ac.cn.key /etc/docker/certs.d/hub.ict.ac.cn/
cp ca.crt /etc/docker/certs.d/hub.ict.ac.cn/
五、修改鏡像存儲路徑
對於高版本的harbor如1.10 由於他的docker-compose.yml是執行安裝后才生成的,所以在harbor.yml里的data_volume即可。
但是對於低版本的如1.07,docker-compose.yml文件是自帶的所以需要修改docker-compose.yml中所有/data的地方改成自己的路徑,然后install即可。
六、鏡像遷移
鏡像遷移方案有兩種,可以使用harbor自帶的鏡像復制功能復制,但是這個要求兩個harbor的版本一致,這種情況比較簡單。另一種是在版本不一致的情況下,有兩個選擇,一是將harbor的版本升級到一致使用自帶的鏡像復制功能。另一種就是使用harbor的api編寫腳本拉取鏡像,再推送到新的harbor上。
1.Harbor升級
由於harbor從v1.6.0版本開始,后端數據庫由MariaDB改為Postgresql,所以在升級過程中如果是1.6版本一下的,必須先升級到v1.6.0版本,再升級至目標版本。在v1.6.0版本之后,harbor會在啟動服務時自行遷移數據庫數據,所以無需再單獨遷移數據庫。
我們升級的版本是1.7-->1.10.1
遷移步驟:
1、遷移並關閉1.7鏡像庫
mv harbor harbor1.7.bak
Cd /root/harbor1.7.bak
docker-compose down
2、下載新的harbor版本
tar -zxvf harbor-offline-installer-v1.10.1.tgz
cd harbor
3、備份數據庫
這里要注意:1.7版本的harbor數據存儲路徑(見8小節)是在docker-compose.yml下配置的。而1.10的數據路徑在harbor.yml下配置。這就導致一個問題,在下一步要升級版本的時候,更新配置文件的過程中更新不了數據存儲路徑。自動更新配置文件的數據存儲路徑是默認的/data,而1.7我安裝的時候在docker-compose.yml修改了存儲路徑為/home/harbordata/。所以需要將/home/harbordata/下的所有數據復制到/data(包含鏡像數據所以特別大)。或者在執行完自動更新配置文件(下一步)后手動編輯harbor.yml修改數據路徑為/home/harbordata/
cd /home/harbordata/
cp -r database database1.7.bak
cp -r /home/harbordata/* /data
4、升級harbor配置文件,也即harbor.cfg到harbor.yml
docker pull goharbor/harbor-migrator:v1.10.1
Tag按需要修改成你要升級的版本號
docker run -it --rm -v /root/harbor1.7.bak/harbor.cfg:/harbor-migration/harbor-cfg/harbor.cfg -v /root/harbor/harbor.yml:/harbor-migration/harbor-cfg-out/harbor.yml goharbor/harbor-migrator:v1.10.1 --cfg up
5、配置證書
6、啟動
./install.sh
2.使用腳本同步鏡像
百度了一篇遷移腳本直接引用了,我沒有使用過這個方案,太煩,原理就是使用hub的api將鏡像全本下載到本地,然后再上傳到新harbor中。
https://www.cnblogs.com/breezey/p/10615242.html
七、開啟漏洞掃描
漏洞掃描工具有很多商業的,可以度娘一下,不過大多都很貴。像我們這種toB的項目基本上不用想。所以就使用自帶的工具體驗一下吧。
1、關閉harbor docker-compose stop
2、開啟漏洞掃描工具 ./prepare --with-clair

3、重啟harbor服務 docker-compose -f docker-compose.yml up -d 不是start哦,要重新加載配置文件
4、驗證

5、開啟漏洞掃描定時任務

八、harbor維護
harbor在使用一段時間后由於迭代頻繁會產生很多垃圾數據,可以在項目里設置TAG保留規則。

這個也是1.10版本以后出來的功能,之前的版本只好使用api刪除了。
1.Harbor 數據清理
Harbor私有倉庫運行一段時間后,倉庫中存有大量鏡像,會占用太多的存儲空間。直接通過Harbor界面刪除相關鏡像,並不會自動刪除存儲中的文件和鏡像。需要停止Harbor服務,執行垃圾回收命令,進行存儲空間清理和回收。
進入compose所在目錄[config.yml]
[root@node ~]# cd /root/harbor
停止Harbor相關的compose服務
[root@node harbor]# docker-compose stop
Stopping harbor-jobservice ... done
Stopping nginx ... done
Stopping harbor-ui ... done
Stopping harbor-db ... done
Stopping registry ... done
Stopping harbor-adminserver ... done
Stopping harbor-log ... done
使用--dry-run參數運行容器,預覽運行效果,但不刪除任何數據
docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.2-photon garbage-collect --dry-run /etc/registry/config.yml
nginx/nginx
blobs marked, 5 blobs eligible for deletion【0個blobs被標記,5個blobs可刪除]
blob eligible for deletion: sha256:3c091c23e29d0ddfc902b0be63b1a08a853ef39973f92fab39ad1727eac012bf
blob eligible for deletion: sha256:4a99993b863683bef1c776732e14d2372f6ed52b48e94783f4a1b58af289db07
blob eligible for deletion: sha256:ae513a47849c895a155ddfb868d6ba247f60240ec8495482eca74c4a2c13a881
blob eligible for deletion: sha256:e4f0474a75c510f40b37b6b7dc2516241ffa8bde5a442bde3d372c9519c84d90
blob eligible for deletion: sha256:f2aa67a397c49232112953088506d02074a1fe577f65dc2052f158a3e5da52e8
不使用--dry-run參數,將刪除相關的文件和鏡像
docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.2-photon garbage-collect /etc/registry/config.yml
nginx/nginx
blobs marked, 5 blobs eligible for deletion#【0個blobs被標記,5個blobs可刪除]
blob eligible for deletion: sha256:3c091c23e29d0ddfc902b0be63b1a08a853ef39973f92fab39ad1727eac012bf
INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/3c/3c091c23e29d0ddfc902b0be63b1a08a853ef39973f92fab39ad1727eac012bf go.version=go1.7.3 instance.id=8a97e002-522a-4a6c-b390-122880d53183 service=registry
blob eligible for deletion: sha256:4a99993b863683bef1c776732e14d2372f6ed52b48e94783f4a1b58af289db07
INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/4a/4a99993b863683bef1c776732e14d2372f6ed52b48e94783f4a1b58af289db07 go.version=go1.7.3 instance.id=8a97e002-522a-4a6c-b390-122880d53183 service=registry
blob eligible for deletion: sha256:ae513a47849c895a155ddfb868d6ba247f60240ec8495482eca74c4a2c13a881
INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/ae/ae513a47849c895a155ddfb868d6ba247f60240ec8495482eca74c4a2c13a881 go.version=go1.7.3 instance.id=8a97e002-522a-4a6c-b390-122880d53183 service=registry
blob eligible for deletion: sha256:e4f0474a75c510f40b37b6b7dc2516241ffa8bde5a442bde3d372c9519c84d90
INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/e4/e4f0474a75c510f40b37b6b7dc2516241ffa8bde5a442bde3d372c9519c84d90 go.version=go1.7.3 instance.id=8a97e002-522a-4a6c-b390-122880d53183 service=registry
blob eligible for deletion: sha256:f2aa67a397c49232112953088506d02074a1fe577f65dc2052f158a3e5da52e8
INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/f2/f2aa67a397c49232112953088506d02074a1fe577f65dc2052f158a3e5da52e8 go.version=go1.7.3 instance.id=8a97e002-522a-4a6c-b390-122880d53183 service=registry
docker-compose start
Starting log ... done
Starting adminserver ... done
Starting registry ... done
Starting ui ... done
Starting mysql ... done
Starting jobservice ... done
Starting proxy ... done
2.刪除鏡像倉庫TAG腳本
【每個項目保留9個版本鏡像,可在下面腳本配置,打 tag 的時候可以按照日期命名,例如:2018-10-29_17-39 】
#!/bin/bash
URL="http://192.168.56.21"
USER="admin"
PASS="Harbor12345"
PRO="nginx"
HARBOR_PAHT="/root/harbor"
SAVE_IAMGE_NUM=9
#軟刪除 harbor tags
del_tags()
{
echo "軟刪除 ${rp}/${t}"
curl -u ${USER}:${PASS} -X DELETE -H 'Accept: text/plain' "${URL}/api/repositories/${rp}/tags/${t}"
}
#硬刪除 harbor tags
har_del_tags()
{
cd ${HARBOR_PAHT}
docker-compose stop
docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.2-photon garbage-collect /etc/registry/config.yml
docker-compose start
}
# 獲取 project id
PID=$(curl -u ${USER}:${PASS} -s -X GET --header 'Accept: application/json' "${URL}/api/projects"|grep -w -B 2 "${PRO}" |grep "project_id"|awk -F '[:, ]' '{print $7}')
#echo ${PID}
# 拿獲取到的 projects_id 獲取 repositories[倉庫]
REPOS=$(curl -u ${USER}:${PASS} -s -X GET --header 'Accept: application/json' "${URL}/api/repositories?project_id=${PID}"|grep "name"|awk -F '"' '{print $4}')
for rp in ${REPOS}
do
echo ${rp}
TAGS=$(curl -u ${USER}:${PASS} -s -X GET --header 'Accept: application/json' "${URL}/api/repositories/${rp}/tags"|grep \"name\"|awk -F '"' '{print $4}'|sort -r |awk "NR > $SAVE_IAMGE_NUM {print $1}")
for t in ${TAGS}
do
echo ${t}
del_tags
done
echo "===================="
done
har_del_tags
