簡體   English   中英

在 kubernetes 中,如何訪問 configmap 中的環境變量?

[英]In kubernetes, How to access the environment variable inside the configmap?

我有用例將 pod 名稱附加到“ jdbc_db_url ”屬性中。 位於“ common-configmap.config ”文件中。 為了實現,我遵循了以下步驟,但不幸的是無法做到。

第 1 步: common-configmap.config

# Database Properties
jdbc_auto_commit=false

jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=${POD_NAME}

第 2 步:使用以下命令將 configmap 部署到集群中

kubectl create configmap common-configmap --from-env-file /app/conf/common-configmap.config -n default

第 3 步:使用以下清單文件創建“myapp”容器和服務

部署清單文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    meta.helm.sh/release-name: master
    meta.helm.sh/release-namespace: default
  generation: 1
  labels:
    app.kubernetes.io/instance: master
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: myapp
    app.kubernetes.io/version: 4.0.0
    helm.sh/chart: myapp-4.0.0
  name: myapp
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: master
      app.kubernetes.io/name: myapp
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"
      labels:
        app.kubernetes.io/instance: master
        app.kubernetes.io/name: myapp
    spec:
      containers:
      - env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        envFrom:
        - configMapRef:
            name: myapp-configmap
        - configMapRef:
            name: common-configmap
        image: docker.com/myapp:4.0.0
        imagePullPolicy: Always
        name: myapp
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always

服務清單文件:

apiVersion: v1
kind: Service
metadata:
  annotations:
    meta.helm.sh/release-name: master
    meta.helm.sh/release-namespace: default
  labels:
    app.kubernetes.io/instance: master
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: myapp
    app.kubernetes.io/version: 4.0.0
    helm.sh/chart: myapp-4.0.0
  name: myapp
  namespace: default
spec:
  ports:
 - name: http
    port: 8080
    protocol: TCP
    targetPort: http
  selector:
    app.kubernetes.io/instance: master
    app.kubernetes.io/name: myapp
  sessionAffinity: None
  type: ClusterIP

驗證結果我進入了一個 shell 運行容器並打印了環境變量:

kubectl exec --stdin --tty myapp-d5db776b9-h25q5 -c myapp -- /bin/sh

實際結果:

# printenv

jdbc_auto_commit=false
jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=${POD_NAME}

預期結果:

jdbc_auto_commit=false
jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=myapp-d5db776b9-h25q5
  • 如何在部署/容器運行時替換 config-map 中的環境變量? 或者有沒有其他方法可以在JDBC_URL中傳遞/替換pod_name

  • 我可以知道,在這種情況下我做錯了什么?

預先感謝您的幫助。

您可以使用 init-container 來做到這一點,該容器在它和您的主容器之間具有類型為emptyDir的共享卷。

首先,編輯您的部署以添加一個emptyDir卷和一個 init 容器,並將該卷掛載到兩個容器:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    meta.helm.sh/release-name: master
    meta.helm.sh/release-namespace: default
  generation: 1
  labels:
    app.kubernetes.io/instance: master
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: myapp
    app.kubernetes.io/version: 4.0.0
    helm.sh/chart: myapp-4.0.0
  name: myapp
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: master
      app.kubernetes.io/name: myapp
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"
      labels:
        app.kubernetes.io/instance: master
        app.kubernetes.io/name: myapp
    spec:
      volumes: # emptyDir volume for the entire pod
        - name: config-volume
          emptyDir: {}
      initContainers: # an init container that will compile the env var with the pod name
      - name: config-compiler
        image: bash
        volumeMounts:
        - name: config-compiler
          mountPath: /configs
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        envFrom:
        - configMapRef:
            name: common-configmap
        command: 
        - bash
        - -c
        - 'echo $jdbc_db_url | sed "s/POD_NAME/${POD_NAME}/" > /configs/compiled.env'
      containers:
      - volumeMounts:
        - name: config-compiler
          mountPath: /configs
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        envFrom:
        - configMapRef:
            name: myapp-configmap
        - configMapRef:
            name: common-configmap
        image: docker.com/myapp:4.0.0
        imagePullPolicy: Always
        name: myapp
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always

然后,您需要確保您的實際 pod 正在讀取 env vars 文件 - 您可以通過編輯入口點腳本來添加如下一行:

source /configs/compiled.env

或將 pod 的命令編輯為如下所示:

command: [ 'source', '/configs/compiled.env;', 'previous-command' ]

以上兩者都有點hack-ish - 所以我建議做的是查看您的應用程序默認讀取哪些配置文件,並將您的編譯腳本與這些文件相匹配。

例如,如果您的應用程序從/etc/myapp/confs.d/files.env讀取 - 將您的空目錄掛載到/etc/myapp/confs.d並將初始化容器寫入files.env ,並在格式化你的應用程序(例如,如果它是一個 ini 文件而不是一個 env 文件,編譯它以便它匹配該格式)

顯然有更好的方法來編譯配置文件然后使用sed - 但如果你想(並且負擔得起)保持簡短,這是一個選擇

一種直接的方法是在部署中使用一個簡單的命令,假設 JDBC_URL 值將僅在示例 pod 中使用。 否則,您可以在自定義基礎映像中或在 init 容器中使用類似的邏輯(如果有的話)。

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    meta.helm.sh/release-name: master
    meta.helm.sh/release-namespace: default
  generation: 1
  labels:
    app.kubernetes.io/instance: master
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: myapp
    app.kubernetes.io/version: 4.0.0
    helm.sh/chart: myapp-4.0.0
  name: myapp
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: master
      app.kubernetes.io/name: myapp
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"
      labels:
        app.kubernetes.io/instance: master
        app.kubernetes.io/name: myapp
    spec:
      containers:
      - env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        envFrom:
        - configMapRef:
            name: myapp-configmap
        - configMapRef:
            name: common-configmap
        image: docker.com/myapp:4.0.0
        imagePullPolicy: Always
        name: myapp
        command: 
        - bash
        - -c
        - export JDBC_URL=$(echo $JDBC_URL | sed "s/POD_NAME/${POD_NAME}/1")
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always

請注意我插入的代碼片段:

    command: 
    - bash
    - -c
    - export JDBC_URL=$(echo $JDBC_URL | sed "s/POD_NAME/${POD_NAME}/1")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM