SaltStack系列(四)之實例編寫

前面已經介紹的夠多了,這裏來讓咱們寫一些完整的實例來梳理一下。php

強調一下,sls文件的抒寫格式都是"-"後面跟一個空格,而後後面跟參數: 而後後面再跟一個空格,而後是要填寫的值。可是粘貼上面中間空格好多......node

1、初始化實例

通常一臺新機器在交付使用以前,都要作一些初始化優化操做,如調整參數啊,優化服務啊,部署監控啊等,這裏咱們就寫一個相對簡單的實例演示一下。mysql

1.1 服務端的前期準備

第一步:

開啓自動驗證功能(既然咱們要自動化,不可能每建立一臺新機器就跑到master端去手工認證一次)(兩種方式根據本身的狀況來)react

第一種:linux

# vim /etc/salt/master  #修改master配置文件,開啓自動認證。並重啓master服務。nginx

auto_accept: True   #默認是關閉狀態c++

第二種:web

http://www.51niux.com/?id=120  #關於event和reactor有講,一種根據監聽事件並作相應操做的事情。 正則表達式

第二步:

開啓相應的目錄設置並重啓master服務sql

# vim /etc/salt/master  #這裏建立了兩個環境,一個環境是base環境是默認環境也是必須環境,還有一個prod生產環境。base環境用來部署出初始化操做
file_roots:
   base:
     - /srv/salt/base

   prod:
      - /srv/salt/prod

pillar_roots:
  base:
    - /srv/pillar/base
  prod:
    - /srv/pillar/prod

#file_roots 配置salt配置的存放目錄, 其中base環境是必要的, 指定top.sls存放的位置.默認沒指定環境時則從base目錄獲取文件其它則是一些自定義的, 能夠經過環境變量指定.這樣能夠邏輯上隔離一些環境配置.每個環境均可以定義多個目錄, 優先級關係由定義目錄的順序決定.

第三步:建立對應的目錄

# mkdir -p /srv/salt/base /srv/salt/prod
# mkdir -p /srv/pillar/base /srv/pillar/prod

1.2 sls文件的編寫

1.2.1 selinux.sls

# cat /srv/salt/base/init/selinux.sls  #關閉selinux服務。

Bash
selinux:  #ID file.replace: #Function,替換文件內容的方法 - name: /etc/selinux/config #在這裏是要替換內容的文件 - pattern: SELINUX=enforcing #要替換的內容 - repl: SELINUX=disabled #替換後的內容 - count: 1 #默認爲0表示表示全部的都將進行替換,這裏加了整數的話就表示替換的次數不超過這個整數 setenforce: cmd.run: - name: setenforce 0 #這裏就是cmd.run後面跟着的要執行的操做。

#若是有那個方法不知道state怎麼寫,請:# salt '*' sys.state_doc file 或者# salt '*' sys.state_doc cmd.run 進行查看。

# salt 'shidc_agent_192.168.1.111' state.sls init.selinux  #若是想測試編寫的時候有錯誤,能夠找一臺測試機器,單獨指定要測試的sls文件進行執行測試。

圖片.png

1.2.2 repos.sls

# cat /srv/salt/base/init/repos.sls  #其實這步通常不用作的,由於咱們用工具安裝操做系統的時候就已經作了,源已經配置好該裝的包已經裝了。

