一、總體技術架構
基於單節點部署的Harbor隨着存儲內容和運行日誌的增加,系統的存儲空間會趨緊飽和。本文將研究和部署基於Ceph的分佈式harbor部署方案。軟件安裝如下:
Docker:version 1.12.6
Docker-compose: version 1.23.2
Ceph:version 10.2.11
Mysql: version 10.2.14(MariaDB)
在資源劃分上harbor分部署集羣和ceph集羣進行了複用。其中一臺服務器作爲Nginx負載均衡,另外Harbor節點和Ceph節點進行了一定的服用。其中一臺服務器作爲共享數據庫。其資源分配如下所示:
Nginx ——10.10.13.1
Admin——10.10.13.21
Node0——10.10.13.22
Node1——10.10.13.30
Mysql ——10.10.13.31
需要說明一下,Ceph存儲集羣搭建,admin作爲ceph-deploy和mon,Node0作爲OSD0,Node1作爲OSD1,並且將創建的cephfs mount到這三個節點上,在這三個節點上部署Harbor服務組成一個鏡像倉庫集羣(這樣Harbor就可以直接掛載本地cephfs路徑上了)。此外,再提供一個節點Nginx作爲負載均衡將請求均衡到這三個節點,最後再提供一個節點Mysql作爲外部數據庫存儲,建議做成HA高可用,鑑於目前資源有限,暫時選用一臺服務器作爲數據庫服務器,後續可以採用容器服務來進行替代。
其總體技術架構如下圖所示:
這裏需要說明的是,由於目前資源有限,上述總體技術架構只能保證數據安全,既不會因爲Harbor節點本身出現故障,從而導致數據丟失的問題。並且harbor多節點能夠共享數據。解決目前現有的單節點harbor系統數據冗餘的情況出現數據丟失和存儲空間無法擴展的問題。真正在生產系統上應用,還需要注意Harbor集羣節點的數據快速同步等問題。真正做到數據實時性訪問等。而針對鏡像數據共享,實現了多Harbor服務共享後端存儲的方式,即通過Ceph分佈式存儲方案來解決。
結合上圖,每一個Harbor節點上都mount配置好的cephfs,然後配置每一個Harbor服務的各個組件volume都掛載cephfs路徑,最後通過統一的入口Nginx負載均衡將流量負載到各個Harbor服務上,來實現整體Harbor集羣的"高可用"。
但是還需要注意的是,在本方案中將默認harbor-db數據庫組件拆出來,讓其連接外部Mysql數據庫(默認Harbor會在每個節點上都啓動Mysql服務進行數據存儲,這樣數據就無法實現統一,即使我們將Mysql數據庫存儲在cephfs上,三個節點共用同一份數據,但是依然不可行,因爲Mysql多個實例之間無法共享一份Mysql數據文件。
二、Ceph介紹及部署
Ceph是一個統一的分佈式存儲系統,設計初衷是提供較好的性能、可靠性和可擴展性。
1、Ceph架構
Ceph主要基於RADOS對象存儲系統來實現可靠的、自動修復、自我管理的分佈式對象存儲系統。上層通過librados封裝了一層接口,支持C/C++/Java/Python/Ruby/PHP等。支持三種接口:
Object:有原生的API,而且也兼容Swift和S3的API;
Block:支持精簡配置、快照、克隆;
File:Posix接口,支持快照。
2、Ceph核心組件及概念介紹
Monitor
一個Ceph集羣需要多個Monitor組成的小集羣,它們通過Paxos同步數據,用來保存OSD的元數據。
OSD
OSD全程Object Storage Device,也就是負責響應客戶端請求返回具體數據的進程。一個Ceph集羣一般都有多個OSD。
MDS
MDS全稱Ceph Metadata Server,是CephFS服務依賴的元數據服務。
Object
Ceph最底層的存儲單元是Object對象,每個Object包含元數據和原始數據。
PG
PG全稱Placement Groups,是一個邏輯的概念,一個PG包含多個OSD。引入PG這一層其實是爲了更好的分配數據和定位數據。
RADOS
RADOS全稱Reliable Autonomic Distributed Object Store,是Ceph集羣的精華,用戶實現數據分配、Failover等集羣操作。
Librados
Librados是Rados提供庫,因爲RADOS是協議很難直接訪問,因此上層額RBD、RGW和CephFS都是通過librados訪問的,目前提供PHP、Ruby、Java、Python、C和C++支持。
CRUSH
CRUSH是Ceph使用的數據分佈算法,類似一致性哈希,讓數據分配到預期的地方。
RBD
RBD全稱RADOS block device,是Ceph對外提供的塊設備服務。
RGW
RGW全稱RADOS Gateway,是Ceph對外提供的對象存儲服務,接口與S3和Swift兼容。
CephFS
CephFS全稱Ceph File System,是Ceph對外提供的文件系統服務。
3、Ceph IO流程及數據分佈
依據上述流程圖所示,其正常IO流程如下:
(1)client創建cluster handle;
(2)client讀取配置文件;
(3)client連接上monitor,獲取集羣map信息;
(4)client讀取IO,根據crush map算法請求對應的主OSD數據節點;
(5)主OSD數據節點同時寫入另外兩個副本節點數據;
(6)等待主節點以及另外兩個副本節點寫完數據狀態;
(7)主節點及副本節點寫入狀態都成功後,返回給client,IO寫入完成。
4、Ceph集羣部署
介紹完Ceph相關概念和實現流程,在本次Ceph部署採用四臺物理服務器作爲Ceph集羣節點進行部署。在部署Ceph集羣時,需要安裝相關的軟件及版本如下:
Centos:release 7.4.1708(Core)
Ceph: jewel-10.2.11
Openssh-server: version 7.4
NTP
根據Ceph 官方文檔中建議安裝一個ceph-deploy管理節點和一個三節點的Ceph存儲集羣來研究Ceph的基本特性。由於資源有限,所以在解決方案中少用了一個節點,將mon.node1節點的Monitor功能遷移到admin-node節點上,所以集羣結構圖如下圖所示:
Ceph分佈式存儲集羣有三大組件組成,分爲:Ceph Mointor、Ceph OSD、Ceph MDS,MDS非必須安裝,只有當使用CephFS文件存儲時才需要安裝。因此暫時不安裝MDS。
4.1 配置節點
爲了方便後續安裝,以及ssh方式連接各個節點,首先修改各個節點的Hostname以及配置Hosts如下:
需要在所有節點上都需要進行上述的配置。在配置完成以後,需要ping一下是否可以互相訪問。如下圖所示:
4.2 安裝部署工具ceph-deploy
Ceph提供部署工具ceph-deploy來方便安裝Ceph集羣,我們只需要在ceph-deploy節點上安裝即可,這裏對應的就是admin-node節點。把Ceph倉庫添加到ceph-deploy管理節點,然後安裝ceph-deploy。根據centos7版本,安裝相關依賴庫,執行如下命令:
$ sudo yum install -y yum-utils \
&& sudo yum-config-manager --add-repo po https://dl.fedoraproject.org/pub/epel/7/x86_64/ \
&&/ && sudo yum install --nogpgcheck -y epel-release \
&& sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 \
&& sudo rm /etc/tc/yum.repos.d/d.d/.d/dl.fedoraproject.org*
#添加Ceph源:
$ sudo vim /etc/tc/yum.repos.d/c.d/.d/ceph.repo
[Ceph-noarch]
name=Ceph noarch packages
baseurl=rl=http://download.ceph.com/rpm-jewel/el7/noarch
ena
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=ey=https://download.ceph.com/keys/release.asc
pri
priority=1
#安裝ceph-deploy
$ sudo yum update && sudo yum install ceph-deploy
4.3 安裝NTP和OpenSSH
根據官方建議,在所有Ceph節點上安裝NTP服務(特別時Ceph Monitor節點),以免因時鐘漂移導致故障。
#yum安裝ntp
sudo yum install ntp ntpdate ntp-doc
#校對系統時鐘
ntpdate 0.cn.pool.ntp.org
# yum 安裝 openssh
$ sudo yum install openssh-server
# 查看ssh版本
$ ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
4.4 創建Ceph用戶
ceph-deploy工具必須以普通用戶登錄Ceph節點,且此用戶擁有無密碼使用sudo的權限,因爲它需要在安裝軟件及配置文件的過程中,不必輸入密碼。官方建議所有Ceph節點上給ceph-deploy創建一個特定的用戶,爲了方便起見,使用cephd這個賬戶作爲特定的用戶,而且每個節點上(admin-node、node0、node1)上都需要創建該賬戶,並且擁有sudo權限。
# 在Ceph集羣各節點進行如下操作
# 創建ceph特定用戶
$ sudo useradd -d /home/cephd -m cephd
$ sudo passwd cephd
# 添加sudo 權限
$ echo "cephd ALL = (root)NOPASSWD:ALL" | sudo tee /etc/sudoers.d/cephd
$ sudo chmod 0440 /etc/sudoers.d/cephd
接下來在ceph-deploy節點(admin-node)上,切換到cephd用戶,生成SSH密鑰並把其公鑰分發到各Ceph節點上,注意使用cephd賬戶生成,且提示輸入密碼時,直接回車,因爲它需要免密碼登錄到各個節點。
# ceph-deploy(admin-node)上執行
# 生成ssh密鑰
$ ssh-keygen
# 將公鑰複製到node0節點
$ ssh-copy-id cephd@node0
# 將公鑰複製到node1節點
$ ssh-copy-id cephd@node1
#測試在ceph-deploy管理節點免密碼登錄各個節點
$ ssh node0
$ ssh node1
測試沒問題,接下來,修改ceph-deploy管理節點上的~/.ssh/config文件,這樣無需每次執行ceph-deploy都要指定-usename cephd.這樣做同時也簡化了ssh和scp的用法。
$ vim ~/.ssh/config
Host node0
Hostname node0
User cephd
Host node1
Hostname node1
User cephd
# 禁用selinux
$ sudo vim /etc/selinux/config
SELINUX=disabled #這裏設置爲disabled
SELINUXTYPE=targeted
5、Ceph存儲集羣搭建
經過上述一系列的預檢設置後,就可以開始Ceph存儲集羣的搭建了。集羣結構爲admin-node(ceph-deploy、Monitor)、node0(osd.0)、node1(osd.1)。首先要提一下的是,如果再安裝過程中出現了問題,需要重新操作的時候,需要清理搭建的這個集羣的話,可以使用以下命令:
# ceph-deploy(admin-node)上執行
# 清理配置
ceph-deploy purgedata admin node0 node1
ceph-deploy forgetkeys
# 清理Ceph安裝包
ceph-deploy purge admin node0 node1
好了,現在開始搭建。首先Cephd用戶創建一個目錄ceph-cluster並進入到該目錄執行如下操作。
#創建執行目錄
$ mkdir ~/ceph-cluster && cd ~/ceph-cluster
#創建集羣
$ ceph-deploy new admin
此時,我們會發現ceph-deploy會在ceph-cluster目錄下生成幾個文件,ceph.conf爲ceph配置文件,ceph-deploy-ceph.log爲ceph-deploy日誌文件,ceph.mon.keyring爲ceph monitor的密鑰環。
接下來,我們需要修改ceph.conf配置文件,增加副本數爲2,因爲我們有兩個OSD節點。
然後,我們需要通過ceph-deploy在各個節點安裝ceph
$ ceph-deploy install admin node0 node1
此過程需要等待一段時間,因爲ceph-deploy會SSH登錄到各node上去,依次執行安裝ceph依賴的組件包。
在等待安裝完畢之後,接下來需要初始化monitor節點並手機所有密鑰。
$ ceph-deploy mon create-initial
執行完畢後,會在當前目錄下生成一系列的密鑰環,應該是各組件之間訪問所需要的認證信息。
至此,ceph monitor已經成功啓動了。接下來需要創建OSD了,OSD是最終數據存儲的地方,這裏我們準備了兩個OSD節點,分別是osd.0和osd.1。官方建議爲OSD及其日誌使用獨立硬盤或者分區作爲存儲空間,不過由於條件不具備,所以在本地磁盤上創建目錄,來作爲OSD的存儲空間。
# ceph-deploy(admin-node)上執行
$ ssh node0
$ sudo mkdir /var/local/osd0
$ sudo chown -R ceph:ceph /var/local/osd0
$ exit
$ ssh node1
$ sudo mkdir /var/local/osd1
$ sudo chown -R ceph:ceph /var/local/osd1
$ exit
**注意:**執行chown -R ceph:ceph操作,是將osd0和osd1目錄的權限賦予ceph:ceph,否則,接下來執行ceph-deploy osd activate時會出現權限報錯。
接下來,需要ceph-deploy節點執行prepare OSD操作,目的時分別在各個OSD節點上創建一些後邊激活OSD需要的信息。
$ ceph-deploy osd prepare node0:/var/local/osd0 node1:/var/local/osd1
接下來需要激活 activate OSD.
$ ceph-deploy osd activate node0:/var/local/osd0 node1:/var/local/osd1
最後一步,通過ceph-deploy admin將配置文件和admin密鑰同步到各個節點,以便在各個node上使用ceph命令時,無需指定monitor地址和ceph.client.admin.keyring密鑰。
$ ceph-deploy admin admin node0 node1
至此,Ceph存儲集羣已經搭建完畢了。可以查看以下集羣是否啓動成功。
# 查看集羣狀態
$ ceph -s
# 查看集羣健康狀況
$ ceph health
# 查看集羣OSD信息
$ ceph osd tree
通過上述的檢查,目前ceph集羣已經安裝部署完成,並且能夠正常運行。
6、CephFS文件系統創建
在部署完成ceph集羣以後,需要創建CephFS文件系統。具體執行如下:
# 在admin-node(ceph-deploy) 節點操作
# 創建MDS元數據服務器
$ ceph-deploy mds create admin node0 node1
# 查看MDS狀態
$ ceph mds stat
# 創建cephFS
$ ceph osd pool create cephfs_data 128
# 掛載cephFS
$ sudo mount -t ceph 10.10.13.21:6789:/ /mnt/cephfs -o name=admin,secretfile=/etc/ceph/admin.secret
$ df -h
接下來,將開始後續的Harbor部署已經相關數據庫的遷移等。
三、數據庫遷移
根據總體技術架構,單獨設置一臺服務器作爲Mysql數據庫進行獨立提供數據庫服務。由於Harbor本身提供數據庫服務,尤其採用高可用的話,多實例Harbor之間無法實現數據共享,因此需要獨立部署一個數據庫服務器,讓所有Harbor實例都統一指定訪問這一個數據庫系統,維護同一套數據,從而保證了數據的一致性。
1、Mariadb數據庫部署
$ sudo yum -y install mariadb-server
$ sudo systemctl start mariadb
2、遷移db數據
經過啓動單節點Harbor服務時,已經有一部分數據存儲到harbor-db數據裏面去了,而且Harbor啓動時也會創建好所需要的數據庫、表和數據等。這裏我們只需要進入Harbor-db容器中,將registry數據庫dump一份,然後Copy到當前節點機器上。
# 進入harbor-db容器
$ docker exec -it <harbor-db容器ID> bash
# 備份數據到默認目錄/tmp/registry.dump
$ mysqldump -u -root -p registry > registry.dump
Enter password: XXXXX
$ exit
# 退出容器,copy備份數據到當前節點機器
$ docker cp <harbor-db容器ID>:/tmp/registry.dump /home/cephd/harbor/
#登陸數據庫並創建用戶
$ mysql -h 10.10.13.31 -P 3306 -u root -p <db_password>
mysql> CREATE USER 'harbor'@'%' IDENTIFIED BY 'XXXXXX';
mysql> GRANT ALL ON *.* TO 'harbor'@'%';
mysql> FLUSH PRIVILEGES;
#導入數據
$ mysql -h 10.10.13.31 -P 3306 -u harbor -pXXXXX
mysql> CREATE DATABASE IF NOT EXISTS registry default charset utf8 COLLATE utf8_general_ci;
mysql> USE registry;
Database changed
mysql> source /home/cephd/harbor/registry.dump;
經過上述指令執行,就已經成功將外部數據庫搞定了。剩下的工作就是對Harbor組件進行配置,從而使得Harbor在訪問數據庫時自動連接外部數據庫。
3、修改配置使用外部db
首先,既然我們已經有外部數據庫了,那麼就不需要Harbor再啓動harbor-db服務了,只需要配置連接外部數據即可。因此就需要刪除docker-compose.yml中mysql相關配置。如下圖所示:
# 刪除以下mysql配置
mysql:
image: vmware/harbor-db:v1.5.3
container_name: harbor-db
restart: always
volumes:
- /data/database:/var/lib/mysql:z
networks:
- harbor
env_file:
- ./common/config/db/env
depends_on:
- log
logging:
driver: "syslog"
options:
syslog-address: "tcp://127.0.0.1:1514"
tag: "mysql"
# 刪除depends_on中mysql部分
depends_on:
# - mysql # 此處刪除
- registry
- ui
- log
其次,還需要修改./common/config/adminserver/env配置,這裏面主要存放的是一些配置信息,裏面就有配置Mysql的連接信息。因爲該文件是執行install.sh的時候根據./common/templates/adminserver/env配置生成的,所以即使我們修改了,也是一次性的,重新install又會覆蓋掉,所以可以直接修改./common/templates/adminserver/env該文件就一勞永逸了。
# 修改 ./common/templates/adminserver/env文件
……
MYSQL_HOST=10.10.13.31
MYSQL_PORT=3306
MYSQL_USR=harbor
MYSQL_PWD=XXXXXX
MYSQL_DATABASE=registry
……
RESET=true
注意:這裏一定要設置RESET=true因爲只有設置了該開關,Harbor纔會在啓動時覆蓋默認配置,啓用我們配置的信息。
再次啓動Harbor服務,看一下能否啓動成功,能否正常連接配置的外部數據庫。
# 重啓 Harbor 服務
$ ./install.sh
查看 Harbor 各組件容器啓動狀態,harbor-db服務已經刪除
查看UI和jobservice日誌,是否連接上Mysql
# 查看UI和jobservice日誌,是否連接上Mysql
$ cat /mnt/cephfs/harbor/log/ui.log | grep database
通過日誌發現,Harbor已經成功啓動了,並且harbor-db服務組件按照設計也沒有啓動,日誌顯示連接外部數據庫也沒有問題,通過瀏覽http://10.10.13.21(harbor部署節點)看一下之前操作的數據是否能夠正常顯示出來。http://10.10.13.21(harbor部署節點)看一下之前操作的數據是否能夠正常顯示出來。
發現之前創建的帳號和導入的鏡像數據都可以訪問。說明原先在harbor-db服務中創建的數據庫和相關賬戶信息等內容都已經成功遷移到外部數據庫中,並且啓動的Harbor服務能夠正常訪問外部數據庫。那麼多節點的Harbor集羣都是按照此方法創建harbor服務,並且將Harbor服務連接和訪問統一的外部數據庫從而維持一套統一的數據庫操作,在此不再贅述。剩下的工作就是針對多節點的Harbor服務如何實現通過以的IP地址訪問,在此通過Nginx方式來實現負載均衡訪問。
四、Nginx負載均衡
爲了保持原有的Rancher容器集羣在訪問原有的單節點Harbor配置不用改變,我們將原先的Harbor單節點服務器10.10.13.1作爲Nginx服務器,這樣通過Nginx進行訪問分發到之前創建的3臺Harbor服務器上,這樣原有的Rancher容器集羣訪問地址就不需要進行修改了。
爲了快速安裝Nginx,採用Docker方式啓動Nginx服務。首先創建配置文件,當Nginx服務啓動時,就可以根據配置文件進行負載均衡。
# 創建 default.conf 配置文件
$ mkdir /root/nginx
$ vim default.conf
upstream service_harbor {
server 10.10.13.21;
server 10.10.13.22;
server 10.10.13.30;
ip_hash;
}
server {
listen 80;
server_name 10.10.13.1;
index index.html index.htm;
#access_log /var/log/nginx/host.acces.log main;
location / {
add_header Access-Control-Allow-Orgin *;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://10.10.13.1;
client_max_body_size 1024m #設置接口客戶端body最大長度爲1024M
}
access_log /var/log/harbor.access.log;
error_log /var/harbor.error.log;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# Docker 啓動 Nginx服務, 掛載上邊配置文件覆蓋默認配置,並開放80端口
$ docker run --name nginx-harbor -p 80:80 -v /root/nginx/default.conf:ro -d nginx
通過瀏覽器訪問Nginx地址 http://10.10.13.1 能否能夠訪問Harbor UI。
至此,已經創建完成了基於Ceph的高可用Harbor部署。目前的基礎資源可以使用一段時間了。不過還需要有幾點還需要繼續改進的地方。
Mysql數據庫可以通過分部署方式提供服務。比如可以通過基於容器平臺的Mysql主從、PXE等方式部署Mysql分佈式集羣,由底層容器平臺提供數據庫服務;
HA高可用部署還可以參數調優的方式,可以進一步提高負載均衡性能;
底層CephFS文件系統還可以持續進行HA高可用。從現有的Ceph進行承載發現在數據訪問等方便確實比原先的單節點Harbor要慢一些。
擴展:
【1】基於Harbor和Cephfs搭建高可用Docker鏡像倉庫集羣:
https://blog.csdn.net/aixiaoyang168/article/details/78909038
【2】Ceph介紹及原理架構分享:
https://www.jianshu.com/p/cc3ece850433
【3】初試Centos7上Ceph存儲集羣搭建:
https://blog.csdn.net/aixiaoyang168/article/details/78788703
【4】原文鏈接:
https://mp.weixin.qq.com/s/2EkFip32FWpp18CQY4RMzg