【Kubernetes】最佳实践2:获取容器应用日志

作者:彭靖田

 

Kubernetes容器内运行的应用,同样有收集和获取日志的需求。通常,我们能够想到的最简单易行的方法就是重定向stdoutstderr到文件,如下所示:

./run.sh > app.log 2>&1

因此,本文以mnist_softmax.py为例,尝试通过重定向的方法获取kubernetes容器内的日志。

应用直接重定向

容器内应用的描述文件如下,不妨设为mnist.yaml,我们将日志输出到/mnt/nfs/dlks/logs/mnist.log中:

kind: Pod

apiVersion:v1

metadata:

  name: mnists-85423658-train

  labels:

    name: mnists-85423658

    type: train

spec:

  containers:

  - name: tensorflow

    image: xx.xx.xx.xx:xxxx/mnists-85423658:latest

    ports:

    - containerPort:xxxx

    command:

    - "/usr/bin/python"

    - "mnist_softmax.py"

    args:

    - "--train_steps=100"

    - "--data_url=/mnt/nfs/dlks/data/mnist-data"

    - "> /mnt/nfs/dlks/logs/mnist.log 2>&1"

    volumeMounts:

    - name: mynfs

      mountPath: /mnt/nfs/dlks

    securityContext:

        privileged: true

  volumes:

  - name: mynfs

    nfs:

      path: /

      server: xx.xx.xx.xx

  restartPolicy: Never

创建应用:

$ kubectl create -f mnist.yaml

应用运行结束后查看日志,发现没有生成日志文件:

$ cat/mnt/nfs/dlks/logs/mnist.log

cat:/mnt/nfs/dlks/logs/mnist.log: No such file or directory

调用kubectllogs方法查看容器内应用的日志:

$ kubectl logsmnists-85423658-train

···

step:95, loss=0.391469

step:96, loss=0.600153

step:97, loss=0.668893

step:98, loss=0.680492

step:99, loss=0.522318

step:100, loss=0.351204

0.8943

我们发现train_steps=100(缺省值1000)的参数确实传进了容器内的应用,但是/mnt/nfs/dlks/logs/mnist.log却没有生成。这是因为通过"> log"进行重定向的shell语法没有被/usr/bin/python识别。

因此,非shell脚本的应用直接重定向stdoutstderr到日志文件的方法是不可行的。

加壳写日志文件

如果不想上ELK这一整套日志解决方案,又想快速解决获取容器内日志的问题。还有一个好办法:为你的应用加一个壳。换句话说,不在容器中直接运行你的应用,而是运行一个外壳程序,如shell脚本,用该脚本调用真正的应用,并将应用的stdoutstderr重定向到日志文件。对于loggingdriver来说,他只会抓取shell脚本的stdoutstderr,真正的日志已经在shell运行时通过写文件的方式完成了,有效的回避了logging driver重定向带来的问题。

不妨假设外壳脚本为run.sh,内容如下:

#!/bin/bash

cd /

boot_file=$1

log_url=$2

shift 2

/usr/bin/python $boot_file$@ > $log_url2>&1

通过解析run.sh的输入参数,我们默认将前两个参数定义为应用文件和日志文件,之后的所有参数都直接输入给应用文件。因此,mnist.yaml文件更新如下:

kind: Pod

apiVersion:v1

metadata:

  name: mnists-85423658-train

  labels:

    name: mnists-85423658

    type: train

spec:

  containers:

  - name: tensorflow

    image: xx.xx.xx.xx:xxxx/mnists-85423658:latest

    ports:

    - containerPort:6666

    command:

    - "/bin/bash"

    - "/mnt/nfs/dlks/run.sh"

    args:

    - "/mnt/nfs/dlks/examples/mnist/mnist_softmax.py"

    - "/mnt/nfs/dlks/logs/mnist.log"

    - "--train_steps=1000"

    - "--data_url=/mnt/nfs/dlks/data/mnist-data"

    volumeMounts:

    - name: mynfs

      mountPath: /mnt/nfs/dlks

    securityContext:

        privileged: true

  volumes:

  - name: mynfs

    nfs:

      path: /

      server: xx.xx.xx.xx

  restartPolicy: Never

创建应用:

$ kubectl create -f mnist.yaml

应用运行结束后查看日志,成功生成日志:

$ cat/mnt/nfs/dlks/logs/mnist.log

step:995, loss=0.253211

step:996, loss=0.209607

step:997, loss=0.326302

step:998, loss=0.324855

step:999, loss=0.267151

step:1000, loss=0.141064

0.9173

综上,在kubernetes容器集群中运行的应用,可以通过加壳的方式,简单有效的获取容器内应用日志。但是,如果想要在生产环境中做到高效、可靠和稳定的日志收集,依然得采取业界通用的ELKElasticsearch + Logstash + Kibana)解决方案。

 

你可能感兴趣的:(【Kubernetes】最佳实践2:获取容器应用日志)