本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

使用容器進行配置管理

編者按:這是我們關於Kubernetes 1.2新功能的系列深度文章中的第七篇。

編寫應用程式時的一個良好實踐是將應用程式程式碼與配置分離。我們希望讓應用程式作者能夠輕鬆地在Kubernetes中採用這種模式。雖然Secrets API允許將憑據和金鑰等資訊與應用程式分離,但過去沒有用於普通非秘密配置的物件。在Kubernetes 1.2中,我們添加了一個名為ConfigMap的新API資源來處理這種型別的配置資料。

ConfigMap基礎知識

ConfigMap API在概念上很簡單。從資料角度來看,ConfigMap型別只是一組鍵值對。應用程式的配置方式不同,因此我們需要靈活地讓使用者儲存和使用配置資料。在Pod中,有三種方式使用ConfigMap

  • 命令列引數
  • 環境變數
  • 卷中的檔案

這些不同的方法適用於不同的資料建模方式。為了儘可能靈活,我們將ConfigMap設計為可以儲存細粒度和/或粗粒度資料。此外,由於應用程式從環境變數和包含配置資料的檔案中讀取配置設定,我們構建ConfigMap以支援這兩種訪問方法。讓我們看一個包含兩種型別配置的ConfigMap示例

apiVersion: v1

kind: ConfigMap

metadata:

  Name: example-configmap

data:

  # property-like keys

  game-properties-file-name: game.properties

  ui-properties-file-name: ui.properties

  # file-like keys

  game.properties: |

    enemies=aliens

    lives=3

    enemies.cheat=true

    enemies.cheat.level=noGoodRotten

    secret.code.passphrase=UUDDLRLRBABAS

    secret.code.allowed=true

    secret.code.lives=30

  ui.properties: |

    color.good=purple

    color.bad=yellow

    allow.textmode=true

    how.nice.to.look=fairlyNice

使用過Secrets的使用者會發現開始使用ConfigMap很容易——它們非常相似。這些API的一個主要區別是,Secret值以位元組陣列的形式儲存,以支援儲存SSH金鑰等二進位制檔案。在JSON和YAML中,位元組陣列被序列化為base64編碼的字串。這意味著從序列化形式中檢視Secret的內容並不容易。由於ConfigMap旨在僅儲存配置資訊而非二進位制檔案,因此值以字串形式儲存,因此在序列化形式中是可讀的。

我們希望建立ConfigMaps能夠像在其中儲存資料一樣靈活。為了建立ConfigMap物件,我們添加了一個名為kubectl create configmap的kubectl命令,它提供了三種不同的方式來指定鍵值對

  • 指定字面鍵和值
  • 指定單個檔案
  • 指定目錄為每個檔案建立鍵

這些不同的選項可以在單個命令中混合、搭配和重複使用

    $ kubectl create configmap my-config \

    --from-literal=literal-key=literal-value \

    --from-file=ui.properties \
    --from=file=path/to/config/dir

使用ConfigMaps很簡單,對於Secrets使用者來說也會很熟悉。以下是一個Deployment的示例,它使用上面的ConfigMap來執行一個假想的遊戲伺服器

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: configmap-example-deployment

  labels:

    name: configmap-example-deployment

spec:

  replicas: 1

  selector:

    matchLabels:

      name: configmap-example

  template:

    metadata:

      labels:

        name: configmap-example

    spec:

      containers:

      - name: game-container

        image: imaginarygame

        command: ["game-server", "--config-dir=/etc/game/cfg"]

        env:

        # consume the property-like keys in environment variables

        - name: GAME\_PROPERTIES\_NAME

          valueFrom:

            configMapKeyRef:

              name: example-configmap

              key: game-properties-file-name

        - name: UI\_PROPERTIES\_NAME

          valueFrom:

            configMapKeyRef:

              name: example-configmap

              key: ui-properties-file-name

        volumeMounts:

        - name: config-volume

          mountPath: /etc/game

      volumes:

      # consume the file-like keys of the configmap via volume plugin

      - name: config-volume

        configMap:

          name: example-configmap

          items:

          - key: ui.properties

            path: cfg/ui.properties

         - key: game.properties

           path: cfg/game.properties
      restartPolicy: Never

在上述示例中,Deployment透過兩種不同的可用機制使用ConfigMap的鍵。ConfigMap的屬性式鍵被用作Deployment模板中單個容器的環境變數,而檔案式鍵則填充一個卷。有關更多詳細資訊,請參閱ConfigMap文件

我們希望這些基本原語易於使用,並期待看到人們使用ConfigMap構建出什麼。感謝為該功能提供反饋的社群成員。還要特別感謝Tamer Tas,他對ConfigMap的提案和實現做出了巨大貢獻。

如果您對Kubernetes和配置感興趣,您會想要參與

當然,有關該專案的更多資訊,請訪問www.kubernetes.io並在Twitter上關注我們@Kubernetesio