在 Kubernetes 集群中將 kubectl 命令作為 cronjobs 執行會導致連接被拒絕錯誤
當使用來自 kubernetes(基於 EKS)集群內部
kubectl
的映像執行命令時,我希望該命令能夠獲取環境變數並連接到本地集群以執行命令。具體來說,我正在使用它在集群上執行一些內務處理,但容器只是出錯(並最終進入 crashBackoff 循環)。bitnami/kubectl``KUBERNETES_SERVICE_HOST``KUBERNETES_SERVICE_PORT
kubernetes 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_token
back 設置為 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" } } } } } }