Bash
yum_base_repo_dir:
    cmd.run:
      - name: mv /etc/yum.repos.d /etc/yum.repos.d.bak #當/etc/yum.repos.d.bak不存在的時候,執行是成功的,再執行就要報錯了,因此加下面的條件。 - unless: test -d /etc/yum.repos.d.bak #unless是若是條件爲false,上面就執行。意思就是若是/etc/yum.repos.d.bak目錄存在,上面就不執行mv操做,防止反覆執行。 file.directory: #這是目錄建立的方法,正好熟悉一下 - name: /etc/yum.repos.d #這是要建立的目錄 - user: root #目錄的用戶 - group: root #目錄的用戶組 - dir_mode: 755 #目錄的權限 - file_mode: 644 #文件的權限 - makedirs: True #目錄不存在就建立,存在就不會執行建立操做了,這樣避免報錯,若是不加這個參數,已經建立了目錄再執行會報錯。 - recurse: # 屬性權限遞歸到文件夾內的文件上 - user #若原本此目錄就存在,且此目錄下有不少文件,則recurse函數會把此目錄和目錄下的全部文件的權限都修改(root 644 755) - group - mode - ignore_files #忽略文件,還有個 - ignore_dirs忽略目錄操做 yum_base_repo_file: file.append: #文件內容的添加,這裏有一點要注意,若是下方的內容沒有變化,屢次執行是不會再次追加的,可是若是下面的四行裏面哪一行發生了改變,是會追加到minion端對應的文件底部成爲新的一行而不是替換。 - name: /etc/yum.repos.d/centos-base.repo #要添加的文件位置 - makedirs: True #加上這個參數,若是上一層目錄不存在的話,會自動建立,否則若是上層目錄不存在的話,會報錯。 - text: #這是要添加的內容,下面每一行- 跟內容。 - '[base]' #這裏若是不是'[base]'的形式,若是直接[base]的話,在minion端的文件裏面就要變成['base']形式了。 - name=CentOS-$releasever - Base - baseurl=http://yum.51niux.com/centos/$releasever/os/$basearch/ - gpgcheck=0 yum_epel_repo: #其實epel這裏也應該是file.append,由於相關的rpm包也應該是咱們從官網搞的作成的一個yum倉庫 pkg.installed: - sources: #這個參數就是能夠執行遠程的rpm包的路徑 {% if grains['os'] == 'CentOS' and grains['osmajorrelease'] == '7' %} #這裏就要用到了判斷了,若是是Centos7的系統下載rpm包的連接跟Centos6的是不同的。 - epel-release: http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-9.noarch.rpm {% elif grains['os'] == 'CentOS' and grains['osmajorrelease'] == '6'%} - epel-release: http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm {% endif %} - unless: rpm -qa|grep epel-release #若是本地沒有安裝epel就執行,否則又是報錯,onlyif:正好跟unless相反,條件爲真時執行 。

圖片.png

#上面是一個屢次執行的一臺主機效果截圖,由於咱們基本每一塊都加了判斷條件,因此不會隨便執行,也就不會報錯。若是不加各類判斷就是下面相似的效果:

圖片.png

1.2.3 dns.sls

# cat /srv/salt/base/init/dns.sls  #這步通常也是安裝完操做系統就作好了,這裏也是選擇作的,好比你用的114.114.114.114的域名,又一次就出問題了好幾天這時候你就須要統一更換dns服務器保證解析的正常,固然若是用的是內網DNS服務的話,這裏就不必搞了,直接再DNS服務器那裏調整就能夠了。

Bash
/etc/resolv.conf:  #這裏沒有設置name,因此/etc/resolv.conf既是ID:又是name,就是咱們要操做的文件。 file.managed: #這裏引用的是file.managed方法 - source: salt://init/files/resolv.conf #下載的文件的源位置。在根目錄下的init/files目錄下。 - user: root - group: root - mode: 0644

# cat /srv/salt/base/init/files/resolv.conf  #這是要發送的resolv.conf文件

Bash
nameserver 223.5.5.5
nameserver 223.6.6.6

1.2.4 history.sls

# cat /srv/salt/base/init/history.sls #這個也是挺有用的記錄時間記錄用戶作了什麼操做

Bash
/etc/profile:
  file.append:
    - text:
      - export HISTTIMEFORMAT="%F %T `whoami` " #只能是這種export生效的方式了,固然新的窗口就能看到效果了,不能期望着source /etc/profile,能夠用cmd.run跑一下都不支持......

1.2.5 sysctl.sls

# cat /srv/salt/base/init/sysctl.sls  #內核的參數優化也是要作的。

Bash
net.ipv4.ip_local_port_range:  #格式比較簡單,這裏是既是ID:又是name,就至關於name: net.ipv4.ip_local_port_range sysctl.present: #格式就是在這個下面,指定name就是哪一個參數要修改 - value: 10000 65000 #- value: 後面指定要修改的值,更新/etc/sysctl.conf文件。並當即生效的,相似於#sysctl -p fs.file-max: sysctl.present: - value: 655350 vm.swappiness: sysctl.present: - value: 0 net.core.rmem_max: sysctl.present: - value: 33554432 net.core.wmem_max: sysctl.present: - value: 33554432

