精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

vivo Pulsar 萬億級消息處理實踐(4)-Ansible運維部署

運維
本篇文章主要從Pulsar運維痛點、Ansible簡介、Ansible核心模塊詳解、Ansible自動化部署zk集群、Ansible自動化部署Pulsar集群幾個維度向大家介紹vivo Pulsar萬億級消息處理實踐之運維部署。

Pulsar作為下一代云原生架構的分布式消息中間件,存算分離的架構設計能有效解決大數據場景下分布式消息中間件老牌一哥“Kafka”存在的諸多問題,2021年vivo 分布式消息中間件團隊正式開啟對Pulsar的調研,2022年正式引入Pulsar作為大數據場景下的分布式消息中間件,本篇文章主要從Pulsar運維痛點、Ansible簡介、Ansible核心模塊詳解、Ansible自動化部署zk集群、Ansible自動化部署Pulsar集群幾個維度向大家介紹vivo Pulsar萬億級消息處理實踐之運維部署。

注:本文是《vivo Pulsar萬億級消息處理實踐》系列文章第4篇。

01、簡介

1.1Pulsar 運維面臨的問題

新業務增長快,很多新業務接入需要搭建獨立的集群或者資源組。

升級頻次高,對于bug修復,配置更改以及依賴組件替換等,都需要對全集群進行升級、配置更改或組件替換。

人力投入大,在集群運維時,需要對公共的執行步驟進行批處理封裝,否則會耗費大量人力在集群的部署和升級上。

1.2什么是 Ansible Playbook

Asnible Playbooks是Ansible自動化工具的核心部分。它是基于YAML文件格式,用于在多個主機上執行的任務。通過在Playbook中設置變量、處理器、角色和任務標簽等功能,可以大大提高自動化腳本的復用性和可維護性。可以理解為批處理任務。

上圖中我們看到Playbook的主要模塊如下:

  • Ansible:Ansible 的核心程序。
  • HostInventory:記錄由 Ansible 管理的主機信息,包括端口、密碼、ip 等。
  • Playbooks:“劇本” YAML 格式文件,多個任務定義在一個文件中,定義主機需要調用哪些模塊來完成的功能。
  • CoreModules:核心模塊,主要操作是通過調用核心模塊來完成管理任務。
  • CustomModules:自定義模塊,完成核心模塊無法完成的功能,支持多種語言。
  • ConnectionPlugins:連接插件,Ansible 和 Host 通信使用。

02、Playbook 語法

2.1書寫格式

playbook 常用到的YMAL格式:

  • 文件的第一行應該以 "---" (三個連字符)開始,表明 YMAL 文件的開始。
  • 在同一行中,# 之后的內容表示注釋,類似于 shell,python 和 ruby。
  • YMAL 中的列表元素以 ”-” 開頭然后緊跟著一個空格,后面為元素內容。
  • 同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
  • play 中 hosts,variables,roles,tasks 等對象的表示方法都是鍵值中間以 ":" 分隔表示,":" 后面還要增加一個空格。

以下是 Playbook 的基本語法書寫格式:

- name: playbook的名稱
  hosts: 目標主機或主機組     # 可以使用普通的 IP 地址或域名,也可以使用主機組名稱
  remote_user: 遠程用戶        # 使用 SSH 登錄遠程主機時使用的用戶名
  become: yes                # 是否使用特權(例如 sudo)運行命令
  tasks:                     # Playbook 中的任務列表
     - name: 任務名稱
       module_name: 參數       # Ansible 模塊的名稱和參數組成的字典,用于執行操作
       tags:                    # 與該任務相關的標記列表,用于執行特定的任務
         - 標簽名稱
       when: 條件             # 指定該任務在滿足特定條件下才會被執行
       notify: 通知列表       # 指定依賴于該任務的另一個任務列表,當這個任務被執行后會自動觸發這些任務

2.2Tasks & Modules

在Ansible Playbook的語法中,

"Tasks"和"Modules"是兩個核心概念。

Tasks(任務):Tasks是Playbook中的操作步驟或任務,它們定義了要在目標主機上執行的操作。可以在Playbook中定義一個或多個任務。Tasks按照順序執行,并且可以有條件地執行或跳過。

Modules(模塊):Modules提供了執行特定任務的功能單元。每個模塊負責處理不同的操作,如管理文件、安裝軟件包、查詢系統信息等。Ansible提供了許多內置模塊,可以滿足大多數常見的操作。

通過組合不同的模塊和任務,可以構建復雜的Playbooks來執行各種操作和配置任務。

2.3任務之間的依賴關系

在 Ansible 的 playbook 中,任務之間可以有依賴關系,你可以使用 dependencies 或者 notify 語句來定義。

2.3.1 使用 dependencies 定義任務依賴關系

如果任務 A 依賴任務 B 完成,可以使用 dependencies 定義任務依賴關系,語法如下:

- hosts: web
  tasks:
    - name: Install Nginx
      yum:
        name: nginx
        state: present


    - name: Start Nginx
      service:
        name: nginx
        state: started
      become: true
      dependencies:
        - Install Nginx

在上面的示例中,Start Nginx 任務在 Install Nginx 任務完成之后才會執行。如果在執行 Start Nginx 任務之前,Install Nginx 任務未完成或者執行失敗,則 Start Nginx 任務也會失敗。

2.3.2 使用 notify 定義任務依賴關系

如果任務 A 完成后需要通知任務 B 執行,可以使用 notify 定義任務依賴關系,語法如下:

- hosts: web
  tasks:
    - name: Install Nginx
      yum:
        name: nginx
        state: present
      notify:
        -Start Nginx
         
    - name: Start Nginx
      service:
        name: nginx
        state: started
      become: true
      listen: Start Nginx

在上面的示例中,Install Nginx 任務完成后會通知 Start Nginx 任務執行。然后 Start Nginx 任務會通過 listen 參數監聽,等待通知執行。

總之,Ansible 支持在 playbook 中定義任務之間的依賴關系。你可以使用 dependencies 或 notify 語句來定義任務之間的順序和依賴關系。

2.4條件判斷

在Playbook中,可以使用when關鍵字來添加條件判斷。when關鍵字后面跟一個條件表達式,如果表達式返回True,則任務會被執行;如果返回False,則任務會被跳過。

