第三话 通过 state 模块定义主机状态

目录

写在最前:

一、撰写第一条状态

1、过程式方法完成

2、用 state 模块完成部署 Apache

二、状态配置文件的各个要素

1、规则一:缩进

2、规则二:冒号

3、规则三:短横杠

4、函数参数

三、常用的状态模块用法

写在最前:

1、file 模块

2、pkg 模块

3、service 模块

4、cron 模块

5、user 模块

6、sysctl 模块

7、pip 模块

四、使用 requisites 对状态进行排序控制

1、以安装并启动 Apache 为例

2、扩展

五、通过 state 模块部署 LAMP 环境


写在最前:

        模块的执行时过程式的,类似于一般的 shell 脚本或 Python 脚本,每次执行都会触发一次相同的功能。在大量 minion 上运行远程命令非常重要,但是对于 minion 的环境控制,使用状态进行管理更为合适。状态是对 minion 的一种描述和定义,管理人员可以不关心具体部署任务是如何完成的,只需要描述 minion 要达到什么状态,底层由 Salt 的状态模块来完成功能。

一、撰写第一条状态

比如我们想在所有 minion 主机上部署 Apache

1、过程式方法完成

// master 端
# salt '*' pkg.install "httpd"
syq-snakenx-02.lehe.com:
    ----------
    apr-util-ldap:
        ----------
        new:
            1.3.9-3.el6_0.1
        old:
    httpd:
        ----------
        new:
            2.2.15-69.el6.centos
        old:
    httpd-tools:
        ----------
        new:
            2.2.15-69.el6.centos
        old:

查看已安装软件版本的信息:

// master 端
# salt '*' pkg.version "httpd"
syq-snakenx-02.lehe.com:
    2.2.15-69.el6.centos
// minion 端
# httpd -version
Server version: Apache/2.2.15 (Unix)
Server built:   Jun 19 2018 15:45:13

上面的事我们熟悉的 pkg 模块的 install 函数,这个函数相当于在每台 minion 上执行 yum -y install httpd 命令,重复执行上面的命令相当于重复在所有 minion 上重新执行 yum -y install httpd 命令。

// minion 端
# ps -ef | grep httpd
root     60199 60195  3 11:15 ?        00:00:00 /usr/bin/python /usr/bin/yum -y install httpd
root     60223 57990  0 11:15 pts/1    00:00:00 grep httpd

2、用 state 模块完成部署 Apache

2.1 首先把之前已经安装了 httpd 软件的 minion 上的 httpd 都卸载掉:

// master 端
# salt '*' pkg.remove "httpd"
syq-snakenx-02.lehe.com:
    ----------
    httpd:
        ----------
        new:
        old:
            2.2.15-69.el6.centos

2.2 然后建立目录,建立 apache.sls 文件:

// master 端
# mkdir -p /srv/salt
# cd /srv/salt/
# vim apache.sls
install_httpd:
  pkg.installed:
    - name: httpd

2.3 执行如下命令:

// master 端
# salt '*' state.sls apache
syq-snakenx-02.lehe.com:
----------
          ID: install_httpd
    Function: pkg.installed
        Name: httpd
      Result: True
     Comment: The following packages were installed/updated: httpd
     Started: 12:03:51.606849
    Duration: 15633.867 ms
     Changes:
              ----------
              httpd:
                  ----------
                  new:
                      2.2.15-69.el6.centos
                  old:
 
Summary for syq-snakenx-02.lehe.com
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time:  15.634 s

可以看到用 state 模块部署 Apache 软件时用了一个描述性的配置文件,命令行调用了 state 模块的 SLS 函数,从返回结果上看也是成功部署了 httpd。为了看出区别,可以再执行一次:

// master 端
# salt '*' state.sls apache
syq-snakenx-02.lehe.com:
----------
          ID: install_httpd
    Function: pkg.installed
        Name: httpd
      Result: True
     Comment: Package httpd is already installed
     Started: 12:07:56.736672
    Duration: 810.75 ms
     Changes:
 
