亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

運行在k8s中的容器如何讀取自己的日志?

運行在k8s中的容器如何讀取自己的日志?

Go
胡說叔叔 2023-03-07 14:04:35
我有一個設計為作為 K8s 應用程序運行的應用程序,它導入了一些運行 s 的依賴項(我不擁有)exec.Cmd。這很好,除了我想捕獲那些日志。出于某種原因,當我這樣做時:r := bufio.NewReader(os.Stdout) ... line, err := r.ReadString('\n')拋出一個錯誤,說這/dev/stdout是一個bad file descriptor. 怎么會這樣?這不是控制臺輸出的標準本地目標嗎?kubectl logs似乎能夠捕獲輸出,更具體地說,我們的中央日志轉發器也能夠捕獲它。但是嘗試從實際生成這些日志的容器內的 kube API 服務器捕獲日志似乎有點愚蠢……有沒有更好的方法來做到這一點?
查看完整描述

2 回答

?
SMILET

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: {}


查看完整回答
反對 回復 2023-03-07
?
汪汪一只貓

TA貢獻1898條經驗 獲得超8個贊

您應該將具有主/應用容器和日志容器的多容器 pod 視為從主/應用容器讀取日志的邊車容器??紤]以下鏈接中的示例,該示例顯示了如何從主容器中跟蹤日志

https://learnk8s.io/sidecar-containers-patterns


查看完整回答
反對 回復 2023-03-07
  • 2 回答
  • 0 關注
  • 281 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號