條件表達式可以使用Ansible的Jinja2模板來編寫,例如:

tasks:
  - name: Install Apache if not installed
    package:
      name: apache2
      state: present
    when: ansible_pkg_mgr == 'apt'

在這個例子中,如果ansible_pkg_mgr變量等于"apt",則安裝Apache;否則跳過這個任務。

除了使用任務級別的條件判斷,還可以使用Play級別的條件判斷來控制整個Playbook的執行。這可以通過在Play的開始處添加when關鍵字來實現,例如:

- name: Deploy Web App
  hosts: all
  vars:
    deploy_web_app: true
  tasks:
    - name: Install Dependencies
      apt:
        name: "{{ item }}"
        state: present
      with_items:
        - python3
        - python3-pip
      when: deploy_web_app


在這個例子中,deploy_web_app變量的值為True時,才會執行任務Install Dependencies。如果deploy_web_app變量的值為False,則跳過整個Playbook的執行。

2.5循環

在Playbook中,可以使用循環結構來遍歷列表或其他可迭代對象,并對每個迭代項執行相同的任務。這可以使用Ansible的with_*系列模塊來實現。

以下是一些常見的循環結構的示例:

2.5.1 使用with_items模塊來遍歷列表

tasks:
  - name: Install packages
    apt:
      name: "{{ item }}"
      state: present
    with_items:
      - python3
      - python3-pip
      - git

在這個例子中,將依次安裝python3、python3-pip和git。

03、Playbook 組織

3.1Inclusions

在Playbook的組織中,include和import兩個指令都可以用來將其他的yaml文件(也就是Tasks文件)包含到當前的Playbook中。

它們的區別在于,當主Playbook執行到include指令時,它將處理包含的文件中的所有任務,并且在處理完之后繼續主Playbook的執行。而當主Playbook執行到import指令時,它只會處理被導入的文件中的變量定義,而不會處理任務,任務只有在需要的時候才會被引入執行。

下面是一個使用include指令包含其他文件的例子:

- hosts: webservers
  tasks:
    - name: Include web tasks
      include: web-tasks.yml

在這個例子中,主Playbook從web-tasks.yml文件中導入任務,并在執行完后繼續執行余下的任務。

下面是一個使用import指令包含其他文件的例子:

- name: Load variables
  import_vars: vars.yml


- name: Deploy web app
  hosts: webservers
  tasks:
    - name: Install dependencies
      apt:
        name: "{{ item }}"
        state: present
      with_items:
        - python3
        - python3-pip


    - name: Deploy app
      include: app-tasks.yml

在這個例子中,在主Playbook中使用import_vars指令來導入變量定義,然后在每個任務中都可以使用這些變量。然后我們使用include指令從app-tasks.yml文件中包含任務,這些任務可以使用在vars.yml文件中定義的變量。這種方式可以在需要時懶加載任務,提高性能。

需要注意的是,在被引入的文件中,不能再次使用- hosts:指令定義新的主機組,因為Ansible只允許在主Playbook中定義主機組。被引入的文件只包含任務,任務必須使用被定義的主機組來指定目標主機。

3.2Roles

Ansible的Roles是一種組織Playbook的方式,它將Playbook和相關的變量、模板和其他資源打包在一起,并且可以輕松地在Playbook中重用和分享。一個Role通常適用于一種操作或功能,比如安裝和配置一個應用程序、部署Web服務、安裝軟件包等等。

一個Role目錄通常包含以下文件和目錄:

my-role/
├── README.md
├── defaults/
│   └── main.yml
├── files/
├── handlers/
│   └── main.yml
├── meta/
│   └── main.yml
├── tasks/
│   └── main.yml
├── templates/
├── tests/
│   ├── inventory
│   └── test.yml
└── vars/
    └── main.yml


  • README.md:Role的說明文檔。
  • defaults/main.yml:默認變量定義文件。
  • files:包含角色使用的文件。
  • handlers/main.yml:Role的處理程序。
  • meta/main.yml:Role的元數據,例如角色名稱、作者、依賴等。
  • tasks/main.yml:包含Role組成部分的主要任務。
  • templates:包含角色使用的Jinja2模板。
  • tests:Role的測試腳本。
  • vars/main.yml:包含Role的變量。

要使用Role,需要在Playbook中定義roles擴展,例如:

- hosts: webservers
  roles:
    - my-role

這將運行my-role目錄中包含的所有任務。

通過使用Role,可以更好地組織和重復使用代碼,并提高代碼的可讀性和可維護性。它還可以幫助您在Ansible社區中分享自己的工作,或從其他用戶那里獲得高質量的Roles。

3.3引用/定義變量

在Playbook中,可以使用vars關鍵字來定義變量。例如:

vars:
  my_var: "Hello World"

這將定義一個名為my_var的變量,其值為字符串"Hello World"。

要在Playbook中訪問這個變量,可以使用{{ my_var }}語法。例如:

tasks:
  - name: Print Message
    debug:
      msg: "{{ my_var }}"

除了在vars中定義變量,還可以通過set_fact模塊來動態設置變量。例如:

tasks:
  - name: SetDynamic Variable
    set_fact:
      my_var: "{{ inventory_hostname }} is awesome"

3.4使用插件和模板

Ansible提供了插件和模板的功能,使得在Playbook中使用動態內容變得更加簡單和方便。

插件是一種可以擴展和定制Ansible功能的機制,可以在Playbook中調用和使用。常見的插件包括Action、Lookup、Filter、Callback等。使用插件和模板可以使Playbook更加具有可讀性和可維護性,使得動態內容的生成更加靈活和方便。

04、服務安裝與主機管理

4.1安裝服務器依賴

Playbook是Ansible的核心組件之一,用于定義和執行一系列任務。在使用Playbook之前,需要確保服務器上已經安裝了Ansible和相關的依賴項。以下是安裝服務器依賴的步驟:

4.1.1 安裝Python3及其相關依賴項

sudo apt update
sudo apt-get install -y python3 python3-pip python3-dev build-essential libssl-dev libffi-dev

4.1.2 安裝Ansible