Summary for syq-snakenx-02.lehe.com
------------
Succeeded: 1
Failed:    0
------------
Total states run:     1
Total run time: 810.750 ms

        从返回结果可以看出 httpd 软件已经安装过了,如果多次运行上面的命令会得到相同的结果。这就表明了执行模块和状态模块之间主要的区别——执行模块是过程式的,而状态模块则是描述性的。当你连续几次调用同一执行模块时,实际上将执行相同的逻辑和指令。而状态模块则恰恰相反,状态模块设计为描述性的,它们只是执行必要的工作,在目标 minion 上创建根据描述文件指定的状态。

        在 salt '*' pkg.install "<package>" 命令中,我们运行了pkg.install 命令,实际上 pkg.install 只是运行了 /usr/bin/python /usr/bin/yum -y install <package> 命令。而用 state 模块时会首先判断 <package> 软件是否被安装了,如果没有安装就进行安装,如果已经安装了就什么叫都不做。

        实际上不只是安装软件这一项任务如此,所有的状态描述都遵循这个原则,只在检测扫真实状态和所需状态不同的情况下才执行功能。你可以一次又一次地运行状态,只要没有不符,就不会有任何变化。可以通过判断来让 minion 以最小的代价进入指定的状态。

二、状态配置文件的各个要素

1、规则一:缩进

YAML 使用了一个固定的缩进风格来表示数据层结构关系。Salt 需要每个缩进级别由两个空格组成,不要使用 tabs。

2、规则二:冒号

字典的 keys 在 YAML 中表现形式是一个以冒号结尾的字符串,values 的表现形式是冒号下面的每一行用一个空格隔开:

name: httpd

3、规则三:短横杠

用一个短横杠加一个空格来表示列表项。多个项使用同样的缩进级别作为同一列表的一部分。

other_packages:
  pkg.installed:
    - pkgs:
      - lrzsz
      - patch
      - htop
      - tmux
      - git
      - tig
      - subversion
      - the_silver_searcher
      - pigz
      - pxz
      - mcelog
      - pv

4、SLS 配置文件格式

<ID Declaration>:                 # 每个状态的 <ID Declaration> 字符串必须独一无二。<ID Declaration> 可以包含字母、数字、空格和下划线,只需要是一个有效的 Python 字符串,ID 尽量保持简洁明了。
  <State Module>.<Function>:        # <State Module>.<Function>: 和远程执行命令采用相同的格式,即”模块.方法“
    - name: <name>                    # 以下全是函数参数。首个参数通常是 name,然后是状态所需的其它参数。这里的不同点是所有使用的模块都是状态模块而不是普通的远程执行模块。
    - <Function Arg>
    - <Function Arg>
    - <Function Arg>
    - <Requisite Declearation>:
      - <Requisite Reference>

下面列举其它几种写法(推荐使用 inline function and names):

# standrad declaration
<ID Declaration>:
  <State Module>:
    - <Function>:
    - name: <name>
    - <Function Arg>
    - <Function Arg>
    - <Function Arg>
    - <Name>: <name>
    - <Requisite Declearation>:
      - <Requisite Reference>
      - <Requisite Reference>
  
# inline function and names
<ID Declaration>:
  <State Module>.<Function>:
    - <Function Arg>
    - <Function Arg>
    - <Function Arg>
    - <Names>:
      - <name>
      - <name>
      - <name>
    - <Requisite Declearation>:
      - <Requisite Reference>
      - <Requisite Reference>
  
# multiple states for single id
<ID Declaration>:
  <State Module>:
    - <Function>:
    - <Name>: <name>
    - <Requisite Declearation>:
      - <Requisite Reference>
  <State Module>:
    - <Function>
    - <Function Arg>
    - <Names>:
      - <name>
      - <name>
    - <Requisite Declearation>:
      - <Requisite Reference>

三、常用的状态模块用法

写在最前:

可以用 sys.list_modules 获取所有可执行模块,命令如下:

