ansible企业级实战(Markdown)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: ansible企业级实战(Markdown)

一、配置文件解释

vim /etc/ansible/

#inventory      = /etc/ansible/hosts  #主机清单文件,默认在此目录,可根据需求修改hostlist位置
#remote_tmp     = ~/.ansible/tmp  #控制机copy要执行指令到被控制机的目录,执行完后会立即删除,所以你可能看不到。
#local_tmp      = ~/.ansible/tmp   #控制机存放指令的位置
#forks          = 5   #并行执行在五个被控制机上执行指令。
#sudo_user      = root #在被控制机上的什么用户权限下执行指令
#host_key_checking = False   (uncomment this to disable SSH key host checkink)检查对应服务器的host_key。
#默认是注释掉的,为了方便操作将此注释打开,不然每新增一个host就需要ssh连接一次才能加入到known_hosts.
#log_path = /var/log/ansible.log   记录ansible 执行的log ,建议打开。
关键参数
remote_tmp     = /home/.ansible/tmp  ansible远程主机脚本临时存放目录
local_tmp      = /home/.ansible/tmp   ansible远程主机脚本临时存放目录
这两个参数默认是关闭的,根目录一般较小的话,磁盘容易爆。根须需要更改。

该参数默认是打开的,发现在/var/log/message 下有大量的ansible-slurp log。

------------------------update 2020年4月30日17:03:23 ---------------------------------------
# prevents logging of tasks, but only on the targets, data is still logged on the master/controller
no_target_syslog = True
#no_target_syslog = False
------------------------update 2020年4月30日17:03:23 ---------------------------------------
 -k 为默认用户名 ,如果在root权限下操作要特别注意。需要注意的是
ansible运行时检查配置文件的顺序
./ansible.cfg:其次,将会检查当前目录下的ansible.cfg配置文件;
~/.ansible.cfg:再次,将会检查当前用户home目录下的.ansible.cfg配置文件;
/etc/ansible/ansible.cfg:最后,将会检查在安装Ansible时自动生成的配置文件。
自定义的配置,例如ansible-playbook -i clusters/default/hosts ..

二、实战

2.1 脚本分发 && 使用copy生成新文件

