Kubernetes

在 Kubernetes 集群中將 kubectl 命令作為 cronjobs 執行會導致連接被拒絕錯誤

  • January 21, 2021

當使用來自 kubernetes(基於 EKS)集群內部kubectl的映像執行命令時,我希望該命令能夠獲取環境變數並連接到本地集群以執行命令。具體來說,我正在使用它在集群上執行一些內務處理,但容器只是出錯(並最終進入 crashBackoff 循環)。bitnami/kubectl``KUBERNETES_SERVICE_HOST``KUBERNETES_SERVICE_PORTkubernetes cronjobs

容器日誌中的錯誤消息如下:

與伺服器 localhost:8080 的連接被拒絕 - 您是否指定了正確的主機或埠?

localhost:8080特別奇怪,因為它從未使用過,也沒有在我知道的任何地方配置 - 切換到簡單的 shell 命令可以讓作業成功執行,但 kubectl 拒絕工作。執行env確認KUBE變數確實被注入並正確設置。最近唯一的變化是將這些作業移動到由terraform kubernetes cronjob 資源管理,而不是直接通過 YAML 文件管理。每個 cronjob 都與具有適當權限的服務帳戶相關聯,並且仍然在 cronjob 中正確配置。

作為參考,這裡是 cronjob 的略微編輯版本:

resource "kubernetes_cron_job" "test_cronjob" {
 provider = kubernetes.region

 metadata {
   name = "test-cronjob"
   namespace = "default"
 }
 spec {
   concurrency_policy = "Allow"
   failed_jobs_history_limit = 5
   schedule = "*/5 * * * *"
   job_template {
     metadata {}
     spec {
       backoff_limit = 2
       parallelism = 1
       completions = 1
       template {
         metadata {}
         spec {
           container {
             name    = "kubectl"
             image   = "bitnami/kubectl"
             command = ["/bin/sh", "-c", <<-EOT
                                           env && echo "test";    
                                           EOT
                                           ]            
                       }
           restart_policy = "OnFailure"
           service_account_name = "sa-test"
         }
       }
     }
   }
 }
}

此處的錯誤消息沒有多大幫助,這意味著問題在於集群的主機和埠配置錯誤,但根本問題實際上是缺少憑據,儘管配置了服務帳戶。

解釋一下,作為作業一部分的 pod 規範包含automount_service_account_token設置,該設置在 Terraform 中預設為 false。我懷疑以前使用預設YAML設置的文件管理這些文件時。true

神秘錯誤的原因是,在沒有有效憑據的情況下,kubectl似乎回退到嘗試“不安全選項”,如文件中所述,預設為 localhost 和埠 8080。它在嘗試不安全後報告錯誤選擇作為最後的手段,而不是指出缺乏憑據或給出更有用的未經授權的錯誤。經過一番探勘,這似乎實際上是底層client-go庫的一個問題,並且它已經以其他方式浮出水面 看到這個問題

要解決此問題,只需將automount_service_account_tokenback 設置為 true,如下所示:

resource "kubernetes_cron_job" "test_cronjob" {
 provider = kubernetes.region

 metadata {
   name = "test-cronjob"
   namespace = "default"
 }
 spec {
   concurrency_policy = "Allow"
   failed_jobs_history_limit = 5
   schedule = "*/5 * * * *"
   job_template {
     metadata {}
     spec {
       backoff_limit = 2
       parallelism = 1
       completions = 1
       template {
         metadata {}
         spec {
           automount_service_account_token = true
           container {
             name    = "kubectl"
             image   = "bitnami/kubectl"
             command = ["/bin/sh", "-c", <<-EOT
                                           env && echo "test";    
                                           EOT
                                           ]            
                       }
           restart_policy = "OnFailure"
           service_account_name = "sa-test"
         }
       }
     }
   }
 }
}

引用自:https://serverfault.com/questions/1050696