背景


查看官方文档,可以很轻易知道在POD外执行某个容器内的某个命令如下:

1
kubectl exec [POD名称] -- [需要执行的命令]

演示(进入容器内并列出当前文件夹文件信息):

1
2
3
4
5
6
7
8
[root@lemonlzy data]# kubectl exec -it kom-7ff799c96d-4tkqh -- ls
'${catalina.base}' commons-daemon.jar shutdown.sh
bootstrap.jar configtest.sh startup.sh
catalina-tasks.xml daemon.sh tomcat-juli.jar
catalina.sh digest.sh tool-wrapper.sh
categoryWebService_Error.log error.log version.sh
ciphers.sh logs
commons-daemon-native.tar.gz setclasspath.sh

但是实际使用中我们通常会遇到一行命令中会使用各种管道命令,这样的话使用上述方式就不行了。

演示(显示容器内部tomcat进程信息):

1
[root@lemonlzy data]# kubectl exec -it kom-7ff799c96d-4tkqh -- ps -ef | grep tomcat

没有任何输出,实际上该命令将| grep tomcat视为kubectl exec -it kom-7ff799c96d-4tkqh -- ps -ef的结果再执行的管道命令,所以没有任何输出,且不符合我们的预期,并不能查询到容器内部tomcat的进程信息。

解决


此时应该如下操作(注意命令用单引号包围,并注意与需执行命令中的单双引号进行区分):

1
kubectl exec [POD名称] -- bash -c '[需要执行的命令]'

调整如下:

1
2
3
4
[root@lemonlzy data]# kubectl exec -it kom-7ff799c96d-4tkqh -- bash -c 'ps -ef | grep tomcat'
root 1 0 1 10:34 ? 00:02:53 /usr/local/openjdk-8/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start
root 3909 0 0 14:28 pts/0 00:00:00 bash -c ps -ef | grep tomcat
root 3916 3909 0 14:28 pts/0 00:00:00 grep tomcat

演练


编写shell脚本,仅保留pod内tomcat容器,三天内的日志信息:

1
2
3
4
5
6
7
8
9
10
#/bin/bash

POD_NAME=`(kubectl get pod | grep kom | awk '{print $1}')`
for pod in ${POD_NAME[@]};
do
kubectl exec -it $pod -- bash -c 'find /usr/local/tomcat/logs/ -mtime +2 | xargs rm -f'
kubectl exec -it $pod -- bash -c 'find /usr/local/tomcat/logs/ -name "debug.log" | xargs truncate -s 0'
kubectl exec -it $pod -- bash -c 'find /usr/local/tomcat/logs/ -name "info.log" | xargs truncate -s 0'
kubectl exec -it $pod -- bash -c 'find /usr/local/tomcat/logs/ -name "error.log" | xargs truncate -s 0'
done