返回文章列表

Paramiko SSH 連線與遠端檔案操作

本文介紹如何使用 Python 的 Paramiko 函式庫進行 SSH 連線、執行遠端命令和管理遠端檔案。涵蓋建立 SSH 連線、設定 Host Key Policy、載入主機金鑰、執行遠端命令、使用 SFTP 管理檔案等關鍵步驟,並提供程式碼範例和注意事項,幫助開發者安全有效地操作遠端伺服器。

Web 開發 系統管理

Paramiko 提供了簡潔易用的 API,讓 Python 開發者能輕鬆地與遠端伺服器互動。在建立 SSH 連線時,務必設定合適的 Host Key Policy 以確保安全性,例如使用 WarningPolicyAutoAddPolicy。載入已知主機金鑰可以進一步提升安全性,避免中間人攻擊。執行遠端命令時,需妥善處理標準輸入、輸出和錯誤輸出,避免潛在的死鎖問題。使用 SFTPClient 管理遠端檔案時,應使用完整路徑以確保操作的準確性,並使用八進位表示法設定檔案許可權,維持程式碼的可讀性。

使用 Paramiko 進行 SSH 連線與操作

Paramiko 是一個 Python 函式庫,用於實作 SSHv2 協定,允許開發者透過 SSH 連線到遠端伺服器並執行命令、傳輸檔案等操作。本文將介紹如何使用 Paramiko 進行 SSH 連線、執行命令、管理遠端檔案等。

建立 SSH 連線

要使用 Paramiko,首先需要建立一個 SSHClient 物件。可以使用 contextlib 模組的 context 函式來確保連線在使用後被正確關閉。

import contextlib
import paramiko
import sys

with contextlib.closing(paramiko.SSHClient()) as client:
    client.connect(sys.argv[1])
    # 在此處執行相關操作

設定 Host Key Policy

在連線之前,可能需要設定 Host Key Policy 以處理主機金鑰驗證。Paramiko 提供了多種策略,例如 WarningPolicyAutoAddPolicy 等。

client.set_missing_host_key_policy(paramiko.WarningPolicy())

載入主機金鑰

可以透過 load_host_keysload_system_host_keys 方法載入已知主機金鑰檔案,以增強安全性。

client.load_host_keys(os.path.expanduser("~/.ssh/known_hosts"))

執行遠端命令

連線建立後,可以使用 exec_command 方法執行遠端命令。

stdin, stdout, stderr = client.exec_command("echo hello world")
print(stdout.read().decode("ascii"))

注意事項

  • exec_command 方法傳回命令的標準輸入、輸出和錯誤輸出。
  • 應避免使用可能從標準輸入讀取的命令,以防止死鎖。
  • 若需要互動式 shell,可以使用 invoke_shell 方法。

管理遠端檔案

Paramiko 的 open_sftp 方法傳回一個 SFTPClient 物件,用於管理遠端檔案。

sftp = client.open_sftp()
# 使用 sftp 物件進行檔案操作

檔案屬性管理

可以使用 SFTPClient 物件的方法來修改檔案屬性,例如 chmod

sftp.chmod("/etc/some_config", 0o644)

注意事項

  • 使用完整路徑進行檔案操作,以避免依賴當前目錄。
  • 使用八進位表示法(如 0o644)設定檔案許可權。

重點整理

  1. 建立 SSH 連線:使用 SSHClient 和適當的 Host Key Policy。
  2. 執行遠端命令:使用 exec_command,注意處理輸入輸出。
  3. 管理遠端檔案:使用 SFTPClient,並注意使用完整路徑和正確的許可權設定。
內容解密:
  1. 本文主要介紹瞭如何使用 Paramiko 函式庫進行 SSH 連線與操作,包括建立連線、執行命令和管理檔案。
  2. 程式碼範例展示瞭如何建立 SSH 連線、設定 Host Key Policy、載入主機金鑰、執行遠端命令和管理遠端檔案。
  3. 重點整理了使用 Paramiko 的關鍵步驟和注意事項,包括使用完整路徑進行檔案操作和正確設定檔案許可權。

