by Devin Yang

建立於: 1年前 ( 更新: 1年前 )

本文是我在MacOS上採用Docker方式,執行Ansible使用經驗分享, 
您可以依這個目錄結構調整成您要的Ansible環境,或進行Ansible的學習。 

情境是這樣的,我希望在我的測試環境可以看到最接近正式機相同的文章, 
但我又不想用測試機程式直接連正式機的資料庫。 
我的手動做法就把正式機db匯出來,copy到測試機再匯入, 
雖然沒幾個步驟,但做起來好像還是有點煩,加上手動操作容易出錯, 
這讓我想起了Ansible這個東西, 
我有聽過但沒試過,不如就來試試看。🫢 

這裡用了我之前的phpenv的文章中有提到的備份跟還原指令, 
這是我用Laravel的console功能寫的簡易資料庫備份及還原範例。 
程式碼在Laravel的routes/console.php中,內容如下:

Artisan::command("db:backup", function(){
    $database = env("DB_DATABASE");
    $command = sprintf("mysqldump -uroot --default-character-set=utf8mb4 -h%s %s",env("DB_HOST"), env("DB_DATABASE"));
    $process = new Process(explode(" ", $command));
    $process->run();
    if (!$process->isSuccessful()) {
        throw new ProcessFailedException($process);
    }
    $data = $process->getOutput();
    Storage::disk('local')->put(sprintf("%s/%s.sql","backup",$database), $data);
    $this->comment(sprintf("已完成備份,已存入: storage/app/backup/%s.sql",$database));
})->purpose('備份MySQL資料庫');

Artisan::command("db:restore {auto=no}", function($auto){
    if(empty($auto)||$auto=="no"){
        $auto = $this->confirm('您要將備份資料匯入Mysql資料庫嗎?');
    }
    if ($auto=='yes') {
        $database = env("DB_DATABASE");
        $command = sprintf("mysql -uroot -h%s --default-character-set=utf8mb4 %s < %s/%s.sql",
                    env("DB_HOST"),
                    $database,
                    Storage::path("backup"),
                    $database);
        $this->comment($command);
        system($command);
    }
})->purpose('備份資料還原');

也就是說,在我的Laravel的正式及測試環境,都可以用這個指令依.env中定義的DB_DATABASE進行資料的備份及還原,artisan指令如下: 
備份:

php artisan db:backup

還原: 
(Ansible的except功能覺的不是很好用,所以直接補上yes參數,
不詢問直接還原的功能,幫助我進行Ansible自動化。)

php artisan db:restore yes


以下內容,我先操作手動流程,#號開頭為我加註的說明:

#連線到正式環境容器環境
ssh www
Last login: Wed Dec 14 16:22:26 2022 from 172.25.0.1
dlaravel@1030cc543f6f:~$ artisan db:backup
已完成備份,已存入: storage/app/backup/ccctc.sql
#我壓了ctrl+d切容器連線
dlaravel@1030cc543f6f:/var/www/html$ logout
Connection to 192.168.99.130 closed.
#執行scp命令,把www上備份的sql檔案拷回本機目錄中
scp www:/home/dlaravel/html/storage/app/backup/ccctc.sql .
ccctc.sql                                                                                          100% 1708KB 111.7MB/s   00:00
#把剛拷貝在本機的sql檔案copy到測試機,並且順便更名為ccc_test,因為測試機的.env中我用的DB名稱是個
scp ccctc.sql test:/home/dlaravel/html/storage/app/backup/ccc_test.sql
ccctc.sql                                                                                          100% 1708KB 114.6MB/s   00:00
#SSH連線進入測試環境,並且執行備份還原的動作
ssh test
Last login: Wed Dec 14 16:58:59 2022 from 172.20.0.1
dlaravel@7d3f3f78d2af:~$ artisan db:restore yes
mysql -uroot -h192.168.99.2 --default-character-set=utf8mb4 ccc_test < /var/www/html/storage/app/backup/ccc_test.sql
dlaravel@7d3f3f78d2af:~$

