本文是我在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。(我可能韓劇看太多)
No Comment
Post your comment