批量初始化服務器
初始化步驟
- 配置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
參考
推薦專欄:https://blog.51cto.com/cloumn/detail/83from_distribution=VQcJVApVVQwxUwIHVQYFDA
代碼gitee:https://gitee.com/wanghui1234/ansible_repo.git