在上方的手動操作流程,光是那個長長的資料夾名稱拷貝貼上,看到就覺的麻煩

於是,我大概Google了下Ansible的玩法,然後開了個容器測試了一下,基本上大至會弄囉。 
在開始前,先來看看下方我的目錄結構,目錄下可以放ansible.cfg因為沒用到,所以不列出來。

root@a79153aa6cae:~/workspace# tree
.
├── Dockerfile
├── inventory
├── play
├── playbook.yml
├── run.sh
└── ssh
    ├── config
    ├── id_ed25519
    └── id_ed25519.pub

檔案: Dockerfile

From ubuntu:latest
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -qq \
locales ssh python3 pip tzdata vim
RUN pip install ansible
#中文環境
RUN echo "Asia/Taipei" > /etc/timezone && \
    dpkg-reconfigure -f noninteractive tzdata && \
    sed -i -e 's/# zh_TW.UTF-8 UTF-8/zh_TW.UTF-8 UTF-8/' /etc/locale.gen && \
    echo 'LANG="zh_TW.UTF-8"'>/etc/default/locale && \
    dpkg-reconfigure --frontend=noninteractive locales && \
    update-locale LANG=zh_TW.UTF-8
ENV LANG zh_TW.UTF-8
ENV LANGUAGE zh_TW.UTF-8
ENV LC_ALL zh_TW.UTF-8

檔案: ssh/config
在workspace中ssh目錄下的config內容,連主機用的ssh/config

Host www
Hostname 192.168.100.1
User dlaravel
StrictHostKeyChecking no
Port 2256
Host test
Hostname 192.168.100.1
User dlaravel
StrictHostKeyChecking no
Port 2051

檔案: run.sh
run.sh,這裡非常單純,有參數就跑參數,沒有就跑bash。

#!/bin/bash
if [ $1 ];then
    docker run --rm -v $(pwd)/ssh:/root/.ssh -v $(pwd):/root/workspace -w /root/workspace -ti ansible ./$1
else
    docker run --rm -v $(pwd)/ssh:/root/.ssh -v $(pwd):/root/workspace -w /root/workspace -ti ansible bash
fi

$(pwd)代表的掛載目前主機端的目錄到容器中,如果您不是很清楚pwd
可以在命令列打pwd看看。

/Users/devin/workspace

所以執行容器時,我會把/Users/devin/workspace/ssh目錄掛載到容器的/root/.ssh目錄。
如此一來,進了容器後,就能用ssh指令連到遠端主機囉,當然,前題是你要把ssh的公鑰加到遠端主機上。
本文我當你已懂建立openssh鑰匙對,及設定連線OpenSSH公鑰驗證,這裡不做討論,請自行Google學習該有的知識點。 

檔案: inventory
inventory 定義我ansible要使用的主機,這裡的test及www主機名稱,就是上面shh的config中主機名稱。

[my_servers]
test
www
localhost ansible_connection=local

檔案: playbook.yml
重頭戲到了playbook.yml (對照一下不難發現就是我上面的手動操作步驟)
看Yaml檔應該還滿直覺的,就不多做說明了,應該會心領神會,我也是看別人的範例調成自己的。
chdir就切目錄,shell就是執行shell的命令,hosts就是連線到該主機,tasksk就是設定要執行的動作。

- hosts: www
  tasks:
    - name: 進行網站資料庫備份
      shell:
        "php artisan db:backup"
      args:
        chdir: "html"
- hosts: localhost
  tasks:
    - name: 拷貝正式機資料到本機
      shell:
        "scp www:/home/dlaravel/html/storage/app/backup/ccctc.sql /root/workspace/ccc.sql"
    - name: 拷貝檔案到測試機
      shell:
        "scp /root/workspace/ccc.sql test:/home/dlaravel/html/storage/app/backup/ccc_test.sql"
