本文将介紹在專有網絡vpc(virtual private cloud)下,基于資源編排服務,快速部署高可用的dubbox服務的過程。dubbox服務采用的注冊中心是zookeeper叢集。做這件事情的意義在于:節約部署dubbox的時間,降低部署dubbox過程中出錯的風險。
ros 阿裡雲資源編排(resource orchestration)是一種簡單易用的雲計算資源管理和自動化運維服務。使用者通過模闆描述多個雲計算資源的依賴關系、配置等,并自動完成所有資源的建立和配置,以達到自動化部署、運維等目的。編排模闆同時也是一種标準化的資源和應用傳遞方式,并且可以随時編輯修改,使基礎設施即代碼(infrastructure as code)成為可能。 ansible ansible是一個簡單的自動化it工具。引用ansible官網的介紹就是:“deploy apps.manage systems.crush complexity.ansible helps you build a strong foundation for devops.”。 dubbox zookeeper
本文将從以下三個方面展開介紹:
準備ansible主機
vpc網絡環境下快速部署高可用的dubbox服務
總結
本章将從以下兩個方面展開:
安裝ansible
安裝ros sdk
首先需要建立一個vpc,并在這個vpc下建立一個vswitch,在這個vpc和vswitch下申請一台ecs執行個體,并給這台機器綁定公網ip,友善通路外網。本文所采用的ansible主機(ecs)系統版本資訊如下:
這個版本的ecs已經安裝了python 2.7.5。
建立好ansible主機以後,我們需要給這台主機安裝ansible和ros sdk。ansible用來實作對遠端主機的控制,ros sdk用來實作對資源棧的操作。
dubbox服務的快速部署需要借助ansible來完成,本文采用了yum來安裝ansible:
ansible預設安裝目錄為<code>/etc/ansible</code>,安裝好以後,<code>/etc/ansible/</code>目錄結構如下:
注意:如果采用的是ubuntu系統,安裝ansible過程如下:
ros提供了restful api和sdk,本文将介紹用python的方式來調用ros api建立資源。
在調用ros api之前需要安裝相關的依賴。
使用pip安裝aliyun-python-sdk-core:
使用pip安裝ros sdk:
如果ansible主機未安裝pip,可使用以下指令安裝pip:
本章将從以下五個方面展開:
建立資源棧
編輯inventory檔案
建構playbook
執行playbook
部署dubbox服務
建立資源棧的過程主要分為以下三步:
定義ros資源模闆
調用ros api,建立資源棧
擷取資源棧輸出資訊
本文通過調用ros api的方式來建立資源棧。
ros資源模闆包括以下幾種資源類型:
<a href="https://ros.console.aliyun.com/#/resourcetype/detail/aliyun::ecs::instancegroup/metadata">"type": "aliyun::ecs::instancegroup"</a>
在資源模闆中使用兩組該類型的資源,一組用來定義dubbox控制台叢集伺服器,一組用來定義zookeeper叢集伺服器。
<a href="https://ros.console.aliyun.com/#/resourcetype/detail/aliyun::slb::loadbalancer/metadata">"type": "aliyun::slb::loadbalancer"</a>
建立一台slb。
<a href="https://ros.console.aliyun.com/#/resourcetype/detail/aliyun::slb::backendserverattachment/metadata">"type": "aliyun::slb::backendserverattachment"</a>
給slb添加後端伺服器。
<a href="https://ros.console.aliyun.com/#/resourcetype/detail/aliyun::slb::listener/metadata">"type": "aliyun::slb::listener"</a>
配置slb監聽,slb監聽dubbox控制台叢集伺服器的8080端口,并配置了健康檢查<code>healthcheck</code>。
資源棧的輸出為<code>"outputs"</code>,包括:ecsprivateips(dubbox控制台叢集伺服器的私有ip),zkprivateips(zookeeper叢集伺服器的私有ip),loadbalanceip(負載均衡slb的公網ip)。
在vpc網絡環境下,給instancegroup指定vpc和vswtich,并保證和anisble主機處在同一個vpc和vswitch下,這樣才能保證ansible主機可通過ecs的私有ip來登入ecs并操控ecs執行個體。
定義ros資源模闆的python檔案為<code>generate_vpc_ros_template.py</code>,檔案内容如下:
建立資源棧的python檔案為<code>create_stack.py</code>,檔案内容如下:
下面詳細解釋該python檔案的執行過程:
初始化sdk用戶端對象:
client = acsclient(ak_id, ak_secret, region_id)
初始化建立資源棧的請求:
req = createstacksrequest.createstacksrequest()
指定請求資源region:
req.set_headers({'x-acs-region-id': region_id})
構造請求體,包括:棧名、過期時間戳、ros資源模闆
create_stack_body = '''
req.set_content(create_stack_body)
發送請求,建立資源棧:
response = client.get_response(req)
6. 擷取資源棧資訊:
資源棧建立好以後,我們再次調用ros api擷取資源棧的輸出資訊。方法如下:
調用時需要傳入建立好的資源棧<code>id</code>和<code>name</code>資訊。由于建立資源棧需要的時間不确定,是以以上方法定義了逾時重試的機制。每次重試以後的等待時間要比上次等待時間少<code>interval</code>秒,在嘗試<code>attempt</code>次若仍未擷取到資源棧資訊視為資源建立失敗(一般不會出現這種情況)。
資源棧的輸出格式如下:
我們将以上輸出定義為<code>outputs</code>。
根據上面擷取的資源棧輸出資訊<code>outputs</code>,擷取dubbox控制台伺服器組的私有ip。方法如下:
根據上面擷取的資源棧輸出資訊<code>outputs</code>,擷取zookeeper叢集伺服器組的私有ip。方法如下:
因為在建立資源棧的時候,已經在配置檔案中配置好了<code>aliyun::ecs::instancegroup</code>的登入密碼,是以可以直接使用配置檔案中的密碼資訊,使用者名預設為root。編輯<code>/etc/ansible/hosts</code>檔案,即通常我們所說的<code>ansible inventory</code>檔案。編輯該檔案的方法如下:
執行該方法以後,生成的<code>inventory</code>檔案,即<code>/etc/ansible/hosts</code>檔案,内容如下:
<code>inventory</code>檔案中定義了兩個遠端主機組,<code>dubbo_admin</code>和<code>zookeeper</code>,并指定了不同主機的ip、登入協定(預設是 ssh )、登入端口、登入使用者名和密碼。ansible在執行playbook的時候通過以上資訊連接配接遠端主機。
本文所描述的高可用dubbox服務,注冊中心采用的是zookeeper叢集,是以需要建構兩個playbook。一個用來部署dubbox控制台叢集,一個用來部署zookeeper叢集。
部署dubbox控制台叢集的playbook為<code>vpc_dubbox_admin_playbook</code>,結構如下:
關于<code>vpc_dubbox_admin_playbook</code>結構的說明如下:
files
存放<code>install_jdk.sh</code>、<code>install_jetty.sh</code>、<code>deploy_admin.sh</code>三個檔案,這三個檔案分别用來安裝jdk、jetty以及部署dubbox控制台服務。
tasks
存放要執行的yml檔案 <code>install_dubbo_admin.yml</code>,檔案内容如下:
name: add config
template:
name: run install jdk
script: install_jdk.sh
name: run install jetty
script: install_jetty.sh
name: run deploy admin
script: deploy_admin.sh
templates
存放配置檔案模闆config.j2,檔案内容如下:
配置檔案config.j2中的參數值從<code>vpc_dubbox_zk.yml</code>檔案中擷取,通過ansible執行playbook的過程中會在每一台遠端主機的<code>/root</code>目錄下生成<code>config</code>檔案,提供給<code>install_jdk.sh</code>、<code>install_jetty.sh</code>、<code>deploy_admin.sh</code>這三個腳本使用。關于<code>vpc_dubbox_zk.yml</code>檔案,後面會提到。
部署zookeeper叢集的playbook為<code>vpc_dubbox_zookeeper_playbook</code>,結構如下:
關于<code>vpc_dubbox_zookeeper_playbook</code>結構的說明如下:
存放<code>install_jdk.sh</code>、<code>install_zk.sh</code>兩個檔案,這兩個檔案分别用來安裝jdk、部署zookeeper叢集。
存放要執行的yml檔案 <code>install_zk.yml</code>,檔案内容如下:
name: run install zookeeper
script: install_zk.sh
配置檔案config.j2中的參數值從<code>vpc_dubbox_zk.yml</code>檔案中擷取,通過ansible執行playbook的過程中會在每一台遠端主機的<code>/root</code>目錄下生成<code>config</code>檔案,提供給<code>install_jdk.sh</code>、<code>install_zk.sh</code>使用。關于<code>vpc_dubbox_zk.yml</code>檔案,後面會說明。
執行playbook,需要以下三個步驟:
生成ansible可執行檔案
下載下傳playbook
我們需要通過ansible執行<code>vpc_dubbox_zk.yml</code>檔案來運作我們建構好的兩個playbook。
<code>vpc_dubbox_zk.yml</code>檔案的生成,需要分兩步進行:
定義檔案模闆
生成檔案
定義<code>vpc_dubbox_zk.yml</code>檔案模闆的python檔案為<code>deploy_vpc_dubbox.py</code>,檔案内容如下:
生成<code>vpc_dubbox_zk.yml</code>檔案,方法如下:
生成的<code>vpc_dubbox_zk.yml</code>檔案的内容如下:
<code>vpc_dubbox_zk.yml</code>檔案中定義了一些參數,下面詳細介紹檔案中參數的作用:
hosts
遠端主機組名稱,和<code>inventory</code>檔案中的遠端主機組相對應。此檔案說明要連接配接的主機組有兩個。
vars
配置檔案<code>config</code>中的參數,提供給<code>install_jdk.sh</code>、<code>install_jetty.sh</code>、 <code>deploy_admin.sh</code>、<code>install_zk.sh</code>使用。
roles
指定要執行的playbook名稱。此檔案說明要執行的playbook有兩個。
最終生成的<code>vpc_dubbox_zk.yml</code>檔案在目錄<code>/etc/ansible/</code>下。
ansible是通過ssh指令連接配接遠端主機,并執行playbook的。首次執行playbook前,由于目前ansible主機并沒有記錄遠端主機的rsa key,會彈出rsa key的确認對話框,對話框内容如下:
因為整個過程不用人為的參與,是以可通過python腳本自動實作上述确認的過程:
由于用到了pexpect這個子產品,在執行腳本前,需要使用pip安裝pexpect子產品:
vpc網絡環境下未給ecs配置設定公網ip,導緻每台ecs無法下載下傳安裝包,但是在安裝jdk、jetty以及部署dubbox admin和zookeeper叢集的時候需要這些安裝包。因為ansible主機配有公網ip,是以可以将安裝包先下載下傳到ansible主機,又因為ansible主機和每台ecs在同一個vswitch下面,可以通過scp指令将安裝包從ansible主機傳到每台ecs上。具體操作過程如下:
在python檔案中填入安裝包的下載下傳位址,運作python腳本,下載下傳安裝包至ansible主機。方法如下:
def wget_files():
通過scp指令将安裝包拷貝到每台ecs。方法如下:
def scp_files_from_ansible_host_to_ecs_zk(host_ips, zk_ips):
通過ansible,執行playbook。方法如下:
subprocess.call('ansible-playbook ' + pb_file_dir + '/' + pb_file_name, shell=true)
運作ansible以後會進行dubbox服務的部署過程。
dubbox服務的部署,需要以下兩個步驟:
搭建zookeeper叢集
搭建dubbox控制台叢集
zookeeper叢集主要用來作為dubbox服務的注冊中心。
搭建zookeeper叢集,需要以下兩個步驟:
安裝jdk
因為zookeeper的運作需要java環境,是以需要先安裝jdk。安裝jdk的腳本為<code>install_jdk.sh</code>,檔案内容如下:
安裝jdk過程中,首先需要檢查目前ecs是否存在java環境,存在就跳過安裝過程,反之則安裝。
聲明:jdk安裝包請從oracle官網下載下傳,并下載下傳本文指定的jdk版本(jdk-8u101-linux-x64.rpm)。從本文連結中下載下傳jdk帶來的任何法律問題,和本文作者無關。
搭建zookeeper叢集的腳本為<code>install_zk.sh</code>,内容如下:
這個腳本的主要功能是安裝zookeeper,并通過修改zookeeper配置檔案<code>conf/zoo.cfg</code>來配置zookeeper叢集。修改後的配置檔案内容如下:
上述檔案,配置了三台機器的zookeeper叢集。在datadir目錄下,建立一個myid檔案,裡面内容為一個數字,用來辨別目前主機号。
由于dubbox控制台需要運作在jetty容器上,jetty容器的運作又需要有java環境,是以部署dubbox控制台之前,需要先安裝jdk和jetty。
搭建dubbox控制台叢集,需要以下三個步驟:
安裝jetty
部署dubbox控制台
安裝jetty的檔案為<code>install_jetty.sh</code>,内容如下:
安裝jetty過程,主要包括:讀取配置檔案,設定jetty安裝目錄,修改jetty的配置檔案<code>etc/webdefault.xml</code>。jetty安裝目錄的選擇包括以下三種情形:
未指定jetty安裝目錄,則選擇預設目錄進行安裝
指定了jetty安裝目錄但是目錄不存在,則建立目錄并安裝jetty
指定了jetty安裝目錄并且目錄已經存在
如果配置了強制執行選項,則覆寫目錄并安裝jetty
如果沒有配置強制執行選項,程式強制退出
部署dubbox服務的檔案為<code>deploy_admin.sh</code>,内容如下:
在部署dubbox服務的過程中,有幾個需要注意的問題:
當通路dubbox服務時,需要通路伺服器的8080端口,由于防火牆的原因,外部可能無法通路到伺服器的dubbox服務,是以需要修改防火牆的設定。本文所采用的ecs系統為centos 7,簡單起見,我直接關閉了系統的防火牆。關閉防火牆的方法如下:
systemctl stop firewalld.service
這裡不建議采用直接關閉防火牆的方式。
通過ansible控制遠端伺服器組啟動jetty服務時,ansible指令執行結束以後,jetty服務也自動退出,這是我們不想看到的結果。可通過nohup指令以守護程序的方式啟動jetty服務,可以解決jetty服務自動退出的問題,啟動jetty指令如下:
nohup $jetty_home/bin/jetty.sh start &
dubbox服務部署好了以後,可通過以下位址通路dubbox服務控制台:
注意:在vpc網絡下,ip指的是slb的公網ip。
dubbox服務部署好以後,可通過以下操作登入控制台:
輸入使用者名密碼,點選登入:

登入進去以後的dubbox控制台界面如下:
現在,我們可以使用dubbox服務了。
本章将從以下兩個方面進行總結:
dubbox服務系統結構圖
如何快速建構高可用dubbox服務
最終,采用zookeeper叢集作為注冊中心,基于資源編排快速部署出來的高可用dubbox服務的系統結構圖,如下圖所示:
dubbox服務的高可用,主要展現在兩個方面:
注冊中心的高可用
注冊中心采用了zookeeper叢集的方式,zookeeper叢集中隻要有超過半數的服務可用,dubbox服務的注冊中心就可以正常工作。
dubbox服務控制台的高可用
建立兩台ecs執行個體并分别部署dubbox控制台服務,這兩台ecs挂載到一個slb上,我們可通過slb來通路dubbox控制台服務。
前面章節描述的部署過程看起來可能比較繁瑣,本文的核心是快速部署,是以你可以根據下面的指導,快速部署屬于你的高可用dubbox服務。四個步驟快速部署高可用dubbox服務:
下載下傳源碼
修改配置檔案
運作main函數
可從本文的附件中下載下傳源碼,然後将vpc_python檔案拷貝到ansible主機。
修改<code>vpc_python/config.py</code>檔案,檔案内容如下:
下面詳細講解配置檔案中一些參數所代表的意義:
<code>vpc_id</code>
ansible主機所在的vpc id
<code>vswitch_id</code>
ansible主機所在的vswitch id
<code>zk_size</code>
zookeeper叢集的大小,zookeeper叢集的大小必須為奇數,且必須大于1
<code>ecs_password</code>
申請的ecs伺服器的登入密碼,使用者名預設為root
<code>ak_id</code>
使用者的ak id
<code>ak_secret</code>
使用者的ak secret
<code>region_id</code>
資源棧建立的區域
<code>jetty_home</code>
jetty預設安裝目錄
<code>jetty_home_enforce</code>
是否強制安裝jetty,f代表強制安裝,其它代表非強制
<code>dubbo_root_password</code>
dubbox控制台root使用者的登入密碼
<code>dubbo_guest_password</code>
dubbox控制台guest使用者的登入密碼
使用者可根據自己的需求更改配置檔案。
運作<code>vpc_python/main.py</code>。函數運作完以後,高可用dubbox服務就部署好了。