32

背景:Kubernetes相當於ENV文件的碼頭工人

目前我們正在使用的碼頭工人和碼頭工人撰寫了我們的服務。我們將不同環境的配置外化爲定義應用程序讀取的環境變量的文件。例如,一個prod.env文件:

ENV_VAR_ONE=Something Prod 
ENV_VAR_TWO=Something else Prod 

test.env文件:

docker run --env-file prod.env <image> 

我們的應用程序,那麼:

ENV_VAR_ONE=Something Test 
ENV_VAR_TWO=Something else Test 

因此,我們可以簡單地啓動容器時使用prod.envtest.env文件根據中定義的環境變量提取其配置0。

問題:

  1. 有(例如定義吊艙時),而不是硬編碼他們這樣的一種方式來提供Kubernetes從文件中的環境變量:
 
apiVersion: v1 
kind: Pod 
metadata: 
    labels: 
    context: docker-k8s-lab 
    name: mysql-pod 
    name: mysql-pod 
spec: 
    containers: 
    - 
     env: 
     - 
      name: MYSQL_USER 
      value: mysql 
     - 
      name: MYSQL_PASSWORD 
      value: mysql 
     - 
      name: MYSQL_DATABASE 
      value: sample 
     - 
      name: MYSQL_ROOT_PASSWORD 
      value: supersecret 
     image: "mysql:latest" 
     name: mysql 
     ports: 
     - 
      containerPort: 3306 
  1. 如果這是不可能的,那麼建議的方法是什麼?

回答

45

您可以通過使用Secrets填充的容器中的環境變量或ConfigMaps。使用祕密,當你正在使用的數據是敏感的(如密碼),並ConfigMaps當它不是。

在你波德定義指定容器應該從祕密拉值:

apiVersion: v1 
kind: Pod 
metadata: 
    labels: 
    context: docker-k8s-lab 
    name: mysql-pod 
    name: mysql-pod 
spec: 
    containers: 
    - image: "mysql:latest" 
    name: mysql 
    ports: 
    - containerPort: 3306 
    envFrom: 
     secretRef: 
     name: mysql-secret 

請注意,此語法僅在Kubernetes 1.6或更高版本可用。在早期版本的Kubernetes上,您必須手動指定每個值,例如:

env: 
    - 
    name: MYSQL_USER 
    valueFrom: 
     secretKeyRef: 
     name: mysql-secret 
     key: MYSQL_USER 

並重復每個值。

無論接近你使用,你現在可以定義兩個不同的祕密,一個用於生產,一個用於開發。

DEV-secret.yaml:

apiVersion: v1 
kind: Secret 
metadata: 
    name: mysql-secret 
type: Opaque 
data: 
    MYSQL_USER: bXlzcWwK 
    MYSQL_PASSWORD: bXlzcWwK 
    MYSQL_DATABASE: c2FtcGxlCg== 
    MYSQL_ROOT_PASSWORD: c3VwZXJzZWNyZXQK 

PROD-secret.yaml:

apiVersion: v1 
kind: Secret 
metadata: 
    name: mysql-secret 
type: Opaque 
data: 
    MYSQL_USER: am9obgo= 
    MYSQL_PASSWORD: c2VjdXJlCg== 
    MYSQL_DATABASE: cHJvZC1kYgo= 
    MYSQL_ROOT_PASSWORD: cm9vdHkK 

和部署正確密碼正確Kubernetes集羣:

kubectl config use-context dev 
kubectl create -f dev-secret.yaml 

kubectl config use-context prod 
kubectl create -f prod-secret.yaml 

現在,每當Pod啓動它將從Secret中指定的值填充其環境變量。

+3

這是我目前的方法,但是我有3個不同的豆莢使用與EnvVars相同的祕密列表。是否可以定義一次並將它們暴露給3個豆莢? –

+1

不是我所知道的。 –

+2

這將是如此之大......看起來像分配的樣板將env變成容器。 @PixelElephant – AndrewMcLagan

9

使用YAML文件爲Kubernetes定義一個容器時,沒有直接的方法來爲容器指定包含環境變量的不同文件。 Kubernetes項目表示,他們將在未來改善這一領域(見Kubernetes docs)。

與此同時,我建議使用配置工具並將pod YAML作爲模板。例如,使用Ansible您莢YAML文件看起來像:

文件my-pod.yaml.template

apiVersion: v1 
kind: Pod 
... 
spec: 
    containers: 
    ... 
    env: 
    - name: MYSQL_ROOT_PASSWORD 
     value: {{ mysql_root_pasword }} 
    ... 

然後你Ansible劇本可以指定變量mysql_root_password方便的地方,並創建資源時,例如替代它:

文件my-playbook.yaml

- hosts: my_hosts 
    vars_files: 
    - my-env-vars-{{ deploy_to }}.yaml 
    tasks: 
    - name: create pod YAML from template 
    template: src=my-pod.yaml.template dst=my-pod.yaml 
    - name: create pod in Kubernetes 
    command: kubectl create -f my-pod.yaml 

文件my-env-vars-prod.yaml

mysql_root_password: supersecret 

文件my-env-vars-test.yaml

現在您可以通過運行創建莢資源,例如:

ansible-playbook -e deploy=test my-playbook.yaml 
+4

理想情況下,你應該能夠定義一個祕密(或最終的配置對象,我們將有),並有注入作爲ENV瓦爾。不幸的是,工作尚未完成,所以我爲此投了票。 –

+0

正在進行或路線圖上這項工作? – Johan

+0

如果您使用ansible,我們有一個共同的角色部署在kubernetes上:https://github.com/ansibl8s/k8s-common。然後,準備新應用程序非常容易,請參閱示例如何在其他repo中使用它:https://github.com/ansibl8s – ant31

0

This comment展示瞭如何做到這一點W/O不必更新kubernetes配置時的環境變量列表改變。

本質: 1)製作的祕密了env.sh 2)地圖的祕密倒入容器中,音量 3)集裝箱的啓動腳本env.sh然後運行應用程序。

6

爲Kubernetes(V1.6)的新版更新讓你問什麼(年前)。

您現在可以使用envFrom像這樣在你的YAML文件:

kubectl create secret generic prod-secrets --from-file=prod/env.txt` 

凡txt文件內容:

containers: 
    - name: django 
    image: image/name 
    envFrom: 
     - secretRef: 
     name: prod-secrets 

哪裏發展,祕密是你的祕密,你可以通過創建是一個關鍵值:

DB_USER=username_here 
DB_PASSWORD=password_here 

該文檔仍然是示例的湖泊,我不得不非常努力尋找那些地方:

+0

你能分享Kubernetes文檔? –

+0

@ArtemDolobanko編輯,請記住,這仍然是新的和湖泊的文檔,你可以找到許多關於Github的問題跟蹤器的討論,如果你想了解更多的細節。 –