1.2.6 service.sls

# cat /srv/salt/base/init/service.sls  #service初始化也是要作的,關閉沒必要要的服務,按理說Centos7和Centos6的應該用個if區分開,我這就都放一塊兒了偷個懶。

Bash
{% set service_list = ['firewalld','iptables','ip6tables','NetworkManager','nfs-config','postfix','auditd','cups','cupsd'] %} #因爲service的格式限制,我這就用了個for循環來避免沒必要要的編寫。 {% for num in service_list %} {{ num }}: service.running: - enable: False cmd.run: - name: service {{num}} stop {% endfor %}

1.2.7 其餘文件配置並查看

# cat /srv/salt/base/init/env_init.sls

Bash
include:   #include多sls文件能夠以列表形式,用下面這種形式。 - init.dns #指定init目錄下面的dns.sls文件,.表明下一級目錄 - init.history - init.sysctl - init.repos - init.selinux - init.service

# cat /srv/salt/base/top.sls #在入口文件top.sls裏面給minion指定狀態並執行init目錄下的env_init.sls文件

Bash
base:
  '*': - init.env_init

# salt '*' state.highstate test=True  #服務端執行,能夠先加test,這樣出問題不執行也能提早解決一下,安全性高一點。

# salt '*' state.highstate  #讓全部的minion端同步狀態,從top.sls進入一看,一看就是執行init.env_init這個配置。

若是是客戶端的操做的話就是:

#salt-call state.highstate  #手工執行

#salt-call state.sls init.env_init  #或者能夠手工指定sls文件執行。

博文來自:www.51niux.com

2、lnmp實例

2.1  建立必要目錄

# mkdir -p /srv/salt/prod/pcre/files

# mkdir -p /srv/salt/prod/nginx/files

# mkdir -p /srv/salt/prod/php/files
# mkdir -p /srv/salt/prod/mysql/files
# mkdir -p /srv/salt/prod/pkg/files

# mkdir -p /srv/salt/prod/user

2.2 編寫pkg包文件

# cat /srv/salt/prod/pkg/pkg-init.sls  #先提早yum安裝必要的軟件包

Bash
pkg-init:  #這是兩種安裝方式,一種是將要安裝的軟件包作成下面列表的形式,這樣包組的之間的安裝基本不會有影響。 pkg.installed: - names: - bison - gcc - gcc-c++ - autoconf - automake - zlib - libxml2 - ncurses-devel - cmake {% if grains['os'] == 'CentOS' and grains['osmajorrelease'] == '7' %} - mariadb-devel {% elif grains['os'] == 'CentOS' and grains['osmajorrelease'] == '6'%} - mysql-devel {% endif %} pkg-yum: #這是另一種經過cmd.run執行yum安裝命令的操做,這種對於要安裝的軟件包組的操做比較方便,可是若是有一個軟件包安裝出現問題將致使整個過程都失敗,因此要提早測試好並yum源倉庫作好配置。 cmd.run: - name: yum install openssl* libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel ncurses ncurses-devel curl curl-devel gd gd2 gd-devel gd2-devel zlib libxml libjpeg freetype libpng gd curl libiconv zlib-devel libxml2-devel libjpeg-devel freetype-devel libpng-devel gd-devel curl-devel libxslt-devel -y

# salt 'tjidc_agent_192.168.1.102_youshi' state.sls saltenv='prod' pkg.pkg-init test=True 或者# salt 'tjidc_agent_192.168.1.102_youshi' state.sls saltenv='prod' pkg.pkg-init  #指定一臺機器測試一下。

#注意上面的格式,state.sls saltenv='prod' 這是針對多環境,由於咱們尚未再top.sls定義,因此不能用那個 state.highstate命令。state.sls 並不讀取 top.sls,如今咱們的sls文件在prod環境下並不是在base環境下,因此要加上指定環境saltenv的參數,而後裏面指定了prod環境。而後後面跟的是哪一個目錄下的哪一個sls文件,就跟以前上面測試單文件沒有什麼差異了。

