kubernetes
  • Introduction
  • 安装
    • 组件端口
    • 二进制安装
    • Kubeadm
      • 安装单Master集群
      • 安装高可用集群(手动分发证书)
      • 安装高可用集群(自动上传证书)
      • 安装ETCD集群
      • 安装高可用集群(外部ETCD)
    • 启动参数解析
      • ETCD相关参数
  • 负载均衡
    • Service
    • Ingress
    • 安装MetalLB
    • Nginx-ingress-controller
      • 转发TCP与UDP服务
      • 启动参数
      • 自定义Nginx模板
  • 存储
    • Volume
    • PV与PVC
    • StorageClass
    • Local-PV
      • Static-Provisioner
    • 实践
      • Ceph-RBD
      • NFS
  • 有状态服务
    • Mysql实践
    • Operator
      • Etcd
      • Zookeeper
      • Mysql
  • 认证与授权
    • 认证
      • 实践
    • 授权
  • Helm
    • 安装
    • Chart
      • 依赖
    • Helm命令
    • Repository
  • 日志
  • 监控
    • Prometheus体系
      • Prometheus
        • 内置函数
        • 配置
          • 规则文件
        • PromQL
      • Exporter
        • Metrics
      • Grafana
        • 配置
      • AlertManager
        • 配置
    • 容器监控
      • Cadvisor的指标
      • k8s中部署Prom与Cadvisor
  • Istio
  • 资源预留
    • imagefs与nodefs
    • 总结
  • 集群联邦
    • 联邦DNS原理
    • 联邦DNS安装
    • 安装federation-v1
  • Other
    • ImagePullSecret
    • QOS
    • Apiserver的代理
    • 资源配额
Powered by GitBook
On this page
  • Pod的stdout日志
  • 日志文件挂载与采集
  • Reference

Was this helpful?

日志

PreviousRepositoryNext监控

Last updated 5 years ago

Was this helpful?

Pod的stdout日志

在讲Pod的stdout日志前,请先阅读

在k8s中,我们可以通过命令kubectl logs <pod> -c <container>命令来查看Pod标准输出日志。其实,该命令最终是通过kubelet调用docker-daemon的API,去拿容器的标准输出日志。

接下来,我们来介绍一下,如何根据Pod的名字去主机上找到它stdout日志的文件。

我们知道,一个Pod里可以编排多个容器,至少都会有两个容器(工作容器与pause容器),比如如下Pod编排了两个工作容器,一个叫nginx,一个叫tomcat

那么这个Pod被调度到节点上后,最终会由docker起三个docker容器。而Pod中的工作容器对应的docker容器的名字为:

k8s_<container>_<pod>_<namespace>_<podID>_0

比如nginx与tomcat对应到的docker容器为

k8s_nginx_peng_default_<podID>_0
k8s_tomcat_peng_default_<podID>_0

而pause容器对应的docker容器为

k8s_POD_peng_default_<podID>_0

上面的podID可以通过命令kubectl get pod peng -o yaml | grep uid来查看。

弄清楚了上述规则后,我们便可以按照以下的方式去找kubectl logs <pod> -c <container>对应的日志文件。

首先第一步,执行以下命令找到Pod所在的主机

$ kubectl get pod -o wide | grep <podName>

然后,我们去到目标主机上,我们先要找到Pod所在宿主机上对应的容器的containerID。在Pod所在主机上执行如下命令,第一列就是Pod对应的docker容器的containerID

$ docker ps --no-trunc | grep <containerName>_<podName>

得到containerID后,就可以找到日志文件/var/lib/docker/containers/<containerID>/<containerID>-json.log。

其实,kubelet还会为Pod的每个Container的stdout日志创建一个符号链接文件,指向上面的这个日志文件,其符号链接文件的路径为:

/var/log/pods/<namespace>_<podName>_<podID>/<container>/0.log

比如nginx与tomcat的stdout文件符号链接就是

/var/log/pods/default_peng_<podID>/nginx/0.log
/var/log/pods/default_peng_<podID>/tomcat/0.log

小结:在节点上查看Pod的Container的stdout日志文件的路径为/var/log/pods/<namespace>_<podName>_<podID>/<container>/0.log

日志文件挂载与采集

我们希望把Pod的日志文件挂载到宿主机上,然后通过ELK的方法采集与查询。我们希望每个Pod的日志目录挂载到宿主机的目录为/host/log/<deployment>/<pod>/。举个例子,假设Deployment在容器内的日志目录为/container/log/,该目录下有很多.log文件,那么我们希望这个Deployment的每个Pod的/container/log/目录挂载到宿主机的目录为/host/log/<deployment>/<pod>/。

为了达到上面的效果,我们在发布Deployment的时候,需要使用到kubernetes的Downward API,如下:

经过验证,上面的方法是不可行的。因为volume1是属于Pod的,而POD_NAME这个环境变量是定义在Container里面的。

另外,DownwardAPI的理念是把Pod与Container的信息注入到容器当中,两种常见的注入方式为“环境变量”与“文件”。而上面我们的需求是:kubelet在主机上自动地创建目录;与DownwardAPI的理念不一致,所以无法实现。

Reference

docker容器stdout日志
https://stackoverflow.com/questions/47931721/kubernetes-volumes-dynamic-path