# salt '*' sys.list_modules
syq-snakenx-02.lehe.com:
    - acl
    - aliases
    - alternatives
    - apache
    - archive
    - artifactory
    - at
    - beacons
    - bigip
    - blockdev
    - bridge
    - btrfs
    - buildout
    - cloud
    - cmd
    - composer
    - config
    - consul
    - container_resource
    - cp
    - cpan
    - cron
    - data
    - defaults
    - devmap
    - dig
    - disk
    - django
    - dnsmasq
    - dnsutil
    - drbd
    - elasticsearch
    - environ
    - etcd
    - ethtool
    - event
    - extfs
    - file
    - gem
    - git
    - grains
    - group
    - grub
    - hashutil
    - hello
    - hipchat
    - hosts
    - http
    - img
    - incron
    - infoblox
    - ini
    - inspector
    - introspect
    - ip
    - iptables
    - iwtools
    - jboss7
    - jboss7_cli
    - jenkins
    - k8s
    - key
    - keyboard
    - kmod
    - locale
    - locate
    - logrotate
    - lowpkg
    - lvm
    - match
    - mine
    - minion
    - modjk
    - mongodb
    - mount
    - mysql
    - nagios_rpc
    - network
    - openstack_config
    - pagerduty
    - pagerduty_util
    - pam
    - partition
    - pecl
    - pillar
    - pip
    - pkg
    - pkg_resource
    - publish
    - pushover
    - pyenv
    - quota
    - rabbitmq
    - raid
    - random
    - random_org
    - rbenv
    - rest_sample_utils
    - ret
    - rsync
    - rvm
    - s3
    - s6
    - salt_proxy
    - saltutil
    - schedule
    - scsi
    - sdb
    - seed
    - serverdensity_device
    - service
    - shadow
    - slack
    - slsutil
    - smbios
    - smtp
    - sqlite3
    - ssh
    - state
    - status
    - supervisord
    - svn
    - sys
    - sysctl
    - sysfs
    - syslog_ng
    - system
    - telemetry
    - temp
    - test
    - timezone
    - udev
    - uptime
    - user
    - vbox_guest
    - virtualenv
    - webutil
    - x509
    - xfs
    - zenoss

类似的 sys 模块也可以获取所有的状态模块,命令如下:

# salt '*' sys.list_state_modules
syq-snakenx-02.lehe.com:
    - acl
    - alias
    - alternatives
    - apache
    - archive
    - artifactory
    - at
    - beacon
    - bigip
    - blockdev
    - buildout
    - ceph
    - chronos_job
    - cloud
    - cmd
    - composer
    - cron
    - csf
    - disk
    - elasticsearch_index
    - elasticsearch_index_template
    - environ
    - etcd
    - ethtool
    - event
    - file
    - firewall
    - gem
    - git
    - gnomedesktop
    - gpg
    - grains
    - group
    - hipchat
    - host
    - http
    - incron
    - infoblox
    - ini
    - iptables
    - jboss7
    - jenkins
    - junos
    - k8s
    - keyboard
    - kmod
    - ldap
    - locale
    - lvm
    - lxc
    - marathon_app
    - modjk
    - modjk_worker
    - module
    - mongodb_database
    - mongodb_user
    - mount
    - mysql_database
    - mysql_grants
    - mysql_query
    - mysql_user
    - netsnmp
    - netusers
    - network
    - openstack_config
    - pagerduty
    - pagerduty_escalation_policy
    - pagerduty_schedule
    - pagerduty_service
    - pagerduty_user
    - pecl
    - pip
    - pkg
    - pkgbuild
    - pkgng
    - pkgrepo
    - powerpath
    - probes
    - pushover
    - pyenv
    - quota
    - rabbitmq_cluster
    - rabbitmq_plugin
    - rabbitmq_policy
    - rabbitmq_user
    - rabbitmq_vhost
    - raid
    - rbenv
    - rsync
    - rvm
    - salt
    - salt_proxy
    - schedule
    - serverdensity_device
    - service
    - slack
    - smtp
    - sqlite3
    - ssh_auth
    - ssh_known_hosts
    - stateconf
    - status
    - supervisord
    - svn
    - sysctl
    - syslog_ng
    - telemetry_alert
    - test
    - timezone
    - tuned
    - uptime
    - user
    - vbox_guest
    - virtualenv
    - webutil
    - winrepo
    - x509
    - zenoss

