基於go的微服務搭建(五) - 部署docker swarm

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

標題: 部署docker swarm

這部分,我們啟動我們的accountservice,運行在本地的docker swarm叢集中.同時討論幾個容器部署的重要概念
這篇部落客要講一下幾點:

  • docker swarm和容器部署
  • 用docker作為容器運行accountservice
  • 建立一個本地的docker swarm叢集
  • 將accountservice作為swarm服務部署
  • 基測和結果

其實寫完這一章,我發現這一章和go沒有關係.但希望你喜歡.

什麼是容器部署

在實踐開始之前,一個容器部署的簡單介紹:
當一個應用越來越複雜,並且開始有更高的負載,將會有成百個服務在很多硬體上運行.容器部署讓我們在一個節點上管理我們的硬體
一篇文章上總結的:

抽象主機的基礎結構,部署工具允許使用者在一個部署目標上控制整個叢集.

這總結的很好.用kubernetes或者docker swarm這種容器部署工具來部署我們的各個服務在不同的節點上.對於docker來說,swarm模式管理docker engine的叢集.kubernetes用一種稍微不同的抽象方法,但是整體概念上是一致的.
容器部署不僅控制我們服務的生命週期,也提供其他服務,例如:服務發現,負載平衡,內部地址和日誌.

docker swarm核心概念

在docker swarm中,有三個核心概念:

  • 節點: 一個節點就是一個docker engine的執行個體.理論上講,他是一個擁有cpu資源,記憶體和網路介面的主機.一個節點可以是一個manager節點或者worker節點.
  • 服務: 服務就是worker節點上啟動並執行指令.一個服務可以是複製的或者全域的.一個服務可以抽象的看成是任意數量的容器組成的邏輯上的服務.這個服務可以用它的名字來調用,而不需要知道它內部的網路結構.
  • 任務: 一個任務可以是docker容器,docker檔案定義任務為:擁有並運行docker容器和指令.manager節點分發任務給worker節點的服務.

展示一個簡單的微服務架構.兩個服務accountservice和quotes-service抽象為兩個節點,運行在五個容器的執行個體中.

![圖片上傳中...]

代碼

這部分沒有改go方面的代碼.

cker.你可以得到這一章完整的代碼

git checkout P5

容器化我們的accountservice

docker安裝

你需要安裝docker.我用的是docker toolbox 和vitualbox.但是你可以直接用docker.

建立dockerfile

一個dockerfile可以看成是你想建立什麼樣的docker鏡像的配方.讓我們在accountservice檔案夾中建立檔案Dockerfile:

FROM iron/baseEXPOSE 6767ADD accountservice-linux-amd64 /ENTRYPOINT ["./accountservice-linux-amd64"]

解釋:

  • FROM-定義我們的基礎鏡像.我們會在這個鏡像上開始.iron/base是一個可以運行go程式的小巧的鏡像
  • EXPOSE-定義一個連接埠,作為外部請求的連接埠
  • ADD-增加一個檔案accountservice-linux-amd64到root(/)目錄下
  • ENTRYPOINT-定義啟動哪一個程式,當docker開啟這個鏡像容器

不同作業系統下的編譯

我們的檔案名稱字包含linux-amd64.我們可以叫他任何名字,但是我喜歡把作業系統和cpu型號放進執行檔案名稱字中.我用的是mac OSX 系統.所以我如果直接編譯go的執行檔案,用go build的話,這產生一個執行檔案在同一個檔案夾中.然而這個執行檔案不能再docker上運行,因為docker容器的環境是linux.因此,我們需要設定一些環境參數,這樣我們的編譯器才知道我們要給其他的系統或者cpu環境編譯檔案.
在goblog/accountservice檔案夾下面運行:

export GOOS=linuxgo build -o accountservice-linux-amd64export GOOS=darwin

-o表示產生二進位執行檔案.我經常用指令檔自動做這些東西(後面會有)
因為OS X和linux容器都在AMD64 cpu架構上,我們不需要設定GOARCH參數.但是你如果用32位系統,或者ARM處理器,你要設定GOARCH參數

建立docker鏡像

現在我們建立第一個docker鏡像,包含我們的執行檔案.去accountservice的上層檔案夾,就是$GOPATH/src/github.com/callistaenterprise/goblog.
對於docker鏡像,我們經常用一個首碼來標註名字.我經常用我的github名字作為首碼,例如eriklupander/myservicename.這裡,我用someprefix作為首碼.執行下面的命令來建立Docker鏡像:

