天天看點

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

本文将介紹在經典網絡環境下,基于資源編排快速部署高可用dubbox服務的過程。做這件事情的意義在于:提供給開發者一套高可用的dubbox服務架構,節約開發人員部署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

本文将從兩個方面展開介紹:

安裝ansible和ros sdk

經典網絡環境下快速部署dubbox服務

需要注意的問題

首先申請一台ecs作為ansible主機,并給這台機器綁定公網ip,友善通路外網。ecs系統版本資訊如下:

此版本的ecs已經安裝了python 2.7.5。

dubbox服務的部署需要通過ansible來完成,本文采用了yum來安裝ansible:

注意:如果采用的是ubuntu系統,安裝ansible過程如下:

ros提供了restful api和sdk,本文将介紹用python的方式調用ros sdk來建立資源。

如果ansible主機未安裝pip,可以使用以下指令先安裝pip:

使用pip安裝aliyun-python-sdk-core:

使用pip安裝ros sdk:

根據ros api的調用方式,在python檔案中定義ros資源模闆。模闆包括以下資源類型:

<a href="https://ros.console.aliyun.com/#/resourcetype/detail/aliyun::ecs::instancegroup/metadata">"type": "aliyun::ecs::instancegroup"</a>

定義了包含兩台ecs的instancegroup

<a href="https://ros.console.aliyun.com/#/resourcetype/detail/aliyun::redis::instance/metadata">"type": "aliyun::redis::instance"</a>

定義一台kvstore,作為dubbox服務的注冊中心

<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監聽兩台ecs的8080端口,并配置了<code>healthcheck</code>

<a href="https://ros.console.aliyun.com/#/resourcetype/detail/aliyun::ecs::securitygroup/metadata">"type": "aliyun::ecs::securitygroup"</a>

定義安全組

在經典網絡環境下,ecs、kvstore、slb均選擇經典網絡類型,資源棧的輸出定義為:ecs的public ip,kvstore的connectiondomain,slb的公網ip以及kvstore port。

定義ros資源模闆的python檔案<code>generate_classic_ros_template.py</code>:

初始化sdk用戶端對象:

構造建立資源棧的請求:

指定請求資源region:

構造請求體的内容,包括:棧名、過期時間戳、ros資源模闆,請求體内容如下:

說明:其中template是通過調用<code>generate_classic_ros_template.generate_template</code>方法生成的ros資源模闆對象,調用方式如下:

發送請求,建立資源棧:

擷取資源棧資訊:

資源棧建立好以後,我們再次調用ros api擷取資源棧的輸出資訊。方法如下:

資源棧的輸出格式如下:

我們将以上輸出定義為<code>outputs</code>。

根據<code>outputs</code>,擷取ecs公網ip。方法如下:

由于ecs登入密碼在配置檔案中已經給出,可以直接使用,使用者預設為root使用者,根據這些資訊編輯<code>/etc/ansible/hosts</code>檔案,即通常我們所說的ansible inventory檔案。方法如下:

生成inventory檔案,即<code>/etc/ansible/hosts</code>檔案。檔案内容如下:

inventory檔案中定義了遠端主機組<code>classic_dubbox</code>,并指明了該主機組下雲主機的登入位址、登入協定(預設是 ssh )、登入端口、登入使用者名和密碼。

根據<code>outputs</code>,擷取kvstore host。方法如下:

根據<code>outputs</code>,擷取kvstore port。方法如下:

根據<code>outputs</code>,擷取slb 公網ip。方法如下:

在<code>/etc/ansible</code>目錄下建立檔案夾<code>classic_dubbox</code>,并在此檔案夾下生成playbook的執行檔案<code>classic_dubbox.yml</code>。生成<code>classic_dubbox.yml</code>的方法如下:

生成的<code>classic_dubbox.yml</code>檔案内容如下:

檔案中的屬性解釋如下:

hosts

遠端主機組名稱,和inventory檔案中的遠端主機組相對應。

vars

配置參數,提供給<code>install_jdk.sh</code> <code>install_jetty.sh</code> <code>deploy_admin.sh</code>這三個腳本使用。

roles

指定要執行的playbook為 <code>classic_dubbox_playbook</code>。

<code>classic_dubbox_playbook</code>定義好後會被傳到阿裡雲oss,運作python腳本會将<code>classic_dubbox_playbook</code>下載下傳至<code>/etc/ansible/classic_dubbox</code>目錄下。下載下傳playbook到ansible主機的方法如下:

<code>classic_dubbox_playbook</code>目錄結構如下:

關于<code>classic_dubbox_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.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>classic_dubbox.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>這三個腳本讀取配置資訊。

ansible是通過ssh指令連接配接遠端主機,并執行playbook的。首次執行playbook前,由于目前ansible主機并沒有記錄遠端主機的rsa key,會彈出确認對話框,輸入yes,回車:

可通過python腳本實作上述過程:

注意:由于用到了pexpect這個子產品,在執行腳本前,使用pip安裝pexpect子產品

最後執行ansible

運作ansible以後會進行dubbox服務的部署。

運作ansible playbook以後,會進行dubbox服務的部署,主要分為以下三個步驟:

安裝jdk的檔案為<code>install_jdk.sh</code>,内容如下:

安裝jdk過程中,首先需要檢查目前ecs是否存在java環境,存在就跳過安裝過程,反之則安裝jdk。

聲明:jdk安裝包請從oracle官網下載下傳,并下載下傳本文指定的jdk版本。由于從本文連結中下載下傳jdk帶來的任何問題,和本文作者無關。

安裝jetty的檔案為<code>install_jetty.sh</code>,内容如下:

安裝jetty過程,主要包括:讀取配置檔案,設定jetty安裝目錄,修改jetty的配置檔案。jetty安裝目錄的選擇包括以下幾種情形:

未指定jetty安裝目錄,則選擇預設目錄進行安裝

指定了jetty安裝目錄并且目錄不存在,則建立目錄并安裝jetty

指定了jetty安裝目錄并且目錄已經存在

如果配置了強制執行選項,則覆寫目錄并安裝jetty

如果沒有配置強制執行選項,程式強制退出

部署dubbox服務的檔案為<code>deploy_admin.sh</code>,内容如下:

部署dubbox服務過程,主要包括:檢查設定是否合理,将dubbox服務部署到jetty,設定dubbox服務注冊中心為redis,修改dubbo.properties配置檔案,設定控制台的登入密碼。

在部署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服務支援redis注冊中心加密的方式,配置檔案dubbo.properties中的格式為:

dubbo.registry.address=redis://user:password@ip:port

<code>user</code>可随便填寫,但是不能為空,<code>password</code>為redis服務的登入密碼,redis服務預設<code>port</code>為6379

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

注意:ip可以是slb的公網ip,也可以是任意一台ecs的公網ip

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

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

dubbox服務控制台如下:

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

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

最終,基于資源編排快速部署出來的高可用dubbox服務架構如下圖所示:

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

dubbox服務的高可用,主要展現在兩個方面:

注冊中心的高可用

注冊中心采用了kvstore,kvstore其實是一個主備雙機的高可用redis伺服器。

dubbox服務控制台的高可用

建立兩台ecs執行個體并分别部署dubbox服務,然後建立一個slb,将之前建立的兩台ecs執行個體作為slb的後端伺服器,最後給這個slb添加監聽,并設定健康檢查。外部通過slb來通路dubbox服務。