通过 sys.list_state_modules 可以列举所有的状态模块,类似的,可以通过如下命令列举状态模块中的所有函数:

# salt '*' sys.list_state_functions pkg
syq-snakenx-02.lehe.com:
    - pkg.group_installed
    - pkg.installed
    - pkg.latest
    - pkg.mod_aggregate
    - pkg.mod_init
    - pkg.mod_watch
    - pkg.purged
    - pkg.removed
    - pkg.uptodate

官方文档:https://docs.saltstack.com/en/latest/salt-modindex.html

1、file 模块

2、pkg 模块

3、service 模块

4、cron 模块

5、user 模块

6、sysctl 模块

7、pip 模块

四、使用 requisites 对状态进行排序控制

如果一个主机涉及多个状态,并且状态之间有相互关联,需要在执行顺序上有先后之分,那就必须引入 requisites 来进行控制。

1、以安装并启动 Apache 为例

install_httpd:
  pkg.installed:
    - name: httpd
start_httpd:
  service.running:
    - name: httpd
    - enable: True
    - require:
      - pkg: install_httpd

这段实例中定义了两个状态,分别是安装 httpd 和启动 httpd,很明显必须先完成安装 httpd 才能启动 httpd,这里通过 require 指定 httpd running 必须在 install httpd安装完成以后才可以执行。

执行如下命令:

# salt 'syq-snakenx-02.lehe.com' state.sls apache
syq-snakenx-02.lehe.com:
----------
          ID: install_httpd
    Function: pkg.installed
        Name: httpd
      Result: True
     Comment: The following packages were installed/updated: httpd
     Started: 16:05:34.450993
    Duration: 9665.532 ms
     Changes:
              ----------
              httpd:
                  ----------
                  new:
                      2.2.15-69.el6.centos
                  old:
----------
          ID: httpd_running
    Function: service.running
        Name: httpd
      Result: True
     Comment: Service httpd has been enabled, and is running
     Started: 16:05:44.124978
    Duration: 314.615 ms
     Changes:
              ----------
              httpd:
                  True
 
Summary for syq-snakenx-02.lehe.com
------------
Succeeded: 2 (changed=2)
Failed:    0
------------
Total states run:     2
Total run time:   9.980 s

2、扩展

# vim apache.sls
install_httpd:
  pkg.installed:
    - name: httpd
start_httpd:
  service.running:
    - name: httpd
    - enable: True
    - require:
      - pkg: install_httpd
    - watch:
      - file: conf_httpd
conf_httpd:
  file.managed:
    - name: /etc/httpd/conf/httpd.conf
    - source: salt://httpd/httpd.conf
    - user: root
    - group: root
    - mode: 644

        再多加入一个 httpd.conf 文件下发的配置,需要在 master 端的/srv/salt/目录中添加一个 httpd.conf(在默认的配置中,Salt 文件服务器的 base 目录在 /srv/salt 中,httpd.conf 为 minion 的统一配置文件),这个状态对比之前的不同点在于下发了一个 httpd.conf 文件,文件下发后需要重新加载 httpd 进程才会生效。

        流程:首先必须安装 httpd 软件,然后再确保 httpd 启动,最后对比下发的文件 httpd.conf 和 minion 上已有的是否相同,如果不同就下发文件,下发文件后触发 httpd 进程重新加载新的配置文件。我们通过 watch 指定当 conf_httpd 完成后触发 start_httpd。

# salt 'syq-snakenx-02.lehe.com' state.sls apache
syq-snakenx-02.lehe.com:
----------
          ID: install_httpd
    Function: pkg.installed
        Name: httpd
      Result: True
     Comment: The following packages were installed/updated: httpd
     Started: 16:56:30.560597
    Duration: 10640.612 ms
     Changes:
              ----------
              httpd:
                  ----------
                  new:
                      2.2.15-69.el6.centos
                  old:
