Linux筆記:自動化運維之部署管理:Fabric、SSH免密碼登錄、Ansible、Paramiko的應用

連接服務器的遠程終端工具

  • SecureCRT 收費
  • Xshell 收費
  • mtputty 免費(windows下的putty的外殼程序,下載後放入putty同級,可以對多臺服務器進行有效管理)

測試服務器代碼的部署

  • 代碼完成後,需要進行測試, 就需要將我們的代碼部署到測試服務器上!
  • 測試服務器上創建一個git倉庫,同步最新的項目代碼!
  • 每次需要測試時, 通過代碼更新, 將最新代碼同步即可!

生產服務器代碼的部署

  • 測試完成後, 我們需要對測試過的代碼進行生產環境部署
  • 本地打包, 如: $ tar -zcf ../new.tar.gz . ,上傳到生產服務器, 如:$scp new.tar.gz [email protected]:/root,
  • 備份線上代碼,如:$mv /data/webroot/project1 /data/webroot/project1_v1
  • 解壓到部署目錄, 如: $cd /data/webroot/project1/, $tar -zxf /root/new.tar.gz
  • 再次進行線上測試驗收
  • 如果有問題,那麼進行回滾操作:將剛纔部署到線上代碼修改爲project1_v2,將之前備份的代碼目錄project1_v1還原爲project1即可!
  • 或者更好的回滾操作, 創建軟鏈接:$ln -s project1_v1 project1, 然後重啓uwsgi服務即可!
  • 通過軟鏈接的形式, 這樣以後有多個版本都可以通過刪除軟鏈接, 重新創建軟鏈接的形式, 無縫切換, 方便,高效,安全,快捷!

使用Fabric批量的自動化部署

  • 如果多臺服務器,手動部署將會變得工作量巨大而又麻煩,我們可以通過使用Fabric批量部署管理
  • Fabric的安裝:$pip3 install fabric3
  • 編寫fabfile.py文件, 不要修改名稱,默認是這個,修改後還需重新指定
    from fabric.api import *
    import datetime
    
    env.user='root'
    env.hosts=['192.168.55.66', '192.168.55.67']
    
    def demo1():
        # local 表示在本機執行
        # 通過執行 `fab demo1` 即可創建一個demo1文件
        local('touch demo1') # 這裏面直接使用shell命令
    
    def demo2():
        # run表示在遠程機器執行
        # `fab demo2 -H 192.168.55.66`
        run('touch demo2')
        # 除了run之外,我們要傳遞文件到遠程服務器上使用put(), 要在遠程服務器上改變當前文件夾,則需要使用cd()命令
    
    def pack():
        '''定義一個打包命令'''
        local('rm -f temp.tar.gz') # 先執行刪除操作
        local('cd project1 && git pull origin master') # 拉取最新代碼
        local('cd project1 && tar -czf ../temp.tar.gz --exclude=.git . ') # 打包除了.git目錄外的所有文件
    
    def deploy():
        '''部署文件'''
        remote_temp_tar = '/tmp/temp.tar.gz'
        run('rm -rf ' + remote_temp_tar) # 先刪除遠程文件
        put('temp.tar.gz', remote_temp_tar) # 傳輸當前壓縮文件
    
        # 定義一個遠程文件夾,用於創建和解壓, 並且保留不同版本
        tag = datetime.datetime.now().strftime('%Y%M%D%H%M%S')
        remote_dist_dir = '/data/deploy/project1@' + tag
        run('mkdir -p ' + remote_dist_dir)
    
        # 開始解壓縮
        with cd(remote_dist_dir):
            run('tar -zxf ' + remote_temp_tar)
    
        # 爲了程序不報錯, 創建文件夾
        run('mkdir -p /data/webroot')
        # 定義和創建軟鏈接
        link = '/data/webroot/project1'
        run('rm -rf' + link)
        run('ln -s %s %s ' % (remote_dist_dir, link))
    
        # 重啓uwsgi服務
        with settings(warn_only=True):
            run('pkill uwsgi') # 結束進程時,可能沒有啓動,會出錯,此處通過with來處理該異常
            run('/usr/local/bin/uwsgi --ini /data/uwsgi.ini')
    
    
  • 注意在部署前要確保服務器上存在/data/uwsgi.ini配置文件
  • 同時也需要手動輸入密碼進行操作
  • 執行 $fab pack 本機打包
  • 執行 $fab deploy 遠程部署
  • 也可以同時執行 $fab pack deploy

