[configuration] Docker의 env-file에 해당하는 Kubernetes

배경:

현재 우리는 서비스에 Docker 및 Docker Compose를 사용하고 있습니다. 다양한 환경에 대한 구성을 응용 프로그램에서 읽은 환경 변수를 정의하는 파일로 구체화했습니다. 예를 들어 prod.env파일 :

ENV_VAR_ONE=Something Prod
ENV_VAR_TWO=Something else Prod

test.env파일 :

ENV_VAR_ONE=Something Test
ENV_VAR_TWO=Something else Test

따라서 컨테이너를 시작할 때 간단히 prod.env또는 test.env파일을 사용할 수 있습니다 .

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

그런 다음 응용 프로그램은에 정의 된 환경 변수를 기반으로 구성을 선택합니다 prod.env.

질문 :

  1. 다음과 같이 하드 코딩하는 대신 Kubernetes의 파일 (예 : 포드를 정의 할 때)에서 환경 변수를 제공하는 방법이 있습니까?
apiVersion : v1
종류 : 포드
메타 데이터 :
  라벨 :
    컨텍스트 : docker-k8s-lab
    이름 : mysql-pod
  이름 : mysql-pod
투기:
  용기 :
    -
      env :
        -
          이름 : MYSQL_USER
          값 : mysql
        -
          이름 : MYSQL_PASSWORD
          값 : mysql
        -
          이름 : MYSQL_DATABASE
          값 : 샘플
        -
          이름 : MYSQL_ROOT_PASSWORD
          값 : 극비
      이미지 : "mysql : latest"
      이름 : mysql
      포트 :
        -
          containerPort : 3306
  1. 이것이 가능하지 않은 경우 제안 된 접근 방식은 무엇입니까?



답변

Secrets 또는 ConfigMaps 사용을 통해 컨테이너의 환경 변수를 채울 수 있습니다 . 작업중인 데이터가 민감한 경우 (예 : 비밀번호) Secrets를 사용하고 그렇지 않은 경우 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

( env배열을 값으로 사용)

그리고 모든 값에 대해 반복합니다.

어떤 접근 방식을 사용하든 이제 프로덕션 용과 개발 용으로 하나씩 두 개의 서로 다른 비밀을 정의 할 수 있습니다.

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

이제 포드가 시작될 때마다 보안 비밀에 지정된 값으로 환경 변수를 채 웁니다.


답변

Kubernetes (v1.6)의 새로운 업데이트 통해 몇 년 전 요청한 내용을 사용할 수 있습니다.

이제 envFromyaml 파일에서 다음과 같이 사용할 수 있습니다 .

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

개발 비밀이 비밀 인 경우 다음을 통해 만들 수 있습니다.

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

txt 파일 콘텐츠가 키-값인 경우 :

DB_USER=username_here
DB_PASSWORD=password_here

문서는 여전히 예제의 호수이므로 그 장소를 정말 열심히 검색해야했습니다.


답변

YAML 파일을 사용하여 Kubernetes 용 포드를 정의 할 때 컨테이너에 대한 환경 변수를 포함하는 다른 파일을 지정하는 직접적인 방법은 없습니다. Kubernetes 프로젝트는 향후이 영역을 개선 할 것이라고 말합니다 ( Kubernetes 문서 참조 ).

그 동안 프로비저닝 도구를 사용하고 포드 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:

mysql_root_password: notsosecret

이제 다음과 같이 실행하여 포드 리소스를 만듭니다.

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


답변

이것은 나를 위해 작동합니다.

파일 env-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: env-secret
type: Opaque
stringData:
  .env: |-
    APP_NAME=Laravel
    APP_ENV=local

그리고 deployment.yaml또는pod.yaml

spec:
  ...
        volumeMounts:
        - name: foo
          mountPath: "/var/www/html/.env"
          subPath: .env
      volumes:
      - name: foo
        secret:
          secretName: env-secret
````


답변

이것은 오래된 질문이지만 시청자가 많기 때문에 답변을 추가합니다. K8 구현에서 구성을 분리하는 가장 좋은 방법은 Helm을 사용하는 것입니다. 각 Helm 패키지에는 values.yaml파일 이있을 수 있으며 Helm 차트에서 해당 값을 쉽게 사용할 수 있습니다. 다중 컴포넌트 토폴로지가있는 경우 우산 Helm 패키지를 작성할 수 있으며 상위 값 패키지도 하위 값 파일을 덮어 쓸 수 있습니다.


답변

이것은 오래된 질문이지만 미래의 초보자를 위해 제 대답을 설명하겠습니다.

kustomize configMapGenerator를 사용할 수 있습니다.

configMapGenerator:
  - name: example
    env: dev.env

포드 정의에서이 configMap / example을 참조하십시오.


답변