一、配置文件解释
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 的临时文件
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(寄存器)和定义变量变化方式多,总结了一个脑图给大家。相信总有一种能满足你的需求。
在本例中使用变量的方式见红色框框。
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"
行前行后插入
在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是幂等的
最终经过一番折腾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'"