使用 Docker Stack 部署多服務(wù)集群

前言


單機(jī)模式下,我們可以使用 Docker Compose 來(lái)編排多個(gè)服務(wù)郭变,而在 上一篇文章 中介紹的 Docker Swarm 只能實(shí)現(xiàn)對(duì)單個(gè)服務(wù)的簡(jiǎn)單部署。于是就引出了本文的主角 Docker Stack 蓖救,通過(guò) Docker Stack 我們只需對(duì)已有的 docker-compose.yml 配置文件稍加改造就可以完成 Docker 集群環(huán)境下的多服務(wù)編排瑞躺。

正文


  • 首先創(chuàng)建一個(gè) docker-compose.yml 文件,使用 Docker Compose v3 語(yǔ)法

    內(nèi)容比較簡(jiǎn)單莺禁,一個(gè)有四個(gè)實(shí)例的 nginx 服務(wù)留量,兩個(gè)只部署在 manager 節(jié)點(diǎn)上的單實(shí)例監(jiān)控工具服務(wù):portainervisualizer

version: "3"

services:
  nginx:
    image: nginx:alpine
    ports:
      - 80:80
    deploy:
      mode: replicated
      replicas: 4

  visualizer:
    image: dockersamples/visualizer
    ports:
      - "9001:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

  portainer:
    image: portainer/portainer
    ports:
      - "9000:9000"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
  • 部署服務(wù)
$ docker stack deploy -c docker-compose.yml stack-demo
  • 部署成功之后查看詳情
$ docker stack services stack-demo 
ID                  NAME                    MODE                REPLICAS            IMAGE                             PORTS
4yb35ywqvo49        stack-demo_portainer    replicated          1/1                 portainer/portainer:latest        *:9000->9000/tcp
mzd2volqug28        stack-demo_nginx        replicated          4/4                 nginx:alpine                      *:80->80/tcp
r0zlzpp3wujg        stack-demo_visualizer   replicated          1/1                 dockersamples/visualizer:latest   *:9001->8080/tcp
  • 在瀏覽器中訪(fǎng)問(wèn)監(jiān)控工具,對(duì)應(yīng)端口如下:
portainer  ——→ ip:9000
visualizer ——→ ip:9001

注意:如果有多個(gè) manager 節(jié)點(diǎn)哟冬,portainer 和 visualizer 可能分別部署在兩臺(tái)機(jī)器上楼熄,所以ip可能會(huì)不一樣。

  • 修改 docker-compose.yml 文件后重新部署即可完成對(duì)修改內(nèi)容的更新
$ docker stack deploy -c docker-compose.yml stack-demo

關(guān)于負(fù)載均衡