> docker build -t someprefix/accountservice accountservice/Sending build context to Docker daemon 13.17 MBStep 1/4 : FROM iron/base ---> b65946736b2cStep 2/4 : EXPOSE 6767 ---> Using cache ---> f1147fd9abcfStep 3/4 : ADD accountservice-linux-amd64 / ---> 0841289965c6Removing intermediate container db3176c5e1e1Step 4/4 : ENTRYPOINT ./accountservice-linux-amd64 ---> Running in f99a911fd551 ---> e5700191acf2Removing intermediate container f99a911fd551Successfully built e5700191acf2

好了,我們有啦一個someprefix/accountservice鏡像.如果我們要在多節點下運行或者分享鏡像,我們可以用docker push來使我們的鏡像被別的主機pull.
我們現在運行鏡像:

> docker run --rm someprefix/accountserviceStarting accountserviceSeeded 100 fake accounts...2017/02/05 11:52:01 Starting HTTP service at 6767

然而,我們的容器不是在你的主機系統下運行,他運行在自己的網路中,我們不能直接從我們的主機來請求他.有辦法來解決這個問題,但現在我們放一放,我們繼續組建我們的docker swarm和部署accountservice.

建立單節點Docker swarm叢集

一個docker swarm叢集包括至少一個swarm manager和零到多個swarm worker.我的例子會包含一個swarm manager.這節過後,你會有一個swarm manager運行.
你可以參考別的文章來看如何運行swarm.下面這條命令初始化docker主機為swarm-manager-1作為一個swarm節點,同時讓swarm-manager-1節點地址和主機一樣

> docker $(docker-machine config swarm-manager-1) swarm init --advertise-addr $(docker-machine ip swarm-manager-1)

如果我們要建立多節點的swarm叢集,我們要把這條命令產生的join-token記錄下來,這樣我們可以加入其他的節點到這個swarm中.

建立網路

一個docker網路的用處是,當我們想請求同一個swarm叢集上的其他的容器,並不需要知道真實的叢集分布.

docker network create --driver overlay my_network

my_network是我們的網路名稱

部署accountservice

現在我們要部署我們的accountservice進Docker swarm服務中.這個docker服務命令有很多參數設定,但不要怕.這裡我們來部署accountservice

docker service create --name=accountservice --replicas=1 --network=my_network -p=6767:6767 someprefix/accountservicentg3zsgb3f7ah4l90sfh43kud

快速看一下這些參數

  • -name:給服務的名字.這也是叢集中其他服務要求我們的名字.所以另一個服務來請求accountservice的話,這個服務只需要Get請求http://accountservice:6767/accounts/10000
  • -replicas: 我們服務的執行個體數量.如果我們有多節點的docker swarm叢集,swarm engine會自動分發執行個體到不同的節點上.
  • -network: 這裡我們告訴我們的服務用剛剛我們建立的網路my_network
  • -p: 映射[內部連接埠]:[外部連接埠].這裡我們用6767:6767.如果我們用6767:80,從外部請求要用80連接埠.注意這部分使我們的服務可以被外界請求.大多數情況,你不應該讓你的服務暴露給外界.你應該用一個EDGE-server(例如反向 Proxy),包括路由機制和安全檢查,所以外界不能隨意請求你的服務
  • someprefix/accountservice: 指明我們想讓容器運行哪一個鏡像.

讓我們看看我們的服務是否運行了

> docker service ls

太好了,我們應該可以curl或者用瀏覽器請求我們的api.唯一要知道的就是我們swarm的ip地址.即使我們只運行一個服務執行個體,我們的網路和swarm也會需要我們的服務外部連接埠,這意味著兩個服務不能用同一個外部連接埠.他們可以有同樣的內部連接埠,但對於外部來說,swarm是一個整體.

> echo $ManagerIP192.168.99.100

如果你換了terminal,你可以重新匯出:

> export ManagerIP=`docker-machine ip swarm-manager-0`

curl請求:

> curl $ManagerIP:6767/accounts/10000{"id":"10000","name":"Person_0"}

部署可視化

