零代码入侵:Kubernetes 部署时自动注入 kube-system UID 到 .NET 9 环境变量

在现代化 .net9 应用部署阶段,零代码入侵模式,自动获取 kubernetes 命名空间 kube-systemUID,并其作为变量配置到应用。

以下是几种实现方式:

方法一:使用 InitContainer + Downward API

您可以通过 KubernetesDownward APIinitContainers 在部署时将 kube-system 命名空间的 UID 自动注入到 .NET 9 应用的环境变量中,无需编写代码。

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dotnet-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dotnet-app
  template:
    metadata:
      labels:
        app: dotnet-app
    spec:
      serviceAccountName: dotnet-app-sa
      initContainers:
      - name: get-cluster-uid
        image: bitnami/kubectl:latest
        command:
        - sh
        - -c
        - |
          # 获取 kube-system 命名空间的 UID
          KUBE_SYSTEM_UID=$(kubectl get namespace kube-system -o jsonpath='{.metadata.uid}')
          echo "kube-system UID: $KUBE_SYSTEM_UID"
          
          # 将 UID 写入共享卷
          echo "$KUBE_SYSTEM_UID" > /shared/cluster-uid
        volumeMounts:
        - name: shared-data
          mountPath: /shared
      containers:
      - name: dotnet-app
        image: your-dotnet-app:latest
        env:
        # 通过 Downward API 从卷中读取 UID
        - name: KUBE_SYSTEM_UID
          valueFrom:
            configMapKeyRef:
              name: cluster-info
              key: kube-system-uid
              optional: true
        volumeMounts:
        - name: shared-data
          mountPath: /shared
      volumes:
      - name: shared-data
        emptyDir: {}
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dotnet-app-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: dotnet-app-cluster-role
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dotnet-app-cluster-rolebinding
subjects:
- kind: ServiceAccount
  name: dotnet-app-sa
  namespace: default
roleRef:
  kind: ClusterRole
  name: dotnet-app-cluster-role
  apiGroup: rbac.authorization.k8s.io

方法二:使用 ConfigMap + Helm 或 Kustomize 预处理

1. 创建预处理脚本 (pre-deploy.sh)

bash 复制代码
#!/bin/bash

# 获取 kube-system UID
KUBE_SYSTEM_UID=$(kubectl get namespace kube-system -o jsonpath='{.metadata.uid}')

# 创建包含 UID 的 ConfigMap
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-info
data:
  kube-system-uid: "$KUBE_SYSTEM_UID"
  cluster-created: "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
EOF

echo "ConfigMap 'cluster-info' created with kube-system UID: $KUBE_SYSTEM_UID"

2. Deployment 配置

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dotnet-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dotnet-app
  template:
    metadata:
      labels:
        app: dotnet-app
    spec:
      containers:
      - name: dotnet-app
        image: your-dotnet-app:latest
        env:
        # 直接从 ConfigMap 注入环境变量
        - name: KUBE_SYSTEM_UID
          valueFrom:
            configMapKeyRef:
              name: cluster-info
              key: kube-system-uid
        - name: CLUSTER_CREATED
          valueFrom:
            configMapKeyRef:
              name: cluster-info
              key: cluster-created

方法三:使用 Kubernetes Job 预先创建 ConfigMap

1. 创建 Job 来生成 ConfigMap

yaml 复制代码
apiVersion: batch/v1
kind: Job
metadata:
  name: create-cluster-info
spec:
  ttlSecondsAfterFinished: 300  # Job 完成后 5 分钟自动清理
  template:
    spec:
      serviceAccountName: cluster-info-sa
      restartPolicy: Never
      containers:
      - name: kubectl
        image: bitnami/kubectl:latest
        command:
        - sh
        - -c
        - |
          # 等待 API Server 准备就绪
          sleep 5
          
          # 获取 kube-system UID
          KUBE_SYSTEM_UID=$(kubectl get namespace kube-system -o jsonpath='{.metadata.uid}')
          
          # 创建 ConfigMap
          kubectl create configmap cluster-info \
            --from-literal=kube-system-uid="$KUBE_SYSTEM_UID" \
            --from-literal=cluster-created="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
            --dry-run=client -o yaml | kubectl apply -f -
          
          echo "Successfully created ConfigMap with kube-system UID: $KUBE_SYSTEM_UID"
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cluster-info-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cluster-info-role
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "list"]
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create", "get", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cluster-info-rolebinding
subjects:
- kind: ServiceAccount
  name: cluster-info-sa