SaltStack 組態管理系統詳解

SaltStack 是一種組態管理系統,旨在簡化大量機器的管理任務。它透過在不同機器上應用相同的規則,確保組態差異是刻意為之。SaltStack 是用 Python 編寫的,並且可以透過 Python 進行擴充套件。

SaltStack 的基本原理

SaltStack 的核心概念是收斂迴圈。當執行 SaltStack 時,它會執行三個主要步驟:

  1. 計算所需的組態
  2. 計算系統與所需組態之間的差異
  3. 發出命令以使系統達到所需的組態

SaltStack 不僅可以組態作業系統,還可以組態一些 SaaS 產品,例如 Amazon Web Services、PagerDuty 和某些 DNS 服務。

SaltStack 的使用方式

SaltStack 有多種使用方式:

  1. 本地模式:在本地執行命令以實作所需的組態。
  2. SSH 模式:伺服器透過 SSH 連線到客戶端並執行命令以實作所需的組態。
  3. 原生協定模式:客戶端連線到伺服器並執行伺服器指示的步驟。

使用 SSH 模式可以避免在遠端主機上安裝專用的客戶端,因為大多陣列態中已經安裝了 SSH 伺服器。然而,SaltStack 的原生協定具有多個優勢:

  • 允許客戶端連線到伺服器,簡化了發現過程。
  • 具有更好的擴充套件性。
  • 允許控制遠端客戶端上安裝的 Python 模組,這對於 SaltStack 擴充套件至關重要。

SaltStack 的安裝

SaltStack 有兩個 PyPI 包可用:

  1. salt:包含客戶端/伺服器程式碼,依賴於 pyzmq,後者又依賴於 libzmq C 函式庫。
  2. salt-ssh:僅包含本地和根據 SSH 的客戶端,不依賴於 libzmq 函式庫。

如果只需要本地/SSH 支援,建議安裝 salt-ssh

SaltStack 組態範例

以下是一個簡單的 SaltStack 組態範例,使用 YAML 檔案定義了一個字典:

# example.sls
package:
  pkg.installed:
    - name: nginx
service:
  service.running:
    - name: nginx
    - enable: True

這個組態檔案確保了 nginx 包已安裝並且服務正在執行。

使用 Python 檔案定義 SaltStack 組態

SaltStack 允許使用 Python 檔案定義組態。下面是一個例子:

# example.py
def run():
    return {
        'package': {
            'pkg.installed': [
                {'name': 'nginx'}
            ]
        },
        'service': {
            'service.running': [
                {'name': 'nginx'},
                {'enable': True}
            ]
        }
    }

這個 Python 檔案定義了一個與上述 YAML 檔案相同的組態。

SaltStack 的優勢

SaltStack 的優勢在於其靈活性和可擴充套件性。它允許使用者使用 Python 編寫自定義模組和擴充套件,以滿足特定的需求。此外,SaltStack 的原生協定模式提供了更好的擴充套件性和控制能力。

SaltStack 設定與測試

SaltStack 是一種強大的自動化工具,用於遠端管理和組態多台機器。本文將探討 SaltStack 的設定流程、測試方法以及常見的使用案例。

SaltStack 的基本設定

在使用 SaltStack 之前,需要先設定 roster 檔案。roster 檔案是一個 YAML 格式的檔案,用於定義需要管理的機器。

file_server:
  user: moshe
  sudo: True
  priv: /usr/local/key

print_server:
  user: moshe
  sudo: True
  priv: /usr/local/key2

內容解密:

  • file_serverprint_server 是機器的邏輯名稱,用於在 SaltStack 中識別機器。
  • user 指定用於 SSH 連線的使用者名稱。
  • sudo 設定是否需要使用 sudo 許可權,大多數情況下設為 True
  • priv 指定私鑰檔案的路徑,用於 SSH 身份驗證。

設定 roster 檔案的位置

