Harbor私有鏡像倉庫
Harbor介紹
參考:
Harbor使用docker官方的Registry倉庫方案保存鏡像,使用數據庫保存harbo的一些配置信息。
Harbor默認把所有這一套組件全部放在容器裡跑,至於如何做高可用和擴展性呢? 官方目前只提供2種方法:
1) 高難度方案
a) 配置使用分佈式storage,比如ceph,這樣就可以搭建多個harbor共享一套鏡像文件了。
b) 數據庫獨立搭建postgresql主從,這樣搭建多個harbor就可以共享一套配置信息了。
2) 弱雞方案
a) 單機磁盤存儲鏡像文件,然後搭建多個harbor,讓其中1個harbor接收上傳鏡像,然後再向其他harbor同步鏡像,這是harbor的一個複製功能。
b) 數據庫使用自帶的容器版本,這樣運維改配置類的東西必須在所有harbor中操作一次。(注意,弱雞方案中,不能讓多個harbor共享一個數據庫,因為複製配置也會被多個harbor共享,比如在A harbor配置複製鏡像給B,結果B也讀到了這個配置,自己複製給自己?就亂套了。)
綜合這個現狀,我提出一個可行的弱雞方案。
1,搭建1個harbor主節點,全部使用harbor單機容器,定時備份postgresql數據庫。
令域名push.harbar.smzdm.com指向主節點,鏡像上傳以及WEB UI管理走這個域名。鏡像複製給N個harbor從節點。
2,搭建N個harbor從節點,全部使用harbor單機容器,域名pull.harbor.smzdm.com指向主節點+從節點做負載均衡,鏡像拉取都走這個域名。
如果主節點宕機,選一個從節點,把備份的postgresql中的registry庫導進去,把push.harbor.smzdm.com指過去,然後繼續用算恢復了。
環境準備
3臺ubuntu 16虛擬機,1核1G。
節點1:做harbor主節點
節點2:做harbor從節點
節點3: 部署nginx反向代理,其中push.harbor.smzdm.com域名反向代理到harbor主節點。pull.harbor.smzdm.com負載均衡到2個harbor節點,僅供拉取。
安裝依賴
新ubuntu沒有sshd服務:
apt-get install ssh
安裝docker:
apt-get update
apt-get install -y docker.io
安裝python:
apt-get install python
安裝openssl(ubuntu默認帶著了):
apt-get install openssl
安裝docker-compose(單機的容器編排工具,和k8s的yaml長的差不多,參考:https://github.com/docker/compose/releases ):
curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
搭建harbor
配置harbor
下載harbor的offline installer,目前是v1.6.2版本:
打開節點1與節點2的harbor.cfg。
hostname:改為節點自身IP,兩臺機器不一樣。
customize_crt:改為off,docker login登錄harbor時,harbor會用一對rsa公私鑰籤一個登錄token給用戶。因為我們最終有N個個harbor對外提供拉取服務,所以得每個harbor的rsa公私鑰是一樣的,否則在節點1申請的token在節點2無法認證通過,就很尷尬。設置成off的意思就是使用harbor默認的一套Rsa證書,以實現N個節點相同的目的。
harbor_admin_password:管理員密碼,內置管理員帳號叫做admin。
auth_mode:harbor的登錄賬號使用數據庫的,還是用公司ldap的,我們先保持db_auth,未來可以接入ldap。
project_creation_restriction :改成adminonly,只有管理員帳號可以建新項目。
首次安裝
執行./install.sh即可全自動安裝,postgresql裡的表都會由adminserver組件自動創建。
harbor的組件都運行在docker container裡,暴露的端口都映射到了宿主機上,持久化的數據也映射在宿主機的/data目錄,日誌在/var/log/harbor目錄(日誌會自動滾動,不需要清理)。
現在,我們打開瀏覽器輸入IP地址即可訪問到harbor:http://172.18.10.236,帳號admin,密碼剛才我們配置過,默認是Harbor12345。
我們按照同樣的方法配置harbor從節點,注意hostname與第一個節點的配置不同,其他都一樣。
配置nginx反向代理
我們在節點3上啟動一個nginx做反向代理,做2個HOST出來:
1, push.harbor.smzdm.com:給jenkins構建發佈系統用的,推鏡像到harbor主節點,然後同步到harbor從節點。主節點故障期間隻影響上傳鏡像。
2, pull.harbor.smzdm.com:給k8s集群拉鏡像用的,負載均衡所有harbor,具備擴展性。
在節點上3操作。
安裝nginx:apt-get install nginx
修改配置文件:
cat /etc/nginx/sites-enabled/default
upstream harbor_pull {
server 172.18.10.236:80 weight=1;
server 172.18.10.240:80 weight=1;
}
upstream harbor_push {
server 172.18.10.236:80 weight=1;
#server 172.18.10.240:80 weight=1;
}
server {
listen 80;
server_name pull.harbor.smzdm.com;
location / {
proxy_pass http://harbor_pull;
}
}
server {
listen 80;
server_name push.harbor.smzdm.com;
location / {
proxy_pass http://harbor_push;
}
}
另外需要修改一下上傳文件大小的限制,否則鏡像太大傳不上來:
http {
##
# Basic Settings
##
client_max_body_size 0;
chunked_transfer_encoding on;
即在http段加上述2行配置。
重啟nginx:systemctl restart nginx
在自己的PC上配置一下/etc/hosts,指向nginx即可:
172.18.10.248 push.harbor.smzdm.com
172.18.10.248 pull.harbor.smzdm.com
確認瀏覽器訪問2個域名正常。
添加項目
在主harbor上建立smzdm項目:
設置為非公開項目,這意味著如果要pull這個項目下的鏡像,需要docker login登錄才行。
上傳鏡像
把上述hosts配置到節點3上的/etc/hosts:
172.18.10.248 push.harbor.smzdm.com
172.18.10.248 pull.harbor.smzdm.com
我們在節點3上用docker push來嘗試上傳一個鏡像到harbor倉庫。
我們說過push.harbor.smzdm.com指向主節點,鏡像將推送到主節點的磁盤上。
因為我們的nginx反向代理沒有開始TLS,而docker默認要求倉庫是https的,所以需要給節點3上的dockerd配置一個白名單,允許使用http訪問push.harbor.smzdm.com和pull.harbor.smzdm.com倉庫:
vim /etc/docker/daemon.json
{
"insecure-registries" : ["pull.harbor.smzdm.com:80", "push.harbor.smzdm.com:80"]
}
(最好還是給nginx配上TLS證書,這樣就省事了)
現在下載一個Nginx鏡像做測試:
docker pull nginx
然後改名到我們的私有倉庫地址:
docker tag nginx:latest push.harbor.smzdm.com:80/smzdm/nginx:v1.0
登錄到私有倉庫:
docker login --username admin --password Harbor12345 push.harbor.smzdm.com:80
docker login --username admin --password Harbor12345 pull.harbor.smzdm.com:80
查看保存的登錄密碼:
root@harbor01:~/harbor# cat ~/.docker/config.json
{
"auths": {
"pull.harbor.smzdm.com:80": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
},
"push.harbor.smzdm.com:80": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
}
}
以後就免登陸了。
現在就可以push一波了:
docker push push.harbor.smzdm.com:80/smzdm/nginx:v1.0
現在看push.harbor.smzdm.com主節點上,已經有鏡像了:
用IP明確的訪問harbor從節點,發現沒有鏡像:
這就是我們接下來要說的,鏡像同步。
鏡像同步
在主harbor上,點擊倉庫管理,把從harbor配置上來:
新建同步規則:
日誌顯式複製正常:
查看harbor從庫:
也有了。
我們可以pull一下鏡像試試:
docker pull pull.harbor.smzdm.com:80/smzdm/nginx:v1.0
注意,拉鏡像的時候使用的是pull.harbor.smzdm.com,也就是從任意harbor節點下載鏡像。
我們之前推送的時候用的是push.harbor.smzdm.com:80,推送和拉取使用不同的域名沒有關係,最終只要讓k8s通過URL把鏡像拉下來就能執行。
故障轉移
首先,我們只使用admin帳號完成鏡像上傳與下載,因為所有harbor初始化過程都會有統一的admin賬號和密碼保存到各自的postgresql數據庫中,這個信息是集群一致的。
其次,我們每個harbor的token服務的rsa公私鑰匙一樣的,所以docker login拿到的token可以在任意harbor進行認證和鑑權。
再其次,上傳鏡像只發給harbor主節點,然後自動複製給所有從節點,所以從任意從節點都可以拉取到完整鏡像。
有了這些前提之後,我們可以輕鬆的實現harbor主節點的故障轉移,下面簡單模擬一波。
先關掉harbor主節點,假裝這臺機器掛了:
docker-compose down -v
現在嘗試push會失敗:
嘗試pull仍舊會成功,因為harbor從庫還活著:
現在只需要找一個harbor從庫,在nginx上把push.harbor.smzdm.com指過去:
重啟nginx:systemctl restart nginx
現在push恢復:
我們harbor主庫:
倉庫和複製規則都沒了,我們現在重新配置一下同步給其他節點即可。
因為我們搭建的集群就2個harbor節點,所以我現在把掛掉的harbor機器重置一下,作為一個新harbor使用。
刪除所有之前的數據:
rm -rf /data/*
重新install一波:
./install.sh
在harbor主節點上配置複製鏡像到該節點:
然後看一下節點1上已經同步了所有鏡像:
閱讀更多 愛新覺羅張三丰 的文章