中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ansible怎么批量初始化服務器

發布時間:2020-06-03 23:06:35 來源:億速云 閱讀:1011 作者:Leah 欄目:系統運維

ansible怎么批量初始化服務器?針對這個問題,今天小編總結這篇有關ansible批量初始化服務器的文章,有需要的小伙伴們可以參考借鑒,希望對大家有所幫助。

1、ansible要初始化的主機

[root@nginx ansible]# tail -3 /etc/ansible/hosts   #要初始的主機如下
[node]
192.168.20.4
192.168.20.5

2、配置ssh免密登錄

playbook文件內容如下:

[root@nginx ansible]# cat ssh.yaml 
---
- name: configure ssh connection
  hosts: node
  gather_facts: false
  connection: local
  tasks:
    - name: configure ssh connection
      shell: |
        ssh-keyscan {{inventory_hostname}} >>~/.ssh/known_hosts
        sshpass -p '123.com' ssh-copy-id root@{{inventory_hostname}}
...

注:

  • gather_facts:如果值為false,則表示不收集目標主機上的節點信息,默認為true,為收集節點信息,如果收集節點信息,則會慢很多,如果在接下來的操作中,不需要節點上的信息,可設置為false。
  • connection:local表示在ansible端本地執行任務,hosts:localhost和connection:local容易搞混,雖然兩者的效果都是在本地執行任務,但是hosts:localhost是從inventory中篩選出了目標節點localhost來執行任務,而connection:local則篩選出來執行任務的目標主機是node組中的節點,但因為指定了local連接類型,使得node組中有多少個節點,就會在ansible本地執行幾次該play。

3、配置主機名

配置主機名可以使用shell模塊,但是對于不太專業,ansible提供了一個專用于配置主機名的模塊:hostname模塊。

當然,要使用ansible去設置多個主機名,要求目標主機和目標名稱已經關聯好,否則多個主機和多個主機名之間無法對應去設置。

例如:分別設置node組中的兩個節點主機名為node01和node02,playbook內容如下:

[root@ansible ansible]# cat test.yaml 
---
- name: set hostname
  hosts: node
  gather_facts: false
  vars:
    hostnames:
      - host: 192.168.20.4
        name: node01
      - host: 192.168.20.5
        name: node02
  tasks:
    - name: set hostname
      hostname:
        name: "{{item.name}}"
      when: item.host == inventory_hostname
      loop: "{{hostnames}}"

在上面的hostname模塊中,需要詳細介紹vars指令以及when、loop指令。

1)vars設置變量

vars指令可用于設置變量,可以設置一個或多個變量。下面幾種方式都是合理的:

# 設置單個變量
vars:
  var1: value1

vars:
  - var1: value1

# 設置多個變量

vars:
  var1: value1
  var2: value2

vars:
  - var1: value1
  - var2: value2

vars可以設置在play級別,也可以設置在task級別,設置在play級別,該play范圍內的task可以訪問這些變量,其他play范圍內則無法訪問;設置在task級別,只有該task能訪問這些變量,其他task和其他play則無法訪問。

例如:

[root@ansible ansible]# cat test.yaml 
---
- name: play1
  hosts: localhost
  gather_facts: false
  vars:
    - var1: "value1"
  tasks:
    - name: access var1
      debug:
        msg: "var1's value: {{var1}}"

- name: play2
  hosts: localhost
  gather_facts: false
  tasks:
    - name: cat's access vars from play1
      debug:
        var: var1

    - name: set and access var2 in this task
      debug:
        var: var2
      vars:
        var2: "value2"

    - name: cat't accesss var2
      debug:
        var: var2

執行結果如下:

[root@ansible ansible]# ansible-playbook test.yaml 

PLAY [play1] **************************************************************************

TASK [access var1] ********************************************************************
ok: [localhost] => {
    "msg": "var1's value: value1"
}

PLAY [play2] **************************************************************************