ansible webserver -m copy -a "src=/etc/yum.repos.d/epel-6.repo dest=/etc/yum.repos.d/ backup=yes"
[root@gptest01 ~]# ansible webserver -m copy -a 'content=hello\nansible\n dest=/home/a2'
10.50.10.179 | SUCCESS => {
    "changed": true, 
    "checksum": "5101b9bb5e88898cd73c7da5750e8d3c181ad08a", 
    "dest": "/home/a2", 
    "failed": false, 
    "gid": 0, 
    "group": "root", 
    "md5sum": "6d609413c2fda2642340bc904365e5ea", 
    "mode": "0644", 
    "owner": "root", 
    "size": 13, 
    "src": "/root/.ansible/tmp/ansible-tmp-1585396958.03-24651708266559/source", 
    "state": "file", 
    "uid": 0
}
^[[A10.50.10.161 | SUCCESS => {
    "changed": true, 
    "checksum": "5101b9bb5e88898cd73c7da5750e8d3c181ad08a", 
    "dest": "/home/a2", 
    "failed": false, 
    "gid": 0, 
    "group": "root", 
    "md5sum": "6d609413c2fda2642340bc904365e5ea", 
    "mode": "0644", 
    "owner": "root", 
    "size": 13, 
    "src": "/root/.ansible/tmp/ansible-tmp-1585396957.99-43733081917653/source", 
    "state": "file", 
    "uid": 0
}
[root@gptest01 ~]# ansible webserver -m command -a 'cat /home/a2'
10.50.10.179 | SUCCESS | rc=0 >>
hello
ansible
10.50.10.161 | SUCCESS | rc=0 >>
hello
ansible
     为了安全起见,将备份打开,此处还可以修改更多属性,详见 ansible-doc copy

-m 后跟模块,默认为command模块,如果使用其他模块可使用 -m 模块名来指定。

2.2 列出所有被管理主机list

[root@gptest01 ~]# ansible all --list
  hosts (15):
    10.50.10.179
    10.50.10.161
[root@gptest01 ~]# ansible webserver --list
  hosts (2):
    10.50.10.179
    10.50.10.161

2.3 基于key验证来避免每次输入密码

Linux Centos 服务器免密验证(ansible版/非root用户)

验证完之后就不需要每次输入密码验证了,也不需要 -k 此参数了。

2.3.1 机器密码不一样的解决方案

对于每个机器密码不一样的该怎么做呢?10台服务器的密码都不一样,难道输10次?如果100/1000台呢?

对于这个问题目前的处理方案是在主机inventory中。


配置/etc/ansible/hosts文件 ansible的携带密码访问

  • ansible_ssh_host 将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.
  • ansible_ssh_port ssh端口号.如果不是默认的端口号,通过此变量设置.这种可以使用 ip:端口 192.168.1.100:2222
  • ansible_ssh_user 默认的 ssh 用户名(后面ansible_su_pass 可以给root密码)
  • ansible_ssh_pass ssh 密码(这种方式并不安全,我们强烈建议使用 –ask-pass 或 SSH 密钥)
  • ansible_sudo_pass sudo 密码(这种方式并不安全,我们强烈建议使用 –ask-sudo-pass)


example:

192.168.1.11 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='jack' ansible_su_pass='root_password' 

2.4 fetch 抓取被控制端的文件

fetch 只能被控端复制单个文件。

ansible webserver -m fetch -a ‘src=/home/setest.sh dest=/home/ansibleDemo’

2.4.1 fetch 如何抓取多个文件?

先tar起来再fetch

[root@gptest01 ansibleDemo]# ansible webserver -m shell -a 'tar Jcf log.tar.xz /var/log/*.log'
 [WARNING]: Consider using the unarchive module rather than running tar.  If you need to use command because unarchive is insufficient you can add warn=False to
this command task or set command_warnings=False in ansible.cfg to get rid of this message.
10.50.10.179 | SUCCESS | rc=0 >>
tar: Removing leading `/' from member names
10.50.10.161 | SUCCESS | rc=0 >>
tar: Removing leading `/' from member names
10.50.10.163 | SUCCESS | rc=0 >>
tar: Removing leading `/' from member names
[root@gptest01 ansibleDemo]# ansible webserver -m shell -a 'ls '
10.50.10.179 | SUCCESS | rc=0 >>
anaconda-ks.cfg
ansibleDep
install.log
install.log.syslog
log.tar.xz
nohup.out
....

看到这个颜色证明 fetch成功了


通过 tar tvf不解压 查看

[root@gptest01 root]# tar tvf log.tar.xz 
-rw------- root/root     18118 2017-08-25 11:01 var/log/anaconda.ifcfg.log
-rw------- root/root     38535 2017-08-25 11:01 var/log/anaconda.log
-rw------- root/root    196997 2017-08-25 11:01 var/log/anaconda.program.log
-rw------- root/root    570708 2017-08-25 11:01 var/log/anaconda.storage.log
-rw------- root/root    113691 2017-08-25 11:01 var/log/anaconda.yum.log
-rw-r--r-- root/root     10910 2019-12-13 10:49 var/log/boot.log
...

2.5 file 模块设定文件属性

在被控制机器上建立文件或者文件夹

ansible webserver -m file -a'name=/home/a3 state=touch'

删除文件

# state = directory 建立文件夹 
ansible webserver -m file -a'name=/home/a3 state=absent'

建立软连接

ansible webserver -m file -a 'src=/etc/yum.repos.d/redhat.repo path=/home/redhat.repo.link state=link'

2.6 cron模块生成crontab脚本

2.6.1 将脚本分发到被控制机器

ansible gpservers -m cron -a 'minute=*/5 job=/home/scripts/formatVmstat_start.sh name=formatvmstat' -k
[root@P1QMSSDW08 scripts]# crontab -l
#Ansible: formatvmstat
*/5 * * * * /home/scripts/formatVmstat_start.sh

每天9点清空k8slog.

ansible k8s-all -m cron -a 'minute=0 hour=9 job=/home/clean-k8s-log.sh' 

2.6.2 禁用cron

禁用cron需要注意要指定 job 和 name,否则先前的crontab 无法删除。

ansible gpservers -m cron -a 'disabled=true job=/home/scripts/formatVmstat_start.sh name=formatvmstat' -k
[root@P1QMSSDW08 scripts]# crontab -l
#Ansible: formatvmstat
#*/5 * * * * /home/scripts/formatVmstat_start.sh

可以看到已经被注释了。

2.6.3 删除cron

ansible gpservers -m cron -a 'job=/home/scripts/formatVmstat_start.sh name=formatvmstat state=absent' -k

2.6.4 生成自动校时cron

ansible ceph-[1-9]* -i hosts -m cron -a "name='sync time' job='/usr/sbin/ntpdate ntp1.aliyun.com' minute='*/1'"

2.7 yum 包批量安装 卸载 查看

2.8 查看被控制端ip对应的hostname

有时候管理的机器太多时,想知道某台机器的ip 和hostname对应的关系,可以使用如下命令

ansible gpservers -m setup -a 'filter=ansible_hostname' -k
10.50.10.173 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "P1QMSSDW03"
    }, 
    "changed": false, 
    "failed": false
}
10.50.10.174 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "P1QMSSDW04"
    }, 
    "changed": false, 
    "failed": false
}
10.50.10.171 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "P1QMSSDW01"
    }, 
    "changed": false, 
    "failed": false
}
......

2.9 如何在ansible 中使用管道命令

有一个这样的需求,在控制机上想cd 到某个目录,然后执行某个脚本。刚开始使用shell模块,先cd 在sh始终提示无法找到shell脚本,后来使用了raw 模块,shell模块也支持管道命令,command是不支持的。才理解ansible的shell 模块是session级别的。事实上可以从执行结果中看到


Shared connection to 10.50.10 closed.。执行完了session就关了。

2.9.1 command、raw、shell、script区别

命令执行模块有四个:command、raw、shell、script。

command是默认模块,建议使用shell,功能较方便,script和shell的区别是一个执行控制端的脚本,一个执行远程端的脚本。

[root@gp01 scripts]# ansible gpservers -m raw -a "cd /home/scripts;pwd;sh /home/scripts/formatVmstat.sh"
10.50.10.** | SUCCESS | rc=0 >>
/home/scripts
ipaddr= 
Shared connection to 10.50.10.169 closed.
10.50.10.1** | SUCCESS | rc=0 >>
/home/scripts
ipaddr= 10.50.10.1**
1**
Shared connection to 10.50.1** closed.

使用管道结合sed或者单独使用sed替换crontab文件中的关键字

[root@gptest01 scripts]# ansible 10.50.10.172 -m shell -a  "find /var/spool/cron -name "root"|xargs sed -i '/vmstat_1/s@vmstat_172@vmstatGene_172@'"
10.50.10.172 | SUCCESS | rc=0 >>
[root@gptest01 scripts]# ansible 10.50.10.173 -m shell -a  "time sed -i '/vmstat_1/s@vmstat_173@vmstatGene_173@' /var/spool/cron/root"

2.10 ansible 中的判断 when

2.11 fansible中的 Liledinline

2.12 清除ansible 的临时文件

rsync实战

cachecloud-web]# ansible gweservers -m shell -a 'rsync -a --delete  /home/.ansible/tmp_1/ /home/.ansible/tmp/'
note:
/home/.ansible/tmp_1/ 为空文件夹
/home/.ansible/tmp/ 为实际要删除的文件夹

2.13 收集gp log

ansible 10.50.10.172 -m shell -a 'find /data*/gpseg*/pg_log/ -name 'gpdb-2020-08-09_000000.csv' -exec scp {} root@10.50.10.170:/redis/ \;'

此种方式貌似不生效。但是find 后面跟exec scp这个不用ansible是可以使用的。

2.14 ansible-playbook 收集greenplum log

需求:greenplum异常时,收集segment 上的pglog。

这个需求第一个想到的是用find 然后fetch ,这两个模块集合可完成。在使用find 的时候,paths 这个参数要求必须是全路径。

#] ansible-doc find
paths
        List of paths of directories to search. All paths must be fully qualified.
        (Aliases: name, path)
fetch 模块要求必须是一个文件
#] ansible-doc fetch
= src
        The file on the remote system to fetch. This `must' be a file, not a directory. Recursive fetching may be supported in a later release.
        [Default: None]

方案设计

综上最后使用了 shell + register + ansible变量 +fetch


其中register 和 ansible变量第一次接触。饶了不少弯路。


register保存的信息就执行结果中"=>"后面的字典信息,信息保存在声明的变量中。

ok: [10.50.10.172] => {
    "failed": false, 
    "find_result.stdout_lines[0]": "/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv"
}
ok: [10.50.10.176] => {
    "failed": false, 
    "find_result.stdout_lines[0]": "/datap11/gpseg20/pg_log/gpdb-2020-08-09_000000.csv"
}

Ansible通过facts组件来收集被管理节点信息,facts收集的信息是json格式的,其中任一项都可以当作变量被直接引用,如在ansible-playbook、jinja2模板中引用。


本列是通过 变量引用json数据的方式

在ansible中,任何一个模块都会返回json格式的数据,即使是错误信息都是json格式的。在ansible中,json格式的数据,其中每一项都可以通过变量来引用它。当然,引用的前提是先将其注册为变量。例如下面的playbook是将shell模块中find命令的结果注册为变量,并使用debug模块输出。可以看出输出是一个jsob 格式。


可以看到stdout_lines中的元素正式我们想要的,如何提取出这个并将其传给fetch?


用列表的索引取出,find_result.stdout_lines[0],这取出的是/datap11/gpseg20/pg_log/gpdb-2020-08-09_000000.csv。


至此该需求的思路完成。

ok: [10.50.10.176] => {
    "failed": false, 
    "msg": {
        "changed": true, 
        "cmd": "find /datap1[1-4]/gpseg*/pg_log/ -name 'gpdb-2020-08-09_000000.csv'", 
        "delta": "0:00:00.034069", 
        "end": "2020-08-10 16:24:43.854496", 
        "failed": false, 
        "rc": 0, 
        "start": "2020-08-10 16:24:43.820427", 
        "stderr": "", 
        "stderr_lines": [], 
        "stdout": "/datap11/gpseg20/pg_log/gpdb-2020-08-09_000000.csv\n/datap12/gpseg21/pg_log/gpdb-2020-08-09_000000.csv\n/datap13/gpseg22/pg_log/gpdb-2020-08-09_000000.csv\n/datap14/gpseg23/pg_log/gpdb-2020-08-09_000000.csv", 
        "stdout_lines": [
            "/datap11/gpseg20/pg_log/gpdb-2020-08-09_000000.csv", 
            "/datap12/gpseg21/pg_log/gpdb-2020-08-09_000000.csv", 
            "/datap13/gpseg22/pg_log/gpdb-2020-08-09_000000.csv", 
            "/datap14/gpseg23/pg_log/gpdb-2020-08-09_000000.csv"
        ]
    }
}
# @date 2020年8月10日16:20:48
# @desc get abnormal pg log
# @author ninesun
# @note 全量收集需要确保dest 目录空间足够
---
- hosts: 10.50.10.172
 # gather_factors: no 
# remote_usr: root
  tasks:
        - name: find pg log
          #find:
            #paths= /datap*/gpseg*/pg_log/
            #paths= /datap11/gpseg4/pg_log/
            #patterns: 'gpdb-2020-08-09_000000.csv'
          shell: find /datap1[1-4]/gpseg*/pg_log/ -name 'gpdb-2020-08-09_000000.csv'
          #shell: /sbin/ifconfig bond0|grep "inet addr"|awk -F'[:" "]+' '{print $4}'
          register: find_result
        - name: output info
          debug: msg="{{find_result}}"
        - name: output info 1
          debug: msg="{{find_result.stdout}}"
        - name : info 2
          debug: var=find_result.stdout_lines[0]
        - name: fetch log
          fetch: src={{ item }} dest=/redis/
          with_items:
                - '{{ find_result.stdout_lines[0] }}'
                - '{{ find_result.stdout_lines[1] }}'
                - '{{ find_result.stdout_lines[2] }}'
                - '{{ find_result.stdout_lines[3] }}'

执行结果

PLAY [10.50.10.172] **********************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.50.10.172]
TASK [find pg log] ***********************************************************************************************************************************************************************************************
changed: [10.50.10.172] => {"changed": true, "cmd": "find /datap1[1-4]/gpseg*/pg_log/ -name 'gpdb-2020-08-09_000000.csv'", "delta": "0:00:00.037452", "end": "2020-08-10 16:07:15.685203", "failed": false, "rc": 0, "start": "2020-08-10 16:07:15.647751", "stderr": "", "stderr_lines": [], "stdout": "/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv\n/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv\n/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv\n/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv", "stdout_lines": ["/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv", "/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv", "/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv", "/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv"]}
TASK [output info] ***********************************************************************************************************************************************************************************************
ok: [10.50.10.172] => {
    "failed": false, 
    "msg": {
        "changed": true, 
        "cmd": "find /datap1[1-4]/gpseg*/pg_log/ -name 'gpdb-2020-08-09_000000.csv'", 
        "delta": "0:00:00.037452", 
        "end": "2020-08-10 16:07:15.685203", 
        "failed": false, 
        "rc": 0, 
        "start": "2020-08-10 16:07:15.647751", 
        "stderr": "", 
        "stderr_lines": [], 
        "stdout": "/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv\n/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv\n/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv\n/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv", 
        "stdout_lines": [
            "/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv", 
            "/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv", 
            "/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv", 
            "/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv"
        ]
    }
}
TASK [output info 1] *********************************************************************************************************************************************************************************************
ok: [10.50.10.172] => {
    "failed": false, 
    "msg": "/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv\n/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv\n/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv\n/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv"
}
TASK [info 2] ****************************************************************************************************************************************************************************************************
ok: [10.50.10.172] => {
    "failed": false, 
    "find_result.stdout_lines[1]": "/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv"
}
TASK [fetch log] *************************************************************************************************************************************************************************************************
ok: [10.50.10.172] => (item=/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv) => {"changed": false, "checksum": "cc879538d8006df2742b10f63a6b173022f6cc1a", "dest": "/redis/10.50.10.172/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv", "failed": false, "file": "/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv", "item": "/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv", "md5sum": "bfef4c763e9af6dad963ade50fcb39d5"}
changed: [10.50.10.172] => (item=/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv) => {"changed": true, "checksum": "2df74ed5b87f3454a6fa0c8de64b56b6a6dc43b1", "dest": "/redis/10.50.10.172/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv", "failed": false, "item": "/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv", "md5sum": "e5b37d86c698caf69e1f6d0896854960", "remote_checksum": "2df74ed5b87f3454a6fa0c8de64b56b6a6dc43b1", "remote_md5sum": null}
changed: [10.50.10.172] => (item=/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv) => {"changed": true, "checksum": "fa96817d013a5b4eb456537e09dff0326f775442", "dest": "/redis/10.50.10.172/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv", "failed": false, "item": "/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv", "md5sum": "7690e87b4cdfbe786df18419e2677c4a", "remote_checksum": "fa96817d013a5b4eb456537e09dff0326f775442", "remote_md5sum": null}
changed: [10.50.10.172] => (item=/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv) => {"changed": true, "checksum": "4214a35e77f776988993c1fe0c18c8dc23582b0f", "dest": "/redis/10.50.10.172/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv", "failed": false, "item": "/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv", "md5sum": "91d8fc83059bb671641d141569f1a716", "remote_checksum": "4214a35e77f776988993c1fe0c18c8dc23582b0f", "remote_md5sum": null}
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.50.10.172               : ok=6    changed=2    unreachable=0    failed=0  

总结一下:ansible 变量的变种比较多,尤其是结合register(寄存器)和定义变量变化方式多,总结了一个脑图给大家。相信总有一种能满足你的需求。


在本例中使用变量的方式见红色框框。

be31f6bd46624afc941392f0c113dec8.png

2.15 lineinfile修改kubelet配置

需求:

需要修改kubelet的配置,之前都是用echo >> 或者cat >> file << EOF 来解决。

但仔细一琢磨,很可能会引发一些意想不到的问题,比如:

  • 如果需要添加的配置已经存在,echo 仍会向配置文件底部添加同样的内容
  • 如果添加配置的任务重复执行多次,则配置文件中也会多次出现重复的内容。无法做到幂等
  • 如何做到,当对应的配置已经存在,则将该配置改为期望的值;当对应的配置不存在,不做任何操作(脚本可以搞得,例如让chatgpt给你写一个)
  • 如何安全地移除指定的配置项


ansible中的lineinfile 可以完成这个需求。

下面这个ansibel的意思是

1、修改的目标文件是/etc/kubernetes/kubelet.conf

2、如果匹配到以 containerLogMaxFiles开头的文件,则替换成 containerLogMaxFiles: 5。

否则直接添加containerLogMaxFiles: 5。


对于 Ansible 而言,我们只需要关注期望达到的状态,而不用纠结为了达到该状态需要执行哪些步骤。

如 lineinfile 模块,line 指定的内容即为我们期望目标文件达到的状态。即该文件最终一定会包含一行与 line 相同的文本。

替换匹配到的行

ansible 10.50.10.33 -m lineinfile -a "dest=/etc/kubernetes/kubelet.conf regexp='^containerLogMaxFiles' line='containerLogMaxFiles: 5' state=present"

和下面的脚本是等价的,state默认为present,

ansible 10.50.10.33 -m lineinfile -a "dest=/etc/kubernetes/kubelet.conf regexp='^containerLogMaxFiles' line='containerLogMaxFiles: 5'"
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
10.50.10.33 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "backup": "",
    "changed": true,
    "msg": "line added"
}