預設情況下,SaltStack 會在 /etc/salt/roster 尋找 roster 檔案。如果需要將 roster 檔案放在其他位置,可以透過設定 roster_file 引數來指定。

salt-ssh:
  config_dir: some/directory

內容解密:

  • config_dir 指定 SaltStack 組態檔案的目錄。
  • 可以在 master 組態檔案中設定 roster_file 引數,指向 roster 檔案的位置。

測試 SaltStack 連線

設定完成後,需要測試 SaltStack 是否能夠正確連線和管理機器。

$ salt '*' test.ping

內容解密:

  • test.ping 是用於測試機器是否可達的命令。
  • 如果機器可達,將傳回 True

其他測試命令

除了 test.ping 之外,SaltStack 還提供了其他測試命令。

$ salt '*' test.false
$ salt '*' test.collatz
$ salt '*' test.fib
$ salt '*' test.kwarg word="hello" number=5 simple_dict='{thing: 1, other_thing: 2}'

內容解密:

  • test.false 用於測試失敗的情況。
  • test.collatztest.fib 用於測試機器的效能。
  • test.kwarg 用於測試引數解析是否正確。

使用 SaltStack 執行遠端命令

SaltStack 不僅可以用於測試連線,還可以用於執行遠端命令。

$ salt '*' cmd.run 'mkdir /src'

內容解密:

  • cmd.run 用於執行遠端命令。
  • 在所有連線的機器上建立 /src 目錄。

設定機器的 desired state

SaltStack 的核心功能之一是將機器設定為 desired state,也就是所謂的 highstate。

$ salt '*' state.highstate
$ salt '*' state.apply

內容解密:

  • state.highstatestate.apply 都用於將機器設定為 desired state。
  • state.highstate 是傳統的命令,而 state.apply 是較新的別名,用於減少混淆。

SaltStack 自動化管理系統詳解

SaltStack 是一種強大的自動化管理工具,用於管理和組態大量伺服器。它透過定義所需的系統狀態,並傳送命令以達到該狀態,從而簡化了系統管理。

SaltStack 的基本工作原理

SaltStack 的核心思想是定義系統的「所需狀態」,並透過傳送命令來實作該狀態。這種狀態通常由 SLS(Salt State)檔案描述,這些檔案通常採用 YAML 格式。

top.sls 檔案的作用

top.sls 檔案是 SaltStack 組態的核心,它定義了哪些 SLS 檔案適用於哪些機器。例如:

# top.sls
base:
  '*':
    - core
    - monitoring
    - kubelet

這個例子表示所有機器都將應用 core.slsmonitoring.slskubelet.sls 中定義的組態。

內容解密:

  • base 是 SaltStack 的預設環境名稱。
  • '*' 表示所有 minion(SaltStack 的客戶端代理)。
  • - core- monitoring- kubelet 是要應用的 SLS 檔案名稱,分別負責基礎包安裝、監控工具組態和 kubelet 的安裝組態。

SaltStack 的關鍵概念

  1. Minion:SaltStack 的客戶端代理,負責執行來自 Salt Master 的命令。
  2. Salt Master:SaltStack 的伺服器端,負責向 Minion 傳送命令。
  3. Salt State:以 .sls 為副檔名的檔案,包含狀態宣告,用於描述所需的系統狀態。

Salt State 範例

process_tools:
  pkg.installed:
    - pkgs:
      - procps

內容解密:

  • process_tools 是狀態名稱。
  • pkg.installed 表示安裝軟體包的狀態。
  • - pkgs: 列出了要安裝的軟體包名稱,例如 procps(包含 ps 命令)。
  1. Salt Module:與 Python 模組不同,Salt Module 用於執行特定任務,不保證冪等性(即多次執行相同的操作會產生相同的結果)。

  2. Pillar:用於將引數附加到特定的 Minion,不同的狀態可以重複使用這些引數。Pillar 非常適合儲存敏感資訊,因為它們不會被髮送到不正確的 Minion。

  3. GPG 加密:可以用於加密 Pillar 中的敏感資訊,確保只有擁有私鑰的 Salt Master 才能解密。