- hosts: test
  tasks:
    - name: 匯入備份資料到測試機
      shell:
        "php artisan db:restore yes"
      args:
        chdir: "html"


建立與執行:
一、首先在workspace目錄中,用docker build建一個ansible的image。 
如果您是Docker初學者,提示您這會蓋掉你系統上原有的image,請確認你知道這是做什麼的再進行。

$docker build -t ansible .
[+] Building 0.1s (8/8) FINISHED
 => [internal] load build definition from Dockerfile                                                                         0.0s
 => => transferring dockerfile: 37B                                                                                          0.0s
 => [internal] load .dockerignore                                                                                            0.0s
 => => transferring context: 2B                                                                                              0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest                                                             0.0s
 => [1/4] FROM docker.io/library/ubuntu:latest                                                                               0.0s
 => CACHED [2/4] RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -qq locales ssh python3 pip tzdata vi  0.0s
 => CACHED [3/4] RUN pip install ansible                                                                                     0.0s
 => CACHED [4/4] RUN echo "Asia/Taipei" > /etc/timezone &&     dpkg-reconfigure -f noninteractive tzdata &&     sed -i -e '  0.0s
 => exporting to image                                                                                                       0.0s
 => => exporting layers                                                                                                      0.0s
 => => writing image sha256:65590a0a9c31de5f611b85b9d5fd14be5a1615aa13746ebfa440bcbe5d8a70c2                                 0.0s
 => => naming to docker.io/library/ansible

二、執行./run.sh play就跑囉,搞定,OK 1,2,3

./run.sh play
PLAY [www] ***********************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************
ok: [www]
TASK [進行網站資料庫備份] ********************************************************************************************************
changed: [www]
PLAY [localhost] *****************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************
ok: [localhost]
TASK [拷貝正式機資料到本機] ******************************************************************************************************
changed: [localhost]
TASK [拷貝檔案到測試機] **********************************************************************************************************
changed: [localhost]
PLAY [test] **********************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************
ok: [test]
TASK [匯入備份資料到測試機] ******************************************************************************************************
changed: [test]
PLAY RECAP ***********************************************************************************************************************
localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
test                       : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
www                        : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


如果,您想驗證環境是否正常,也可以用同一支bash進入容器中,看看是不是可以正常連線到主機
我在下方的操作中,我在MacOS系統上,透過./run.sh進入到容器內,並執行了ssh的指令測試遠端主機連線。

 devin@m1Max > ~/workspace > ./run.sh
root@1e2c1ff05843:~/workspace# ssh www
Last login: Wed Dec 14 17:45:04 2022 from 172.25.0.1
dlaravel@1030cc543f6f:~$ logout
Connection to 192.168.100.1 closed.
root@1e2c1ff05843:~/workspace# ssh test
Last login: Wed Dec 14 17:45:08 2022 from 172.20.0.1
dlaravel@7d3f3f78d2af:~$


Ansible還有很多的設定方式及功能,這就待您自已去發覺了,這不是結束只是開始,Fighting。(我可能韓劇看太多)

Tags: ansible bash

Devin Yang

文章內容無法一一說明,如果您有什麼不了解處,歡迎提問哦:)

No Comment

Post your comment

需要登入才可留言!

類似的文章


cwebp,bash

我如何用bash優化網站圖檔,透過cwebp轉圖

我的網站中有大量背景圖在同一個頁面中,下載下來太大囉,需要瘦身,這cwebp工具不錯。在ubunut的環境apt install webp就可以安裝囉。

terminal,shortcuts,bash

終端機熱鍵攻略

本文介紹及整理一些終端機的熱鍵,來看看有那些你不知道的吧?快來試試。

bash,cli

命令列主機資訊查詢cpu、ram及disk

介紹Linux主機上可以用那些指令查硬體資訊&nbsp;