backrefs 改变默认行为

lineinfile 默认的行为是若 line 指定的内容未存在,regexp 正则表达式也没有任何匹配,就在文件末尾添加一行 line 指定的内容。

当 backrefs 设定为 true 时,若 line 指定的内容不存在,正则表达式也没有匹配。则不做任何操作(有时候适合替换)

ansible 10.50.10.33 -m lineinfile -a "dest=/etc/kubernetes/kubelet.conf regexp='^containerLogMaxFiles' line='containerLogMaxFiles: 5' backrefs=true"

删除匹配到的行

ansible 10.50.10.33 -m lineinfile -a "dest=/etc/kubernetes/kubelet.conf regexp='^containerLogMaxFiles' line='containerLogMaxFiles: 5' absent=true"

483812d3b26e4658b44d8f9318fc43b3.png

行前行后插入

在container开头的行后加入containerLogMaxSize: 50Mi。

insertbefore则是在匹配的行前加入

ansible 10.50.10.33 -m lineinfile -"dest=/etc/kubernetes/kubelet.conf insertafter='^containerLogMaxFiles' line='containerLogMaxSize: 50Mi'"
ansible 10.50.10.33 -m lineinfile -"dest=/etc/kubernetes/kubelet.conf insertbefore='^containerLogMaxFiles' line='containerLogMaxSize: 50Mi'"

