# ansible_repo **Repository Path**: wanghui1234/ansible_repo ## Basic Information - **Project Name**: ansible_repo - **Description**: ansible使用实例【一步到位玩儿透Ansible】https://blog.51cto.com/cloumn/detail/83?from_distribution=VQcJVApVVQwxUwIHVQYFDA - **Primary Language**: Python - **License**: CC-BY-4.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2020-03-03 - **Last Updated**: 2022-05-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 批量初始化服务器 [toc] ## 初始化步骤 - 配置ssh密钥认证 - 远程配置主机名 - 控制远程主机互相添加HOSTS解析 - 配置远程主机的yum源以及一些软件 - 时间同步配置 - 关闭selinux/iptables - 修改sshd配置 ### 配置ssh密钥认证 - 在主控节点的`/etc/ansible/hosts`配置节点 ``` $ vim /etc/ansible/hosts [new] 192.168.56.12 192.168.56.13 ``` #### 在控制节点配置到受控节点的ssh认证方式 ``` # 主控节点执行 $ ssh-keygen -t rsa -f ~/.ssh/id_rsa -N '' $ for host in 192.168.56.{11..12};do ssh-keyscan $host >> ~/.ssh/hnow_hosts 2> /dev/null sshpass -p '123456' ssh-copy-id root@$host &> /dev/null done ``` 将上面的方案playbook化: ``` --- - name: config ssh connection hosts: new gather_facts: false tasks: - name: configure ssh connection shell: | ssh-keyscan {{inventory_hostname}} >> ~/.ssh/know_hosts sshpass -p '123456' ssh-copy-id root@{{inventory_hostname}} ``` #### ansible命令执行模块 以下的四个模块不满足幂等性 - command:执行简单的shell命令 - shell: 和command相同,但支持管道富豪 - raw: 执行底层shell命令,通常在目标主机上安装python时才使用这个模块 - script: 在远程主机上执行脚本 以下命令具备幂等性: - creates: 当指定的文件或者目录不存在时执行,存在不执行 - removes:当指定的文件或者目录不存在时不执行,存在执行 ``` --- - name: modules use hosts: new gather_facts: false tasks: - name: use shell module shell: cp /tmp/my.cnf /etc/my.cnf args: creates: /etc/my.cnf - name: exec perl scripts script: /opt/script.pl args: executable: perl ``` #### 重点 - connection: 连接方式(smart|ssh|paramiko|local|docker|winrm),默认为smart表示只能选择ssh或者paramiko - delegate_to: 只能定义在task级别上,效果和connection相似 ``` --- - name: play1 hosts: zabbix gather_facts: false tasks: - name: task 1 debug: msg: "{{ inventory_hostname }} is executing task" delegate_to: localhost ``` #### authorized_key模块 特点: - 分发ssh公钥 - 不负责主机认证阶段 前提需要配置好hosts下的ansible_passwd字段 ``` [new] 192.168.56.11 ansible_hostname="centos7-node1" 192.168.56.12 ansible_hostname="centos7-node2" [new:vars] ansible_password="yeecallk8s" ``` 分发认证配置 ``` --- - name: "configure ssh connection" hosts: new gather_facts: false tasks: - authorized_key: key: "{{lookup('file','~/.ssh/id_rsa.pub')}}" state: present user: root ``` 外部数据读取的方式: - lookup() :支持从file,redis,etcd,pipe,vars,list,dict - fileglob: 支持统配文件名,file指定文件,pipe从命令执行结果中返回数据 ``` --- - name: "fileglob and file task" hosts: new gather_facts: false tasks: - name: task1 debug: msg: "filenames: {{ lookup('fileglob','/etc/*.conf')}}" - name: task2 debug: msg: "filecontents: {{ lookup('file','/etc/hosts')}} ``` - query() : 统配文件读取,返回list格式 ``` --- - name: "fileglob and files query" hosts: new gather_facts: false tasks: - name: "fileglob" debug: msg: "fileglob {{lookup('fileglob','/etc/*.conf')}}" - name: "fileglob wantlist" debug: msg: "fileglob wantlist {{lookup('fileglob','/etc/*.conf',wantlist=True)}}" - name: "query" debug: msg: "query {{q('fileglob','/etc/*.conf')}}" ``` ### 设置主机名 使用的是hostname模块,会直接修改/etc/hostname 配置文件 ``` --- - name: set hostname hosts: new gather_facts: false vars: hostnames: - host: 192.168.56.13 name: centos7-node3 - host: 192.168.56.14 name: centos7-node4 tasks: - name: set hostname hostname: name: "{{ item.name }}" when: item.host == inventory_hostname loop: "{{ hostnames }}" ``` vars变量设置注意: - 设置在play级别,该play范围内的task都能访问这些变量,其他的play则无法访问 - 设置在task级别,只有该task范围内才能访问这个变量 ``` --- - name: vars task1 hosts: new gather_facts: false vars: - var1: "value1" tasks: - name: access value1 debug: msg: "var1 in task1 {{var1}}" - name: vars task2 hosts: new gather_facts: false tasks: - name: can not access vars from task1 debug: msg: var1 - name: set and access var2 in this task debug: msg: var2 vars: var2: "value2" - name: cant access var2 debug: msg: var2 ``` when条件判断 - 当when判断为true的时候执行任务,反之不执行 ``` --- - name: when judge hosts: new gather_facts: false vars: - myname: "alex" tasks: - name: task skip debug: msg: "my name is {{myname}}" when: myname == "hello" #这个判断条件是false的 - name: task will execute debug: msg: "my name is {{myname}}" when: myname == "alex" ``` loop循环: 解决重复问题 - 未使用循环的例子 ``` --- - name: make dirs for localhost hosts: localhost gather_facts: false tasks: - name: create test1 file: path: /tmp/test1 state: directory - name: create test2 file: path: /tmp/test2 state: directory ``` - 使用循环的例子 ``` --- - name: mkdir loop hosts: localhost gather_facts: false tasks: - name: create test1,2 directory file: path: "{{item}}" state: directory loop: - /tmp/test01 - /tmp/test02 ``` ### 互相添加hosts(DNS)主机名解析 互相添加指定hosts组的host之间的hosts解析 ``` --- - name: add hosts DNS hosts: new gather_facts: false tasks: - name: add DNS lineinfile: path: /etc/hosts line: "{{item}} {{hostvars[item].ansible_hostname}}" when: item != inventory_hostname loop: "{{ play_hosts }}" ``` - lineinfile模块: 在源文件中插入,删除,替换行,跟sed类似 ``` # 创建测试文件a.txt paragraph 1 first line in paragraph 1 second line in paragraph 1 paragraph 2 first line in paragraph 2 second line in paragraph 2 ## lineinfile追加实例 --- - name: add line to a.txt hosts: localhost gather_facts: false tasks: - lineinfile: path: "a.txt" line: "append new line" state: absent # 删除上面的line定义的行(append new line) ### 插入操作,定义在摸个行前或者行后新增(insertbefore,insertafter) --- - name: lininfile demo for before and after insert hosts: localhost gather_facts: false tasks: - name: line infile lineinfile: path: "a.txt" line: "LINE1" insertbefore: '^para.* 2' firstmatch: yes lineinfile: path: "a.txt" line: "LINE2" insertafter: '^para.* 2' firstmatch: yes ``` - play_hosts和hostvars变量 - inventory_hostname: 表示在主机inventory中定义的名称 - play_hosts和hostvars: 是预定义变量,执行任务时可以直接拿出来使用,play_hosts相当于是new这个主机组里面的所有主机列表; - hostvars: 保存了所有目标主机的变量 ``` - name: add DNS lineinfile: path: /etc/hosts line: "{{item}} {{hostvars[item].ansible_hostname}}" when: item != inventory_hostname loop: "{{ play_hosts }}" ``` ### 配置yum源并下载安装软件 更换yum源,安装软件 ``` --- - name: "init yum" hosts: new gather_facts: false tasks: - name: "backup old yum_repo" shell: cmd: "mkdir bak; mv *.repo bak" chdir: /etc/yum.repos.d creates: /etc/yum.repos.d/bak - name: "add new os repo and release repo" yum_repository: name: "{{item.name}}" description: "{{item.name}} repo" baseurl: "{{item.baseurl}}" file: "{{item.name}}" enabled: 1 gpgcheck: 0 reposdir: /etc/yum.repos.d loop: - name: os baseurl: "https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/os/$basearch" - name: epel baseurl: "https://mirrors.tuna.tsinghua.edu.cn/epel/$releasever/$basearch" - name: install pkgs yum: name: vim,net-tools,git-core,lrzsz,wget,curl,sysstat,iotop,gcc,gcc-c++,cmake,pcre,pcre-devel,zlib,zlib-devel,openssl,openssl-devel,vim,wget,telnet,setuptool,lrzsz,dos2unix, net-tools,bind-utils,tree,screen,iftop,ntpdate,tree,lsof,iftop,iotop,sysstat,procps state: present ``` ### 时间同步 使用ntpdate 同步时间 ``` --- - name: sync time hosts: new gather_facts: false tasks: - name: install and sync time block: - name: install ntpdate yum: name: ntpdate state: present - name: ntpupdate to sync time shell: | ntpdate ntp1.aliyun.com hwclock -w ``` - block是组织了两个有关联性的任务 ### 关闭selinux 命令行关闭和修改配置文件两种手段 ``` --- --- - name: disable selinux hosts: new gather_facts: false tasks: - block: - name: disable selinux by command shell: setenforce 0 - name: disable selinux by config lineinfile: path: /etc/selinux/config line: "SELINUX=disabled" regexp: '^SELINUX=' ignore_errors: true ``` ### 配置防火墙 ``` --- - name: set firewalld hosts: new gather_facts: false tasks: - name: set iptables rule shell: | iptables-save > /tmp/iptables.bak$(date +"%F-%T") iptables -X iptables -F iptables -Z systemctl disable firewalld systemctl stop firewalld ``` ### 配置sshd服务 - 需求: - 禁止root用户登陆 - 不允许使用密码登陆 ``` --- - name: "set sshd service" hosts: new gather_facts: false tasks: - name: backup old sshd config shell: | /usr/bin/cp -f {{path}} {{path}}.bak vars: - path: /etc/ssh/sshd_config - name: disable root login lineinfile: path: "/etc/ssh/sshd_config" line: "PermitRootLogin no" regexpr: '^PermitRootLogin' notify: "restart sshd" - name: disable passwd auth lineinfile: path: "/etc/ssh/sshd_config" line: "PasswordAuthentication no" regexp: '^PasswordAuthentication yes' notify: "restart sshd" handlers: - name: "restart sshd" service: name: sshd state: restarted ```