評(píng)論區(qū)有小伙伴提到浩峡,容器間通過(guò)服務(wù)名 ( 比如文中的 nginx ) 通訊時(shí)可岂,對(duì)應(yīng)的 IP 卻和容器的實(shí)際 IP 對(duì)不上。出現(xiàn)這個(gè)情況是因?yàn)樨?fù)載均衡( 對(duì)外表現(xiàn)為一個(gè)服務(wù)翰灾,內(nèi)部為多個(gè)服務(wù) )缕粹。下面是我做的試驗(yàn),希望能幫助大家理解纸淮。

  1. 按上面的配置啟動(dòng)集群 ( 由兩臺(tái)服務(wù)器構(gòu)成 )

  2. manager 節(jié)點(diǎn)服務(wù)器中看下運(yùn)行的服務(wù)

    $ docker ps
    CONTAINER ID IMAGE NAMES
    9b96f07bbb91 dockersamples/visualizer:latest stack-demo_visualizer.1.p5hy7gsc50vbm0wkxm1c17rl6
    942dd34d024e nginx:alpine stack-demo_nginx.4.tp6u05jmg9iuookqc9i9e11kz
    706ae42e0089 nginx:alpine stack-demo_nginx.2.vnlmlky5m5qy7l8qxq6k5nllk
    6dba55dd7d63 portainer/portainer:latest stack-demo_portainer.1.yv76gf0i7gou2awen44kshm1j
    
  3. 在這臺(tái)服務(wù)器上啟動(dòng)了兩個(gè) nginx 容器實(shí)例平斩,隨便進(jìn)一個(gè)實(shí)例看下 IP

    $ docker exec -it stack-demo_nginx.2.vnlmlky5m5qy7l8qxq6k5nllk ifconfig
    eth0 Link encap:Ethernet HWaddr 02:42:0A:FF:00:3E
    inet addr:10.255.0.62 Bcast:10.255.255.255 Mask:255.255.0.0
    eth1 Link encap:Ethernet HWaddr 02:42:0A:00:06:07
    inet addr:10.0.6.7 Bcast:10.0.6.255 Mask:255.255.255.0
    eth2 Link encap:Ethernet HWaddr 02:42:AC:13:00:04
    inet addr:172.19.0.4 Bcast:172.19.255.255 Mask:255.255.0.0
    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    

    發(fā)現(xiàn)容器中綁了3個(gè)網(wǎng)卡 eth0eth1 咽块、eth2 绘面,我猜想分別對(duì)應(yīng) 整個(gè) Swarm 集群的局域網(wǎng)當(dāng)前 Stack 集群的局域網(wǎng) 侈沪、當(dāng)前主機(jī)下 Compose 服務(wù)的局域網(wǎng) 三個(gè)網(wǎng)絡(luò)揭璃。

  4. 查看當(dāng)前主機(jī)下的 docker 網(wǎng)絡(luò)

    $ docker network ls
    NETWORK ID NAME DRIVER SCOPE
    bd4fa8219483 bridge bridge local
    e51735fef0d6 docker_gwbridge bridge local
    26360437865a host host local
    yvupj4ex3odl ingress overlay swarm
    f0a0190c3b1f none null local
    oft930l7jpdn stack-demo_default overlay swarm
    
  5. 上一步看到有兩個(gè) swarm 的網(wǎng)絡(luò),進(jìn)去看下具體信息

    $ docker network inspect ingress
    "IPAM": {
        "Config": [
            {
                "Subnet": "10.255.0.0/16",
                "Gateway": "10.255.0.1"
            }
        ]
    },
    "Containers": {
        "6dba55dd7d63f7166e2e0ee3afed8e427089b7140d62f39a835d3145a058b868": {
            "Name": "stack-demo_portainer.1.yv76gf0i7gou2awen44kshm1j",
            "IPv4Address": "10.255.0.59/16",
        },
        "706ae42e00890444087aa6d51ccb966b76b5ad4c985b48fdf5215c192bcf0836": {
            "Name": "stack-demo_nginx.2.vnlmlky5m5qy7l8qxq6k5nllk",
            "IPv4Address": "10.255.0.62/16",
        },
        "942dd34d024e218aad4e5034e1194a2cfa1d9be81a839ec86403cf237d41368b": {
            "Name": "stack-demo_nginx.4.tp6u05jmg9iuookqc9i9e11kz",
            "IPv4Address": "10.255.0.64/16",
        },
        "9b96f07bbb91a570bb8d26945996d77151c5633c0a6057361ab4474b393da364": {
            "Name": "stack-demo_visualizer.1.p5hy7gsc50vbm0wkxm1c17rl6",
            "IPv4Address": "10.255.0.66/16",
        },
        "ingress-sbox": {
            "Name": "ingress-endpoint",
            "IPv4Address": "10.255.0.2/16",
        }
    }
    

    內(nèi)容太多就省略其他無(wú)關(guān)內(nèi)容了亭罪,從上面的信息已經(jīng)可以證明第三步的猜想了 ( ingress 對(duì)應(yīng) Swarm 集群 , stack-demo_default 對(duì)應(yīng) Stack 集群 ) 瘦馍,要進(jìn)一步確認(rèn)可以再看下另一臺(tái)服務(wù)器上的網(wǎng)絡(luò)。

  6. 通過(guò)容器 nginx.4 使用服務(wù)名的方式 ping 一下 nginx

    $ docker exec -it stack-demo_nginx.4.tp6u05jmg9iuookqc9i9e11kz ping nginx
    PING nginx (10.0.6.5): 56 data bytes
    64 bytes from 10.0.6.5: seq=0 ttl=64 time=0.121 ms
    

    發(fā)現(xiàn) IP10.0.6.5 皆撩,屬于 stack-demo_default 網(wǎng)絡(luò)扣墩,但是在兩臺(tái)服務(wù)器的 docker 網(wǎng)絡(luò)詳情里面都找不到這個(gè)實(shí)例哲银。

  7. 在容器 nginx.4 中安裝 curl 然后再訪(fǎng)問(wèn) nginx 看下效果

    $ docker exec -it stack-demo_nginx.4.tp6u05jmg9iuookqc9i9e11kz sh -c 'echo -e "https://mirrors.ustc.edu.cn/alpine/latest-stable/main\nhttps://mirrors.ustc.edu.cn/alpine/latest-stable/community" > /etc/apk/repositories && apk --update add curl'
    $ docker exec -it stack-demo_nginx.4.tp6u05jmg9iuookqc9i9e11kz curl nginx
    

    可以看到訪(fǎng)問(wèn)成功扛吞,再多調(diào)用幾次。

  8. 打印 nginx 容器的日志 ( 可以多開(kāi)幾個(gè)終端打印日志荆责,再訪(fǎng)問(wèn) nginx 看下實(shí)時(shí)日志的效果滥比,這樣更直觀 )

    $ docker logs stack-demo_nginx.2.vnlmlky5m5qy7l8qxq6k5nllk && echo "---分界線(xiàn)---" && docker logs stack-demo_nginx.4.tp6u05jmg9iuookqc9i9e11kz
    10.0.6.4 - - [06/Dec/2018:10:15:18 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.60.0" "-"
    ---分界線(xiàn)---
    10.0.6.4 - - [06/Dec/2018:10:13:16 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.60.0" "-"
    10.0.6.4 - - [06/Dec/2018:10:15:19 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.60.0" "-"
    

    可以看到明顯的負(fù)載均衡的效果,請(qǐng)求都來(lái)自 10.0.6.4做院,它就是 stack-demo_default 網(wǎng)絡(luò)中一個(gè)名為 lb- 開(kāi)頭的實(shí)例盲泛,它就是這個(gè)負(fù)載均衡的入口濒持。

    "lb-stack-demo_default": {
     "Name": "stack-demo_default-endpoint",
     "IPv4Address": "10.0.6.4/24",
    }
    
  9. 再去另一臺(tái)服務(wù)器看下 nginx 的日志

    發(fā)現(xiàn)并沒(méi)有訪(fǎng)問(wèn)記錄,說(shuō)明這個(gè)負(fù)載均衡僅限于 當(dāng)前服務(wù)器 寺滚、相同服務(wù)多個(gè)實(shí)例柑营,不會(huì)跨服務(wù)器負(fù)載均衡。

  10. 在另一臺(tái)服務(wù)器上再重復(fù) 7 & 8 兩個(gè)步驟

    發(fā)現(xiàn)另一臺(tái)服務(wù)器上不存在名為 lb- 開(kāi)頭的實(shí)例村视,而負(fù)載均衡的入口是其中一個(gè)普通的 nginx 實(shí)例官套。

總結(jié)下:

整個(gè)請(qǐng)求的調(diào)用流程應(yīng)該就是:通過(guò)服務(wù)名 nginx 訪(fǎng)問(wèn) -- 指向 --> stack 集群網(wǎng)關(guān) ( 10.0.6.5 ) -- 轉(zhuǎn)發(fā) --> stack 集群中,位于當(dāng)前服務(wù)器的負(fù)載均衡實(shí)例 ( 10.0.6.4 ) -- 分發(fā) --> 最終的應(yīng)用 蚁孔。

相關(guān)命令


命令 描述
docker stack deploy 部署新的堆椖膛猓或更新現(xiàn)有堆棧
docker stack ls 列出現(xiàn)有堆棧
docker stack ps 列出堆棧中的任務(wù)
docker stack rm 刪除一個(gè)或多個(gè)堆棧
docker stack services 列出堆棧中的服務(wù)

參考文章



系列文章


Docker 學(xué)習(xí)總結(jié)

Docker 常用指令詳解

使用 Dockerfile 構(gòu)建鏡像

使用 Docker Compose 構(gòu)建容器

Docker Daemon 連接方式詳解

Docker 下的網(wǎng)絡(luò)模式


轉(zhuǎn)載請(qǐng)注明出處:http://www.reibang.com/p/1db6f0150fdb

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市杠氢,隨后出現(xiàn)的幾起案子站刑,更是在濱河造成了極大的恐慌,老刑警劉巖鼻百,帶你破解...
    沈念sama閱讀 212,185評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绞旅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡愕宋,警方通過(guò)查閱死者的電腦和手機(jī)玻靡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,445評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)中贝,“玉大人囤捻,你說(shuō)我怎么就攤上這事×谑伲” “怎么了蝎土?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,684評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)绣否。 經(jīng)常有香客問(wèn)我誊涯,道長(zhǎng),這世上最難降的妖魔是什么蒜撮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,564評(píng)論 1 284
  • 正文 為了忘掉前任暴构,我火速辦了婚禮,結(jié)果婚禮上段磨,老公的妹妹穿的比我還像新娘取逾。我一直安慰自己,他們只是感情好苹支,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,681評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布砾隅。 她就那樣靜靜地躺著,像睡著了一般债蜜。 火紅的嫁衣襯著肌膚如雪晴埂。 梳的紋絲不亂的頭發(fā)上究反,一...
    開(kāi)封第一講書(shū)人閱讀 49,874評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音儒洛,去河邊找鬼精耐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛琅锻,可吹牛的內(nèi)容都是我干的黍氮。 我是一名探鬼主播,決...
    沈念sama閱讀 39,025評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼浅浮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼沫浆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起滚秩,我...
    開(kāi)封第一講書(shū)人閱讀 37,761評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤专执,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后郁油,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體本股,經(jīng)...
    沈念sama閱讀 44,217評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,545評(píng)論 2 327
  • 正文 我和宋清朗相戀三年桐腌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拄显。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,694評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡案站,死狀恐怖躬审,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蟆盐,我是刑警寧澤承边,帶...
    沈念sama閱讀 34,351評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站石挂,受9級(jí)特大地震影響博助,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜痹愚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,988評(píng)論 3 315
  • 文/蒙蒙 一富岳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拯腮,春花似錦窖式、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,778評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)飒箭。三九已至狼电,卻和暖如春蜒灰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肩碟。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,007評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工强窖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人削祈。 一個(gè)月前我還...
    沈念sama閱讀 46,427評(píng)論 2 360
  • 正文 我出身青樓翅溺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親髓抑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咙崎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,580評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容