2.3 user用戶編寫 

# cat /srv/salt/prod/user/www.sls  #指定一個www用戶

Bash
www-user-group:   #ID: group.present: #調用的是建立組的函數 - name: www #組名稱 - gid: 500 #gid設置 user.present: - name: www #用戶名 - fullname: www - shell: /sbin/nologin #用戶不登陸 - uid: 500 #uid - gid: 500 #gid

# cat /srv/salt/prod/user/mysql.sls  #建立一個MySQL的用戶組和用戶

Bash
mysql-user-group:
  group.present:
     - name: mysql
     - gid: 600
  user.present:
     - name: mysql
     - fullname: mysql
      -  gid_from_name: True  #其實通常能夠不用建立組的,直接在這裏加上這麼一句話,默認是False。就是讓組id也跟着建立而且gid跟uid一致。 - shell: /sbin/nologin - uid: 600 - gid: 600

2.4 mysql安裝

# cat /srv/salt/prod/mysql/install.sls

Bash
include:
   - pkg.pkg-init
   - user.mysql
cmake-install:
  file.managed:
    - name: /opt/cmake-2.8.6.tar.gz
    - source: salt://mysql/files/cmake-2.8.6.tar.gz
  cmd.run:
    - name: cd /opt/ && tar zxf cmake-2.8.6.tar.gz && cd cmake-2.8.6 && ./configure && make && make install mysql-install: file.managed: - name: /opt/mysql-5.5.35.tar.gz - source: salt://mysql/files/mysql-5.5.35.tar.gz - user: root - group: root - mode: 644 cmd.run: - name: cd /opt/ && tar zxf mysql-5.5.35.tar.gz && cd mysql-5.5.35 && /usr/local/bin/cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql-5.5.35 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DEXTRA_CHARSETS=all -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DENABLED_LOCAL_INFILE=1 -DMYSQL_DATADIR=/mysqldata -DMYSQL_TCP_PORT=3306 && make && make install && chown -R mysql:mysql /usr/local/mysql-5.5.35 && ln -s /usr/local/mysql-5.5.35 /usr/local/mysql && \cp support-files/mysql.server /etc/init.d/mysqld && \cp support-files/my-small.cnf /etc/my.cnf && chmod 755 /etc/init.d/mysqld && chown mysql:mysql /etc/my.cnf && mkdir /mysqldata && chown mysql:mysql /mysqldata && /usr/local/mysql/scripts/mysql_install_db --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql --datadir=/mysqldata - unless: test -d /usr/local/mysql - require: #由於頭部已經加載了,因此這裏能夠直接引用文件裏面定義的內容 - user: mysql-user-group #多行就是這種形式用- 隔開 - pkg: pkg-init /etc/profile: file.append: - text: - export PATH=$PATH:/usr/local/mysql/bin

2.5 pcre安裝

# cat /srv/salt/prod/pcre/install.sls

Bash
pcre-install:
   file.managed:
     - name: /opt/pcre-8.40.tar.gz
     - source: salt://pcre/files/pcre-8.40.tar.gz  #由於咱們已經在master定義了prod的files根路徑,因此這裏/srv/salt/prod是根路徑 - user: root - group: root - mode: 644 cmd.run: - name: cd /opt/ && tar zxf pcre-8.40.tar.gz && cd pcre-8.40 && ./configure --prefix=/usr/local/pcre && make && make install - unless: test -d /usr/local/pcre #這裏仍是爲了防止反覆安裝 - require: - file: pcre-install #首先得把pcre.tar.gz傳過來才能安裝嘛

# salt 'tjidc_agent_192.168.1.102_youshi' state.sls saltenv='prod' pcre.install -v  #能夠找一臺測試機執行一下並加-v看一看詳細的過程。

2.6 pillar設置

# cat /srv/pillar/prod/top.sls  #要有這個top.sls文件,在裏面設置一下環境和引用哪一個文件。否則使用pillar的時候會找不到。