----------
          ID: conf_httpd
    Function: file.managed
        Name: /etc/httpd/conf/httpd.conf
      Result: True
     Comment: File /etc/httpd/conf/httpd.conf is in the correct state
     Started: 16:56:41.210936
    Duration: 140.49 ms
     Changes:
----------
          ID: start_httpd
    Function: service.running
        Name: httpd
      Result: True
     Comment: Service httpd has been enabled, and is running
     Started: 16:56:41.351753
    Duration: 332.97 ms
     Changes:
              ----------
              httpd:
                  True
 
Summary for syq-snakenx-02.lehe.com
------------
Succeeded: 3 (changed=2)
Failed:    0
------------
Total states run:     3
Total run time:  11.114 s

五、通过 state 模块部署 LAMP 环境

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的第一个问题是关于密码过期及密码复杂度、尝试登录多少次锁定登录多少秒的配置,涉及/etc/login.defs、/etc/pam.d/login、/etc/pam.d/system-auth这三个文件。要编写yaml脚本,使用ansible配置所有主机的这三个文件。 为了实现这个需求,我们可以按照以下步骤操作: 1. 编写一个yaml脚本,指定要修改的文件路径和配置项。 2. 在yaml脚本中定义变量,以便将此脚本应用于所有主机。 3. 配置ansible服务器的ssh连接,允许连接到所有目标主机。 4. 运行ansible playbook,检查配置是否被正确应用于所有主机。 以下是一个简单的yaml脚本示例,用于配置/etc/login.defs、/etc/pam.d/login、/etc/pam.d/system-auth,以包括密码过期及密码复杂度、尝试登录多少次锁定登录多少秒的配置。 ```yaml --- - name: Configure password policies hosts: all become: yes vars: # Define the password policies you want to set password_policy: PASS_MAX_DAYS: 90 PASS_MIN_DAYS: 7 PASS_WARN_AGE: 14 PASS_MIN_LEN: 12 PASS_REMEMBERED: 5 FAIL_DELAY: 3 FAILLOG_ENAB: yes FAIL_DELAY_SECS: 600 FAIL_LOCKOUT_COUNT: 3 # Define the files you want to modify login_defs: /etc/login.defs pam_login: /etc/pam.d/login pam_system_auth: /etc/pam.d/system-auth tasks: - name: Configure login.defs lineinfile: path: "{{ login_defs }}" regexp: '^{{ item.key }}\s' line: "{{ item.key }}\t{{ item.value }}" state: present with_dict: "{{ password_policy }}" notify: restart-login-service - name: Configure pam login template: src: templates/login.j2 dest: "{{ pam_login }}" notify: restart-login-service - name: Configure pam system auth template: src: templates/system-auth.j2 dest: "{{ pam_system_auth }}" notify: restart-login-service handlers: - name: restart-login-service service: name: login state: restarted ``` 在这个yaml脚本中,我们首先定义了一些变量,然后在任务中使用了这些变量。在实际操作中,您需要将这些变量替换为您自己的值。 任务中的第一个任务使用lineinfile模块来配置/etc/login.defs文件。该模块使用with_dict循环为每个密码策略设置一个新行。 第二个任务使用template模块将我们定义的login.j2模板复制到目标主机上的/etc/pam.d/login文件中。这个任务需要一个login.j2文件作为模板。您可以根据需要自定义这个模板。 第三个任务与第二个任务类似,它将我们定义的system-auth.j2模板复制到/etc/pam.d/login文件中。 最后一个区段定义了一个名为restart-login-service的处理程序。每当我们对这些文件进行更改时,这个处理程序都会重启login服务以使更改生效。 在运行此yaml脚本之前,您需要确保ansible服务器与所有目标主机都可以通过ssh进行连接,并且您已经在其中的/etc/ansible/hosts文件中配置了这些主机。 运行以下命令以运行这个yaml脚本: ```bash ansible-playbook -i hosts configure-password-policies.yaml ``` 这个命令将ansible操作与您的主机进行通信,并配置所有主机的密码策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值