证明lineinfile是幂等的

19d1cd477e2f4d4e9163ec3e46655724.png

最终经过一番折腾kubelet log rotate的配置就ok了

ansiblee k8s-node -m lineinfile -a "dest=/etc/kubernetes/kubelet.conf regexp='^containerLogMaxFiles' line='containerLogMaxFiles: 5'"
ansible k8s-node -m lineinfile -a "dest=/etc/kubernetes/kubelet.conf rinsertbefore='^containerLogMaxFiles' line='containerLogMaxSize: 50Mi'"

参考


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
1月前
|
运维 应用服务中间件 持续交付
自动化运维的利器:Ansible实战应用
【9月更文挑战第33天】本文将带你深入理解Ansible,一个强大的自动化运维工具。我们将从基础概念开始,逐步探索其配置管理、任务调度等功能,并通过实际案例演示其在自动化部署和批量操作中的应用。文章旨在通过浅显易懂的语言和实例,为读者揭开Ansible的神秘面纱,展示其在简化运维工作中的强大能力。
156 64
|
2月前
|
运维 安全 应用服务中间件
自动化运维的利剑:Ansible实战应用
【9月更文挑战第24天】在现代IT基础设施的快速迭代与扩展中,自动化运维成为提升效率、保障稳定性的关键。本文将深入探讨Ansible这一流行的自动化工具,通过实际案例分析其如何简化日常运维任务,优化工作流程,并提高系统的可靠性和安全性。我们将从Ansible的基础概念入手,逐步深入到高级应用技巧,旨在为读者提供一套完整的Ansible应用解决方案。
|
25天前
|
运维 关系型数据库 MySQL
自动化运维工具Ansible的实战应用
【10月更文挑战第9天】在现代IT运维领域,效率和可靠性是衡量一个系统是否健康的重要指标。自动化运维工具Ansible因其简洁、易用的特性,成为了众多企业和开发者的首选。本文将通过实际案例,展示如何利用Ansible进行日常的运维任务,包括配置管理、软件部署以及批量操作等,帮助读者深入理解Ansible的应用场景及其带来的效益。
|
6月前
|
运维 监控 安全
构建高效自动化运维体系:Ansible与Docker的协同实战
【5月更文挑战第25天】 在当今快速迭代的软件发布环境中,自动化运维成为确保部署效率和可靠性的关键。本文通过深入分析Ansible和Docker技术,探索它们如何协同工作以构建一个高效的自动化运维体系。文章不仅介绍了Ansible的配置管理功能和Docker容器化的优势,还详细阐述了将两者结合的实践策略,旨在帮助读者理解并实现更智能、更灵活的基础设施管理。
|
2月前
|
运维 监控 应用服务中间件
自动化运维的新篇章:Ansible Playbooks入门与实战
【9月更文挑战第1天】在追求效率和稳定性的今天,自动化运维已经成为IT行业的必修课。本文将带你走进自动化工具Ansible的世界,通过实战案例深入理解Ansible Playbooks的编写和应用。文章不仅介绍基础概念,更通过具体代码示例,展示如何利用Ansible简化日常运维任务,提升工作效率。无论你是运维新手还是希望深化自动化技能的资深人士,本指南都将为你开启一段新的学习旅程。
|
3月前
|
运维 安全 应用服务中间件
自动化运维的利器:Ansible入门与实战网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【8月更文挑战第30天】在当今快速发展的IT时代,自动化运维已成为提升效率、减少错误的关键。本文将介绍Ansible,一种流行的自动化运维工具,通过简单易懂的语言和实际案例,带领读者从零开始掌握Ansible的使用。我们将一起探索如何利用Ansible简化日常的运维任务,实现快速部署和管理服务器,以及如何处理常见问题。无论你是运维新手还是希望提高工作效率的资深人士,这篇文章都将为你开启自动化运维的新篇章。
|
3月前
|
运维 Ubuntu 应用服务中间件
自动化运维的利器:Ansible入门与实战应用
【8月更文挑战第28天】在现代IT运维领域,自动化已成为提升效率、确保一致性和可靠性的关键。本文将引导读者了解Ansible——一种流行的自动化工具,它通过简化配置管理、部署和任务自动化流程,助力运维人员轻松应对日常挑战。从基础安装到高级用法,我们将一步步探索Ansible的魔力,并通过实际案例展示如何有效利用Ansible优化运维工作。无论你是初学者还是有经验的管理员,这篇文章都将为你提供宝贵的知识和技能,让你的运维之旅更加顺畅。
|
3月前
|
运维 Linux Apache
自动化运维工具:Ansible入门与实战
【8月更文挑战第31天】 本文将引导读者理解自动化运维的重要性,并通过介绍Ansible这一强大的自动化工具,展示如何简化和加速IT管理任务。文章不仅讲解了Ansible的基础概念,还通过实例展示了如何配置和使用Ansible进行日常的运维工作,包括部署、配置管理和任务自动化等。无论你是运维新手还是希望提高现有工作流程的效率,这篇文章都会为你提供实用的知识和技能。
|
3月前
|
运维 安全 测试技术
自动化运维的利剑:Ansible在企业级部署中的应用与挑战
本文深入探讨了Ansible,这一领先的IT自动化工具,如何在企业级部署中扮演关键角色。我们将通过实际案例分析,揭示Ansible在简化配置管理、加速应用部署和提高运维效率方面的优势。同时,文章也将不回避Ansible实施过程中可能遇到的技术挑战与限制,并提供针对性的解决策略。阅读本文后,您将获得一个全面的视角,理解Ansible在现代企业运维中不可或缺的地位,以及如何克服其面临的主要问题。
76 1
|
3月前
|
运维 Devops 应用服务中间件
自动化运维工具:Ansible的实战应用
【8月更文挑战第24天】在现代IT运维管理中,自动化已成为提升效率、减少错误的关键。本文将深入探讨Ansible,一款流行的自动化运维工具,通过实际案例展示其在配置管理、任务执行等方面的应用。我们将从Ansible的基础架构出发,逐步解析其模块和插件的使用,以及如何构建Playbooks来自动化日常任务。文章不仅提供代码示例,还着重讨论了Ansible在实际工作中的最佳实践和问题解决策略,旨在帮助读者更好地理解和运用Ansible,以实现运维工作的高效和自动化。