使用 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 文件。