sudo apt-add-repository ppa:ansible/ansible
sudo apt update
sudo apt-get install -y ansible

4.1.3 (可選)安裝 git

sudo apt update
sudo apt-get install -y git

4.1.4  檢查Ansible是否安裝

ansible --version

這樣,您的服務器就已經安裝了所需的依賴項以及Ansible。如果您計劃在多臺服務器上使用Ansible,則需要在每臺服務器上重復這些步驟。

4.2配置遠程服務器

在使用Playbook配置遠程服務器之前,需要確保Ansible已經正確安裝在本地機器上。然后,您需要做以下幾個步驟:

4.2.1 創建inventory文件

創建新的inventory文件,用于定義您要配置的遠程服務器的IP地址或域名。例如,您可以創建一個名為inventory的文件,并包含以下內容:

[webservers]
192.168.1.100
192.168.1.101


[dbservers]
192.168.1.102

在此示例中,我們定義了兩個組,webservers和dbservers,并列出了它們中每個服務器的IP地址。

4.2.2 編寫Playbook

編寫一個Playbook,用于在遠程服務器上執行特定的任務。例如,您可以創建一個名為web.yml的Playbook,并包含以下內容:

- name: Install andstart Nginx
  hosts: webservers
  become: true
  tasks:
  - name: Install Nginx
    apt:
      name: nginx
      update_cache: yes
      state: latest
  - name: Start Nginx
    service:
      name: nginx
      state: started
      enabled: true

在這個Playbook示例中,我們定義了一個名為Install and start Nginx的任務,它會在webservers組中的服務器上啟動Nginx服務器。

4.2.3 運行Playbook

運行Playbook,在遠程服務器上執行配置任務。例如,要在遠程服務器上運行示例中的web.yml Playbook,可以使用以下命令:

ansible-playbook -i inventory web.yml

在執行此命令后,Ansible將使用inventory文件中定義的遠程服務器的IP地址,并執行web.yml Playbook中定義的任務。

這是一個基本的Playbook配置遠程服務器的示例。需要根據具體的場景和任務需求來進行個性化配置和修改。

4.3部署應用程序

Playbook部署應用程序一般步驟:

1、準備應用程序的部署包。這通常是一個.tar.gz或.zip文件,包含應用程序代碼、依賴項和其他必要文件。
2、在目標主機上安裝所需的依賴項和軟件包。例如,在部署Python應用程序時,需要安裝Python解釋器、pip和其他依賴項。
3、創建一個目錄用于應用程序的部署。這通常是在目標主機上的一個新目錄,例如/home/user/myapp。
4、上傳應用程序部署包到目標主機并解壓縮。您可以使用copy模塊將部署包部署到目標主機上。
5、配置應用程序的運行環境。例如,在部署Flask應用程序時,需要設置環境變量、安裝必要的Python包等。
6、配置Web服務器以偵聽應用程序的請求。例如,您可以使用Nginx或Apache等Web服務器來代理應用程序請求。

05、常用模塊的 playbook 語法

  • file模塊:可以管理文件系統中的文件和目錄。下面是該模塊的常用參數:
  • copy模塊:可以將本地文件復制到遠程服務器上。
  • unarchive模塊:Ansible 中用于將壓縮文件解壓縮的模塊。
  • apt模塊:可以在Ubuntu或Debian系統上安裝、升級、刪除軟件包。
  • service模塊:可以在系統上管理服務。
  • user模塊:可以管理系統用戶。
  • shell模塊:可以在遠程服務器上運行基于命令行的任務。該模塊只能運行命令,不能使用管道、重定向和通配符。
  • script模塊:可以將本地腳本或可執行文件上傳到遠程服務器并在遠程服務器上運行。該模塊適用于運行復雜的命令和復雜的腳本。
  • template模塊:可以將在Ansible中定義的Jinja2模板應用于遠程服務器上的文件。在應用模板時,您可以使用變量來一次生成多個文件的不同版本。
  • lineinfile模塊:可以從文件中添加、修改或刪除單行文本。該模塊可用于修改文件中的配置文件或語言文件,或添加新行。
  • blockinfile模塊:可以在遠程服務器文件中添加、修改或刪除代碼塊。該模塊可以替代lineinfile模塊,以單個塊更新文件。
  • debug模塊:可以輸出調試信息。該模塊在編寫Playbooks時非常有用,因為可以檢查任務的變量和結果。

06、Ansible部署Pulsar集群運維實戰

6.1部署zookeeper集群

6.1.1 定義host文件

host 文件指定了要在哪些主機上執行任務。在 playbook 中,可以將 hosts 指定為一個變量,也可以通過 -i 參數指定一個主機清單文件,該文件包含要操作的主機列表。

[all:vars]
ansible_ssh_user=xxx
ansible_ssh_pass=xxx


[zk]
127.xxx.xxx.1 myid=1
127.xxx.xxx.2 myid=2
127.xxx.xxx.3 myid=3
127.xxx.xxx.4 myid=4
127.xxx.xxx.5 myid=5

6.1.2 定義變量

group_vars 目錄用于存放針對不同主機組的變量文件,其中 all 文件是一種特殊的變量文件,它包含了全局的變量定義,將適用于所有主機組。路徑結構如下:

group_vars/
├── all

在all文件中,我們可以定義安裝路徑、JDK版本為、zookeeper版本以及zookeeper相關的配置信息。比如:

inst_home: /opt/bigdata/inst
app_home: /opt/bigdata/app
zk_inst_home: zookeeper-3.6.3
zk_app_home: zookeeper
jdk_inst_home: jdk1.8.0_192
jdk_app_home: jdk
jdk_tgz: jdk1.8.0_192.tar.gz
zk_tgz: zookeeper-3.6.3.tar.gz


cluster_name=clusterName
client_port=2181
server_port1=2881
server_port2=2882
jmx_port=9012
admin_port=18080
dataDir="/data/bigdata/zookeeper_{{cluster_name}}/zkDataDir"
dataLogDir="/data/bigdata/zookeeper_{{cluster_name}}/zkDataLogDir"
zoo_log_dir="/opt/bigdata/inst/zookeeper-3.6.3-{{cluster_name}}/logs/"

6.1.3 編輯roles模塊

