SwarmKit初步評測
我計劃為一款新應用部署一套測試環境,而當時恰逢Docker SwarmKit發布。這絕對是個一探其究竟的好機會,在本篇文章中,我們將共同分享我在EC2服務器上安裝SwarmKit的實際體會。
在Replicated,我們編寫了一套平臺,旨在幫助SaaS企業利用Docker將業務部署至專有環境當中。另外,過去兩年中我個人在這款平臺的構建中積累到大量調度與編排工具的使用經驗。我們甚至專門為Docker容器構建起自己的調度與編排運行時,旨在為部分早期客戶提供支持。我設置并運行有Kubernetes與Mesosphere集群,同時也比較熟悉容器化生產環境的運行工作。
在利用swarmctl部署應用的過程當中,我快速分析了Swarmkit的優點,并匯總了其中尚缺少的生產環境必要工具選項——部分可利用其它現有工具替代,部分可能需要自行構建。另外,在撰寫本文的過程中,README文檔中又新增了一系列評論內容,旨在展示更多用例并指導用戶使用內置功能。我個人建議大家首先參閱SwarmKit說明文檔的最新版本。
內容摘要
配置
設置集群的過程非常簡單,只需要運行幾條命令即可同步推進。Docker提供的服務發現機制在這里發揮了巨大作用。相比之下,除非大家決定使用谷歌Container Engine,否則Kubernetes集群的設置則相對更為繁瑣。
運行容器
很明顯,設置集群的目的在于運行容器。我能夠輕松運行容器、對實例進行規劃伸縮、編輯環境變量及容器的其它屬性,各項工作都可快速完成。即使是由于設置錯誤而導致容器發生重啟,我也能夠使用swarmctl service rm與swarmd快速清理已經停止運行的各容器。
上手難度
我使用Docker已經有一段時間,swarmctl也并不會帶來夸張的額外學習曲線。當然,在添加更多新功能之后,其使用復雜性也會隨之提高。但就目前而言,其仍然算是一套平易近人的方案。
默認安全性
我不需要以手動方式創建或者轉移任何TLS證書。這套集群能夠輕松實現自動配置,而且效果也還不錯。正是因為這種強制配置證書的機制,集群的基本安全性得到了有效保障。我個人也傾向于讓一切通信都以TLS加密連接作為載體。
穩定性?
老實說,我的測試時間還不長,所以沒法公正地評判其穩定性。SwarmKit才剛剛發布數天,因此生產級別的穩定性恐怕還要過段時間才能實現。不過其立足于相當成熟的技術成果(Docker與Raft),所以穩定性與安全性應該比較扎實。
節點管理
大家可以立足于單一節點對流量進行添加、移除與控制。以此為基礎,我可以構建起一套定制化更新策略。如果制定出高度復雜的升級策略,我想我應該可以在此基礎上創建起滾動升級功能。
尚不具備的元素
ServiceSpec文件
要實現變更管理、版本歷史以及其它一切我所需要的生產環境功能,我需要在文件中定義一套ServiceSpec并將其傳遞至service create/update命令。相較于swarmctl service create --name redis --image=redis --env KEY=VALUE,我更樂于使用swarmctl service create --file redis.yaml。在運行swarmctl service create --help時,其中列出了這項參數,但在審查代碼時我覺得其應該尚未實裝。 https://github.com/docker/swarmkit/issues/537 上對此進行了探討,不過討論內容有些混亂,因為其與代碼內容并不相符。我認為可能是某些舊問題導致了這一狀況,相信其在不久的將來會得到合理解決。當然,CLI幫助文本中的大部分內容與實際支持情況還是比較一致的。
負載均衡/入口
目前還很難斷定Docker在這方面有著怎樣的發展規劃。我自己也不清楚自己希望如何為這些容器設置入口。默認情況下定義了一套入口網絡,但我個人運行在EC2服務器中,因此我更傾向于使用ELB。我的服務器不具備公共IP地址,因此我該如何進行服務公開?我當然希望由swarmd管理這些工作,但目前這一想法還無法實現——或者說還不受支持。
升級策略
雖然可以使用swarmctl service update api ...,但我希望更為具體地定制自己的滾動更新策略。我需要安全關閉容器,停止其運行并重新啟動新的版本。另外,我還希望能夠在升級出現錯誤時停止這一流程。我們需要編寫一些代碼來實現這些目標,但我暫時還沒弄清楚要如何在SwarmKit中加以實現。我認為提供一些默認設置與樣本能夠很好地補充這段學習上的空白。
系統服務
我希望在已知版本中將swarmd作為系統服務運行。我希望能夠將這項服務提取出來并通過upstart或者systemd加以管理。當然,我自己也能完成這些操作,因此不必將其納入服務的核心部分。
遠程集群日志
在Kubernetes中,我可以運行kubectl logs <podname>。我希望能夠使用swarmctl service <service-name> logs -f以調試或者監控運行中的系統。
專有庫憑證
我需要部署存儲在Docker Hub以及quay.io上的專有鏡像。我認為我可以利用docker-machine對其進行管理,但事實證明目前還無法實現。在以上部署當中,我以手動方式從quay.io處將鏡像提取至集群中的每個節點,這種作法在生產環境下顯然是不行的。
我的初始設置與部署流程
那么上述結論是如何得出的?這個嘛,我將與大家分享我在SwarmKit中設置并部署一套相對標準的SaaS環境的流程; 下面來看我的SwarmKit集群部署初體驗。
這套應用環境的部署并不困難,其中主要涉及以下組件:
- MySQL
- Elasticsearch
- RabbitMQ
- 靜態React build站點
- 另一靜態React built站點
- 以Golang編寫的API
- 以Golang編寫的工作程序
我希望確保部署在實例中的一切都被托管在一套可擴展Docker集群當中,另外我會最終將其發布至個人環境當中,從而確保不會涉及任何專利工具。
環境
我決定在us-west-1(北加利福尼亞州)內設置一套全新VPC。我設置了6套子網(2套公共、2套專有、2套db)。現在我已經在us-west-1a與us-west-1c中擁有全部必要的地址。我還設置了一套OpenV*N服務器并進行了配置,這樣專有子網內的各服務器盡管不具備公共IP地址,我仍然可以通過該V*N對其進行訪問。
但我還需要一套管理器機器。因此,我在一套專有子網內啟動了一個t2.medium實例。我將利用該機器管理整套集群、推送更新并對各容器進行故障排查/監控。
安裝SwarmKit
終于到了期待的步驟了——最后設置基礎設施,現在是時候體驗新鮮事物了!
接下來,我在管理節點上安裝Docker 1.11.2。這是DOcker的當前版本,我預計SwarmKit應該能夠兼容。另外,我需要利用主(惟一分支)repo構建二進制文件。
$ git clone https://github.com/docker/swarmkit.git Cloning into 'swarmkit'... remote: Counting objects: 11236, done. remote: Compressing objects: 100% (27/27), done. remote: Total 11236 (delta 8), reused 0 (delta 0), pack-reused 11209 Receiving objects: 100% (11236/11236), 6.94 MiB | 1.49 MiB/s, done. Resolving deltas: 100% (7199/7199), done. Checking connectivity... done. $ docker run -it -v `pwd`/swarmkit:/go/src/github.com/docker/swarmkit golang:1.6 /bin/bash Unable to find image 'golang:1.6' locally 1.6: Pulling from library/golang 51f5c6a04d83: Pull complete a3ed95caeb02: Pull complete 7004cfc6e122: Pull complete 5f37c8a7cfbd: Pull complete e0297283ad9f: Pull complete a7164db3234c: Pull complete 6bb08da223d8: Pull complete c718b2eba451: Pull complete Digest: sha256:66618c0274d300e897bcd2cb83584783e66084ea636b88cb49eeffbeb7f9b508 Status: Downloaded newer image for golang:1.6 root@96fa53925bbc:/go# cd /go/src/github.com/docker/swarmkit/ root@96fa53925bbc:/go/src/github.com/docker/swarmkit# make binaries
root@96fa53925bbc:/go/src/github.com/docker/swarmkit# exit
使用這些剛剛構建完成的二進制文件:
$ swarmkit/bin/swarmd -d /tmp/node-mgmt-01 --listen-control-api /tmp/mgmt-01/swarm.sock --hostname mgmt-01 Warning: Specifying a valid address with --listen-remote-api may be necessary for other managers to reach this one. INFO[0000] 4a678cf4eff2b943 became follower at term 2 INFO[0000] newRaft 4a678cf4eff2b943 [peers: [], term: 2, commit: 8, applied: 0, lastindex: 8, lastterm: 2] WARN[0000] ignoring request to join cluster, because raft state already exists INFO[0000] 4a678cf4eff2b943 became follower at term 2 INFO[0000] newRaft 4a678cf4eff2b943 [peers: [], term: 2, commit: 8, applied: 0, lastindex: 8, lastterm: 2] INFO[0000] Listening for local connections addr=/tmp/mgmt-01/swarm.sock proto=unix INFO[0000] Listening for connections addr=[::]:4242 proto=tcp INFO[0005] 4a678cf4eff2b943 is starting a new election at term 2 INFO[0005] 4a678cf4eff2b943 became candidate at term 3 INFO[0005] 4a678cf4eff2b943 received vote from 4a678cf4eff2b943 at term 3 INFO[0005] 4a678cf4eff2b943 became leader at term 3 INFO[0005] raft.node: 4a678cf4eff2b943 elected leader 4a678cf4eff2b943 at term 3 INFO[0005] node is ready
贊!管理節點已經開始運行了!
這套應用暫時不會接收太多流量。我決定先從比較小的t2.medium實例3節點SwarmKit集群入手。我在專有子網內啟動這些服務器,而后安裝docker-engine。我的集群已經開始運轉,但其還不算完整——目前其只能屬于內部網絡中能夠相互通信的3套服務器。
我當然不希望每次都進行SwarmKit二進制文件構建,因此我將各文件復制到3套新服務器中,并利用以下命令將其作為workers 1、2與3進行啟動引導:
$ scp ubuntu@<mgmt_01_address>:/home/ubuntu/swarmkit/bin/swarmd . $ scp ubuntu@<mgmt_01_address>:/home/ubuntu/swarmkit/bin/swarmctl . $ swarmd -d /tmp/node --hostname work-<N> --join-addr <mgmt_01_address>:4242 Warning: Specifying a valid address with --listen-remote-api may be necessary for other managers to reach this one. INFO[0000] node is ready
非常簡單吧。我想一切應該運轉正常,因為我沒看到任何連接失敗提示,但其目前也沒有給出成功連接信息。應該沒事,咱們繼續進行。
返回管理節點,我運行以下命令:
$ export SWARM_SOCKET=/tmp/mgmt-01/swarm.sock $ ./swarmctl node ls ID Name Membership Status Availability Manager status -- ---- ---------- ------ ------------ -------------- 0fd1wrr78xdld work-1 ACCEPTED READY ACTIVE 14qektqj267gj mgmt-01 ACCEPTED READY ACTIVE REACHABLE * 2mi1lv4edolas work-3 ACCEPTED READY ACTIVE 2rvbyfbhcgi2h work-2 ACCEPTED READY ACTIVE
集群搞定!下面我們開始部署容器!
稍等,README到這里就有些含糊不清了。我當然可以部署Redis,但這實在太沒挑戰了。我想部署自己的定制化鏡像。我有多項服務可供部署,而且我打算創建一項服務來描述自己的API,并將其運行在新集群內的多個工作程序之上。我懷疑swarmctl service create -f <filename>同樣會在docker-compose yaml文件內作為服務定義,在實驗之后,我發現自己的猜想可能無法實現。總而言之,雖然CLI help中列出,但看起來我無法利用spec文件創建服務:
$ ./swarmctl service create --help Create a service Usage: ./swarmctl service create [flags] Flags: --args value Args (default []) --env value Env (default []) -f, --file string Spec to use --image string Image --instances uint Number of instances for the service Service (default 1) --mode string one of replicated, global (default "replicated") --name string Service name --network string Network name --ports value Ports (default []) Global Flags: -n, --no-resolve Do not try to map IDs to Names when displaying them -s, --socket string Socket to connect to the Swarm manager (default "/tmp/mgmt-01/swarm.sock")
不過這也算不上什么大問題。接下來我手動部署自己的服務:
$ ./swarmctl service create --name api --image quay.io/my_org/api:7dab5f6 --env PROJECT_NAME=api 0icvt9xvf7ja0yspn26yfvvn8
這里我跳過了關于專有鏡像提取的手動步驟。雖然只使用了一條env var,但我敢肯定它完全能夠支持全部必要的環境變量、分卷與端口。
$ ./swarmctl service ls ID Name Image Instances -- ---- ----- --------- 0icvt9xvf7ja0yspn26yfvvn8 api quay.io/my_org/api:7dab5f6 1
我的容器已經部署完成并開始運行。下面看看swarmctl能做些什么。
對這套集群進行規模擴展:
$ ./swarmctl service update api --instances 2 0icvt9xvf7ja0yspn26yfvvn8 $ ./swarmctl service ls ID Name Image Instances -- ---- ----- --------- 0icvt9xvf7ja0yspn26yfvvn8 api quay.io/my_org/api:7dab5f6 2 $ ./swarmctl service inspect api ID : 0icvt9xvf7ja0yspn26yfvvn8 Name : api Instances : 2 Template Container Image : quay.io/my_org/api:7dab5f6 Env : [PROJECT_NAME=api] Task ID Service Instance Image Desired State Last State Node ------- ------- -------- ----- ------------- ---------- ---- bartp5krui1815paw2srmtd28 api 1 quay.io/my_org/api:7dab5f6 RUNNING RUNNING 3 minutes ago work-1 70kexpn10suulum0hxursil28 api 2 quay.io/my_org/api:7dab5f6 RUNNING RUNNING 41 seconds ago work-2
很好,它還能做點別的么?我能否更新該環境變量?是的,當然可以,但需要重啟各容器:
$ ./swarmctl service update api --env PROJECT_NAME=api,TEST=1 0icvt9xvf7ja0yspn26yfvvn8 ubuntu@ip-10-10-5-87:~$ ./swarmctl service inspect api ID : 0icvt9xvf7ja0yspn26yfvvn8 Name : api Instances : 2 Template Container Image : quay.io/my_org/api:7dab5f6 Env : [PROJECT_NAME=api, TEST=1] Task ID Service Instance Image Desired State Last State Node ------- ------- -------- ----- ------------- ---------- ---- 0q3kiohsucrimhcl40xomi47h api 1 quay.io/my_org/api:7dab5f6 RUNNING RUNNING 1 second ago work-1 c1kq8hx4whdbtldb7gtapn0ut api 2 quay.io/my_org/api:7dab5f6 RUNNING ACCEPTED 5 seconds ago work-2
總結陳詞
Docker SwarmKit似乎確實是對現有調度及編排生態系統的一種有益補充。截至目前,我們只能利用Kubernetes或者Mesosphere來支持規模合理的生產基礎設施,從而實現規模化容器管理。而SwarmKit當前版本的出現則帶來了新的選擇,意味著我們能夠進一步擴展以支持其它環境。目前其功能的豐富程度尚不及其它調度方案,但它擁有扎實的成熟技術成果作為基礎,而且似乎并不打算發展為適合任意用戶、任意任務的普適型解決方案。我樂于為SwarmKit做出貢獻,并將積極為這款新型應用的部署與管理提供我認為有效的功能。
原文鏈接: First look at SwarmKit
來自: http://dockone.io/article/1372