LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

使用 Ansible 将公司运维自动化和项目化

安装

公司服务器统一为 CentOS 7,配的开发机为 Mac OSX。

远端命令执行的机器(服务端)需要安装 python 和开启 ssh 服务:

yum install -y python
yum install -y openssh-server
systemctl start sshd

而命令发布的机器(客户端)需要安装 Ansible:

brew install ansible # Mac

配置

服务器列表信息

Ansible 要知道远端机器的信息,可以直接指定,当然更好的是维护一个 inventory list,本身除了复用之外,还可以声明得更加适合理解和划分得更加容易管理。这里使用 yml 格式来描述:

all:
  hosts:
	local_dreamy:
      ansible_user: dreamy
      ansible_port: 22
      ansible_host: 169.254.142.35
    shenzhen_java_test:
      ansible_user: deploy
      ansible_port: 22
      ansible_host: 169.254.142.35
    shenzhen_java_prepare:
      ansible_user: deploy
      ansible_port: 22
      ansible_host: 169.254.142.35
    hongkong_java_product:
      ansible_user: deploy
      ansible_port: 22
      ansible_host: 169.254.142.35

机器描述时候可以有很多参数,常用的还有 ansible_ssh_private_key_file 来指定密钥,但是因为我们都是使用 Jenkins 来管理统一管理权限。

服务器的 ssh key

现在公司采取的方案是,全部服务器都统一使用 deploy 用户来发布,然后针对机器配置可以 sudo 的用户,例如是 java 的机器,就给 deploy 可以作为 java_world 用户 sudo 的权限。

公司现在统一由堡垒机生成和发布 ssh 的 key,下面是简单给出本地 Mac 和服务器的测试例子:

# Mac
ssh-keygen -m pem -t rsa -f deploy_id_rsa

将生成的 deploy_id_rsa.pub 内容追加到服务器 deploy 用户的 ~/.ssh/authorized_keys 文件里面,然后测试下查看深圳测试和预发布服务器里面 java_world 用户的目录信息:

ansible -i ansible_hosts.yml 'shenzhen_java_*' \
        -m shell -a 'ls -alh ~' \
        -b --become-user=java_world --become-method=sudo \
        --private-key=apline_id_rsa

安全验证

Ansible 提供 ansible-vault 工具来加密解密:

echo 'secret: "$password"' > vaultfile.yml
ansible-vault encrypt vaultfile.yml
cat vaultfile.yml
ansible-vault view vaultfile.yml

终端操作

Ansible 提供 ansible-console 作为终端交互工具,可以直接在上面调用模块,也可以使用 raw 来执行原生命令:

ansible-console -i ansible_hosts.yml 'shenzhen_java_*' \
        -b --become-user=java_world --become-method=sudo \
        --private-key=apline_id_rsa
# hostname (2)[f:5]$ ping
# hostname (2)[f:5]$ raw ls -al

Playbook

Ansible 提供了 ansible-playbook 来执行 ansible 的脚本,脚本本身是 yml 文件,描述要做的事情,例如:

- hosts: all
  become: true
  become_user: root
  become_method: sudo
  
  vars:
  handlers:
    - name: restart-nginx
      service:
        name: nginx
        state: restarted
  tasks:
    - yum:
        name: ["nginx"]
        state: installed
    - template:
        src: "./files/nginx.conf.j2"
        dest: "/etc/nginx/nginx.conf"
      notify: restart-nginx

因为 ansible-playbook 可以指定 host 的规则,所以我一般的配置可以写得比较粗粒度:

ansible-playbook -i ansible_hosts.yml -l 'shenzhen_java_*' nginx.yml

项目化

只是写脚本,是比较难维护和可持续的,Ansible 本身提供 ansible-galaxy 来项目化我们的脚本和下载别人的 roles,先简单创建一个:

cd playbooks
touch plan.yml
ansible-galaxy init roles/todo

生成的目录结构也是比较明显:

.
├── plan.yml
└── roles
    └── todo
        ├── README.md
        ├── defaults   # 默认变量,能被覆盖
        ├── files      # 静态文件
        ├── handlers   #
        ├── meta       # 包含发布到 Ansible Galaxy 的信息
        ├── tasks      #
        ├── templates  # 模板文件
        ├── tests      # 测试使用
        └── vars       # 变量,能被 group_vars 或顶层变量覆盖

除了可以自己编写 roles 之外,还能在 galaxy 上下载别人的:

ansible-galaxy search xxx.xxx
ansible-galaxy info xxx.xxx
ansible-galaxy install xxx.xxx
ansible-galaxy list

对应在刚才的 plan.yml 指明 roles,可以指定多个 roles:

- hosts: all
  become: true
  become_user: root
  become_method: sudo

  roles:
    - roles/todo
    - roles/xxx.xxx

最后用 ansible-playbook 来执行 plan.yml 文件。