① check_port:檢查端口

判斷配置的端口是否被占用,如果被占用,則不能執行后續的步驟。

目錄結構如下:

check_port/
├── tasks/
│   └── main.yml
main.yml

#循環檢查端口是否是停用狀態

- name: Check port
  wait_for:
    host: "{{ inventory_hostname }}"
    port: "{{ item }}"
    delay: 2
    timeout: 3
    state: stopped
  register: result
  with_items:
    - "{{ client_port }}"
    - "{{ server_port1 }}"
    - "{{ server_port2 }}"
    - "{{ jmx_port }}"
    - "{{ admin_port }}"


- name: print result
  debug:
    msg: "Port {{ item.item }} is {{ item.state }}"
  with_items: "{{ result.results }}"

② dispatch_zk:分發安裝包

目錄結構如下:

dispatch_zk/
├── files/
│   └── zookeeper-3.6.3.tar.gz
├── tasks/
│   └── main.yml

files:放zookeeper安裝包文件。

main.yml

#分發zk安裝包并解壓到/tmp路徑下
- name: dispatch_zk
  unarchive:
    src: "{{zk_tgz}}"
    dest: "/tmp"
    mode: 755
    owner: root
    group: root

③ config_zk:配置zookeeper

目錄結構如下:

config_zk/
├── tasks/
│   └── main.yml
├── templates/
│   └── zoo.cfg

main.yml

#zoo.cfg模板文件應用到指定的路徑下
- name: zoo.cfg
  template:
    src: zoo.cfg
    dest: "{{ app_home }}/zk-{{ cluster_name }}/conf"
#創建zoo_log_dir目錄
- name: mkdir forlog
  shell: mkdir -p "{{zoo_log_dir}}"


#創建zk數據目錄
- name: mkdir for dataDir
  shell: mkdir -p "{{dataDir}}"


#創建zk日志目錄
- name: mkdir for dataLogDir
  shell: mkdir -p "{{dataLogDir}}"


#myid文件中輸入每臺主機的編號
- name: myid file
  shell: echo "{{myid}}" > {{dataDir}}/myid

zoo.cfg:zookeeper配置文件模板。

tickTime=2000
initLimit=10
syncLimit=5
maxClientCnxns=65535
autopurge.snapRetainCount=30
autopurge.purgeInterval=48
clientPort={{client_port}}
admin.serverPort={{admin_port}}
dataDir={{dataDir}}
dataLogDir={{dataLogDir}}
{% for host in groups.zk%}
server.{{ hostvars[host]['myid'] }}={{host}}:{{server_port1}}:{{server_port2}}
{% endfor %}

deploy_zk:部署zookeeper服務

目錄結構如下:

deploy_zk/
├── files/
│   └── env.sh
│   └── jdk1.8.0_192.tar.gz
├── tasks/
│   └── main.yml

env.sh:jdk環境變量配置

JAVA_HOME=/opt/bigdata/app/jdk
JRE_HOME=$JAVA_HOME/jre
PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib/rt.jar:$CLASSPATH

main.yml

#創建/opt/bigdata/inst目錄
- name: mkdir for inst_home
  shell: mkdir -p {{ inst_home }}


#創建/opt/bigdata/app目錄
- name: mkdir for app_home
  shell: mkdir -p {{ app_home }}


#注冊zk_dir變量
- name: stat_dir
  stat: path={{ inst_home }}/{{zk_inst_home}}-{{cluster_name}}
  register: zk_dir


#當zk_dir存在時,將/tmp路徑安裝包移到指定目錄并重命名
- name: rename zookeeper dir
  command: mv /tmp/{{zk_inst_home}} {{ inst_home }}/{{zk_inst_home}}-{{cluster_name}}
  when: zk_dir.stat.exists == False


#創建zk集群軟連接
- name: soft link
  file:
    path: "{{ app_home }}/zk-{{ cluster_name }}"
    src: "{{ inst_home }}/{{ zk_inst_home }}-{{ cluster_name }}"
    state: link


#分發并解壓jdk安裝包
- name: deploy jdk
  unarchive:
    src: "{{ jdk_tgz }}"
    dest: "{{ inst_home }}"


#創建jdk軟連接
- name: create soft link for jdk
  file:
    path: "{{ app_home }}/{{ jdk_app_home }}"
    src: "{{ inst_home }}/{{ jdk_inst_home }}"
    state: link


#運行jdk環境變量,使其生效
- name: env
  script: env.sh

⑤ start_zk:啟動zookeeper服務

目錄結構如下:

start_zk/
├── tasks/
│   └── main.yml

main.yml

#啟動zk服務

- name: start zookeeper
  shell: cd {{ app_home }}/zk-{{cluster_name}}; sh bin/zkServer.sh start

6.1.4 編輯任務執行和啟動腳本

zookeeper.yml:任務執行腳本

---
- name: check_port
  hosts: zk
  remote_user: root
  roles:
    - check_port
  tags: check_port


- name: dispatch_zk
  hosts: zk
  remote_user: root
  roles:
    - dispatch_zk
  tags: dispatch_zk


- name: deploy_zk
  hosts: zk
  remote_user: root
  roles:
    - deploy_zk
  tags: deploy_zk


- name: config_zk
  hosts: zk
  remote_user: root
  roles:
    - config_zk
  tags: config_zk
   
- name: start_zk
  hosts: zk
  remote_user: root
  roles:
    - start_zk
  tags: start_zk

6.1.5 部署并啟動zookeeper服務

# 部署并啟動zookeeper服務
ansible-playbook -i hosts-clusterName zookeeper.yml


#只檢查端口和分發安裝包
ansible-playbook -i hosts-clusterName zookeeper.yml --tags "check_port,dispatch_packages"

6.2部署Pulsar集群

6.2.1 定義hosts文件

[all:vars]
ansible_ssh_user=xxx
ansible_ssh_pass=xxx


[pulsar]
127.xxx.xxx.1
127.xxx.xxx.2
127.xxx.xxx.3
127.xxx.xxx.4
127.xxx.xxx.5

6.2.2 定義全局變量

group_vars 目錄用于存放針對不同主機組的變量文件,其中 all 文件是一種特殊的變量文件,它包含了全局的變量定義,將適用于所有主機組。路徑結構如下:

