Docker의 env-file에 해당하는 Kubernetes


84

배경:

현재 우리는 서비스에 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. 이것이 가능하지 않은 경우 제안 된 접근 방식은 무엇입니까?

나는 또한 이와 같은 것을 찾고 있습니다. Secret또는 ConfigMap리소스는 일시적이고 테스트에 사용하기 때문에 만들고 싶지 않습니다 . k8s 클러스터에 제한된 권한이 있습니다. Secret리소스 를 생성 할 수는 있지만 이미 생성 된 후에는 삭제할 수 없습니다.
alltej

답변:


114

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

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


5
이것이 나의 현재 접근 방식이지만 EnvVars로 노출 된 동일한 비밀 목록을 사용하는 3 개의 다른 포드가 있습니다. 한 번 정의하고 3 개의 포드에 노출 할 수 있습니까?
jävi

1
내가 아는 한에서는 아니다.
Pixel Elephant

2
그것은 너무 좋을 것입니다 ... 환경 변수를 컨테이너로 가져 오기 위해 상용구를 할당 한 것 같습니다. @PixelElephant
AndrewMcLagan

@ jävi 복제 컨트롤러를 의미합니까? 그럼에도 불구하고 비밀 / 구성 맵을 단일 pod / RC / 배포에 바인딩하는 것은 없습니다. 위와 같이 매니페스트에 정의되어 있으며 원하는만큼 마운트 할 수 있습니다.
aronchick

@aronchick 나는 그들이이 기능을 찾고 있다고 생각합니다 : github.com/kubernetes/kubernetes/issues/26299 곧 출시 될 것 같습니다. 기능이 출시 된 Kubernetes 버전에 있으면 답변을 업데이트하겠습니다.
Pixel Elephant

36

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

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


이에 대한 Kubernetes 문서를 공유 할 수 있습니까?
Artem Dolobanko

@ArtemDolobanko Edited, 이것은 여전히 ​​새로운 문서이며 문서의 호수라는 것을 명심하십시오. 더 자세한 정보를 원하면 Github의 이슈 트래커에서 많은 토론을 찾을 수 있습니다.
또는 Duan

@Or 두안 어떻게 ENV 사용하여 고정 표시기의 이미지에 버전 번호를 통과 할 것
DEV-스택

텍스트 파일을 어떤 위치에 마운트해야하고 앱이 거기에서 자동으로 env를 생성한다면 어떻게
Tara Prasad Gurung

2
이것이되어야 --from-env-file합니까? 사용하면 --from-file파일 내용과 함께 하나의 키 (입력 파일 이름을 따서 명명)가 생성됩니다. 를 사용 --from-env-file하면 파일 내부의 키가 비밀로 확장됩니다. 자세한 내용은 이 Google 문서 를 참조하세요 .
David

11

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

4
이상적으로는 Secret (또는 우리가 갖게 될 최종 구성 객체)을 정의하고 env vars로 주입 할 수 있어야합니다. 불행히도 그 일은 아직 끝나지 않았기 때문에 나는 이것을 투표하고 있습니다.
Tim Hockin 2015

ansible을 사용하는 경우 kubernetes에 배포 할 공통 역할이 있습니다 : github.com/ansibl8s/k8s-common . 그런 다음 새로운 애플리케이션을 준비하는 것은 매우 쉽습니다. 다른 저장소에서 사용하는 방법의 예를 참조하십시오. github.com/ansibl8s
ant31

나는 우리가 ENV의 비밀을 할 것입니다 바라고은 1.2 바르
폴 Morie

1
템플릿에 대한 제안이 있습니다. github.com/kubernetes/kubernetes/blob/master/docs/proposals/…
luebken

kubectl-run20 개의 env 변수를 전달하는 데 사용 하려면 어떻게해야합니까 ??? 12factor를 더 쉽게하지 않는 이유는 무엇입니까 ??
holms

3

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

파일 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
````

나는 버전 증가 할 때마다 deployment.yaml 업데이트 할 필요가 없습니다 그래서 내가 어떻게 고정 표시기 이미지를 ENV를 사용합니다
DEV-스택

0

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


0

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

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

configMapGenerator:
  - name: example
    env: dev.env

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.