我尽力详细解释一下关于配置管理工具Ansible

什么是Ansible?

这是一种配置管理工具,它可以自动安装应用程序所需的模块、中间件以及网络构建等,以便在目标服务器上运行应用程序。

作为类似的配置管理工具,它们包括:

    • Chef(シェフ)

 

    • Puppet(パペット)

 

    Itamae(イタマエ)

可以举出诸如此类的例子。

通过使用构成管理工具,

    • 今まで手作業やっていた部分が自動化される

 

    • ヒューマンエラーが減る

 

    似たような環境を構築する際にもスピーディーに対応可能

因此,对于对现代技术敏感的公司来说,它们经常被采用,以便享受这些好处。

使用Ansible的好处

与上述的配置管理工具相比,

    • YAML形式で処理を書いていくため、ノンプログラマーでも入門しやすい

 

    ディレクトリ構成にベストプラクティスがあるため、そのレールに乗ることでプロジェクトが変わっても内容を把握しやすい

Ansible的缺点是什么?

    YAML形式であるため、条件分岐や繰り返し処理ができず、似たような構成を作る際にはコピペになりがち

如果想更了解Ansible的概念的话,请

由于下面的幻灯片整理得很好,建议阅读一下。

请参考以下链接获取有关Ansible的幻灯片:https://www.slideshare.net/dcubeio/ansible-72056386

安装ansible

您可以使用Homebrew来安装Ansible。

$ brew install ansible

当我们完成安装后,让我们来确认一下是否可以使用 ansible 命令。

当在终端上执行ansible –version命令时,如果显示出下列结果,则表示ansible已成功安装。

$ ansible --version
ansible 2.8.2
  config file = /Users/yuta_ushizima/yuta-ushijima-git/workspace/Ansible/qiita_clone_2019_ansible/ansible/ansible.cfg
  configured module search path = [u'/Users/yuta_ushizima/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.15 (default, Jan 12 2019, 21:07:57) [GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)]

运行Ansible所需的基本命令

在这里,我们介绍常用于执行ansible的典型命令。

ansible命令

在执行指定操作时,用于指定的主机上使用选项。

【ansible-与命令行工具一起使用-】
https://docs.ansible.com/ansible/latest/cli/ansible.html

【ansible-使用命令行工具的方法-】
https://docs.ansible.com/ansible/latest/cli/ansible.html

【ansible-与命令行工具的运作方式-】
https://docs.ansible.com/ansible/latest/cli/ansible.html

在公式中提供了几个选项,但通常我们会选择指定模块来使用。

$ ansible -i hosts <IPアドレス> -m <モジュール名>

ansible-playbook命令

这是执行所创建的playbook时使用的命令。

【ansible-playbook-与命令行工具合作】
https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html

在官方网站上,playbook名称通常为playbook.yml,但如果文件扩展名是YAML,可以自由选择任意名称。

通常都是根据不同环境的名称(如staging.yml和production.yml)创建对应的文件,这是我们的工作任务之一。

$ ansible-playbook -i <インベントリファイル> <playbook名>.yml

关于其他命令

关于其他命令的详细信息,请参考下面的官方文档,如果您感兴趣的话,可以查阅一下。

【使用命令行工具】
请参考以下链接了解有关使用命令行工具的详细信息:
https://docs.ansible.com/ansible/latest/user_guide/command_line_tools.html

样本库

在创建了一个类似于Qiita的克隆应用程序时,使用Ansible自动化EC2上的模块安装等任务,以解决Take off Rails的挑战。

样本存储库的目录结构

ansinle/
  - roles/
    - common/
      - tasks/
        - main.yml
    - git/
        - tasks/
          - main.yml
    - mysql/
      - tasks/
        - main.yml
      - templates/
        - my.conf.j2
    - nginx/
      - tasks/
        - main.yml
      - templates/
        - nginx.conf.j2
    - nodejs/
      - tasks/
        - main.yml
    - ruby/
      - files/
        - .gemrc
      - tasks/
        - main.yml
      - templates/
        - rbenv_system.sh.j2
    - vim/
      - tasks/
        - main.yml
  - vars/
    - common.yml
  - ansible.cfg
  - hosts
  - production.yml
.gitignore
requirements.txt

参考公式网站的最佳实践,将其限定在必要的部分进行构成。

要求.txt的内容

ansible使用python内部实现,为了进行自动化执行,需要安装一些库。

可以单独安装,但通常会准备一个名为 requirements.txt 的文本文件,使用它会更方便。

在使用时,请使用pip命令进行如下操作。

$ pip install -r ../requirements.txt

通过这样做,它会按顺序帮您安装在 requirements.txt 文件中列出的库。

如果您自己制作playbook的话,将其放在远程存储库中可能会在协同开发时变得更加方便。

关于roles目录。

在roles目录下的每个目录都根据其安装或构建的模块名和中间件名来划分。

因此,当参与已经在Ansible上运作的项目时,

只需一个选项,用中文进行原生释义的改写如下:
如果查看roles目录,就可以知道使用了哪些模块和中间件。

那就是这个意思咯。

关于common目录

常见目录用于处理在目标服务器上共享的设置等。

---
- name: Create app dir
  become: yes
  file:
    path: /var/www
    state: directory
    owner: ec2-user
    group: ec2-user
    mode: 0777

在此示例中,我们创建了一个名为/vars/www的目录。

通过添加”yes”,可以在服务器上使用sudo并执行,具有相同的意思。

关于任务目录的内容。

在tasks目录中,每个角色都有一个名为main.yml的文件。

这个main.yml文件中,我们将记录用于自动化任务,如安装和路径设置等操作。

---
- name: Install packages
  become: yes
  yum:
    name: "{{ packages }}"
  vars:
    packages:
      - git-core
      - gcc
      - gcc-c++
      - gdbm-devel
      - libffi-devel
      - libselinux-python
      - libyaml-devel
      - mysql
      - mysql-devel
      - ncurses-devel
      - openssl-devel
      - sqlite-devel
      - readline-devel
      - zlib-devel

这是在示例存储库的Ruby中的main.yml。

在这里,我们使用yum来安装运行ruby所需的库。

有关templates目录。

在templates目录中,使用一个名为Jinja2的Python模板引擎进行编写。

【Jinja2】
Jinja2是一个Python模板引擎,可以帮助开发者设计可重用的、动态生成的网页和文件。具体使用方法和文档可以参考Jinja2官方网站:https://jinja.palletsprojects.com/en/2.10.x/。

所以,文件的扩展名是.j2对吧。

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
  worker_connections 1024;
}