group_vars/
├── all

all文件內容中定義變量信息,如下:

bigdata_home: /opt/bigdata
inst_home: /opt/bigdata/inst
app_home: /opt/bigdata/app
pulsar_app_home: pulsar
pulsar_inst_home: apache-pulsar-2.9.2-1.3
pulsar_tgz: apache-pulsar-2.9.2-1.3-bin.tar.gz
pulsar_conf: "{{ app_home }}/pulsar/conf"
secret_key_dir: "{{ app_home }}/pulsar/data"


#bookkeeper.conf
ledgerDirectories: /data1/bookkeeper/ledger,/data2/bookkeeper/ledger,/data3/bookkeeper/ledger,/data4/bookkeeper/ledger


#broker.conf or client.conf
zkServers: "127.xxx.xxx.1:2183,127.xxx.xxx.2:2183,127.xxx.xxx.3:2183/clusterName"
clusterName: wenzhu
webServiceUrl: http://clusterNamexxxx:8080
brokerServiceUrl: pulsar://clusterNamexxxx:6650

6.2.3 編輯roles模塊

① dispatch_pulsar:分發安裝包

目錄結構如下:

dispatch_pulsar/
├── files/
│   └── apache-pulsar-2.9.2-1.3-bin.tar.gz
├── tasks/
│   └── main.yml

main.yml

#創建inst_home定義的目錄
- name: mkdir_inst_home
  file:
    path: "{{ inst_home }}"
    state: directory


#創建app_home定義的目錄
- name: mkdir_app_home
  file:
    path: "{{ app_home }}"
    state: directory


#分發并解壓pulsar安裝包到指定目錄
- name: dispatch_packages
  unarchive:
    src: "{{ pulsar_tgz }}"
    dest: "{{ inst_home }}"


#創建pulsar軟連接
- name: soft_link
  file:
    path: "{{ app_home }}/pulsar"
    src: "{{ inst_home }}/{{ pulsar_inst_home }}"
    state: link

② check_nar:校驗分層存儲和kop擴展的依賴包

目錄結構如下:

check_nar/
├── tasks/
│   └── main.yml

main.yml

#匹配指定路徑protocols和offloaders下是否有nar后綴的文件
- name: check nar
  find:
    paths: "{{ app_home }}/pulsar/{{ item }}/"
    patterns: "*.nar"
  register: result
  with_items:
    - "offloaders"
    - "protocols"


#設置文件匹配的結果(大于0表示文件存在)
- name: set nar_files_exist variable
  set_fact:
    nar_files_exist_{{item.item}}: "{{ item.matched > 0 }}"
  with_items: "{{ result.results }}"


#如果文件不存在,進行提示
- name: nar files not exist
  fail:
    msg: "{{ item.item }} nar files not found"
  when: nar_files_exist_{{ item.item }} == false
  ignore_errors: true
  with_items: "{{ result.results }}"


#如果文件存在,列出存在的文件名
- name: print nar files list
  debug:
    msg: "{{ item.files | map(attribute='path') | list }}"
  when: nar_files_exist_{{item.item}}
  with_items: "{{ result.results }}"

③ config_pulsar:配置pulsar

目錄結構如下:

config_pulsar/
├── tasks/
│   └── main.yml
├── templates/
│   └── bkenv.sh
│   └── pulsar_env.sh

main.yml

#匹配broker.conf中的advertisedAddress值并設置為遠程主機ip地址
- name: config_advertisedAddress
  lineinfile:
    path: "{{ pulsar_conf }}/broker.conf"
    regexp: "^advertisedAddress="
    line: "advertisedAddress={{ inventory_hostname }}"


#配置broker.conf中的zookeeperServers值
- name: config_zookeeperServers
  lineinfile:
    path: "{{ pulsar_conf }}/broker.conf"
    regexp: "^zookeeperServers="
    line: "zookeeperServers={{ zkServers }}"


#配置broker.conf中的clusterName值
- name: config_clusterName
  lineinfile:
    path: "{{ pulsar_conf }}/broker.conf"
    regexp: "^clusterName="
    line: "clusterName={{ clusterName }}"
     
#配置broker.conf中的kafkaAdvertisedListeners值
- name: config_kafkaAdvertisedListeners
  lineinfile:
    path: "{{ pulsar_conf }}/broker.conf"
    regexp: "^kafkaAdvertisedListeners="
    line: "kafkaAdvertisedListeners=PLAINTEXT://{{ inventory_hostname }}:9093"


#配置bookkeeper.conf中的advertisedAddress值,設置為主機ip地址
- name: config_bk_advertisedAddress
  lineinfile:
    path: "{{ pulsar_conf }}/bookkeeper.conf"
    regexp: "^advertisedAddress="
    line: "advertisedAddress={{ inventory_hostname }}"


#將模板文件bkenv.sh應用到pulsar的配置文件中
- name: config_bkenv.sh
  template:
    src: bkenv.sh
    dest: "{{ pulsar_conf }}"


#將模板文件pulsar_env.sh應用到pulsar的配置文件中
- name: config_pulsar_env.sh
  template:
    src: pulsar_env.sh
    dest: "{{ pulsar_conf }}"

④ create_data_dir:創建存儲數據的目錄

目錄結構如下:

create_data_dir/
├── tasks/
│   └── main.yml

main.yml

#循環創建with_items中的數據目錄

- name: mkdir_data_dir
  file:
    path: "{{ item }}"
    state: directory
  with_items:
    - /data1/bookkeeper/ledger
    - /data2/bookkeeper/ledger
    - /data3/bookkeeper/ledger
    - /data4/bookkeeper/ledger

⑤ config_secret_key:配置安全秘鑰

目錄結構如下:

config_secret_key/
├── files/
│   └── admin-secret.key
├── tasks/
│   └── main.yml

main.yml

#創建存放安全秘鑰的目錄
- name: create_secret_key_dir
  file:
    path: "{{ secret_key_dir }}"
    owner: root
    group: root
    state: directory


#將安裝秘鑰文件分發到指定的路徑下
- name: dispatch_secret.key
  copy:
    src: admin-secret.key
    dest: "{{ secret_key_dir }}"