用docker的命令來查看swarm的狀態不容易看,一個圖形化的方法比較好.例如manomarks docker swarm visualizer可以被部署為一個Docker swarm的服務.這可以給我們提供我們叢集分布的圖形,同事確保我們在叢集中外部暴露的服務可不可以請求到.
初始化這個可視器在容器鏡像中

docker service create \ --name=viz \ --publish=8080:8000/tcp \ --constraint=node.role==manager \ --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \ manomarks/visualizer

這將在8000連接埠產生一個服務.讓我們用瀏覽器瀏覽http://$ManagerIP:8000

額外內容

我也做了一個swarm的可視化介面叫做dvizz,展示docker 遠程api和D3.js force圖.你可以安裝她

docker service create \ --constraint=node.role==manager \ --replicas 1 --name dvizz -p 6969:6969 \ --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \ --network my_network \ eriklupander/dvizz

瀏覽 http://$ManagerIP:6969

加入quote-service

只有一個服務的微服務不能看出微服務的全貌.讓我們部署一個基於spring boot的quotes-service.我把這個容器鏡像放在docker hub中的eriklupander/quotes-service.

> docker service create --name=quotes-service --replicas=1 --network=my_network eriklupander/quotes-service

如果你輸入docker ps來看那些docker容器在運行:

> docker psCONTAINER ID    IMAGE                       COMMAND                 CREATED         STATUS                           PORTS                                           NAMES98867f3514a1    eriklupander/quotes-service "java -Djava.security"  12 seconds ago  Up 10 seconds

注意,我們沒有暴露一個外界連接埠給這個服務,所以我們只能在叢集內部的連接埠8080內請求.我們會整合這個服務在第七部分同時看一下服務探索和負載平衡.
如果你加入了dvizz,你應該能看到quotes-service和accountservice

copyall.sh指令碼

我們來做一個指令碼協助我們編譯和部署.在root/goblog檔案夾中,建立一個指令檔叫做copyall.sh

#!/bin/bashexport GOOS=linuxexport CGO_ENABLE=0cd accountservice; go get; go build -o accountservice-linux-amd64;echo build `pwd`;cd ..export GOOS=darwindocker build -t someprefix/accountservice accountservice/docker service rm accountservicedocker service create --name=accountservice --replicas=1 --network=my_network -p=6767:6767someprefix/accountservice

這段指令碼編譯執行檔案,重新編譯docker鏡像,部署到docker swarm服務上.
我喜歡指令碼的簡化,雖然有時我用gradle plugin.

效能

現在開始,所有的基測都在docker swarm上進行.這意味之前的結果不能用來和之後的比較
cpu使用率和記憶體使用量會用 docker stats來收集.我們也會用gatling測試.
如果你喜歡壓力測試,第二節的仍然可以用,但需要改變-baseUrl參數

> mvn gatling:execute -dusers=1000 -Dduration=30 -DbaseUrl=http://$ManagerIP:6767

記憶體使用量率

> docker stats $(docker ps | awk '{if(NR>1) print $NF}')CONTAINER                                    CPU %               MEM USAGE / LIMIT    accountservice.1.k8vyt3dulvng9l6y4mj14ncw9   0.00%               5.621 MiB / 1.955 GiBquotes-service.1.h07fde0ejxru4pqwwgms9qt00   0.06%               293.9 MiB / 1.955 GiB

啟動後,包含linux和我們accountservice的容器用5.6mb的記憶體,java開發的quotes-service用了300mb.雖然這可以通過調整jvm來降低.

cpu和記憶體使用量壓力測試

CONTAINER                                    CPU %               MEM USAGE / LIMIT   accountservice.1.k8vyt3dulvng9l6y4mj14ncw9   25.50%              35.15 MiB / 1.955 GiBB

在1K req/s下,虛擬機器中啟動並執行swarm和在第二三節中的OS x系統相比,記憶體稍微升高,cpu大略相同.

效能

![圖片上傳中...]

延遲上升到4ms.這和直接運行有所升高,原因有幾點.我認為gatling測試通過橋接的網路和swarm上的路由會有一些延遲.但是4ms的延遲也不錯.畢竟我們從boltDB讀資料,序列化到json並輸出到HTTP.

總結

我們學習如何啟動docker swarm和部署accountservice到swarm上.下一節,我們會給我們的微服務加入healthcheck.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.