prod:   #咱們定義的prod環境
  '*':     #這裏應該加個過濾的,什麼樣的主機才能引用下面的service.sls,如web服務器啊啥的
     - service  #這裏指定了引用哪一個文件

# cat /srv/pillar/prod/service.sls #簡單設置了一個nginx引用的pillar數據文件,裏面能夠用if來判斷的。

nginx:   #這裏至關於字典的key是要被調用的
  port: 80  #port也是一個key,而80是值。
  user: www

2.7 nginx安裝

# cat /srv/salt/prod/nginx/install.sls 

Bash
include:
  - pcre.install
  - user.www
nginx-install:
  file.managed:
    - name: /opt/nginx-1.0.6.tar.gz
    - source: salt://nginx/files/nginx-1.0.6.tar.gz
    - user: root
    - group: root
    - mode: 644
  cmd.run:
    - name : cd /opt/ && tar zxf nginx-1.0.6.tar.gz && cd nginx-1.0.6 && ./configure --user=www --group=www --prefix=/usr/local/nginx-1.0.6 --with-http_stub_status_module --with-http_ssl_module && make && make install && echo "/usr/local/lib" >> /etc/ld.so.conf &&ln -s /usr/local/nginx-1.0.6 /usr/local/nginx - unless: test -d /usr/local/nginx #出現unless的地方都是爲了防止重複安裝 - require: - user: www-user-group - file: nginx-install

# cat /srv/salt/prod/nginx/service.sls

Bash
include:
  - nginx.install
nginx-config:
  file.managed:
    - name: /usr/local/nginx/conf/nginx.conf
    - source: salt://nginx/files/nginx.conf.jinja  #這裏就須要調用jinja模板了,根據客戶機的不一樣設置不一樣的參數 - template: jinja - user: www - group: www - mode: 644 - defaults: #這裏一共用了四個變量,第一個用戶用的是/srv/pillar/prod/service.sls文件下面ID:是nginx下面的user對應的值,也就是www。 Web_User: {{ pillar['nginx']['user'] }} Nginx_Port: {{ pillar['nginx']['port'] }} #這個就是對應的port: 80,也就是Nginx_Port被傳參80. Cpu_Num: {{ grains['num_cpus'] }} #這裏用到了grains,也就是客戶機傳送上來的本機信息中的CPU數量。 IP: {{ grains['ip_interfaces']['eth0'][0]}} #這裏必定要用[0]來取一下,萬一你獲取的是多個值,這裏就要是這種形式了:server_name ['192.168.1.112', 'fe80::20c:29ff:fea8:3398']; - unless: test -d /usr/local/nginx #防止反覆編寫nginx.conf文件 nginx-service: cmd.run: - name: /usr/local/nginx/sbin/nginx - unless: test -f /usr/local/nginx/logs/nginx.pid #防止反覆啓動nginx,上面的命令不是重啓操做,若是這裏不指定可能會報錯。

#  cat /srv/salt/prod/nginx/files/nginx.conf.jinja |grep '\{{'   #查看一下咱們上面設置的那四個變量都對應着配置文件中那四個參數

Bash
user  {{Web_User}}; worker_processes {{Cpu_Num}} ; listen {{Nginx_Port}}; server_name {{IP}};

# salt 'shidc_agent_192.168.1.111' state.sls saltenv='prod' nginx.service test=True  #能夠找一臺測試機測試執行一下看下有沒有報錯,內容太多就不截圖了。 

圖片.png

2.8 php安裝

php安裝就不記錄了,寫也是照着上面的重複的來,好多該介紹和舉例的地方上面已經介紹完畢了,php就是照着安裝過程文檔改爲salt的安裝方式。

博文來自:www.51niux.com

2.9 整體調用執行

上面已經記錄瞭如何單獨的去測試執行。編寫測試的時候卻是能夠這樣,可是實際使用要簡單就部署了,因此還須要一些設計和調用。

第一種方式(這樣作可能自動化稍弱一點人工干預的動做作一點,可是相對複雜度和對總體設計的要求要低一點):

# cat /srv/salt/prod/web_lnmp.sls  #如作成這種,每一個軟件的安裝都是一個單獨的目錄,而後寫一個sls針對不一樣的業務來調不一樣的軟件。

