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

需要登入才可留言!

类似文章


bash,cli

命令行主机信息查询cpu、ram及disk

介绍Linux主机上可以用那些命令查硬体信息&nbsp;

bash,ffmpeg

webm to mp4

怎样用ffmpeg把webm转mp4呢。

terminal,shortcuts,bash

终端机热键攻略

本文介绍及整理一些终端机的热键,来看看有那些你不知道的吧?快来试试。