批量運維管理

  • 目前我們需要管理的機器越來越多了,如果每次連接都要手動輸入密碼,那麼就沒法稱之爲自動化了, 那麼就需要對這些機器進行科學的管理

1 ) SSH免密碼登錄 原理

  • RSA非對稱加密算法

    • Public Key 公鑰 (公開出去)
    • Private Key 私鑰 (自己保管)
    • 它們之間成對使用, 公鑰加密的數據,只有對應的私鑰才能解密;使用私鑰加密的數據,只有對應的公鑰才能解密
    • 由於加密和解密過程中使用了2個不同的密鑰,所以我們稱之爲非對稱加密算法
    • 無法通過公鑰計算出私鑰是什麼
  • 利用RSA算法來實現免密碼登錄

    • 生成密鑰對之後,我們把公鑰放在服務器上,即可實現免密碼登錄
    • 服務器是如何進行身份驗證呢?服務器通過公鑰加密一段隨機的內容,只要客戶端能正確解密,就可以確定身份了
    • 因爲擁有對應私鑰的人才能解密成功,所以我們的私鑰絕對不能泄露
    • 首先我們需要使用$ssh-keygen來生成我們的一對密鑰(公鑰、私鑰), 默認生成在/root/.ssh/id_rsa
    • 使用ssh-copy-id命令將我們的公鑰放到服務器上, $ssh-copy-id [email protected], 第一次連接需要輸入密碼 (假設66主機爲我們的服務器)
    • 備註:ssh-copy-id命令不需進入/root/.ssh/目錄,即可進行拷貝
    • 退出後再次進行連接ssh [email protected], 無需密碼即可登錄
    • 進行驗證,登錄66服務器主機,切換到/root/.ssh/ 進行查看 ls, 發現有了一個文件authorized_keys, 使用cat命令查看該文件,經過對比可知,它和我們客戶端的公鑰id_rsa.pub完全一致, 如果想要取消授權,我們只需要將authorized_keys這個文件刪除即可!

2 ) SSH免密碼登錄 應用

  • 我們的客戶端A想要同時連接多臺機器C、D、E,存在防火牆,就需要進行相關的安全部署設計
  • 我們可以建立一臺目標機器, 設爲B, 通過B去控制連接C、D、E, 來響應客戶端A
  • 我們將B上的公鑰拷貝到C、D、E上後,只要A可以連接上B, 那麼就可以控制C、D、E
  • 只需要做好B主機的安全措施即可!

