如果出现无法载图的情况,请检查与github的连通性
centos安装ansible 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 control-host节点(可联网) 外网网络-从dhcp获取 内部网络 从epel安装 yum -y install ansible yum list | grep ansible ansible.noarch 2.9.27-1.el7 epel ansible-collection-microsoft-sql.noarch 1.1.0-1.el7_9 extras ansible-doc.noarch 2.9.27-1.el7 epel ansible-inventory-grapher.noarch 2.4.4-1.el7 epel ansible-lint.noarch 3.5.1-1.el7 epel ansible-openstack-modules.noarch 0-20140902git79d751a.el7 epel ansible-python3.noarch 2.9.27-1.el7 epel ansible-review.noarch 0.13.4-1.el7 epel ansible-test.noarch 2.9.27-1.el7 epel centos-release-ansible-27.noarch 1-1.el7 extras centos-release-ansible-28.noarch 1-1.el7 extras centos-release-ansible-29.noarch 1-1.el7 extras centos-release-ansible26.noarch 1-3.el7.centos extras kubernetes-ansible.noarch 0.6.0-0.1.gitd65ebd5.el7 epel python2-ansible-runner.noarch 1.0.1-1.el7 epel python2-ansible-tower-cli.noarch 3.3.9-1.el7 epel vim-ansible.noarch 3.2-1.el7 epel yum -y install ansible ansible --version ansible 2.9.27 config file = /root/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules' , u'/usr/share/ansible/plugins/modules' ] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Nov 14 2023, 16:14:06) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
sshpass快速分发 分发hosts文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #!/bin/bash ips=$(awk 'NR > 2 { print $1 }' /etc/hosts) ip_count=$(echo "$ips " | wc -l) PASSWORD="1" if [ $ip_count -eq 0 ]; then echo "No IP addresses found to ping." exit 1 fi for ip in $ips ; do if ping -c 1 -W 1 "$ip " &> /dev/null; then echo "Ping successful for $ip , attempting to SCP /etc/hosts." sshpass -p "$PASSWORD " scp /etc/hosts "$ip " :/etc/hosts if [ $? -eq 0 ]; then echo "/etc/hosts successfully copied to $ip ." else echo "Failed to copy /etc/hosts to $ip ." fi else echo "Ping failed for $ip , skipping SCP." fi done echo "Ping and SCP process completed for $ip_count IP addresses."
ansible配置文件 静态inventory文件 定义了ansible管理的主机
静态inventory文件
动态inventory文件是一个脚本,会连接到管理系统的节点信息数据库,并将节点信息以特定的格式输出(json)
支持子组children
支持通过ipv4划分管理主机的范围,如192.168.[10:11].[1:254],2001:db8::[a:f]
inventroy文件中有两个特殊主机组,all表示所有主机,ungrouped表示不属于任何主机组的被管理主机
查看主机信息(测试)ansible -i inventory all --list-hosts
新节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 yum -y install epel-release yum update yum -y install ansible cat > inventory << EOF 1panel pve ws-k8s-master1 ws-k8s-master2 ws-k8s-master3 harbor ws-k8s-node1 ws-k8s-node2 ws-k8s-node3 ceph-node1 ceph-node2 ceph-node3 docker-host [k8s:children] master worknode [manager] 1panel pve [master] ws-k8s-master1 ws-k8s-master2 ws-k8s-master3 [worknode] ws-k8s-node1 ws-k8s-node2 ws-k8s-node3 [storage] ceph-node1 ceph-node2 ceph-node3 [activity] harbor docker-host EOF ansible -i inventory all --list-hosts hosts (13): ws-k8s-node1 ws-k8s-node2 ws-k8s-node3 ceph-node1 ceph-node2 ceph-node3 1panel pve harbor docker-host ws-k8s-master1 ws-k8s-master2 ws-k8s-master3 ansible -i inventory k8s --list-hosts hosts (6): ws-k8s-master1 ws-k8s-master2 ws-k8s-master3 ws-k8s-node1 ws-k8s-node2 ws-k8s-node3
ansible.cfg配置文件 配置文件不是全局的,不同的用户管理的配置文件不同,一般每个用户都会有自己的配置文件和inventory文件。
默认配置文件为/etc/ansible/ansible.cfg
基本参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 以sector进行划分 sudo参数也可以 [defaults] inventory = /root/inventory remote_user = root ask_pass = true [privilege_escalation] become = true become_method = sudo become_user = root become_ask_pass = false
连接方式可以不使用ssh。如连接windows时,需要添加变量group_vars,添加名为windows文件,指定ansible_connection和ansible_port
优先级 通过ansible --version
可以查看当前使用的配置文件
优先级从低到高
1.如果没有指定,则会默认使用/etc/ansible/ansible.cfg
2.家目录下的~/ansible.cfg
3.当前目录下的ansible.cfg(使用最多)
4.ANSIBLE_CONFIG变量指定的配置文件
使用方式——adhoc 1 2 3 4 5 6 7 8 9 10 11 12 ansible 主机组 -m 模块 -a 模块参数 -u remote_user --become表示提权 -i inventory路径 ansible-doc 模块 ansible k8s -m ping ansible k8s -m user -a "name=xhy uid=2345 state=present" ansible k8s -m user -a "name=xhy uid=2345 state=absent" ansible master -m command -a "kubectl get pods" ansible localhost -a "id root" ansible master -m yum -a "name=httpd state=latest"
使用方式——playbook 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 cat first.yaml --- - name: first playbook hosts: k8s tasks: - name: create user user: name: xhy uid: 1234 state: present ansible-playbook first.yaml -v 增加输出详细信息 --syntax-check 检查错误 -C 模拟运行 在play中除了name hosts tasks 还可以指定remote_user,become这种参数优先级高于ansible.cfg stableinterface ——稳定版 preview ——不稳定版 deprecated ——马上要被移除 removed ——已经移除 core 核心团队 curated 友商支持的付费模块 community 社会开发者
yaml的写法特点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 asdsada qwe q 'asdasd sda sa' "qweqws sadqfq qwes" --- - name: play1 hosts: all tasks: - debug: msg: | 123123 123123 123123 msg: > 123123 123123 123123 hosts: servera,serverc hosts: - servera - serverc hosts: [servera,serverc]
变量 var变量 命名规则:与linux类似,只能包含字母,数字和下划线
变量范围(由高到低): 全局级——对整个主机生效 ——写在命令行里 play级——只在单个play中生效 ——在playbook中定义 Host级——对单个host或主机组生效,一般生产环境使用的 ——在inventory文件中定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 全局级(命令行): ansible-playbook xxx.yaml -e "user=xxx" play级(列表定义): --- - name: hosts: vars: - name: wangshneg - name2: xhy play级(文件定义): --- - name: hosts: vars_files: - /home/xxx.yml hosts级(inventory文件):——主机变量与主机组变量 servera user=ws [test ] serverb serverc [test :vars] user=xhy {{ }} vars_files: ws/ws.yml debug: var: user
group_vars与host_vars 为了让ansible条理清晰,需要将变量从inventory文件中解耦出来,最后的产物就是group_vars与host_vars
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 mkdir group_varsmkdir host_varscd group_varsvim k8s user: ws --- - name: debug-test hosts: k8s tasks: - name: test debug: var: user 创建ws-k8s-node1,node2,node3的文件,在其中添加变量
变量矩阵 也就是变量的层级,一些变量是某个变量下的子变量
1 2 3 4 5 6 7 8 9 10 cat ws-k8s-master1.yamluser: ws: name: ws age: 25 password: 123 xhy: name: xhy age: 24 password: 456
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 --- - name: debug-test hosts: ws-k8s-master1 tasks: - name: test debug: var: user.ws.password TASK [test ] ******************************************************************** ok: [ws-k8s-master1] => { "user.ws.password" : "123" } debug: var: user['ws' ]['password' ]
register变量 能将task的运行状态记录下来,并以json文件格式输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 --- - name: debug-test hosts: ws-k8s-master1 tasks: - yum: name: httpd state: latest register: details ignore_errors: yes - debug: var: details - debug: var: details.rc TASK [debug] ******************************************************************* ok: [ws-k8s-master1] => { "details" : { "changed" : false , "changes" : { "installed" : [], "updated" : [] }, "failed" : false , "msg" : "" , "rc" : 0, "results" : [ "All packages providing httpd are up to date" , "" ] } } TASK [debug] ******************************************************************************************************** ok: [ws-k8s-master1] => { "details.rc" : "0" } 比如这个rc值就可以用来做流程控制
vault加密(不常用) ansible vault是ansible组件,可以解密加密ansible使用的数据。可以使用ansible-vault来创建,编辑,加密,解密或查看文件。比如一些敏感数据:密钥,token等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 常用用法: ansible-vault create vault-test.yaml name: ws cat vault-test.yamlansible-vault view vault-test.yaml ansible-vault rekey vault-test.yaml ansible-vault edit vault-test.yaml ansible-vault decrypt vault-test.yaml ansible-vault --vault-id=./mima.yaml edit vault-test.yaml
vault和playbook
调用加密文件的情况下,通过ansible-playbook --vault-id @prompt debug.yaml
facts变量 在ansible运行时自动采集的系统参数,如内存大小、系统版本、硬盘大小、FQDN等信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ansible ws-k8s-node1 -m setup >> facts.json 常见facts: ansible_hostname ansible_fqdn ansible_default_ipv4.addresses ansible_interfaces ansible_devices.vda.partitions.vda1.size ansible_dns.nameservers ansible_kernel 以上变量都可以通过debug{{ ansible_hostname }}来输出进行测试 实际场景中使用ansible_devices.vda.partitions或者cpu来判断硬件条件 在流程控制中做判断,来控制是否执行task 在playbook文件中 --- - name: facts hosts: all gather_facts: no ... mkdir /etc/ansible/facts.d/ -p创建一个.fact结尾的文件 [web] name: https 此时收集facts变量,就会发现ansible_local内有了这个变量
magic变量 magic变量就是主机变量与主机组变量,与facts变量一样,是通过ansible自动采集的。| 与facts变量一样,主要用于ansible的条件判断。
四个主要的magic变量:
hostvars: 包含被管理主机的变量,并且可以用于获取其它主机变量的值。如果还没有为该主机搜集被管理主机的facts,就不会包含被管理主机的facts。 group_names: 列出所有当前被管理主机所在的组 groups: 列出所有在inventory中的groups和hosts inventory_hostname 包含inventory中配置的当前被管理主机的hostname。由于各种原因,这可能和fact报告的主机名不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 ansible ws-k8s-node1 -m debug -a "var=hostvars['ws-k8s-node1']" 输出了ws-k8s-node1的hostvars ws-k8s-node1 | SUCCESS => { "hostvars['ws-k8s-node1']" : { "ansible_check_mode" : false , "ansible_diff_mode" : false , "ansible_facts" : {}, "ansible_forks" : 5, "ansible_inventory_sources" : [ "/root/inventory" ], "ansible_playbook_python" : "/usr/bin/python2" , "ansible_verbosity" : 0, "ansible_version" : { "full" : "2.9.27" , "major" : 2, "minor" : 9, "revision" : 27, "string" : "2.9.27" }, "group_names" : [ "k8s" , "worknode" ], "groups" : { "activity" : [ "harbor" , "docker-host" ], "all" : [ "ceph-node1" , "ceph-node2" , "ceph-node3" , "1panel" , "pve" , "harbor" , "docker-host" , "ws-k8s-master1" , "ws-k8s-master2" , "ws-k8s-master3" , "ws-k8s-node1" , "ws-k8s-node2" , "ws-k8s-node3" ], "k8s" : [ "ws-k8s-master1" , "ws-k8s-master2" , "ws-k8s-master3" , "ws-k8s-node1" , "ws-k8s-node2" , "ws-k8s-node3" ], "manager" : [ "1panel" , "pve" ], "master" : [ "ws-k8s-master1" , "ws-k8s-master2" , "ws-k8s-master3" ], "storage" : [ "ceph-node1" , "ceph-node2" , "ceph-node3" ], "ungrouped" : [], "worknode" : [ "ws-k8s-node1" , "ws-k8s-node2" , "ws-k8s-node3" ] }, "inventory_dir" : "/root" , "inventory_file" : "/root/inventory" , "inventory_hostname" : "ws-k8s-node1" , "inventory_hostname_short" : "ws-k8s-node1" , "omit" : "__omit_place_holder__b39936729c630932058e036789f5741d8fdea663" , "playbook_dir" : "/root" , "user" : "ws" } }
task控制 简单loop的使用 循环控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 --- - name: loop hosts: worknode vars: - firewallservice: firewalld - web_server: httpd tasks: - name: install yum: name: - "{{ firewallservice }}" - "{{ web_server }}" state: latest - name: service service: name: "{{ item }}" enabled: false state: stopped loop: - "{{ firewallservice }}" - "{{ web_server }}" ========================================================= --- - name: loop hosts: worknode vars: web_service: - firewalld - httpd tasks: - name: install yum: name: - "{{ item }}" state: latest loop: "{{ web_service }}" - name: service service: name: "{{ item }}" enabled: false state: stopped loop: "{{ web_service }}" ========================================================= --- - name: loop hosts: worknode vars_files: var/yum.yaml tasks: - name: install yum: name: - "{{ item }}" state: latest loop: "{{ web_service }}" - name: service service: name: "{{ item }}" enabled: false state: stopped loop: "{{ web_service }}"
带变量矩阵的loop 1 2 3 4 5 6 7 8 9 10 11 ... - user: name: "{{ item.name }}" state: present groups : "{{ item.groups }}" loop: - name: ws group: jingyue - name: xhy group: youshi ...
条件判断 常用判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 vars: ws: true tasks: - debug: msg: "true" when: ws ========================================== tasks: - debug: msg: "defined" when: ws is define ========================================== supported_distres: - redhat - centos ... tasks: - yum: name: http state: present when: ansible_distribution in supported_distres ...
多条件判断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 when: ansible_distribution == "Redhat" and ansible_kernel == "xxx" when: - ansible_distribution == "Redhat" - ansible_kernel == "xxx" when: ansible_distribution == "Redhat" or ansible_distribution == "Centos" ====================== when: > ( ansible_distribution == "redhat" and ansible_distribution_major_version == "7" ) or ( ansible_distribution == "fedora" and ansible_distribution_major_version == "28" )
loop+条件判断 1 2 3 4 5 6 7 8 9 10 11 12 13 user: - name: ws age: 25 - name: xhy age: 24 ... tasks: - debug: msg: "{{ item }}" loop: "{{ user.name }}" when: user.age >= 25 ...
handlers 检测task状态,如果task的条件达到handlers的要求,那么就会触发事件; 如果检测到比如服务已启动,那么就不会进行重启
1 2 3 4 5 6 7 8 9 10 11 12 13 14 tasks: - template: src: xxxx dest: xxxx notify: - restart httpd handlers: - name: restart httpd service: name: httpd state: restarted
注:只有当一个play的所有task都成功,才会执行handlers
1 2 3 4 5 6 7 tasks: ignore_error: yes force_handlers: yes tasks:
fail与changed控制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 此时可以通过输出register failed_when: "'Password missing' in register.stdout" 手动对脚本进行标记失败 直接输出错误信息 - fail: msg: "" when: "'Password missing' in register.stdout" - name: xxx command : "echo 'hello'" changed_when: false 永远不是changed状态
block-rescue-always 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 block是一个块,可以包括多个task,被映射为一组逻辑的task,方便对多个task进行管理 比如在block后添加when,或者changed_when等 在block运行失败时,会运行rescue下的内容 无论block运行失败或成功,都会执行always下的内容 tasks: - block: - name: 升级 shell: cmd: xxx rescue: - name: 回滚 shell: cmd: xxx always: - name: 重启服务 shell: cmd: xxx
常用模块 文件管理:
blockinfile 文件中插入内容 copy 复制 file 创建、删除文件 lineinfile 文本中插入内容 state 状态 synchronize 同步
J2模板文件:
在ansible安装服务后,服务使用的配置文件为默认文件,现在就有J2文件,可以根据变量进行配置文件的修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 { {{ ansible_facts['xxx' ]['xxx' ]}} {{ ansible_facts['hostname' ]}} tasks: - template: src: /tmp/j2/xxx dest: /etc/hosts 在ansible.cfg中添加 ansible_managed = Ansible managed 在j2文件中首行添加 {{ ansible_managed }} 下发后,会标注这个被ansible接管不要手动修改 for 循环,类似于{% for user in users %} {{ user }} {% endfor %} 条件判断if {% if %} {% else %} {% enfif %}
简单调优 1 2 3 4 5 6 7 8 forks = 4 数量受cpu核心数量限制,允许OS同时操作的线程数 如果=1,则task会一个一个执行 serial: 2 表示单次执行2个task