fix(api): Use in-cluster K8s config for executor in K8s pods

- Try load_incluster_config() first (for pods running in K8s)
- Fallback to kubeconfig file (for local development)
- Fixes "K8s connection not available" error in production

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-23 14:45:58 +08:00
parent 182410a995
commit 6eccb45757

View File

@@ -98,6 +98,10 @@ class ActionExecutor:
"""
初始化 K8s 連線
優先順序:
1. In-cluster 配置 (ServiceAccount Token) - 用於 K8s Pod 內部
2. Kubeconfig 檔案 - 用於本地開發
Returns:
bool: 是否成功初始化
"""
@@ -106,23 +110,34 @@ class ActionExecutor:
try:
from kubernetes_asyncio import client
from kubernetes_asyncio.config import load_kube_config
from kubernetes_asyncio.config import (
load_incluster_config,
load_kube_config,
ConfigException,
)
# 檢查 kubeconfig 檔案
kubeconfig_path = Path(settings.KUBECONFIG_PATH)
if not kubeconfig_path.is_absolute():
# 相對路徑基於 apps/api/
kubeconfig_path = Path(__file__).parent.parent.parent / settings.KUBECONFIG_PATH
config_source = None
if not kubeconfig_path.exists():
logger.error(
"kubeconfig_not_found",
path=str(kubeconfig_path),
)
return False
# 優先嘗試 in-cluster 配置 (K8s Pod 內部)
try:
load_incluster_config()
config_source = "in-cluster"
logger.info("k8s_using_incluster_config")
except ConfigException:
# 不在 K8s 內部,嘗試 kubeconfig 檔案
kubeconfig_path = Path(settings.KUBECONFIG_PATH)
if not kubeconfig_path.is_absolute():
kubeconfig_path = Path(__file__).parent.parent.parent / settings.KUBECONFIG_PATH
# 載入 kubeconfig
await load_kube_config(config_file=str(kubeconfig_path))
if not kubeconfig_path.exists():
logger.error(
"kubeconfig_not_found",
path=str(kubeconfig_path),
)
return False
await load_kube_config(config_file=str(kubeconfig_path))
config_source = str(kubeconfig_path)
# 建立 API clients
self._api_client = client.ApiClient()
@@ -132,7 +147,7 @@ class ActionExecutor:
self._initialized = True
logger.info(
"k8s_executor_initialized",
kubeconfig=str(kubeconfig_path),
config_source=config_source,
)
return True