⑥ init_meta:初始化集群元數據

目錄結構如下:

init_meta/
├── tasks/
│   └── main.yml
├── templates/
│   └── init_meta.sh

main.yml

#應用init_meta.sh腳本到遠程主機
- name: scp init_meta.sh
  template:
    src: init_meta.sh
    dest: "{{ app_home }}/pulsar"


#執行初始化腳本文件
- name: init_meta
  shell: nohup sh {{ app_home }}/pulsar/init_meta.sh > {{ app_home }}/pulsar/init.log2>&1 &


#等待20s查詢初始化日志中是否出現初始化成功的日志
- name: wait20s
  wait_for:
    path: "{{ app_home }}/pulsar/init.log"
    search_regex: "Cluster metadata for '{{ clusterName }}' setup correctly"
    delay: 20


#殺掉集群元數據初始化進程
- name: kill metadata
  shell: ps -efww|grep PulsarClusterMetadataSetup|grep -v grep|cut -c 9-15|xargs kill -9
init_meta.sh:初始化集群元數據腳本


{{ app_home }}/pulsar/bin/pulsar initialize-cluster-metadata \
--cluster {{ clusterName }} \
--zookeeper {{ zkServers }} \
--configuration-store {{ zkServers }} \
--web-service-url {{ webServiceUrl }} \
--broker-service-url {{ brokerServiceUrl }}

⑦ start_service:啟動broker和bookkeeper服務

目錄結構如下:

start_service/
├── tasks/
│   └── main.yml

main.yml

#啟動遠程主機bookkeeper服務
- name: start bookie
  shell: sh {{ app_home }}/pulsar/bin/pulsar-daemon start bookie


#啟動遠程主機broker服務
- name: start broker
  shell: sh {{ app_home }}/pulsar/bin/pulsar-daemon start broker

6.2.4 編輯任務執行腳本

pulsar.yml:任務執行腳本

---
#分發pulsar安裝包
- name: dispatch_pulsar
  hosts: pulsar
  remote_user: root
  become: yes
  become_flags: '-i'
  roles:
    - dispatch_pulsar
  tags: dispatch_pulsar


#檢查安裝包中kop和分層存儲nar包是否存在
- name: check_nar
  hosts: pulsar
  remote_user: root
  roles:
    - check_nar
  tags: check_nar


#修改pulsar配置
- name: config_pulsar
  hosts: pulsar
  remote_user: root
  become: yes
  become_flags: '-i'
  roles:
    - config_pulsar
  tags: config_pulsar
   
  #創建磁盤數據目錄
- name: create_data_dir
  hosts: pulsar
  remote_user: root
  become: yes
  become_flags: '-i'
  roles:
    - create_data_dir
  tags: create_data_dir


#配置證書文件
- name: config_secret_key
  hosts: pulsar
  remote_user: root
  become: yes
  become_flags: '-i'
  roles:
    - config_secret_key
  tags: config_secret_key


#初始化meta信息
- name: init_meta
  hosts: pulsar[0]
  remote_user: root
  become: yes
  become_flags: '-i'
  roles:
    - init_meta
  tags: init_meta
   
#啟動broker和bookkeeper服務
- name: start_service
  hosts: pulsar
  remote_user: root
  become: yes
  become_flags: '-i'
  roles:
    - start_service
  tags: start_service

6.2.5 執行playbook任務

#執行所有pulsar.yml中的任務
ansible-playbook -i hosts pulsar.yml


#只執行pulsar.yml中標簽為dispatch_pulsar,check_nar的任務
ansible-playbook -i hosts pulsar.yml --tags "dispatch_pulsar,check_nar"

07、Playbooks運維Pulsar集群總結

7.1Pulsar運維實踐總結

Pulsar作為新一代云原生架構的分布式消息中間件,目前再超大流量規模、海量分區、超高QPS等場景下缺乏長時間的穩定性驗證,在極端場景下還存在較多穩定性風險,當前社區版本迭代活躍;Pulsar集群在vivo內部日均處理消息達萬億+,需要不斷的合并社區issue及灰度升級高版本。運維事項較多、投入的運維人力較大。vivo分布式消息中間件團隊通過借助Ansible的模塊化、任務依賴、配置check、批量腳本執行等能力實現Pulsar集群從zk集群搭建、Pulsar安裝包編譯、自動化配置填充、批量分發部署、服務啟動的一鍵運維部署能力。大大縮減了Pulsar集群的運維人力投入,Pulsar組件存算分離的架構設計優秀,但部署配置項非常繁雜,通過自動化配置填充可有效規避配置信息不一致、版本不一致等高頻錯誤。

7.2playbooks服務部署步驟

根據以上實戰經驗,我們可以總結出部署某個服務時編寫playbooks腳本的一般步驟如下:

Ansible更多運維實踐可參考:https://github.com/ansible/ansible-examples

責任編輯:龐桂玉 來源: vivo互聯網技術
相關推薦

2025-07-17 07:40:17

2025-06-12 02:00:00

2025-06-05 09:06:08

2022-09-14 23:14:10

vivoPulsar大數據

2025-03-06 10:33:04

2015-10-08 10:55:23

云服務自動化運維 ANSIBLE

2022-06-09 13:45:18

vivoK8S集群Kubernetes

2015-06-24 10:42:19

云計算運維自動化運維ANSIBLE

2015-08-29 13:03:24

運維技術沙龍MDSA

2015-11-03 16:03:09

AppDeploy運維工具

2019-09-27 08:44:46

Ansible運維DevOps

2016-06-17 15:21:43

小米運維

2023-12-06 21:44:28

RocksDBvivo

2022-05-19 09:31:50

Kafka 集群數據存儲服務端

2015-03-02 09:21:03

運維監控系統小米

2020-08-06 14:36:24

Elasticsear集群運維

2013-06-09 10:38:54

IT運維管理運維管理ITIL管理

2025-04-30 05:00:00

批量運維系統

2014-09-22 11:24:18

運維

2020-04-30 15:00:17

運維Ansible自動化
點贊
收藏

51CTO技術棧公眾號

