如何在Linux作業系統上使用sshpass實現自動登入並執行腳本作業?

前言

最近,筆者自行建置了三台實體機器,每台皆需要安裝Docker,如果不透過腳本,以自動化的方式執行,則需要使用ssh指令逐一登入至機器並重複執行相同的指令進行安裝與設定Docker。在本篇文章中,筆者將會使用sshpass工具,開發自動化腳本,並透過預先設定遠端機器的密碼,使用SSH方式個別登入實體機器進行安裝與設定Docker。

前置條件

在開始執行自動腳本前,需要確定執行腳本的機器具備下列的條件:

  • 機器可以是實體或是虛擬,而且必須要Linux-like作業系統的發行版本,例如:Ubuntu、CentOS與RedHat等。
  • 具有執行腳本的環境,本篇文章是以Bash腳本為主。
  • 在機器中,安裝好sshpass套件,以下為Ubuntu底下安裝sshpass套件的指令範例。

sudo apt-get update

sudo apt-get install -y sshpass

開發腳本

分別在機器上,開發名為「remote_docker_installer.sh」與「docker_installer.sh」腳本,相關的內容如下所示:


#!/bin/bash

export SSHPASS="your_remote_ssh_password"

for host_name in "docker-leader" "docker-worker1" "docker-worker2"
do
    sshpass -e scp -o StrictHostKeyChecking=no docker_installer.sh "user_name@$host_name":~/
    sshpass -e ssh -o StrictHostKeyChecking=no "user_name@$host_name" './docker_installer.sh && sudo -S gpasswd -a user_name docker'
done;

以上的腳本內容為「remote_docker_installer.sh」,此腳本解釋內容如下:

  • 定義「SSHPASS」環境變數,假設三台實體機的密碼皆相同,因此僅設定一組透過SSH登入所需要的密碼。
  • 宣告一個陣列,以雙引號標示並使用空白隔開,分別有三台主機,主機名稱分別為「docker-leader」、「docker-worker1」與「docker-worker2」。
    • 主機名稱也可以使用IP位址,這裡主機名稱為範例。
  • 使用for迴圈走訪各個主機名稱,並分別執行兩項動作:
    • 使用sshpass執行scp指令,由於先前已經設定了SSHPASS環境變數,則sshpass會存取此環境變數作為登入遠端主機的密碼。
    • scp指令搭配「StrictHostKeyChecking=no 」選項,則表示遠端登入時不強制檢查HostKey,登入成功後,將「docker_installer.sh」腳本複製至遠端的主機。
      • 「sudo – S」指的是使用標準輸入(STDIN)方法,在執行腳本中能夠以互動式方式輸入使用者密碼,來暫時取得root使用者的權限;缺點是輸入的密碼會在終端機上顯示。
    • 使用sshpass執行ssh指令,並搭配「StrictHostKeyChecking=no 」選項。連線上實體主機後,先執行「docker_installer.sh」再將指定的使用者加入到docker群組中。

#!/bin/bash

sudo -S apt-get update

sudo -S apt-get install -y ca-certificates curl gnupg lsb-release

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg \
--dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo -S tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo -S apt-get update
sudo -S apt-get install -y docker-ce docker-ce-cli containerd.io

以上的腳本內容為「docker_installer.sh」,此腳本解釋內容如下:

  • 「sudo – S」指的是使用標準輸入(STDIN)方法,在執行腳本中能夠以互動式方式輸入使用者密碼,來暫時取得root使用者的權限;缺點是輸入的密碼會在終端機上顯示。
  • 其他操作皆為安裝最新的Docker引擎的相關動作。

執行腳本

完成腳本的開發後,執行下列的指令,以執行自動化的腳本,以下是執行的片段內容:


$ ./remote_docker_installer.sh
[sudo] password for user_name: password
Hit:1 http://us.archive.ubuntu.com/ubuntu noble InRelease
Get:2 http://us.archive.ubuntu.com/ubuntu noble-updates InRelease [126 kB]
Hit:3 https://download.docker.com/linux/ubuntu noble InRelease
Get:4 http://us.archive.ubuntu.com/ubuntu noble-backports InRelease [126 kB]
Get:5 http://us.archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages [1,739 kB]
Get:6 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB]
Get:7 http://us.archive.ubuntu.com/ubuntu noble-updates/main amd64 Components [175 kB]
Get:8 http://us.archive.ubuntu.com/ubuntu noble-updates/restricted amd64 Components [212 B]
Get:9 http://us.archive.ubuntu.com/ubuntu noble-updates/universe amd64 Components [386 kB]
Get:10 http://us.archive.ubuntu.com/ubuntu noble-updates/multiverse amd64 Components [940 B]
Get:11 http://us.archive.ubuntu.com/ubuntu noble-backports/main amd64 Components [7,292 B]
Get:12 http://us.archive.ubuntu.com/ubuntu noble-backports/restricted amd64 Components [216 B]
Get:13 http://us.archive.ubuntu.com/ubuntu noble-backports/universe amd64 Components [10.5 kB]
Get:14 http://us.archive.ubuntu.com/ubuntu noble-backports/multiverse amd64 Components [212 B]
Get:15 http://security.ubuntu.com/ubuntu noble-security/main amd64 Components [21.6 kB]
Get:16 http://security.ubuntu.com/ubuntu noble-security/restricted amd64 Components [212 B]
Get:17 http://security.ubuntu.com/ubuntu noble-security/universe amd64 Components [74.2 kB]
Get:18 http://security.ubuntu.com/ubuntu noble-security/multiverse amd64 Components [208 B]
Fetched 2,793 kB in 1s (3,100 kB/s)
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
ca-certificates is already the newest version (20240203).
curl is already the newest version (8.5.0-2ubuntu10.6).
gnupg is already the newest version (2.4.4-2ubuntu17.4).
lsb-release is already the newest version (12.0-2).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
gpg: cannot open '/dev/tty': No such device or address
Hit:1 http://security.ubuntu.com/ubuntu noble-security InRelease
Hit:2 http://us.archive.ubuntu.com/ubuntu noble InRelease
Hit:3 https://download.docker.com/linux/ubuntu noble InRelease
Hit:4 http://us.archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:5 http://us.archive.ubuntu.com/ubuntu noble-backports InRelease
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
docker-ce is already the newest version (5:29.2.1-1~ubuntu.24.04~noble).
docker-ce-cli is already the newest version (5:29.2.1-1~ubuntu.24.04~noble).
containerd.io is already the newest version (2.2.1-1~ubuntu.24.04~noble).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

從上述所輸出的腳本內容,因為先前已經執行過了,因此Docker相關的套件皆顯示已經安裝的訊息,「[sudo] password for user_name: password」則是先前提到因為使用的是「sudo -S」,因此輸入的密碼會在終端機上顯示。

參考文章