在Docker Swarm上部署Apache Storm:第2部分

OneAPM官方技術部落格發表於2016-06-01

【編者按】本文來自 Baqend Tech Blog,描述瞭如何在 Docker Swarm,而不是在虛擬機器上部署和調配Apache Storm叢集。文章系國內 ITOM 管理平臺 OneAPM 編譯呈現。

點此檢視《在Docker Swarm上部署Apache Storm:第1部分》

建立Swarm叢集

如果一切順利,那麼你現在已經有了三臺Ubuntu伺服器,每個上面都執行了一個Docker守護程式。可以通過私有網路中的zk1.cloud和manager.swarm訪問Ubuntu 1,或者也可以從外部通過manager.swarm.baqend.com(至少在8080埠)訪問。我們一直在這臺機器上折騰,並且,從現在開始,這是我們唯一需要訪問的機器。為了保證Swarm節點之間的協調通暢,我們需要配置ZooKeeper ensemble和Swarm管理器。

1.通過SSH連線Ubuntu1,接著快速檢查一遍。如果Docker安裝正確,執行下列程式碼可以顯示出一個所有執行中的Docker容器的列表(只有針對Swarm的):

docker ps

2.現在我們可以按下面的方法在每臺機器上啟動一個ZooKeeper節點:

docker -H tcp://zk1.cloud:2375 run -d --restart=always \
      -p 2181:2181 \
      -p 2888:2888 \
      -p 3888:3888 \
      -v /var/lib/zookeeper:/var/lib/zookeeper \
      -v /var/log/zookeeper:/var/log/zookeeper  \
      --name zk1 \
      baqend/zookeeper zk1.cloud,zk2.cloud,zk3.cloud 1
docker -H tcp://zk2.cloud:2375 run -d --restart=always \
      -p 2181:2181 \
      -p 2888:2888 \
      -p 3888:3888 \
      -v /var/lib/zookeeper:/var/lib/zookeeper \
      -v /var/log/zookeeper:/var/log/zookeeper  \
      --name zk2 \
      baqend/zookeeper zk1.cloud,zk2.cloud,zk3.cloud 2
docker -H tcp://zk3.cloud:2375 run -d --restart=always \
      -p 2181:2181 \
      -p 2888:2888 \
      -p 3888:3888 \
      -v /var/lib/zookeeper:/var/lib/zookeeper \
      -v /var/log/zookeeper:/var/log/zookeeper  \
      --name zk3 \
      baqend/zookeeper zk1.cloud,zk2.cloud,zk3.cloud 3

通過明確說明-H……引數,我們可以在不同的主機上啟動ZooKeeper容器。-p命令開啟ZooKeeper預設需要的那些埠。兩個-v命令通過將ZooKeeper使用的資料夾對映到對應的主機資料夾,可以在發生容器錯誤的情況仍然保持連貫性。以逗號分隔的主機名列表通知ZooKeeper這一集合中有哪些伺服器。集合中的每個節點都不例外。唯一的變數就是ZooKeeper的ID(第二個引數),因為它對每個容器都是不一樣的。

你可以使用以下命令列來檢查ZooKeeper是否一切正常:

docker -H tcp://zk1.cloud:2375 exec -it zk1 bin/zkServer.sh status && \
docker -H tcp://zk2.cloud:2375 exec -it zk2 bin/zkServer.sh status && \
docker -H tcp://zk3.cloud:2375 exec -it zk3 bin/zkServer.sh status

如果你的叢集一切正常,每個節點都會彙報它們是主節點還是從節點。

3.現在,開啟Swarm管理器:

docker run -d --restart=always \
      --label role=manager \
      -p 2376:2375 \
      swarm manage zk://zk1.cloud,zk2.cloud,zk3.cloud

4.現在Swarm叢集正在執行。但是我們必須把這一點告訴Docker客戶端。最後你只須保證之後所有的Docker執行語句都指向Swarm管理器的容器(它會負責排程),並且不違反本地Docker守護程式。

cat << EOF | tee -a ~/.bash_profile
    # this node is the master and therefore should be able to talk to the Swarm cluster:
    export DOCKER_HOST=tcp://127.0.0.1:2376
