天天看點

基于資源編排在專有網絡環境下快速部署高可用的Dubbox服務(ZooKeeper版)

本文将介紹在專有網絡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 &amp;

dubbox服務部署好了以後,可通過以下位址通路dubbox服務控制台:

注意:在vpc網絡下,ip指的是slb的公網ip。

dubbox服務部署好以後,可通過以下操作登入控制台:

輸入使用者名密碼,點選登入:

基于資源編排在專有網絡環境下快速部署高可用的Dubbox服務(ZooKeeper版)

登入進去以後的dubbox控制台界面如下:

基于資源編排在專有網絡環境下快速部署高可用的Dubbox服務(ZooKeeper版)

現在,我們可以使用dubbox服務了。

本章将從以下兩個方面進行總結:

dubbox服務系統結構圖

如何快速建構高可用dubbox服務

最終,采用zookeeper叢集作為注冊中心,基于資源編排快速部署出來的高可用dubbox服務的系統結構圖,如下圖所示:

基于資源編排在專有網絡環境下快速部署高可用的Dubbox服務(ZooKeeper版)

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服務就部署好了。