3 ) Ansible運維工具的使用

  • Ansible是一個python開發的遠程運維工具
  • 我們可以很方便的同時在多臺服務器上進行維護任務,使用起來很簡單
  • 官網:https://www.ansible.com
  • 安裝:$apt install -y ansible
  • 查看版本:$ansible --version, 通過輸出信息,可以看到它的默認配置文件在 /etc/ansible/ansible.cfg
  • 我們想要通過ansible來批量管理我們的機器, 我們就需要在其中配置好我們的機器列表, $cd /etc/ansible/ && ls 看到有個hosts文件
  • hosts文件就是用來配置機器列表的, 編輯它:$vi hosts, 我們使用[]來表示分組, 將我們需要批量部署的機器ip地址寫進去
    # web服務器分組
    [web]
    192.168.55.66
    192.168.55.67
    # 數據庫服務器分組
    [db]
    192.168.55.68
    
  • 保存後,我們就可以使用ansible對這些機器進行管理了
  • 首先我們通過uptime命令來打印機器時間和負載情況
  • 然後通過ansible的命令$ansible all -m raw -a "uptime"
    • all 代表機器列表中所有的機器, 我們可以將其替換成上面的web、db等我們配置好的分組
    • -m 表示使用模塊
    • raw 表示ansible中的raw模塊來執行我們的原生命令
    • -a 是這個模塊需要的參數
    • "uptime" 就是這個例子中具體的參數
  • 備註:我們執行這條命令前要確保所有配置的機器都可以進行SSH免密碼登錄
  • 我們繼續測試命令, $ansible all -m ping
    • 注意ping模塊需要目標主機上安裝python
    • 上面的檢測是必須項,如果滿足條件就可以使用ansible提供的其他模塊了
    • 如果沒有安裝,我們可以通過$ansible all -m raw -a "apt update && apt install -y python"
    • 注意apt安裝軟件如果已經安裝會自動跳過,不會產生問題
  • 我們繼續測試命令, $ansible all -m script -a "./test.sh"
    • script 模塊是將本機的腳本文件傳送到目標機器然後去執行它
    • 可以在test.sh中編寫一句簡單的輸出測試echo test
    • raw模塊一樣,不需要主機有python環境,我們可以利用這一特性,用於初始化裸機操作,比如:基礎軟件的安裝
  • 我們繼續測試命令, $ansible all -m command -a "uptime"
    • command 模塊需要目標主機上有python運行環境的,是ansible的默認模塊
    • 可以省略-m command, 即:$ansible all -a "uptime"
    • 列出根目錄:$ansible all -a "ls /"
    • 查看磁盤空間:$ansible all -a "df -h"
    • 查看內存空間:$ansible all -a "free -m"
  • 我們繼續測試命令, $ansible all -m copy -a "src=./test.sh dest=/tmp"
    • 用於拷貝文件的命令, 將當前文件夾下的test.sh文件拷貝到目標主機的/tmp目錄下
    • src和dest分別表示源文件和目標文件
  • 我們繼續測試命令, $ansible all -m file -a "path=/tmp/test.sh mode=0755"
    • 改變目標主機上的文件權限,用於執行遠程文件
    • 默認創建的文件權限是-rw-r--r--, 不可以執行, 使用file模塊改變了文件的權限
  • 我們繼續測試命令, $ansible all -m shell -a "/tmp/test.sh"
    • shell模塊用於執行shell腳本和script模塊類似
    • 這條命令需要該文件有執行的權限
  • 我們繼續測試命令, $ansible all -m fetch -a "src=/var/log/auth.log dest=./down"
    • fetch模塊用於將遠程機器上的文件auth.log下載回來,存放於當前目錄下的down目錄中
    • 備註:如果當前沒有down目錄,則會自動創建

4 ) Paramiko的使用

  • 使用Paramiko來編寫自己的python程序來滿足一些其他工具無法或很難實現的功能

  • Paramiko模塊基於SSHv2版本協議, 封裝了SSH客戶端和sftp客戶端, 我們可以很方便的使用它來連接遠程的主機

  • 編寫一個python程序,連接到遠程主機, 執行一個命令獲取遠程主機的可用內存數據, 然後在python中做更多處理:監控、報警等等

  • 安裝paramiko, $pip3 install paramiko

  • 創建一個run.py的文件

    import paramiko
    
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # ssh.connect(hostname='192.168.55.66', username='root', password='root') # 備註,此處password明文傳輸非常不安全,建議不寫密碼,先處理好SSH免密碼登錄
    ssh.connect(hostname='192.168.55.66', username='root') 
    # command = "free -m"
    command = "free -m | awk '/^Mem/{print $7}'" # 使用awk來過濾數據,這裏輸出第7列的數據
    stdin, stdout, stderr = ssh.exec_command(command)
    res = stdout.read().decode()
    print(res)
    
  • 執行該段代碼, $python3 run.py 即可獲取數據

自動化運維的專業知識

  • 網絡相關知識
  • linux操作系統
  • 各種服務器軟件的安裝配置
  • python編碼能力及相關web框架
  • 通過web界面發佈指令來執行監控,備份,發佈代碼等
發佈了410 篇原創文章 · 獲贊 221 · 訪問量 69萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章