EOF
export DOCKER_HOST=tcp://127.0.0.1:2376

上面這段會立即執行,並且保證下次我們登入機器的時候被再次執行。

健康度檢查

現在一切都被啟動執行了。鍵入docker info檢查一下manager節點上的叢集狀態。你會看到3個執行中的worker,類似這樣:

Nodes: 3
 docker1: zk1.cloud:2375
  └ Status: Healthy
  └ Containers: 3
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 2.053 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-40-generic, operatingsystem=Ubuntu 14.04.1 LTS, server=manager, storagedriver=devicemapper
  └ Error: (none)
  └ UpdatedAt: 2016-04-03T15:39:59Z
 docker2: zk2.cloud:2375
  └ Status: Healthy
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 2.053 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-40-generic, operatingsystem=Ubuntu 14.04.1 LTS, storagedriver=devicemapper
  └ Error: (none)
  └ UpdatedAt: 2016-04-03T15:39:45Z
 docker3: zk3.cloud:2375
  └ Status: Healthy
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 2.053 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-40-generic, operatingsystem=Ubuntu 14.04.1 LTS, storagedriver=devicemapper
  └ Error: (none)
  └ UpdatedAt: 2016-04-03T15:40:15Z

最重要的是每個節點的Status: Healthy那一行。如果你發現出現了其它的狀態,例如Status: Pending,或者有的節點沒有顯示出來,那麼即使其它地方還沒有報錯,也應該用以下命令試著重啟管理容器,