roleRef:
  kind: Role
  name: cluster-info-role
  apiGroup: rbac.authorization.k8s.io

2. 主应用 Deployment

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dotnet-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dotnet-app
  template:
    metadata:
      labels:
        app: dotnet-app
    spec:
      containers:
      - name: dotnet-app
        image: your-dotnet-app:latest
        env:
        # 从预先创建的 ConfigMap 注入环境变量
        - name: KUBE_SYSTEM_UID
          valueFrom:
            configMapKeyRef:
              name: cluster-info
              key: kube-system-uid
        - name: CLUSTER_CREATED
          valueFrom:
            configMapKeyRef:
              name: cluster-info
              key: cluster-created

方法四:使用 Admission Controller 或 Mutating Webhook

如果您有更高级的需求,可以创建一个 Mutating Webhook,在 Pod 创建时自动注入环境变量:

yaml 复制代码
# 简化的示例,实际实现需要编写 Webhook 服务
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: cluster-info-injector
webhooks:
- name: cluster-info.example.com
  clientConfig:
    service:
      name: webhook-service
      namespace: webhook-namespace
      path: "/mutate"
  rules:
  - operations: ["CREATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
  # 其他配置...

在 .NET 9 应用中读取环境变量

无论使用哪种方案,您的 .NET 9 应用都可以通过标准方式读取环境变量:

bash 复制代码
// Program.cs
var kubeSystemUID = Environment.GetEnvironmentVariable("KUBE_SYSTEM_UID");
Console.WriteLine($"Kube System UID: {kubeSystemUID}");

// 或者使用 IConfiguration
var kubeSystemUID = builder.Configuration["KUBE_SYSTEM_UID"];

推荐方案

对于大多数场景,我推荐使用 方法二(ConfigMap + 预处理脚本),因为:

  1. 简单可靠:不需要复杂的初始化逻辑
  2. 易于维护ConfigMap 可以独立管理和更新
  3. 性能好 :不需要在每次 Pod 启动时执行额外操作
  4. 灵活性高:可以同时注入多个集群相关信息

部署流程:

bash 复制代码
# 1. 运行预处理脚本创建 ConfigMap
./pre-deploy.sh

# 2. 部署应用
kubectl apply -f deployment.yaml

这样您的 .NET 9 应用就可以通过标准的环境变量方式获取 KUBE_SYSTEM_UID,而无需编写任何代码来获取该信息。

相关推荐
engchina9 小时前
WSL Ubuntu で Kubernetes v1.34.2 + Docker 環境を構築する
ubuntu·docker·kubernetes
Gold Steps.12 小时前
OpenEBS — 云原生 CNS 高性能存储
云原生·kubernetes·存储
永远是我的最爱18 小时前
基于.NET的小小便利店前台收银系统
前端·sqlserver·.net·visual studio
广州中轴线19 小时前
OpenStack on Kubernetes 生产部署实战(十三)
容器·kubernetes·openstack
菜鸟特工00719 小时前
javax.net.ssl.SSLPeerUnverifiedException 异常如何处理
网络协议·.net·ssl
切糕师学AI20 小时前
Helm Chart 是什么?
云原生·kubernetes·helm chart
牧马人win21 小时前
Dapper轻量级扩展库SmartDapper
.net·dapper
广州中轴线1 天前
OpenStack on Kubernetes 生产部署实战(十七)
容器·kubernetes·openstack
吹牛不交税1 天前
安装Framework4.0时提示:Microsoft .NET Framework 4 已是此操作系统的一部分。不需要安装 .NET Framework
microsoft·.net
无风听海1 天前
.NET10之ASP.NET Core的Filter管线
java·asp.net·.net