狀態之間的依賴關係

SaltStack 允許定義狀態之間的依賴關係,以確保操作的正確順序。例如:

Extract archive:
  archive.extracted:
    - name: /src/some-files
    - source: /src/some-files.tgz
    - archive_format: tar
    - require:
      - file: Copy archive

Copy archive:
  file.managed:
    - name: /src/some-files.tgz
    - source: salt://some-files.tgz

內容解密:

  • Extract archive 狀態依賴於 Copy archive 狀態,確保在解壓縮之前先複製檔案。
  • require 用於指定依賴關係。

其他重要概念

  • Grains:用於引數化系統組態,由 Minion 自行決定並儲存。與 Pillar 不同,Grains 由 Minion 控制。
  • 金鑰管理:SaltStack 使用金鑰來建立信任關係。Minion 在首次連線時會生成金鑰,並需要被 Salt Master 接受或拒絕。

SaltStack 環境與格式處理深度解析

SaltStack 作為一個強大的自動化維運工具,其環境組態與格式處理機制是實作高效管理的關鍵。本文將探討 SaltStack 的環境組態、範本處理以及擴充套件機制,為讀者提供全面且深入的技術解析。

10.3 SaltStack 格式處理機制詳解

SaltStack 的 SLS 檔案預設採用 YAML 格式,並透過 Jinja 範本引擎進行預處理。這種設計使得組態檔案能夠根據不同的環境變數(如 grains 或 pillars)進行動態調整。

Jinja 範本應用實務

在異構環境中,Jinja 範本的條件判斷功能顯得尤為重要。以下是一個典型的應用場景:

{% if grains['os'] == 'CentOS' %}
python-devel:
{% elif grains['os'] == 'Debian' %}
python-dev:
{% else %}
{{ raise('Unrecognized operating system: ' + grains['os']) }}
{% endif %}
pkg:
  - installed

內容解密:

  1. 使用 grains['os'] 判斷作業系統型別
  2. 根據不同的作業系統安裝對應的軟體包
  3. 使用 raise 函式丟擲明確的錯誤訊息,避免產生不合法的 YAML 格式
  4. pkg: - installed 確保指定的軟體包被正確安裝

這種實作方式充分體現了 SaltStack 在處理複雜環境組態時的靈活性。

程式碼最佳化建議

在實際應用中,我們可以對上述程式碼進行最佳化:

#!py
def run():
    os_map = {
        'CentOS': 'python-devel',
        'Debian': 'python-dev'
    }
    package_name = os_map.get(__grains__['os'])
    if not package_name:
        raise ValueError(f"Unrecognized operating system: {__grains__['os']}")
    return {package_name: {'pkg': 'installed'}}

內容解密:

  1. 使用 Python 字典實作作業系統與軟體包名稱的對映
  2. 透過 get() 方法取得對應的軟體包名稱
  3. 使用 raise 陳述式丟擲明確的錯誤訊息
  4. 回傳結構化的狀態資料

這種實作方式不僅提高了程式碼的可讀性,也增強了錯誤處理的能力。

SaltStack 擴充套件機制解析

SaltStack 的擴充套件性是其一大特色。開發者可以透過編寫自定義模組來擴充套件其功能。這些自定義模組可以放置在 file_roots 目錄下,並在執行 state.applysaltutil.sync_state 時同步到 minions。

自定義 State 模組實作

以下是一個自定義的 State 模組範例,用於確保指定目錄下不包含特定名稱的檔案:

def enforce_no_mean_files(name):
    mean_files = __salt__['file.find'](name, name="*mean*")
    if mean_files:
        # 處理找到的檔案
        pass
    return {'name': name, 'result': True, 'changes': {}, 'comment': ''}

內容解密:

  1. 使用 __salt__['file.find'] 方法查詢符合條件的檔案
  2. 根據查詢結果進行相應的處理
  3. 回傳標準的 State 執行結果字典

這種自定義模組的方式大大增強了 SaltStack 的功能性和靈活性。