docker restart $(docker ps -a --no-trunc --filter "label=role=manager"

然後再檢查一次(這個操作可能會引發一個錯誤資訊;無視它)。

配置Storm叢集

現在Swarm已經執行起來了,你將要建立一個覆蓋網路來跨越所有的Swarm節點,為單獨的Storm組建運轉多個容器。儘管Supervisor節點(即Storm workers)散佈於Swarm叢集中的所有節點,Nimbus和UI會在manager節點上,每臺伺服器上一個。

1.先建立覆蓋網路stormnet:

docker network create --driver overlay stormnet

然後通過Docker來檢查stormnet是否存在:

docker network ls

2.現在一個一個地啟動Storm元件。每個Storm相關的容器會有一個cluster=storm標記,這樣你在後面殺死整個Storm叢集時,不會錯殺其它容器。

首先,啟動UI

docker run \
    -d \    
    --label cluster=storm \    
    --label role=ui \    
    -e constraint:server==manager \    
    -e STORM_ZOOKEEPER_SERVERS=zk1.cloud,zk2.cloud,zk3.cloud \    
    --net stormnet \    
    --restart=always \    
    --name ui \    
    -p 8080:8080 \    
    baqend/storm ui \
      -c nimbus.host=nimbus

接下來是Nimbus:

docker run \
    -d \    
    --label cluster=storm \    
    --label role=nimbus \    
    -e constraint:server==manager \    
    -e STORM_ZOOKEEPER_SERVERS=zk1.cloud,zk2.cloud,zk3.cloud \    
    --net stormnet \    
    --restart=always \    
    --name nimbus \    
    -p 6627:6627 \    
    baqend/storm nimbus \
      -c nimbus.host=nimbus

為了確保這些在manager節點上執行,我們加入一個限制條件:constraint:server==manager。

3.你現在可以訪問Storm UI了,就好像它是在manager節點上執行一樣:假如你的manager節點有個公開IP並且其埠8080開放,你就可以用連結http://manager.swarm.baqend.com:8080通過瀏覽器來訪問Storm叢集。但是目前還沒有執行任何supervisor節點。

4.執行以下語句三次,來啟動三個supervisor:

docker run \
    -d \    
    --label cluster=storm \    
    --label role=supervisor \    
    -e affinity:role!=supervisor \    
    -e STORM_ZOOKEEPER_SERVERS=zk1.cloud,zk2.cloud,zk3.cloud \    
    --net stormnet \    
    --restart=always \    
    baqend/storm supervisor \
     -c nimbus.host=nimbus \     
     -c supervisor.slots.ports=[6700,6701,6702,6703]

因為我們無所謂具體啟動哪裡的supervisor節點,這裡我們不用加入任何限制條件或容器名。但是,為了防止同一臺機器上的有兩個supervisor被啟動,我們用了一個affinity標記:affinity:role!=supervisor。如果你要用更多的supervior容器,就得新增更多的Swarm worker節點(Ubuntu 4、Ubuntu 5等等)。

5.看一眼Storm UI,確保有三個Supervisor在執行。

(遠端)拓撲部署

可以通過與manager主機在同一網路中的任意一臺裝有Docker守護程式的伺服器來部署拓撲網路。在下面的程式碼中,假設你目前使用的目錄中,拓撲fatjar是一個名為topology.jar的檔案。

docker -H tcp://127.0.0.1:2375 run \
   -it \   
   --rm \   
   -v $(readlink -m topology.jar):/topology.jar \   
   baqend/storm \
     -c nimbus.host=manager.swarm \     
     jar /topology.jar \
       main.class \
       topologyArgument1 \
       topologyArgument2

注意:這個命令會生出一個Docker容器,部署拓撲,接著刪除容器。我們用-H tcp://127.0.0.1:2375引數來確保容器是在你當前使用的機器上啟動的。如果讓Docker Swarm自己來編排,部署就可能會失敗,因為在生成容器的主機上可能找不到必要的拓撲檔案。

另外,readlink -m topology.jar會為topology.jar生成一個絕對路徑,因為並不支援相對路徑。但是你也可以直接提供一個絕對路徑。

終止一個拓撲

可以通過與Storm web UI互動從而終止一個拓撲,或者也可以通過下面的方式,假設正在執行的拓撲叫做runningTopology:

docker run \
   -it \   
   --rm \   
   baqend/storm \
     -c nimbus.host=manager.swarm \     
     kill runningTopology

此處並不需要主機引數-H …,因為上述命令是獨立的,並不依賴任何檔案。

關掉Storm叢集

由於每個與Storm相關的容器都有一個cluster=storm標籤,你可以用下述語句終止所有的容器:

docker rm -f $(docker ps -a --no-trunc --filter "label=cluster=storm"

不要忘記安全性!

我們在此教程中示範瞭如何在Docker上用多節點的ZooKeeper集為了高可用性和容錯性執行一個分散式Storm叢集。為了不讓這個教程過分複雜,我們跳過了針對TLS配置Docker Swarm的部分。如果你打算把Docker Swarm用於關鍵的業務應用中,你必須在這個方面多下些功夫。

Baqend是怎樣使用Apache Storm的?

我們利用Storm的能力來提供低延遲的流查詢和查詢快取:

連續查詢

如果你的APP允許連續查詢,Apache Storm能接受你的連續查詢和所有你的寫入操作,並且將它們相比對:每當寫一個物件時,所有註冊的連續查詢都與之比對。既然Storm一直在跟蹤所有查詢的結果,它就能發現新的主機或者新的匹配或不匹配的情況,並且在變更剛發生的時候通知你。

查詢快取

對於查詢快取來說,我們用這些通知來主動讓快取失效:Baqend Cloud用一段合理長度的TTL來快取一個查詢結果,一旦發生變更就自動讓快取的查詢結果無效。得益於Storm,我們的匹配網路延遲僅為幾毫秒,相較以往,資料的獲取速度顯著提高。

Baqend Cloud將很快釋出這兩大功能,近期,我們也會在Baqend Tech部落格發表更多有關架構的細則和標杆性測試結果。敬請期待!

結束語

本教程是為1.10.3版本的Docker和1.1.3的Swarm所做,並在OpenStack和AWS上測試。本教程及我們的Storm和ZooKeeper Docker映象檔案都在Chicken Dance License v0.2的保護下有效。

你可以在GitHub上覆制我們的專案,如有任何改進,也歡迎發起pull請求!

OneAPM Cloud Insight 產品集監控、管理、計算、協作、視覺化於一身,幫助所有 IT 公司,減少在系統監控上的人力和時間成本投入,讓運維工作更加高效、簡單。想閱讀更多技術文章,請訪問 OneAPM 官方技術部落格

本文轉自 OneAPM 官方部落格

原文地址:http://highscalability.com/blog/2016/4/25/the-joy-of-deploying-apache-storm-on-docker-swarm.html

相關文章