国产第一精品| 午夜av免费观看| 中文字幕人成人乱码| 欧美精品一区二区三区蜜臀 | 亚洲性视频h| 亚洲欧美综合另类中字| 欧美性猛交xxxx乱大交91| a在线视频v视频| 国产精品美女久久久久久久网站| 99在线视频首页| 亚洲图片欧美日韩| 狠狠干成人综合网| 久久精品国产99国产精品澳门 | 成人性做爰aaa片免费看不忠| 国产在线高清视频| 国产欧美视频一区二区三区| 国产精品国产精品| 最新黄色网址在线观看| 一本色道久久综合亚洲精品高清| 久久综合五月天| 免费在线观看你懂的| 亚洲国产精选| 欧美性xxxxxx少妇| 国产裸体舞一区二区三区| 欧美卡一卡二| 一区二区高清在线| 特级毛片在线免费观看| 国产福利在线| 久久这里只有精品视频网| 风间由美久久久| 国产成人麻豆精品午夜在线| 久久99国产精品免费网站| 欧美专区在线观看| 国产无精乱码一区二区三区| 久久久久午夜电影| 日韩中文字幕在线视频播放| 我不卡一区二区| 亚洲涩涩av| 日韩av在线看| 丰满大乳奶做爰ⅹxx视频| theporn国产在线精品| 欧美大片在线观看一区| 精品人妻一区二区三区免费| 精品国产亚洲日本| 在线播放91灌醉迷j高跟美女| 久久久久国产一区| 欧美高清你懂的| 欧美日韩免费一区二区三区| 牛夜精品久久久久久久| 福利一区二区三区视频在线观看| 色婷婷精品久久二区二区蜜臀av| 男人天堂999| 东京一区二区| 在线区一区二视频| 乌克兰美女av| 台湾天天综合人成在线| 欧美精品亚洲一区二区在线播放| 五月激情婷婷在线| 蜜桃精品视频| 亚洲第一页自拍| 一本色道综合久久欧美日韩精品| 日本在线中文字幕一区| 亚洲视频在线播放| 你懂得视频在线观看| 香蕉精品视频在线观看| 久久91精品国产91久久跳| 久久综合色综合| 夜夜嗨一区二区| 日本不卡免费高清视频| 欧美 亚洲 另类 激情 另类| 久久精品国产亚洲一区二区三区| 亚洲综合日韩在线| 亚洲 欧美 激情 另类| 久久精品视频网| 一个色的综合| 女子免费在线观看视频www| 天天色综合天天| 美女黄色片视频| 精品午夜视频| 亚洲激情电影中文字幕| 久久久久无码精品国产sm果冻| 国产国产精品| 韩国19禁主播vip福利视频| 欧美一级淫片免费视频黄| 麻豆成人免费电影| 国产乱码精品一区二区三区不卡| 蜜桃成人在线视频| 亚洲精品成人在线| 成人小视频在线看| 日本高清精品| 亚洲性生活视频在线观看| 国产免费一区二区三区四区| 亚洲最黄网站| 成人在线中文字幕| 色视频在线看| 亚洲欧美日韩人成在线播放| 欧洲黄色一级视频| 国产精品1区在线| 亚洲女人被黑人巨大进入al| 欧美在线视频第一页| 美女尤物久久精品| 91成人伦理在线电影| 美丽的姑娘在线观看免费动漫| 亚洲日本在线天堂| 日韩一级片播放| 精品中国亚洲| 久久在线观看视频| 亚洲色成人www永久网站| 国产99久久久国产精品潘金| 日韩视频在线播放| 污污网站在线看| 欧美午夜影院一区| 91网站免费入口| 亚洲看片一区| 7777精品久久久大香线蕉小说| 成年人在线观看网站| 亚洲成人av一区二区| 色偷偷中文字幕| 日韩夫妻性生活xx| 国产精品18久久久久久首页狼| 亚洲国产成人一区二区| 亚洲欧洲国产专区| 天堂在线资源视频| 久久爱www成人| 91wwwcom在线观看| 欧美自拍偷拍一区二区| 一区二区三区成人| 欧美成人福利在线观看| 国精一区二区| 日韩美女视频免费看| 一本一道人人妻人人妻αv| 国产精品88av| 粉嫩av一区二区三区天美传媒| 国产极品嫩模在线观看91精品| 亚洲午夜久久久久久久| 中文字幕在线欧美| 2022国产精品视频| 免费高清在线观看免费| 欧美调教视频| 91成人在线视频| 天堂网在线中文| 精品久久久免费| 91精品小视频| 男女精品网站| 日韩国产欧美一区| 成人国产精品一区二区免费麻豆| 一区二区国产精品视频| 中文字幕乱码中文字幕| 国产精品免费av| 成人综合久久网| 午夜精品一区二区三区国产| 91精品免费视频| 欧美极品少妇videossex| 精品国产乱码久久久久久久| 亚洲精品视频在线观看免费视频| 99re在线视频这里只有精品| 天天摸天天碰天天添| 精品国产一区二区三区小蝌蚪| 国产精品精品一区二区三区午夜版| 成人综合影院| 91 com成人网| 国产香蕉在线视频| 久久综合色天天久久综合图片| www.超碰com| 国产精品亚洲人成在99www| 国产精品九九九| www在线免费观看视频| 欧美大片免费久久精品三p| 日本午夜精品理论片a级app发布| www久久精品| 手机免费av片| 亚洲欧洲另类| 天堂√在线观看一区二区| 亚洲aⅴ网站| 高清欧美性猛交| 国产女主播在线写真| 欧美一区二区三区免费视频| 中日韩黄色大片| 国产精品麻豆久久久| 成人一区二区三区仙踪林| 国产精品入口| 伊人久久青草| 欧美日韩另类图片| 国产一区二区丝袜| 美女av在线免费看| 久久精品99无色码中文字幕| 亚洲人妻一区二区| 91精品福利在线一区二区三区 | 在线一区二区三区四区五区 | 日韩欧美国产黄色| xxxx日本少妇| 久久综合九色欧美综合狠狠| 91网址在线观看精品| 国产亚洲一级| 免费在线精品视频| 久久99国产精品视频| 999热视频在线观看| 九色成人搞黄网站| 午夜精品在线视频| 老司机免费在线视频| 亚洲精品天天看| www.com欧美| 欧美三级在线播放| 成年人视频在线免费看| 亚洲欧美日韩成人高清在线一区| 中文字幕成人动漫| heyzo一本久久综合| 中文字幕色网站| 日韩成人伦理电影在线观看| 激情深爱综合网| 亚洲国产日韩欧美在线| 色综合666| 亚洲色图丝袜| 久久99久久精品国产| 99久久人爽人人添人人澡| 成人黄色大片在线免费观看| 深夜视频一区二区| 欧美最猛性xxxx| 超碰成人av| 色综合久久精品亚洲国产 | 狠狠色丁香婷婷综合影院| 国产精品区一区二区三含羞草| 国产午夜精品一区在线观看 | 人人干人人视频| 免费在线亚洲| 97国产精东麻豆人妻电影 | 偷拍精品一区二区三区| 欧美不卡在线视频| www.97超碰| 欧美一二三区在线| 国产成人av免费看| 欧美一级免费观看| 国产高中女学生第一次| 欧美一卡二卡三卡| 国产v在线观看| 欧美一级艳片视频免费观看| 国产精品久久久久久在线| 欧美精品在线观看播放| 亚洲精品一区二区二区| 欧美影院精品一区| 一区二区三区免费观看视频| 67194成人在线观看| 一级黄色片在线播放| 欧美日韩电影在线| 国产人妖一区二区| 日韩三级中文字幕| 成人av手机在线| 亚洲成人久久电影| 亚洲欧美日韩免费| 亚洲天堂2020| 人人干在线视频| 超在线视频97| 精灵使的剑舞无删减版在线观看| 国模gogo一区二区大胆私拍| 岛国在线视频网站| 欧美在线一级va免费观看| 免费污视频在线一区| 国产美女精品视频免费观看| 国产精品亚洲欧美一级在线| 国产精华一区| 免费观看久久av| 亚洲一区二区免费视频软件合集| 亚州av乱码久久精品蜜桃| 成人黄色片免费| 国产欧美在线| 午夜免费高清视频| 国产精品影视在线| 中文在线一区二区三区| 国产三级精品在线| wwwav国产| 欧美视频免费在线| 亚洲图片视频小说| 精品国产免费人成电影在线观看四季| 四虎影视精品成人| 久久精品最新地址| 成人国产电影在线观看| 国产精品91在线| 日韩中文字幕| 欧美一级日本a级v片| 中文字幕日韩一区二区不卡| 久久成人免费观看| 久久成人久久爱| jlzzjizz在线播放观看| 国产精品三级电影| 久久夜靖品2区| 欧美美女黄视频| 在线观看xxx| 久久香蕉国产线看观看av| 涩涩视频在线| 成人久久18免费网站漫画| 国内精品视频在线观看| 成人小视频在线观看免费| 可以免费看不卡的av网站| 欧洲成人午夜精品无码区久久| 久久久美女艺术照精彩视频福利播放| 国产精品99久久久久久成人| 日韩欧美大尺度| 亚洲高清视频在线播放| 伊人男人综合视频网| 国产伦子伦对白在线播放观看| 成人黄色免费在线观看| 久久不见久久见中文字幕免费| 久久视频免费在线| 青青草精品视频| 亚洲av片不卡无码久久| 亚洲在线观看免费视频| 11024精品一区二区三区日韩| 精品调教chinesegay| 欧美aaa免费| 91免费观看网站| 日韩av自拍| 91蝌蚪视频在线观看| 97se亚洲国产综合自在线不卡| 国产小视频在线观看免费| 8x福利精品第一导航| 黄色av网站在线| 欧美影院久久久| 精品国产乱子伦一区二区| 国产一级大片免费看| 韩国精品在线观看| 亚洲一级理论片| 欧洲精品中文字幕| 激情小视频在线| 国产成人福利视频| 九九热爱视频精品视频| 免费欧美一级视频| 99久久99久久精品国产片果冻| 久久精品无码人妻| 精品国产自在久精品国产| 3d玉蒲团在线观看| 亚洲自拍小视频| 午夜欧美理论片| 欧美69精品久久久久久不卡| 亚洲美腿欧美偷拍| www.国产麻豆| 久久久久久美女| 国产劲爆久久| 日韩中文字幕在线视频观看| av电影一区二区| 狠狠人妻久久久久久| 亚洲美女av电影| 3d欧美精品动漫xxxx无尽| 色播五月综合| 麻豆精品新av中文字幕| 后入内射无码人妻一区| 欧美欧美欧美欧美| 中文av资源在线| 国产欧美日韩亚洲| 国产一区二区三区久久| 一本加勒比北条麻妃| 在线观看国产日韩| 日本中文字幕在线看| 亚洲自拍偷拍第一页| 极品av少妇一区二区| 三上悠亚ssⅰn939无码播放 | av影片在线一区| 天天干天天av| 一区二区三区成人| 深夜福利在线视频| 国产精品久久久久久久久影视| 久久成人综合| 亚洲成人福利视频| 欧美性高跟鞋xxxxhd| 成人影院免费观看| 91国产在线播放| 在线亚洲欧美| 少妇愉情理伦三级| 精品久久人人做人人爽| 一区二区电影免费观看| 在线观看欧美激情| 成人免费福利片| 国产男人搡女人免费视频| 久久精品影视伊人网| 国产毛片久久久| 中文字幕在线观看第三页| 亚洲人精品午夜| 涩爱av在线播放一区二区| 成人乱色短篇合集| 国产麻豆综合| 国产又色又爽又高潮免费| 欧美精品一区二区三区蜜桃视频| 日本另类视频| 欧美日韩成人免费视频| 国产精品色噜噜| 少妇喷水在线观看| 国产有码在线一区二区视频| 亚洲激情婷婷| 大地资源高清在线视频观看| 亚洲国内精品视频| 欧美成人福利| 97成人在线观看视频| 一区二区三区四区中文字幕| 国产福利小视频在线| 国产精品免费观看高清| 蜜臀a∨国产成人精品| 成年免费在线观看| 美女国内精品自产拍在线播放| 国产一区二区三区四区大秀| 国内精品免费视频| 欧美日韩成人综合天天影院|