TASK [cat's access vars from play1] ***************************************************
ok: [localhost] => {
    "var1": "VARIABLE IS NOT DEFINED!"
}

TASK [set and access var2 in this task] ***********************************************
ok: [localhost] => {
    "var2": "value2"
}

TASK [cat't accesss var2] *************************************************************
ok: [localhost] => {
    "var2": "VARIABLE IS NOT DEFINED!"
}

PLAY RECAP ****************************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

回到我們更改主機名的配置vars指令中:

  vars:
    hostnames:
      - host: 192.168.20.4
        name: node01
      - host: 192.168.20.5
        name: node02

上面只設置了一個變量hostnames,但這個變量的值是一個數組結構,數組的兩個元素又都是對象(字典/hash)結構。

所以想要訪問主機名node01和它的IP地址192.168.20.4,可以:

  tasks:
    - debug:
        var: hostnames[0].name
    - debug:
        var: hostnames[0].host
2)when條件判斷

在ansible中,提供的唯一一個通用的條件判斷是when指令,當when指令的值為true時,則執行該任務,否則不執行該任務。

例如:

[root@ansible ansible]# cat test.yaml 
---
- name: play1
  hosts: localhost
  gather_facts: false
  vars:
    - myname: "Ray"
  tasks:
    - name: task will skip
      debug:
        msg: "myname is : {{myname}}"
      when: myname == "lv"

    - name: task will execute
      debug:
        msg: "myname is : {{myname}}"
      when: myname == "Ray"

在上面的myname值設置為Ray,第一個任務因為when的判斷條件是myname==“lv”,所以判斷結果為false,該任務不執行,同理,第二個任務因為when的值為true,所以執行了。

該playbook的執行結果:

PLAY [play1] **************************************************************************

TASK [task will skip] *****************************************************************
skipping: [localhost]

TASK [task will execute] **************************************************************
ok: [localhost] => {
    "msg": "myname is : Ray"
}

PLAY RECAP ****************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0  

4、互相添加DNS解析記錄

[root@ansible ansible]# cat add_dns.yaml 
---
- name: play1
  hosts: node
  gather_facts: true
  tasks:
    - name: add DNS
      lineinfile:
        path: "/etc/hosts"
        line: "{{item}} {{hostvars[item].ansible_hostname}}"
      when: item != inventory_hostname
      loop: "{{ play_hosts }}"

執行結果如下:

TASK [Gathering Facts] ****************************************************************
ok: [192.168.20.4]
ok: [192.168.20.5]

TASK [add DNS] ************************************************************************
skipping: [192.168.20.4] => (item=192.168.20.4) 
changed: [192.168.20.4] => (item=192.168.20.5)
changed: [192.168.20.5] => (item=192.168.20.4)
skipping: [192.168.20.5] => (item=192.168.20.5) 

5、配置yum鏡像源并安裝軟件

需求如下:

  • 備份原有yum鏡像源文件,并配置清華大學的yum鏡像源:os源和epel源
  • 安裝常用軟件,包括lrzsz、dos2unix、wget、curl、vim等;

playbook如下:

[root@ansible ansible]# cat config_yum.yaml 
- name: config yum repo add install software
  hosts: node
  gather_facts: false
  tasks:
    - name: backup origin yum repos
      shell:
        cmd: "mkdir bak; mv *.repo bak"
        chdir: /etc/yum.repos.d
        creates: /etc/yum.repos.d/bak

    - name: add os repo and epel 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/7/os/$basearch"
        - name: epel
          baseurl: "https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch"

    - name: install pkgs
      yum:
        name: lrzsz,vim,dos2unix,wget,curl
        state: present

在上面的yaml文件中,第一個任務是將所有系統默認的repo文件備份到bak目錄中,chdir參數表示在執行shell模塊的命令前先切換到/etc/yum.repos.d目錄下,creates參數表示bak目錄存在時則不執行shell模塊。

第二個任務是使用yum_repository模塊配置yum源,該模塊可添加或移除yum源。

相關參數如下:

  • name:指定repo的名稱,對應于repo文件中的[name];
  • description:repo的描述信息,對應repo文件中的name:xxx;
  • baseurl:指定該repo的路徑;
  • file:指定repo的文件名,不需要加.repo后綴,會自動加上;
  • reposdir:repo文件所在的目錄,默認為/etc/yum.repos.d目錄;
  • enabled:是否啟用該repo,對應于repo文件中的enabled;
  • gpgcheck:該repo是否啟用gpgcheck,對應于repo文件中的gpgcheck;
  • state:present表示保證該repo存在,absent表示移除該repo。

在上面的配置中使用了一個loop循環來添加兩個repo:os和epel。

第三個任務是使用yum模塊安裝一些rpm包,yum模塊可以更新、安裝、移除、下載包。

yum常用參數說明:

  • name:指定要操作的包名
    • 可以帶版本號;
    • 可以是單個包名,也可以是包名列表,或者逗號分隔多個包名;
    • 可以是url;
    • 可以是本地rpm包
  • state:
    • present和installed:保證包已安裝,它們是等價的別名;
    • latest:保證包已安裝了最新版本,如果不是則更新;
    • absent和removed:移除包,它們是等價的別名;
  • download_only:僅下載不安裝包(ansible 2.7才支持)
  • download_dir:下載包存放在哪個目錄下(ansible 2.8才支持)

yum模塊是RHEL系列的包管理器,如果是ubuntu則無法使用,可以使用另一個更為通用的包管理器模塊:package,它可以自動探測目標節點的包管理器類型并使用它們去管理軟件。大多數時候使用package來代替yum或代替apt-install等不會有什么問題,但是有些包名在不同的操作系統上是不一樣的,這是需要注意的。

6、時間同步

保證時間同步可以避免很多玄學性的問題,特別是對集群中的節點。

通常會使用ntpd時間服務器來保證時間的同步,這里使用aliyun提供的時間服務器來保證時間同步,并將同步后的時間同步到硬件。

playbook文件如下:

---
- name: sync time
  hosts: node
  gather_facts: false
  tasks:
    - name: install and sync time
      block:
        - name: install ntpdate
          yum:
            name: ntpdate
            state: present
        - name: ntpdate to sync time
          shell: |
            ntpdate ntp1.aliyun.com
            hwclock -w

上面使用了一個block指令來組織了兩個有關聯性的任務,將他們作為了一個整體。block更多的用于多個關聯性任務之間的異常處理。

7、關閉selinux

關閉selinux的playbook如下:

[root@ansible roles]# cat disable_selinux.yaml 
---
- name: disable selinux
  hosts: node
  gather_facts: false
  tasks:
    - name: disable on the fly
      shell: setenforce 0
      ignore_errors: true   #由于上條命令執行后的返回狀態碼不一定為0,所以為了防止非0報錯并停止palsybook接下來的任務,所以使用ignore_errors忽略錯誤

    - name: disable forever in config
      lineinfile:
        path: /etc/selinux/config
        line: "SELINUX=disabled"     #修改配置文件中的值,以便永久關閉
        regexp: '^SELINUX='          #要修改的內容

注:ignore_errors也經常結合block使用,因為在block級別上設置異常處理,可以處理block內部的所有錯誤。

8、配置iptables規則

playbook文件如下:

- name: Set Firewall
  hosts: node
  gather_facts: false
  tasks: 
    - name: set iptables rule
      shell: |
        # 備份已有規則
        iptables-save > /tmp/iptables.bak$(date +"%F-%T")
        # 給它三板斧
        iptables -X
        iptables -F
        iptables -Z

        # 放行lo網卡和允許ping
        iptables -A INPUT -i lo -j ACCEPT
        iptables -A INPUT -p icmp -j ACCEPT

        # 放行關聯和已建立連接的包,放行22、443、80端口
        iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
        iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
        iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
        iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

        # 配置filter表的三鏈默認規則,INPUT鏈丟棄所有包
        iptables -P INPUT DROP
        iptables -P FORWARD DROP
        iptables -P OUTPUT ACCEPT

9、遠程修改sshd配置文件并重啟

有時候為了服務器的安全,可能會去修改目標節點上sshd服務的默認配置,比如禁止root用戶登錄、禁止密碼認證登錄而只允許使用ssh密碼認證等。

在修改服務的配置文件時,一般有幾種方法:

  • 通過遠程執行sed等命令進行修改配置文件;
  • 通過lineinfile模塊去修改配置文件;
  • 在ansible本地段寫好配置文件,然后使用copy模塊或者template模塊傳輸到目標節點上。

相對來說,第三種方案是最統一、最易維護的方案。

此外,對于服務進程來說,修改了配置文件往往意味著要重啟服務,使其加載新的配置文件,對于sshd也一樣如此,但是sshd要比其他服務特殊一些,因為ansible默認基于ssh連接,重啟sshd服務會使ansible連接斷開,好在ansible默認會重試建立連接,無非是多等待幾秒。但重建連接有可能會失敗,比如修改了配置文件不允許重試、修改了sshd的監聽端口等,這可能會使得ansible因連接失敗而無法再繼續執行后續任務。

所以,在修改sshd配置文件時,有如下建議:

  • 將此任務作為初始化服務器的最后一個任務,即使連接失敗也無所謂;
  • 在playbook中加入連接失敗的異常處理;
  • 如果目標節點修改了sshd端口號,建議通過ansible自動或者我們手動去修改inventory文件中的ssh連接端口號。

這里為了簡單,我準備使用lineinfile模塊去修改配置文件,要修改的內容只有兩項:

  • 將PermitRootLogin指令設置為no,禁止root用戶直接登錄;
  • 將PasswordAuthentication指令設置為no,不允許使用密碼認證的方式登錄

playbook內容如下:

[root@ansible roles]# cat sshd_config.yaml 
---
- name: modify sshd_config
  hosts: node
  gather_facts: false
  tasks:
    # 1.備份/etc/ssh/sshd_config文件
    - name: backup sshd config
      shell:
        /usr/bin/cp -f {{path}} {{path}}.bak
      vars:
        - path: /etc/ssh/sshd_config

    # 2.設置PermitRootLogin no
    - name: disable root login
      lineinfile:
        path: "/etc/ssh/sshd_config"
        line: "PermitRootLogin no"
        insertafter: "^#PermitRootLogin"
        regexp: "^PermitRootLogin"
      notify: "restart sshd"
    # 3.設置PasswordAuthentication no
    - name: disable password 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

關于notify和handlers的作用如下:

ansible會監控playbook執行后的changed的狀態,如果changed=1,則表示關注的狀態發生了改變,即本次任務的執行不具備冪等性,如果changed=0,則表示本次任務要么沒執行,要么執行了也沒有影響,即本次任務具備冪等性。

ansible提供了notify指令和handlers功能,如果在某個task中定義notify指令,當ansible在監控到該任務changed=1時,會觸發該notify指令所定義的handler,然后去執行handler。所謂handler,其實就是task,無論是在寫法上還是作用上它和task都沒有什么區別,唯一的區別在于handler是被觸發而被動執行的,不像普通task一樣會按流程正常執行。

唯一需要注意的是,notify和handler中任務的名稱必須一致。比如: notify: "restart sshd",那么handlers中必須得有一個任務設置了 name: "restart sshd"。

此外,在上面的playbook中,兩個lineinfile任務都設置了相同的notify,但ansible不會多次去重啟sshd,而是在最后重啟一次。實際上,ansible在執行完某個任務之后,并不會立即去執行對應的handler,而是在當前play中所有普通任務都執行完成后再去執行handler,這樣的好處是可以多次觸發notify,但最后只執行一次對應的handler,從而避免多次重啟。

10、整合所有任務到單個playbook中

這里將前面所有的playbook集合到單個playbook文件中去,這樣就可以一次性執行所有任務。

整合后的playbook如下:

---
- name: Configure ssh Connection
  hosts: node
  gather_facts: false
  connection: local
  tasks:
    - name: configure ssh connection
      shell: |
        ssh-keyscan {{inventory_hostname}} >>~/.ssh/known_hosts
        sshpass -p'123.com' ssh-copy-id root@{{inventory_hostname}}

- name: Set Hostname
  hosts: node
  gather_facts: false
  vars:
    hostnames:
      - host: 192.168.20.4
        name: node01
      - host: 192.168.20.5
        name: node02
  tasks: 
    - name: set hostname
      hostname: 
        name: "{{item.name}}"
      when: item.host == inventory_hostname
      loop: "{{hostnames}}"

- name: Add DNS For Each
  hosts: node
  gather_facts: true
  tasks: 
    - name: add DNS
      lineinfile: 
        path: "/etc/hosts"
        line: "{{item}} {{hostvars[item].ansible_hostname}}"
      when: item != inventory_hostname
      loop: "{{ play_hosts }}"

- name: Config Yum Repo And Install Software
  hosts: node
  gather_facts: false
  tasks: 
    - name: backup origin yum repos
      shell: 
        cmd: "mkdir bak; mv *.repo bak"
        chdir: /etc/yum.repos.d
        creates: /etc/yum.repos.d/bak

    - name: add os repo and epel 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/7/os/$basearch"
        - name: epel
          baseurl: "https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch"

    - name: install pkgs
      yum: 
        name: lrzsz,vim,dos2unix,wget,curl
        state: present

- name: Sync Time
  hosts: node
  gather_facts: false
  tasks: 
    - name: install and sync time
      block: 
        - name: install ntpdate
          yum: 
            name: ntpdate
            state: present

        - name: ntpdate to sync time
          shell: |
            ntpdate ntp1.aliyun.com
            hwclock -w

- name: Disable Selinux
  hosts: node
  gather_facts: false
  tasks: 
    - block: 
        - name: disable on the fly
          shell: setenforce 0

        - name: disable forever in config
          lineinfile: 
            path: /etc/selinux/config
            line: "SELINUX=disabled"
            regexp: '^SELINUX='
      ignore_errors: true

- name: Set Firewall
  hosts: node
  gather_facts: false
  tasks: 
    - name: set iptables rule
      shell: |
        # 備份已有規則
        iptables-save > /tmp/iptables.bak$(date +"%F-%T")
        # 給它三板斧
        iptables -X
        iptables -F
        iptables -Z

        # 放行lo網卡和允許ping
        iptables -A INPUT -i lo -j ACCEPT
        iptables -A INPUT -p icmp -j ACCEPT

        # 放行關聯和已建立連接的包,放行22、443、80端口
        iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
        iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
        iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
        iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

        # 配置filter表的三鏈默認規則,INPUT鏈丟棄所有包
        iptables -P INPUT DROP
        iptables -P FORWARD DROP
        iptables -P OUTPUT ACCEPT

- name: Modify sshd_config
  hosts: node
  gather_facts: false
  tasks:
    - name: backup 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"
        insertafter: "^#PermitRootLogin"
        regexp: "^PermitRootLogin"
      notify: "restart sshd"

    - name: disable password 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

看完這篇文章,你們學會ansible批量初始化服務器的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

承德县| 义乌市| 滁州市| 阳新县| 维西| 建水县| 新郑市| 广平县| 武山县| 黄梅县| 抚宁县| 从化市| 石景山区| 崇阳县| 芦山县| 多伦县| 荣昌县| 嘉义市| 定兴县| 徐州市| 紫金县| 湖南省| 青川县| 岳阳县| 岱山县| 杭锦旗| 克拉玛依市| 雅安市| 文登市| 任丘市| 安岳县| 崇仁县| 江城| 云阳县| 长治市| 瓮安县| 黑河市| 盈江县| 漳浦县| 定西市| 宁安市|