iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0

今天會透過 ShellScript 來部署 SSH Public Key 到各 Host 上
完成後透過 Ansible 來大量處理 Node-Exporter 的安裝
最後用 Prometheus 來檢視一下 Metric 是否成功

Bastion ssh 公鑰上傳

待會 ansible 會透過 SSH 來進行操作
所以這邊來生個 SSH Private/Public KeyPair 來簡化驗證流程

ssh-keygen

https://ithelp.ithome.com.tw/upload/images/20231002/20162773Cz3W5SHzSS.png

ssh-copy-id root@<remote-ip>

https://ithelp.ithome.com.tw/upload/images/20231002/20162773V14dcwrb8t.png

這樣子就成功把 Bastion 公鑰上傳到另一台 Linux 上了
但如果有上百台 Linux 準備被納管 這不是會輸入到累死嗎?
這時就可以用 shell 來幫助我們來進行大量操作
(為避免 A:我要先使用 ansible 來匯入 ssh key 驗證ansible
B:那就用 ansible 匯入 的迴圈所以跑去用 shell

這邊要多安裝 expect 來自動跑交互式命令的輸入密碼給 ssh-copy-id 做驗證

apt-get install -y expect

用 APT 安裝好後就來處理 Shell Code 吧

#!/bin/bash

read -s PWD
hosts=("5" "6" "101" "102" "103") # Host IP need to add ssh key.

for i in "${hosts[@]}"; do
        /usr/bin/expect <<EOT
        set timeout 1
        spawn ssh-copy-id root@10.0.0.$i
        expect "Password will auto fill in"
        send "$PWD\n"
        expect EOF
EOT
done

稍微解釋一下

  • read -s PWD 是將 ssh-copy-id 要用的密碼輸入進入 shell 存為 PWD 這個變數
    在 read 輸入時是看不見輸入的文字的
  • hosts=("5" "6"...) 是將要存放公鑰的 Server IP 存入 hosts 陣列 待會使用 for 來讀取
  • set timeout 1 是為了減少 expect 運行的等待時間

大致上是這個樣子 下方是 shell 執行的結果

root@router:~# bash ssh-copy-id.bash
spawn ssh-copy-id root@10.0.0.5
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@10.0.0.5's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@10.0.0.5'"
and check to make sure that only the key(s) you wanted were added.
spawn ssh-copy-id root@10.0.0.6
......

Bastion Ansible 安裝/腳本撰寫

先在 Bastion 上裝 Ansible 吧

apt-get install -y ansible
mkdir /etc/ansible

接著要寫 Ansible 腳本(Playbook) 來執行待會安裝 node-exporter 的流程
這邊先來寫 Ansible 的基本設定 透過 /etc/ansible/ansible.cfg 來指定
這邊設定 Ansible 的 Inventory 路徑和 remote_user 為 root

nano /etc/ansible/ansible.cfg

[defaults]
    inventory = ./inventory
    remote_user = root
    ask_pass = false

這邊透過 Inventory 來指定 Group 的成員

  • prometheus_node_exporter_inst 是正式安裝的對象
  • tester 是專門開來測試用的群組 (雖然可以 --check 來 dry run :D
nano /etc/ansible/inventory

[prometheus_node_exporter_inst]
    lcr.ironman.test
    ipam.ironman.test
    lke-main.ironman.test
    lke-node1.ironman.test
    lke-node2.ironman.test

[tester]
    10.0.0.6

接著就是 Ansible 的 Playbook 本體
透過 hosts 來指定要被操作的群組 / IP 這邊先用 tester 來做測試
這一個 playbook 有兩個 play 會執行
第一個 play 主要是安裝 prometheus-node-exporter 詳細的操作如下

  • 更新 APT Package list
  • 透過 APT Install prometheus-node-exporter
  • 透過 APT Install curl 給等等 Local 端測試連線
  • 透過 systemd 啟動 prometheus-node-exporter 和設定開機啟動

第二個 play 是用來 local 端測試服務正不正常

  • 透過 curl 敲 prometheus-node-exporter 的路徑 檢測 html 內容有沒有 "Node Exporter"
  • 如果有 "Node Exporter" 就回傳 "node-exporter successful"
  • 如果沒有 "Node Exporter" 就回傳 "node-exporter failure"
---
- name: Install_prometheus_node_exporter_to_servers
  hosts: tester
  tasks:
    - name: update apt package list
      ansible.builtin.apt:
        update_cache: yes
    - name: Install prometheus node-exporter
      ansible.builtin.apt:
        name: prometheus-node-exporter
        state: present
    - name: Install curl
      ansible.builtin.apt:
        name: curl
        state: present
    - name: Make sure a service unit is running and startup when booting
      ansible.builtin.systemd_service:
        name: prometheus-node-exporter
        state: started
        enabled: true

- name: check localhost:9100 from localhost
  hosts: tester
  tasks:
    - name: Check if 'Node Exporter' string exists in localhost:9100/metric
      shell: curl -s http://localhost:9100/metric | grep "Node Exporter"
      register: grep_result
      ignore_errors: yes
    - name: Show result
      debug:
        msg: "node-exporter successful"
      when: grep_result.rc == 0
    - name: Show result if string is not found
      debug:
        msg: "node-exporter failure"
      when: grep_result.rc != 0

測試執行結果https://ithelp.ithome.com.tw/upload/images/20231002/20162773X1mFzmVcyw.png

最終執行結果
https://ithelp.ithome.com.tw/upload/images/20231002/20162773vXsBdWsTNt.png

這邊在第一次執行時遇到 ssh host key 衝突導致執行失敗 ==

Prometheus 伺服端設定

最後來 Prometheus 伺服端把設定 Key 上去
再到網頁端確認結果就結束了
打開 prometheus 的設定檔

nano /etc/prometheus/prometheus.yml
  • job_name 設成可辨識的名字
  • targets 設成對象的 IP
- job_name: 'router'
  static_configs:
    - targets: [ 'router.ironman.test:9100' ]
- job_name: 'lcr'
  static_configs:
    - targets: [ 'lcr.ironman.test:9100' ]
- job_name: 'ipam'
  static_configs:
    - targets: [ 'ipam.ironman.test:9100' ]
- job_name: 'lke-main'
  static_configs:
    - targets: [ 'lke-main.ironman.test:9100' ]
- job_name: 'lke-node1'
  static_configs:
    - targets: [ 'lke-node1.ironman.test:9100' ]
- job_name: 'lke-node2'
  static_configs:
    - targets: [ 'lke-node2.ironman.test:9100' ]

接著回到 Prometheus 的網頁上
這次使用 node_memory_MemAvailable_bytes 來看看現在哪台 VM 的 RAM 最閒 欠砍RAM Size
https://ithelp.ithome.com.tw/upload/images/20231002/20162773alJace1y3k.png
非常成功!

補充

其實官方就有自己的 Ansible Role 可以使用
但秉持著 DIY(Destroy It Youself) 的精神這邊還是用自己寫的了


上一篇
Day16 Prometheus(一) Playing God… 開始進入主線任務
下一篇
Day18 Prometheus(三) Blackbox Exporter
系列文
地端建置大雜燴-下從網路線上到Grafana的建置之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言