http {

  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio"';

  access_log  /var/log/nginx/access.log  main;
(中略)

例如,上述内容是关于Nginx的nginx.conf.j2文件,但实际上该文件的描述就是nginx.conf本身。

这个nginx.conf.j2文件会在nginx的main.yml中被调用并部署到目标服务器上。

(中略)
- name: Put local.conf
  become: yes
  template:
    src: roles/nginx/templates/nginx.conf.j2
    dest: /etc/nginx/nginx.conf
(中略)

在template这个父键中,有两个子键分别为src和dest。

src...テンプレートが置かれているpathを記述(ansibleディレクトリからみて絶対パスで)
dest...対象のサーバー内でテンプレートを配置するpathを記述

如果在模板的src和dest参数上传递路径作为值,那么当运行ansible时,目标服务器将以模板中写入的内容进行配置。

关于files文件夹

Files目录类似于模板目录,但重点在于不使用Jinja2模板,而是将文件直接部署到目标服务器上。

由于很少被使用,基本上只需要使用模板就可以了,但在示例存储库中,我们会使用Ruby角色来放置隐藏文件.gemrc。

在调用时,请在main.yml中按照以下方式进行描述。

(中略)
- name: Copy .gemrc to ~/.gemrc to Avoid to Install rb-docs
  become: yes
  copy: 
    src: .gemrc
    dest: ~/.gemrc
(中略)

copy具有两个子键src和dest(与template相同)。

src...対象のファイルをそのまま記述(パス指定でもOK)
dest...対象のサーバー内でファイルを配置するpathを記述

通过将位于files目录中的文件复制到目标服务器的路径,实现在运行ansible时自动部署的机制。

关于vars目录

在Vars目录中,将ansible内的每个角色共享使用的变量汇总到名为common.yml的文件中。

ruby_version: 2.6.2
bundler_version: 2.0.1
db_pass: password
db_user: root
db_name: local
local_db_user: local
public_ip: 127.0.0.1
application_name: qiita_clone_2019

在样本库中,我们以上述形式,综合了Ruby版本和MySQL密码等信息。

让我们在每个角色的 main.yml 文件中引用时,指定如下方式。

(中略)
- name: Install Ruby
  shell: bash -lc "RUBY_CONFIGURE_OPTS="--disable-install-rdoc" rbenv install -s {{ ruby_version }}"
(中略)

通过使用双引号和{{}},可以像字符串展开一样调用在vars/common.yml中定义的变量。

有关hosts文件。

在这个hosts文件中,我们会记录连接到目标服务器的信息。

在中文中有两种方式可以做到。

- 自分のマシンの`~/.ssh/cofig`でSSH接続に関する名前解決を行い、その情報を記述する
- 直接IPアドレスを記述し、Ansible側で接続情報を記述する

这主要是两个选项。

如果是个人开发或学习用途的话,选择前者没问题。

然而,在业务流程中,为了实现对开发者根据各个阶段的权限授予的自动化需求,通常会选择使用Ansible进行自动化。

这次我们选择后者进行。

在ansible的目录下,创建一个名为hosts的文件,并在其中以没有扩展名的方式记录IP地址。

[production-app]
18.182.21.236

[product-app]指的是表示适用于哪个环境的IP地址或主机名(如果在~/.ssh/config中进行名称解析,则为HostName)。

将在下面提到的production.yml中使用。

关于production.yml文件

在将应用程序部署到生产环境时,基本原则是根据不同的环境创建相应的EC2实例。

用类似于production.yml的配置文件,

<環境名>.yml

我們會創建這樣一個文件,並描述自動化的內容。


---
- name: Playbook for production
  hosts: production-app
  become: yes
  vars_files:
    - vars/common.yml
  roles:
    - git
    - nginx
    - nodejs
    - mysql
    - ruby
    - vim

在示例存储库中,通过将[production-app]作为hosts指定在hosts文件中来指示连接到哪台服务器。

在vars_files中指定的键是包含所使用环境变量的文件。

关于角色,我们将使用的角色都以列表形式进行了描述。

如何使用Ansible

使用ping模块进行连接确认。

如果准备好playbook,就可以在本地使用ansible命令来执行。

但是,首先我们需要确认ansible能否正确连接到目标服务器。

请使用任何文本编辑器,按照以下方式编辑hosts文件。

[<任意の名前>]
<IPアドレス> ansible_user=ec2-user ansible_ssh_private_key_file=<ec2にsshログインするためのpemファイル>

作为设定的例子,可以是以下这样的感觉。

[production-app]
3.113.242.122 ansible_user=ec2-user ansible_ssh_private_key_file=~/.ssh/yuta-ushijima.pem

完成编辑后,请保存并使用Ansible的ping模块进行连接确认。

$ ansible-playbook -i hosts production.yml

如果连接成功,终端应该显示如下结果。

3.113.242.122 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

如果设置项目存在缺陷,或者SSH连接的IP地址有误,将显示以下类型的错误。

3.113.242.122 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: ec2-user@3.113.242.122: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).",
    "unreachable": true
}

如果出现了”unreachable: true”这个错误提示,意味着无法访问目标服务器。在出现这种情况时,建议您检查配置项等相关设置。

使用ansible-playbook命令自动化模块安装。

如果使用ping模块进行连接确认成功,接下来可以使用playbook命令来运行。

当您使用ping命令时,请再次按如下方式编辑hosts文件。

[production-app]
3.113.242.122

请根据各自的环境对于[production-app]和3.113.242.122进行相应的更改。

确认您已经在存有playbook的目录下,如果可以保存,执行以下命令。

$ ansible-playbook -i hosts staging.yml

如果发生错误,请仔细阅读错误信息,并根据需要逐步进行处理!

bannerAds