include:
  - mysql.install
  - pcre.install
  - nginx.install

# salt 'shidc_agent_192.168.1.111' state.sls saltenv='prod' web_lnmp  #如咱們就能夠制定某一臺機器或者以前不是說過能夠設置組還有各類篩選條件來控制讓哪些主機來按照咱們指定的的方式去操做執行。這樣就能夠實現控制多機去部署不一樣的業務。

# salt-call state.sls saltenv='prod'  web_lnmp #固然也能夠在minion機上面執行命令,也能很快的部署業務。如是mfs的部署,你就能夠把web_lnmp改爲data_hadoop。

第二種方式(這種方式首先是要對主機有一個很合理的規劃設計,而後再文件編寫方面要加一些判斷):

# cat /srv/salt/prod/top.sls

Bash
prod:
   'nodename:*_web_*_youshi': #這裏千萬不能再指'*'了。這裏是根據grain信息裏的主機名稱進行匹配,讓全部的中間帶web的以youshi結尾的去執行web_lnmp - match: grain - web_lnmp

注:由於前面已經提過了top.sls是入口文件,那麼若是這個地方你設置的是'*'而不是其餘的過濾條件,而後無論是minion端仍是master端只要一運行state.highstate,那麼不只init下面的初始化的env_init.sls會運行,連prod下面的這個web_lnmp也會運行,這就至關於全部的minion端都會部署lnmp環境,之後若是再有別的環境也是要部署進來的,那麼久很差玩了。

固然你能夠就只留下init下面的一個env_init.sls放到top.sls裏面,其餘的都用state.sls的方式手工指定,固然也是能夠的。

可是若是咱們想就是採起服務端執行:# salt '*' state.highstate test=True或者客戶端執行:salt-call state.highstate。無論是初始優化仍是我所須要該安裝的軟件該配置的文件該啓動的服務都給我作好呢?

就是我上面配置語言那種方式,前面咱們已經說到過了,關於要去執行的目標咱們有多種的匹配方式,並且支持正則表達式。咱們就在咱們要執行的sls上面加好過濾條件,設置的精準嚴格一點,這樣就不會出現一運行state.highstate,全部的節點無論是否是web服務器或者別的什麼,都把全部的軟件裝一遍。

以下面的小例子:

# salt '*' grains.items|grep nodename -A 1

圖片.png

#從上如中能夠看出我又兩種不一樣業務的主機,而後主機名是固定格式,在第二部分會標註他們的業務屬性。我上面的的top.sls簡單示例就是根據主機名中所體現的業務出行作的過濾。若是匹配不上就不會執行web_lnmp,至少能保證大部分的minion服務器除了執行初始優化之外不會再去執行其餘的管理操做。

# salt '*' state.highstate test=True  

#能夠執行測試看一下,其實在實際生產中,這裏在執行的時候也是有匹配條件的,有些主機還會作成組,因此說這種第二種方式,自動化更高,不過須要咱們在sls文件編寫方面要更加嚴格和精準,而且在top.sls裏面的匹配必定要是正確的,否則會形成有的主機明明是這個業務,可是由於沒有匹配上而形成沒有進行必要的管理配置。

# hostname   #首先在一臺web機器上面查看咱們的匹配條件設置的是否成功。
shidc_web_192.168.1.111_youshi

# salt-call state.highstate  #而後執行客戶端拉拉取top.sls並執行配置管理的操做

圖片.png

圖片.png

#內容太多就不所有截圖了,從這兩張圖就能夠看出來,192.168.1.111這臺機器由於主機名裏面有web,因此分別從base和prod裏面都同步了top.sls文件,而且不只進行了初始化的管理也進行了web_lnmp的配置。

# hostname  #在看下另一臺主機是cache業務的主機。
zwidc_cache_192.168.1.112_youshi

# salt-call state.highstate  #執行同步操做

圖片.png

圖片.png

#從上圖中能夠看出,192.168.1.112這臺機器,雖然兩個top.sls文件都同步了,可是由於其主機名所帶業務特徵裏面是cache而非web,因此只執行了初始化env_init的操做,並無執行web_lnmp的操做。

相關文章
相關標籤/搜索