小編給大家分享一下基于docker-swarm搭建持續(xù)集成集群服務(wù)的方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名申請、網(wǎng)站空間、營銷軟件、網(wǎng)站建設(shè)、馬村網(wǎng)站維護(hù)、網(wǎng)站推廣。
為了能在本機(jī)(macOS)模擬集群環(huán)境,使用了vb和docker-machine。整體持續(xù)集成的幾個機(jī)器設(shè)施如下:
1、服務(wù)節(jié)點:三個manager節(jié)點,一個worker節(jié)點。manager需要占用更多的資源,manager配置盡量高一些。swarm的manager節(jié)點的容錯率是 (N-1)/2 。N是manager節(jié)點數(shù)。也就是如果有3個manager,那就能容忍一個manager節(jié)點掛掉。官方的算法說明:Raft consensus in swarm mode。
2、本地的鏡像倉庫 registry:用來存儲所有需要部署的服務(wù)docker鏡像。
https://docs.docker.com/registry/deploying/
因為使用swarm機(jī)制,所以不需要在服務(wù)間通信問題考慮服務(wù)發(fā)現(xiàn)以及負(fù)載均衡的問題(代替原有的consul®istor方式)。
3、構(gòu)建鏡像的運維節(jié)點 ops:
也即運維機(jī)器。一個獨立的節(jié)點即可。主要負(fù)責(zé)build鏡像,push鏡像。在ops里可以構(gòu)建gitlab的私庫。維護(hù)構(gòu)建腳本。機(jī)器所需配置不高,對網(wǎng)絡(luò)寬帶還是盡量多一些。
用docker-machine 模擬集群環(huán)境
創(chuàng)建registry節(jié)點
docker-machine create -d virtualbox --virtualbox-memory "512" registry
–engine-registry-mirror 這個參數(shù)是可以設(shè)置一些加速倉庫的地址。
創(chuàng)建manager,worker節(jié)點
manager
復(fù)制代碼 代碼如下:
docker-machine create -d virtualbox --virtualbox-memory "800" manager1
worker:
docker-machine create -d virtualbox --virtualbox-memory "800" worker1 docker-machine create -d virtualbox --virtualbox-memory "800" worker2 docker-machine create -d virtualbox --virtualbox-memory "800" worker3
創(chuàng)建ops 節(jié)點
docker-machine create -d virtualbox --virtualbox-memory "512" ops
查看機(jī)器列表狀態(tài)
docker-machine ls
創(chuàng)建registry服務(wù)
登錄到registry機(jī)器上。
docker-machine ssh registry
創(chuàng)建一個registry服務(wù)。
docker run -d -p 5000:5000 --restart=always --name registry \ -v `pwd`/data:/var/lib/registry \ registry:2
命令設(shè)置了-v volumn選項,這樣在每次容器服務(wù)重啟的時候,不會丟失已經(jīng)pull的鏡像數(shù)據(jù)。registry,MySQL等存儲類型的容器,建議設(shè)置一下volumn.如果為了更好的擴(kuò)展,也可以將鏡像倉庫備份到其他driver里,如阿里云的OSS.
運行docker ps就可以看到一個啟動好的registry服務(wù)。當(dāng)然,為了更好的擴(kuò)展,也可以掛載在自己的域名下,重新run 的時候添加認(rèn)證信息。
為了更方便管理容器,可以使用docker-compose 組件。安裝:
curl -L "https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
也可以寫好compose文件之后直接啟動:
docker-compose up -d
本地倉庫push鏡像
現(xiàn)在可以嘗試?yán)粋€鏡像,然后tag到本地的registry倉庫,如
docker pull lijingyao0909/see:1.0.3 && docker tag lijingyao0909/see:1.0.3 localhost:5000/see:1.0.3
然后再執(zhí)行push 命令:
docker push localhost:5000/see:1.0.3
這個鏡像就push到了registry服務(wù)中,最直接的方式可以通過查看本地的volumn目錄,如本例中的 data目錄查看到鏡像數(shù)據(jù)。
如果為了更方便的可視化管理registry,也可以試用下registry UI 相關(guān)的鏡像如hyper/docker-registry-web。
docker run -it -p 8080:8080 --name registry-web --link registry-srv -e REGISTRY_URL=http://registry-srv:5000/v2 -e REGISTRY_NAME=localhost:5000 hyper/docker-registry-web
然后訪問 hostname:5000/registory/index可以看到簡單的鏡像列表UI。
https 問題
在本地測試時如果執(zhí)行以上步驟,在push,或者在其他vb中pull鏡像時遇到以下問題:
Error response from daemon: Get https://registry:5000/v1/_ping: dial tcp 218.205.57.154:5000: i/o timeout
處理方式是,修改registry的認(rèn)證,如下先修改“/var/lib/boot2docker/profile”:
sudo vi /var/lib/boot2docker/profile
添加
DOCKER_OPTS="--insecure-registry:5000" DOCKER_OPTS="--insecure-registry registry:5000"
因為registry的hostname就是 registry。所以執(zhí)行docker ifno命令可以看到:
Insecure Registries: registry:5000 127.0.0.0/8
同時,在其他的worker機(jī)器,manager機(jī)器也需要修改–insecure-registry屬性,才可以pull私庫的鏡像。修改之后需重新restart vb。
重啟后,在manager重新嘗試pull
docker pull registry:5000/see:1.0.3
可以看到成功連接倉庫并拉取鏡像。注意,本示例使用的是機(jī)器名,registry,而不是IP地址。所以,在拉取鏡像的時候,需在各自的vb 的etc/hosts文件配置ip和機(jī)器名的映射。用機(jī)器名的方式比較操作易記。當(dāng)然最好的方式還是通過域名訪問倉庫。
參考資源
部署registry服務(wù)
創(chuàng)建ops服務(wù)
swarm的服務(wù)集群會直接從registry上pull鏡像,直接啟動應(yīng)用的service服務(wù)。服務(wù)的鏡像直接打在registry倉庫中,但是源碼可以維護(hù)在ops機(jī)器上。前面創(chuàng)建的ops的virtual-box,可以部署gitlab服務(wù)。啟動參數(shù)可以參考Deploy GitLab Docker images
先pull一個gitlab鏡像
docker run --detach \ --hostname gitlab.lijingyao.com \ --publish 443:443 --publish 80:80 --publish 22:22 \ --name gitlab \ --restart always \ --volume `pwd`/gitlab/config:/etc/gitlab \ --volume `pwd`/gitlab/logs:/var/log/gitlab \ --volume `pwd`/gitlab/data:/var/opt/gitlab \ gitlab/gitlab-ce:8.14.4-ce.0
使用git私庫
因綁定了80端口,啟動gitlab后訪問:http://machine-host/
第一次進(jìn)入gitlab會自動跳轉(zhuǎn)到重置密碼。可以設(shè)置一個新的密碼,這個是root賬號的密碼。后續(xù)就可以注冊其他git用戶使用了。
這里,如果申請了域名服務(wù),或者本地綁定gitlab.lijingyao.com 到這個virtualbox的ip地址,就可以直接訪問gitlab.lijingyao.com地址。在實際生產(chǎn)環(huán)境有固定公網(wǎng)ip,自己的DNS服務(wù),就不需要綁定host。這里只是本地測試,所以暫時就通過綁定host的方式。
swarm
本例中的服務(wù)是一個簡單的springboot 和gradle的工程,服務(wù)鏡像可以在docker hub pull,see service image。打包好鏡像后,直接在gradle task中push到registry倉庫中。在本地環(huán)境可以直接在工程目錄里執(zhí)行。gradle task然后push到vb的registry中,再在registry 倉庫pull鏡像即可?,F(xiàn)在開始準(zhǔn)備初始化swarm 集群。
現(xiàn)在整個vb 集群的機(jī)器,查看如下:
$docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS haproxy - virtualbox Running tcp://192.168.99.103:2376 v1.12.3 manager1 - virtualbox Running tcp://192.168.99.100:2376 v1.12.3 ops - virtualbox Running tcp://192.168.99.106:2376 v1.12.3 registry - virtualbox Running tcp://192.168.99.107:2376 v1.12.3 worker1 - virtualbox Running tcp://192.168.99.101:2376 v1.12.3 worker2 - virtualbox Running tcp://192.168.99.102:2376 v1.12.3 worker3 - virtualbox Running tcp://192.168.99.105:2376 v1.12.3
然后用docker-machine ssh manager1登陸到manager1機(jī)器上。
初始化swarm manager節(jié)點
在manager1 機(jī)器上初始化swarm,這個初始化的機(jī)器就是swarm的manager.執(zhí)行:
docker swarm init --advertise-addr 192.168.99.100
會看到以下執(zhí)行輸出:
Swarm initialized: current node (03x5vnxmk2gc43i0d7xpycvjg) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-5ru6lyco3upj7oje6hidug3erqczok84wk7bekzfaca4uv51r9-22bcjhkbxnclmw3nl3ui8601l \ 192.168.99.100:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
這個生成的token值,是其他swarm集群節(jié)點join到整個swarm的key。如果忘記了token,可以在manager1上執(zhí)行:
$docker swarm join-token manager
來查看目前的token值。官方建議至少6個月更換以下token。更換命令:
$docker swarm join-token --rotate worker
添加worker節(jié)點
分別登錄 worker1,worker2,worker3,執(zhí)行join命令。
在join之前,先查看下docker 網(wǎng)絡(luò)設(shè)施。執(zhí)行
$ docker network ls NETWORK ID NAME DRIVER SCOPE 4b7fe1416322 bridge bridge local 06ab6f3352b0 host host local eebd5c8e0d5d none null local
按照manager1 初始化之后的命令,執(zhí)行:
docker swarm join \ --token SWMTKN-1-5ru6lyco3upj7oje6hidug3erqczok84wk7bekzfaca4uv51r9-22bcjhkbxnclmw3nl3ui8601l \ 192.168.99.100:2377
此時在任何worker節(jié)點再執(zhí)行docker network ls 即可看到多了一個overlay的覆蓋范圍為swarm的網(wǎng)絡(luò)通道。
三個worker都加入之后,在manager1 上即可看到manager的node節(jié)點情況
docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 03x5vnxmk2gc43i0d7xpycvjg * manager1 Ready Active Leader 2y5wrndibe8c8sqv6851vrlgp worker1 Ready Active Reachable dwgol1uinkpsybigc1gm5jgsv worker2 Ready Active etgyky6zztrapucm59yx33tg1 worker3 Ready Active Reachable
manager status的Reachable狀態(tài)表示該節(jié)點也是manager節(jié)點。這是因為我們在worker1,worker3分別執(zhí)行了
docker node promote worker1 docker node promote worker3
worker1,worker3此時也可以執(zhí)行swarm命令,在manager1關(guān)停時,就會選舉其中之一作為新的leader。如果要去除node的manager狀態(tài),可以通過demote命令去除。執(zhí)行后,worker節(jié)點就變成普通的任務(wù)節(jié)點。
docker node demote worker1 worker3
swarm節(jié)點的其他狀態(tài)
swarm節(jié)點可以設(shè)置drain狀態(tài),drain狀態(tài)的節(jié)點不會執(zhí)行任何service。
將某個node設(shè)置不可用:
docker node update --availability drain worker1
Pause,Drain,Active三個狀態(tài),pause標(biāo)識有任務(wù)運行,不接受新任務(wù)。
如果要將worker1 節(jié)點去除swarm中心,現(xiàn)在需被移除的節(jié)點(worker1)執(zhí)行:docker swarm leave 然后在manager上執(zhí)行:docker node rm worker1,即可移除一個swarm節(jié)點。
創(chuàng)建swarm服務(wù)
本例中使用swarm部署一個基于springboot的rest api服務(wù)。倉庫的地址:springboot-restful-exam,創(chuàng)建的服務(wù)name是deftsee,綁定80端口,并且擴(kuò)展4個運行容器服務(wù)。
docker service create \ --replicas 4 \ --name deftsee \ --update-delay 10s \ --publish 8080:80 \ lijingyao0909/see:1.0.3
服務(wù)創(chuàng)建之后,可以查看服務(wù)節(jié)點的狀態(tài)
docker@manager1:~$ docker service ls ID NAME REPLICAS IMAGE COMMAND a6s5dpsyz7st deftsee 4/4 lijingyao0909/see:1.0.3
REPLICAS 代表服務(wù)的運行容器數(shù),如果是0/4就代表所有服務(wù)都沒有起來。詳細(xì)查看各個節(jié)點運行狀態(tài)可以用docker service ps servicename
docker@manager1:~$ docker service ps deftsee ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 8lsdkf357lk0nmdeqk7bi33mp deftsee.1 lijingyao0909/see:1.0.3 worker2 Running Running 5 minutes ago cvqm5xn7t0bveo4btfjsm04jp deftsee.2 lijingyao0909/see:1.0.3 manager1 Running Running 7 minutes ago 6s5km76w2vxmt0j4zgzi4xi5f deftsee.3 lijingyao0909/see:1.0.3 worker1 Running Running 5 minutes ago 4cl9vnkssedpvu2wtzu6rtgxl deftsee.4 lijingyao0909/see:1.0.3 worker3 Running Running 6 minutes ago
可以看到任務(wù)被平分到所有的四個任務(wù)節(jié)點運行。下面再擴(kuò)容deftsee服務(wù)
docker@manager1:~$ docker service scale deftsee=6 deftsee scaled to 6 docker@manager1:~$ docker service ps deftsee ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 8lsdkf357lk0nmdeqk7bi33mp deftsee.1 lijingyao0909/see:1.0.3 worker2 Running Running 8 minutes ago cvqm5xn7t0bveo4btfjsm04jp deftsee.2 lijingyao0909/see:1.0.3 manager1 Running Running 10 minutes ago 6s5km76w2vxmt0j4zgzi4xi5f deftsee.3 lijingyao0909/see:1.0.3 worker1 Running Running 8 minutes ago 4cl9vnkssedpvu2wtzu6rtgxl deftsee.4 lijingyao0909/see:1.0.3 worker3 Running Running 9 minutes ago 71uv51uwvso4l340xfkbacp2i deftsee.5 lijingyao0909/see:1.0.3 manager1 Running Running 5 seconds ago 4r2q7q782ab9fp49mdriq0ssk deftsee.6 lijingyao0909/see:1.0.3 worker2 Running Running 5 seconds ago
lijingyao0909/see:1.0.3是dockerhub的公共倉庫的鏡像,服務(wù)創(chuàng)建時會去pull鏡像,整體速度偏慢,所以可以結(jié)合私有倉庫,直接在registry機(jī)器上pull鏡像。服務(wù)可以直接用docker service rm deftsee移除服務(wù),然后通過registry重建服務(wù)。
docker service create \ --replicas 6 \ --name deftsee \ --update-delay 10s \ --publish 8080:80 \ registry:5000/see:1.0.4
此時登錄任何一臺worker服務(wù),查看運行的容器鏡像:
docker@worker2:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 89d4f588290b registry:5000/see:1.0.4 "/bin/sh -c 'java -Dc" About a minute ago Up About a minute 8080/tcp deftsee.1.eldpgb1aqtf9v49cxolydfjm9
如果要更新服務(wù),可以直接通過update命令更新版本,并且服務(wù)滾動發(fā)布,通過設(shè)置*–update-delay 10s *可以改變更新時各個節(jié)點的延遲時間。
docker service update --image registry:5000/see:1.0.5 deftsee
重啟某個node的服務(wù)
關(guān)閉:docker node update –availability drain worker1
開啟:docker node update –availability active worker1
更新服務(wù)端口
更新一個服務(wù)的端口會重啟服務(wù)(關(guān)閉原有服務(wù),重新創(chuàng)建服務(wù)并啟動):
docker service update \ --publish-add: \ docker@manager1:~$docker service update \ --publish-add 8099:8080 \ deftsee docker@manager1:~$ docker service ps deftsee ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 3xoe34msrht9eqv7eplnmlrz5 deftsee.1 registry:5000/see:1.0.4 manager1 Running Running 39 seconds ago eldpgb1aqtf9v49cxolydfjm9 \_ deftsee.1 registry:5000/see:1.0.4 worker2 Shutdown Shutdown 39 seconds ago 9u4fh4mi5kxb14y6gih6d8tqv deftsee.2 registry:5000/see:1.0.4 manager1 Running Running about a minute ago 0skgr5fx4xtt6y71yliksoft0 \_ deftsee.2 registry:5000/see:1.0.4 worker1 Shutdown Shutdown about a minute ago 8hposdkqe92k7am084z6kt1j0 deftsee.3 registry:5000/see:1.0.4 worker3 Running Running about a minute ago c5vhx1wx0q8mxaweaq0mia6n7 \_ deftsee.3 registry:5000/see:1.0.4 manager1 Shutdown Shutdown about a minute ago 9se1juxiinmetuaccgkjc3rr2 deftsee.4 registry:5000/see:1.0.4 worker1 Running Running about a minute ago 4wofho0axvrjildxhckl52s41 \_ deftsee.4 registry:5000/see:1.0.4 worker3 Shutdown Shutdown about a minute ago
服務(wù)驗證和網(wǎng)絡(luò)
例子中的服務(wù)啟動后,可以直接通過ip:port訪問。如http://192.168.99.100:8099/see,可以看到服務(wù)請求會分發(fā)到各個運行的節(jié)點中。也就是swarm的overlay網(wǎng)絡(luò)層,各個節(jié)點的網(wǎng)絡(luò)是互通的,swarm做了load balance,在swarm的lb的基礎(chǔ)上也可搭建自己定義的overlay網(wǎng)絡(luò),創(chuàng)建的這個overlay 網(wǎng)絡(luò),所有節(jié)點都可以和這個network互通。但是在服務(wù)創(chuàng)建的時候需要制定network選項。
$docker network create \ --driver overlay \ --subnet 10.0.9.0/24 \ --opt encrypted \ my-network $docker service create \ --name deftsee \ --publish 8099:80 \ --replicas 4 \ --network my-network \ -l com.df.serviceDomain=deftsee.com \ -l com.df.notify=true \ lijingyao0909/see:1.0.3
–network my-network制定了服務(wù)可連接到的docker network,可以在swarm的節(jié)點創(chuàng)建一個name為my-network的網(wǎng)絡(luò)。所以也可以在swarm機(jī)制中搭建consul和haproxy的服務(wù)發(fā)現(xiàn)和lb機(jī)制。
當(dāng)為一個服務(wù)指定一個network的時候,swarm上執(zhí)行的任務(wù)也必須都在這個指定的網(wǎng)絡(luò)上才能和服務(wù)互通。如果節(jié)點上沒有加入到swarm模式的node中,或者沒有運行掛載在這個指定網(wǎng)絡(luò)的時候,也不會和這個network互通.docker network ls也不會查出該網(wǎng)絡(luò)。創(chuàng)建服務(wù)時通過–network my-network這個標(biāo)簽鏈接到這個網(wǎng)絡(luò)。在查看網(wǎng)絡(luò)時,docker network inspect my-network可以查看返回的Containers 列出的該節(jié)點的掛載容器。
創(chuàng)建了一個網(wǎng)絡(luò)服務(wù),有service連接到網(wǎng)絡(luò)時,swarm會給這個網(wǎng)絡(luò)下的服務(wù)(service)指定一個vip. swarm 內(nèi)部的lb會自動分發(fā)服務(wù),不需要指定每個服務(wù)端口,即在同一個network連接的容器,通過service name就可以訪問到服務(wù)。因為所有加入到這個network的容器都會通過gossip協(xié)議共享一個DNS映射(vip映射根據(jù)service name 綁定到的dns別名映射)。
查看服務(wù)的vip網(wǎng)絡(luò)信息:
$docker service inspect \ --format='{{json .Endpoint.VirtualIPs}}' \ deftsee 輸出:[{"NetworkID":"dn05pshfagohpebgonkhj5kxi","Addr":"10.255.0.6/16"}]
swarm管理
為了保持manager節(jié)點的可用性(心跳機(jī)制,leader選舉),可以將manager節(jié)點設(shè)置成不接受服務(wù)運行,節(jié)省manager節(jié)點資源,將manager節(jié)點隔離出任務(wù)環(huán)境。
docker node update --availability drain
備份/var/lib/docker/swarm/raft 狀態(tài)
清理不可用的節(jié)點
docker node demotedocker node rm .
節(jié)點重新加入manager re-join
$docker node demote. $docker node rm . $docker swarm join ...
初始化的時候指定固定ip ,init –advertise-addr。worker節(jié)點可以用動態(tài)ip 。
以上是“基于docker-swarm搭建持續(xù)集成集群服務(wù)的方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!