Ansible 是一种IT自动化工具。它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署,滚动更新。Ansible 适用于管理企业IT基础设施,从具有少数主机的小规模到数千个实例的企业环境。Ansible 也是一种简单的自动化语言,可以完美地描述IT应用程序基础结构。
具备以下三个特点:
(资料图片仅供参考)
简单:减少学习成本 强大:协调应用程序生命周期 无代理:可预测,可靠和安全使用文档:https://releases.ansible.com/ansible/
安装 Ansible:
yum -y install ansibleInventory:Ansible管理的主机信息,包括IP地址、SSH端口、账号、密码等Modules:任务均有模块完成,也可以自定义模块,例如经常用的脚本。Plugins:使用插件增加Ansible核心功能,自身提供了很多插件,也可以自定义插件。例如connection插件,用于连接目标主机。Playbooks:“剧本”,模块化定义一系列任务,供外部统一调用。Ansible核心功能。
[webservers] 192.168.20.232 192.168.20.233 192.168.20.234 192.168.20.235 192.168.20.236 [dbservers] db01.intranet.mydomain.net db02.intranet.mydomain.net 10.25.1.232 10.25.1.233
ssh-keygen -t rsa ssh-copy-id -i /root/.ssh/id_rsa.pub -p "20100" "root@192.168.20.231" ssh-copy-id -i /root/.ssh/id_rsa.pub -p "20100" "root@192.168.20.232" ssh-copy-id -i /root/.ssh/id_rsa.pub -p "20100" "root@192.168.20.23 chown 0700 -R /root/.ssh/ cat /root/.ssh/id_rsa.pub > /root/.ssh/authorized_keys chown root.root -R /root/.ssh/ cd /root/.ssh/
sed -i "s/#host_key_checking = .*/host_key_checking = False/g" /etc/ansible/ansible.cfg
SSH密码认证:
[webservers] 192.168.20.232:20100 ansible_ssh_user=root ansible_ssh_pass=’200271200’ 192.168.20.233:20100 ansible_ssh_user=root ansible_ssh_pass=’200271200’ 192.168.20.234:20100 ansible_ssh_user=root ansible_ssh_port=’200271200’ [dbservers] db01.intranet.mydomain.net db02.intranet.mydomain.net 10.25.1.56 10.25.1.57
SSH密钥对认证:
[webservers] 10.206.240.111:22 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa 10.206.240.112:22 ansible_ssh_user=root 也可以在配置文件中指定: [defaults] private_key_file = /root/.ssh/id_rsa # 默认路径
选项 | 描述 |
-C, --check | 运行检查,不执行任何操作 |
-e EXTRA_VARS,--extra-vars=EXTRA_VARS | 设置附加变量 key=value |
-u REMOTE_USER, --user=REMOTE_USER | SSH连接用户,默认None |
-k, --ask-pass | SSH连接用户密码 |
-b, --become | 提权,默认root |
-K, --ask-become-pass | 提权密码 |
ansible all -m ping ansible all -m shell -a "ls /root" -u root -k
ansible-doc –l 查看所有模块
ansible-doc –s copy 查看模块文档
在目标主机执行shell命令。
- name: 将命令结果输出到指定文件 shell: somescript.sh >> somelog.txt - name: 切换目录执行命令 shell: cmd: ls -l | grep log chdir: somedir/ - name: 编写脚本 shell: | if [ 0 -eq 0 ]; then echo yes > /tmp/result else echo no > /tmp/result fi args: executable: /bin/bash
将文件复制到远程主机。
- name: 拷贝文件 copy: src: /srv/myfiles/foo.conf dest: /etc/foo.conf owner: foo group: foo mode: u=rw,g=r,o=r # mode: u+rw,g-wx,o-rwx # mode: "0644" backup: yes
管理文件和文件属性。
- name: 创建目录 file: path: /etc/some_directory state: directory mode: "0755" - name: 删除文件 file: path: /etc/foo.txt state: absent - name: 递归删除目录 file: path: /etc/foo state: absent
present,latest:表示安装
absent:表示卸载
软件包管理。
ansible webservers -m yum -a "name=http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.1-1.el7.ngx.x86_64.rpm state=present" ansible webservers -m systemd -a "name=http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.1-1.el7.ngx.x86_64.rpm state=restarted enabled=yes"
- name: 安装最新版apache yum: name: httpd state: latest - name: 安装列表中所有包 yum: name: - nginx - postgresql - postgresql-server state: present - name: 卸载apache包 yum: name: httpd state: absent - name: 更新所有包 yum: name: "*" state: latest - name: 安装nginx来自远程repo yum: name: http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm # name: /usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm state: present
管理服务。
- name: 服务管理 service: name: httpd state: started #state: stopped #state: restarted #state: reloaded - name: 设置开机启动 service: name: httpd enabled: yes
- name: 解压 unarchive: src=test.tar.gz dest=/tmp
执行过程中打印语句。
- debug: msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }} - name: 显示主机已知的所有变量 debug: var: hostvars[inventory_hostname] verbosity: 4
变量是应用于多个主机的便捷方式; 实际在主机执行之前,变量会对每个主机添加,然后在执行中引用。
[webservers] 192.168.1.100 ansible_ssh_user=root hostname=web1 192.168.1.100 ansible_ssh_user=root hostname=web2 [webservers:vars] ansible_ssh_user=root hostname=web1
- shell: /usr/bin/uptime register: result - debug: var: result verbosity: 2
Playbooks是Ansible的配置,部署和编排语言。他们可以描述您希望在远程机器做哪些事或者描述IT流程中一系列步骤。使用易读的YAML格式组织Playbook文件。
如果Ansible模块是您工作中的工具,那么Playbook就是您的使用说明书,而您的主机资产文件就是您的原材料。
与adhoc任务执行模式相比,Playbooks使用ansible是一种完全不同的方式,并且功能特别强大。
https://docs.ansible.com/ansible/latest/user_guide/playbooks.html
--- - hosts: webservers vars: http_port: 80 server_name: www.ctnrs.com remote_user: root gather_facts: false tasks: - name: 安装nginx最新版 yum: pkg=nginx state=latest - name: 写入nginx配置文件 template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf notify: - restart nginx - name: 确保nginx正在运行 service: name=httpd state=started handlers: - name: restart nginx service: name=nginx state=reloaded
- hosts: webservers remote_user: root become: yes become_user: lizhenliang
Ansible中的首选做法是不将变量存储在Inventory中。
除了将变量直接存储在Inventory文件之外,主机和组变量还可以存储在相对于Inventory文件的单个文件中。
- hosts: webservers vars: http_port: 80 server_name: www.ctnrs.com
每个play包含一系列任务。这些任务按照顺序执行,在play中,所有主机都会执行相同的任务指令。play目的是将选择的主机映射到任务。
tasks: - name: 安装nginx最新版 yum: pkg=nginx state=latest
语法检查:ansible-playbook --check /path/to/playbook.yaml
测试运行,不实际操作:ansible-playbook -C /path/to/playbook.yaml
debug模块在执行期间打印语句,对于调试变量或表达式,而不必停止play。与"when:"指令一起调试更佳。
- hosts: webservertasks:- debug:msg: {{group_names}}- debug:msg: {{inventory_hostname}}- debug:msg: {{ansible_hostname}}
如果你有一个大的剧本,那么能够在不运行整个剧本的情况下运行特定部分可能会很有用。
tasks: - name: 安装nginx最新版 yum: pkg=nginx state=latest tags: install - name: 写入nginx配置文件 template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf tags: config
使用:
ansible-playbook example.yml --tags "install"ansible-playbook example.yml --tags "install,config"ansible-playbook example.yml --skip-tags "install"
条件:
tasks: - name: 只在192.168.1.100运行任务 debug: msg="{{ansible_default_ipv4.address}}" when: ansible_default_ipv4.address == "192.168.1.100"
循环:
tasks: - name: 批量创建用户 user: name={{ item }} state=present groups=wheel with_items: - testuser1 - testuser2
- name: 解压 copy: src={{ item }} dest=/tmp with_fileglob: - "*.txt"
常用循环语句:
语句 | 描述 |
with_items | 标准循环 |
with_fileglob | 遍历目录文件 |
with_dict | 遍历字典 |
tasks: - name: 写入nginx配置文件 template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
定义变量:
{% set local_ip = inventory_hostname %}
条件和循环:
{% set list=["one", "two", "three"] %} {% for i in list %} {% if i == "two" %} -> two {% elif loop.index == 3 %} -> 3 {% else %} {{i}} {% endif %} {% endfor %}
例如:生成连接etcd字符串
{% for host in groups["etcd"] %} https://{{ hostvars[host].inventory_hostname }}:2379 {% if not loop.last %},{% endif %}{% endfor %}
里面也可以用ansible的变量。
Roles是基于已知文件结构自动加载某些变量文件,任务和处理程序的方法。按角色对内容进行分组,适合构建复杂的部署环境。
Roles目录结构:
site.yml webservers.yml fooservers.yml roles/ common/ tasks/ handlers/ files/ templates/ vars/ defaults/ meta/ webservers/ tasks/ defaults/ meta/
tasks
-包含角色要执行的任务的主要列表。handlers
-包含处理程序,此角色甚至在此角色之外的任何地方都可以使用这些处理程序。defaults
-角色的默认变量vars
-角色的其他变量files
-包含可以通过此角色部署的文件。templates
-包含可以通过此角色部署的模板。meta
-为此角色定义一些元数据。请参阅下面的更多细节。通常的做法是从tasks/main.yml
文件中包含特定于平台的任务:
# roles/webservers/tasks/main.yml - name: added in 2.4, previously you used "include" import_tasks: redhat.yml when: ansible_facts["os_family"]|lower == "redhat" - import_tasks: debian.yml when: ansible_facts["os_family"]|lower == "debian" # roles/webservers/tasks/redhat.yml - yum: name: "httpd" state: present # roles/webservers/tasks/debian.yml - apt: name: "apache2" state: present
# site.yml - hosts: webservers roles: - common - webservers 定义多个: - name: 0 gather_facts: false hosts: all roles: - common - name: 1 gather_facts: false hosts: all roles: - webservers
- name: 0.系统初始化 gather_facts: false hosts: all roles: - common tags: common
组变量:
group_vars 存放的是组变量
group_vars/all.yml 表示所有主机有效,等同于[all:vars]
grous_vars/etcd.yml 表示etcd组主机有效,等同于[etcd:vars]
角色 | IP | 组件 |
k8s-master1 | 192.168.31.61 | kube-apiserver kube-controller-manager kube-scheduler etcd |
k8s-master2 | 192.168.31.62 | kube-apiserver kube-controller-manager kube-scheduler |
k8s-node1 | 192.168.31.63 | kubelet kube-proxy docker etcd |
k8s-node2 | 192.168.31.66 | kubelet kube-proxy docker etcd |
Load Balancer(Master) | 192.168.31.61 192.168.31.60 (VIP) | nginx keepalived |
Load Balancer(Backup) | 192.168.31.62 | nginx keepalived |
编写建议:
梳理流程和Roles结构如果配置文件有不固定内容,使用jinja渲染人工干预改动的内容应统一写到一个文件中确保所有节点系统时间一致
下载Ansible部署文件:
git clone https://github.com/lizhenliang/ansible-install-k8s cd ansible-install-k8s
修改hosts文件,根据规划修改对应IP和名称。
vi hosts
修改group_vars/all.yml文件,修改软件包目录和证书可信任IP。
vim group_vars/all.yml software_dir: "/root/binary_pkg" ... cert_hosts: k8s: etcd:
架构图
单Master架构
多Master架构
部署命令单Master版:
ansible-playbook -i hosts single-master-deploy.yml -uroot -k
多Master版:
ansible-playbook -i hosts multi-master-deploy.yml -uroot -k
如果安装某个阶段失败,可针对性测试.
例如:只运行部署插件
ansible-playbook -i hosts single-master-deploy.yml -uroot -k --tags addons
示例参考:https://github.com/ansible/ansible-examples