2 回答
TA贡献1796条经验 获得超4个赞
通常,stdin是一个只读流,用于检索写入程序的输入,而stdout是一个只写流,用于发送程序编写的输出。换句话说,没有人可以从 /dev/stdout 读取,除了 Chuck Norris。
默认情况下,stdout“指向”您的终端。但是可以stdout从您的终端重定向到一个文件。此重定向是在您的程序启动之前设置的。
通常会发生以下情况:容器运行时将容器进程重定向stdout到运行容器的节点上的文件(例如,/var/log/containers/<container-name>-<container-id>.log)。当您使用 请求日志时kubectl logs,kubectl 连接到 kube-apiserver,它连接到运行容器的节点上的 kubelet,并要求它从日志文件发回内容。
另请查看https://kubernetes.io/docs/concepts/cluster-administration/logging/,其中解释了各种日志记录设计方法。
从安全性和可移植性的角度来看,您绝对不会实施的解决方案是hostPath在您的容器中添加一个挂载,挂载/var/log/containers您的节点目录并直接访问容器日志。
一个合适的解决方案可能是更改图像的命令并将输出写入stdout容器以及容器内的本地文件。这可以使用命令来实现tee。然后您的应用程序可以从该文件中读回日志。但请记住,如果没有适当的轮换,日志文件将不断增长,直到您的容器终止。
apiVersion: v1
kind: Pod
metadata:
name: log-to-stdout-and-file
spec:
containers:
- image: bash:latest
name: log-to-stdout-and-file
command:
- bash
- -c
- '(while true; do date; sleep 10; done) | tee /tmp/test.log'
稍微复杂一点的解决方案是,将容器中的日志文件替换为使用mkfifo. 这避免了文件大小不断增长的问题(只要您的应用程序不断从命名管道文件中读取日志)。
apiVersion: v1
kind: Pod
metadata:
name: log-to-stdout-and-file
spec:
# the init container creates the fifo in an empty dir mount
initContainers:
- image: bash:latest
name: create-fifo
command:
- bash
- -c
- mkfifo /var/log/myapp/log
volumeMounts:
- name: ed
mountPath: /var/log/myapp
# the actual app uses tee to write the log to stdout and to the fifo
containers:
- image: bash:latest
name: log-to-stdout-and-fifo
command:
- bash
- -c
- '(while true; do date; sleep 10; done) | tee /var/log/myapp/log'
volumeMounts:
- name: ed
mountPath: /var/log/myapp
# this sidecar container is only for testing purposes, it reads the
# content written to the fifo (this is usually done by the app itself)
#- image: bash:latest
# name: log-reader
# command:
# - bash
# - -c
# - cat /var/log/myapp/log
# volumeMounts:
# - name: ed
# mountPath: /var/log/myapp
volumes:
- name: ed
emptyDir: {}
TA贡献1898条经验 获得超8个赞
您应该将具有主/应用容器和日志容器的多容器 pod 视为从主/应用容器读取日志的边车容器。考虑以下链接中的示例,该示例显示了如何从主容器中跟踪日志
https://learnk8s.io/sidecar-containers-patterns
- 2 回答
- 0 关注
- 352 浏览
添加回答
举报
