说明

函数链在执行时需要时刻监督系统的资源状态,想来想去用shell命令是最合适的。

内容

1 使用管道连接命令

管道符号,是unix一个很强大的功能,符号为一条竖线:"|"。
用法: command 1 | command 2 他的功能是把第一个命令command 1执行的结果作为command 2的输入传给command 2

ls | sort -nr

2 查询命令

这条命令可以参考这篇文章

docker stats

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
a188d40614e3        andy_mysql          0.04%               5.965MiB / 31.29GiB   0.02%               48.1kB / 0B         1.29GB / 12.7MB     27
7666e8af2dda        andy_mongo_1        0.36%               15.55MiB / 31.29GiB   0.05%               48.3kB / 0B         4.24GB / 766MB      32
3fb43f45a7f3        andy_mongo          0.35%               15.99MiB / 31.29GiB   0.05%               49.4kB / 1.03kB     6.01GB / 767MB      32
cb8fc79c909b        prj3_neo4j_1        0.17%               243.4MiB / 31.29GiB   0.76%               47.1kB / 3.2kB      3.84GB / 602kB      65
f2d9d2d269bc        vigorous_almeida    100.62%             10.25GiB / 31.29GiB   32.76%              1.17GB / 1.03GB     240GB / 1.02GB      166

3 awk

这个是个比较强大的工具,不过我应该只需要简单的过滤。详细的用法和介绍可以参考这篇文章

接着上一条命令, 此时改为只输出一次

docker stats --no-stream| awk '{print $1, $3}'

# 只输出第一和第三列
└─ $ docker stats | awk '{print $1, $3}'
CONTAINER NAME
a188d40614e3 0.04%
7666e8af2dda 0.34%
3fb43f45a7f3 0.34%

4 存文件/最大保留行数

tee 命令将终端内容保存到文件内(-a)是追加模式。

docker stats --no-stream| awk '{print $1, $3}' | tee -a test.log

为了方式文件过大,我想限制一下行数。另外不可以用tail -6 abc.txt > abc.txt的方法,同名文件这样会变成空。本来应该用sed文件内编辑的,但那个命令实在太麻烦,还要管道传递变量,我用一个折中的方法解决:

  • 1 每次命令的结果传输到test.log
  • 2 将test.log的文件取末尾n行给到tem.log
  • 3 将 tem.log重新覆盖test.log
# 一直保留最后三行
docker stats --no-stream  | awk '{print $1, $3}' | tee -a test.log && tail -3 test.log > tem.log && cat tem.log > test.log

---
CONTAINER NAME
a188d40614e3 0.04%
7666e8af2dda 0.38%
3fb43f45a7f3 0.40%
cb8fc79c909b 0.19%
f2d9d2d269bc 100.48%

└─ $ cat test.log
3fb43f45a7f3 0.40%
cb8fc79c909b 0.19%
f2d9d2d269bc 100.48%

5 加上时间

docker stats --no-stream  | awk '{print $1, $3 ,strftime("%Y-%m-%d %H:%M:%S",systime())}'

如果出现

awk: line 2: function strftime never defined
awk: line 2: function systime never defined

需要安装

apt-get install gawk

最好再跳过首行

└─ $ docker stats --no-stream  | awk 'NR > 1 {print $1, $3 ,strftime("%Y-%m-%d %H:%M:%S",systime())}'
a188d40614e3 0.04% 2021-06-12 12:10:16
7666e8af2dda 0.28% 2021-06-12 12:10:16
3fb43f45a7f3 0.30% 2021-06-12 12:10:16
cb8fc79c909b 0.15% 2021-06-12 12:10:16
f2d9d2d269bc 103.94% 2021-06-12 12:10:16

编辑并保存为一个sh文件

  • 1 先建立文件夹。脚本放在cron_task里面,日志存在log下面。
┌─root@m5-desktop:~
└─ $ mkdir log
┌─root@m5-desktop:~
└─ $ mkdir cron_task
┌─root@m5-desktop:~
└─ $ ls
cron_task  log
  • 2 编辑文档
#!bin/bash
# 1 读取并使用-v + OFS指定输出分隔符
docker stats --no-stream  | awk  -v OFS=',' 'NR > 1 {print $1,$2,$3,$4,$5,$6,$7 ,strftime("%Y-%m-%d %H:%M:%S",systime())}' |  \
tee -a /root/docker_running_stat.log

# 2 只取最后的10行输出到临时文件
tail -10 /root/docker_running_stat.log >/root/docker_running_stat_tem.log

# 3 将临时文件再覆盖源文件
cat /root/docker_running_stat_tem.log > /root/docker_running_stat.log

5 cron任务

cron是一个Linux下的后台进程,用来定期的执行一些任务。

关于编辑器

select-editor

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed
# 我习惯了用vim选2
Choose 1-4 [1]: 2

查看cron的状态

ps -ef | grep cron
---
└─ $ ps -ef | grep cron
root       721     1  0 6月07 ?       00:00:00 /usr/sbin/cron -f  <----- 应该是在运行的
root     25521 21284  0 12:14 pts/1    00:00:00 grep --color=auto cron

可以通过命令控制启停

service cron start/restart/stop

编辑任务,这部分可以参考这篇文章

crontab -e
*  *  * *  *   command
分 时 天 月 周   命令

似乎只能做到按分钟的定义,还有一些通过sleep + 循环的方法可以按秒执行,但是那样有点费事。监控资源我觉得到分就差不多了。

...
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command


*/1 * * * *  /root/cron_task/docker_stat_query.sh > /dev/null 2>&1
~
~
~

总结

差不多就这样了:

  • 1 宿主机周期性的执行系统资源的查询,将结果挂在/root/log 下面
  • 2 容器挂载这个目录,就可以获得对应的信息了