CKA를 준비해보자 16일차 - Configure Environment Variables in Applications

0

CKA

목록 보기
16/43

Configure Environment Variables in Applications

docker에서 환경변수를 전달할 때는 다음과 같이 전달할 수 있다.

docker run -e APP_COLOR=pink simple-webapp-color

pod역시도 마찬가지인데, 다음과 같다.

  • pod-definition.yaml
apiVersion: v1
kind: Pod
metadata:
  name: simple-webapp-color
spec:
  containers:
  - name: simple-webapp-color
    image: simple-webapp-color
    ports:
    - containerPort: 8080
    env:
    - name: APP_COLOR
      value: pink

simple-webapp-color container의 환경변수로 APP_COLOR key로 pink value가 들어가는 것이다.

이렇게 직접 environment variable을 써주는 방법도 있지만 configmap이나 secret과 같은 kubernetes object를 활용하여 환경변수를 숨기거나 다르게하여 pod에 넘겨줄 수 있다.

  • configmap
env:
  - name: APP_COLOR
    valueFrom:
      configMapKeyRef:
  • secret
env:
  - name: APP_COLOR
    valueFrom:
      secretKeyRef:

configMapKeyRefsecretKeyRef에 각 kubernetes object 이름들을 넣어주면 되는 것이다.

ConfigMap

configmap은 key-value pair로 수많은 환경변수와 데이터들을 저장하여 pod에 제공할 수 있다.

kubectl create configmap {config-name} --from-literal={key}={value}

from-literal 뒤에 key=value형식으로 넣어주면 된다.

kubectl create configmap {config-name} --from-literal=APP_COLOR=blue

여러 개의 환경 변수를 추가하고 싶으면 --from-literal을 여러번쓰면 된다. 단, 이렇게 쓰기에는 너무 번거로우므로 file로 key-value형식의 환경변수를 제공하는 방법이 있다.

kubectl create configmap {config-name} --from-file={path-to-file}

가령 환경변수를 담은 file이름이 app_config.properties라면 다음과 같다.

kubectl create configmap app-config --from-file=app_config.properties
  • app_config.properties
APP_COLOR: blue
APP_MODE: prod

다음과 같이 key-value 형식의 환경변수를 제공해주면 configmapfile을 읽어 환경변수를 설정해주는 것이다.

위와 같이 configmap을 imperative방식으로 만드는 것 이외에 declarative방식으로 만드는 방법이 있다.

kubectl create -f ./config-map.yaml
  • config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
 APP_COLOR: blue
 APP_MODE: prod

data아래에 있는 환경변수들이 pod에 들어가게 되는 것이다.

  • view configmap
kubectl get configmaps
  • describe
kubectl describe configmaps

각 configmap에 어떤 data가 있는 지 알 수 있다.

이제 pod에 configmap을 넣어주어 환경변수를 설정해주도록 하자.

  • pod-definition.yaml
apiVersion: v1
kind: Pod
metadata:
  name: simple-webapp-color
spec:
  containers:
  - name: simple-webapp-color
    image: simple-webapp-color
    ports:
    - containerPort: 8080
    envFrom:
    - configMapRef:
        name: app-config

envFrom.configMapRef.name에 우리가 만든 configmap이름을 넣어주면 된다.

이렇게 configmap자체를 제공해주어, configmap에 있는 황경변수를 모두 pod에 설정하도록 할 수 있다.

그러나, 이러한 방법 이외에 configmap 내부의 일부 환경변수만 가져오고 싶다면 다음과 같이 쓸 수 있다.

env:
  - name: APP_COLOR
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: APP_COLOR

app-config configmap에서 APP_COLOR key를 가진 환경변수를 pod의 APP_COLOR 환경변수로 넣으라는 것이다.

이외에 volume을 통해서 넣는 방법도 있다.

volumes:
- name: app-config-volume
  configMap:
    name: app-config

app-config configmap안에 있는 모든 환경변수가 해당 pod안에 다 들어가게 된다.

Secrets

secret은 kubernetes cluster에 민감한 정보를 저장하기 위해서 사용한다. 가령, DB에 접근하는 환경변수들이나 API key과 같은 것들이 있다.

secret을 사용하는 방법은 두 단계로 이루어진다고 생각하면 된다.
1. Secret를 만들어, 중요한 정보를 넣고
2. pod에 해당 secret를 주입시켜준다. 즉, 읽을 수 있게 만들어준다.

다음의 방법으로 쉽게 secret을 만들 수 있다.

kubectl create secret generic <secret-name> --from-literal=<key>=<value>

generic은 secret의 type이다.

가령 다음과 같이 쓸 수 있다.

kubectl create secret generic app-secret -from-literal=DB_Host=mysql \
-from-literal=DB_User=root \
-from-literal=DB_Password=paswrd

app-secret secret을 만들어 DB_Host=mysql, DB_User=root, DB_Password=paswrd 정보를 저장하도록 한다.

그러나 이렇게 작성하는 방법은 매우 번잡하다. 매번 key=value를 써주는 방식은 귀찮기 때문이다. 따라서, 다음과 같이 key-value의 환경변수가 적힌 파일 이름을 넘겨 secret에 content를 채우는 방법이 있따.

kubectl create secret generic <secret-name> --from-env-file=<path-to-file>

가령 다음과 같이 쓸 수 있다.

  • temp.env
DB_Host=sql01
DB_user=root
DB_Password=password123
kubectl create secret generic app-secret --from-env-file=temp.env

temp.env 파일의 데이터를 읽어 secret를 만드는 방법이다.

다음으로는 declarative방식으로 secret을 만드는 방식이다.

  • secret-data.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
data:
  DB_Host: mysql
  DB_User: root
  DB_Password: paswrd

실행하는 방법은 다음과 같다.

kubectl create -f ./secret-data.yaml

관례상 secret 데이터는 민감한 데이터이므로 인코딩하여 데이터를 저장하는 것이 좋다. 따라서, base64를 이용하여 데이터를 인코딩하면되는데 linux에서는 다음의 명령어를 사용하면 된다.

echo -n 'target' | base64

targetbase64인코딩되어 결과로 나오게 될 것이다.

echo -n 'mysql' | base64
bXlzcWw=
echo -n 'root' | base64
cm9vdA==
echo -n 'paswrd' | base64
cGFzd3Jk

이 정보들을 secert의 data에 넣어주면 된다.

DB_Host: bXlzcWw=
DB_User: cm9vdA==
DB_Password: cGFzd3Jk

만들어진 secret을 보는 방법은 kubectl getkubectl describe를 쓰면 된다. 재밌는 것은 describe를 호출해도 데이터가 숨겨져 있다는 것이다.

만약 데이터를 보고 싶다면 kubectl get secret <secret-name> -o yaml을 사용하도록 하자.

kubectl get secret app-secret -o yaml
apiVersion: v1
data:
  DB_Host: cWwwMQ==
  DB_Password: cGFzc3dvcmQxMjM=
  DB_user: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2024-07-06T15:33:10Z"
  name: app-secret
  namespace: default
  resourceVersion: "1066"
  uid: 91b2798f-1517-4467-9b9f-cea6f209d00a
type: Opaque

인코딩된 data결과가 보일 것이다.

인코딩된 data를 디코딩하여 보여주기 위해서는 어떻게해야할까?? 이 역시도 echo를 사용하면 된다.

echo -n 'bXlzcWw=' | base64 --decode
mysql

이제 두 번째 step으로 pod에 secret를 넣어주도록 하자. 여기에는 3가지 방법이 존재하는데, 먼저 환경변수로 집어넣는 방법이다.

  • pod-definition.yaml
apiVersion: v1
kind: Pod
metadata:
  name: simple-webapp-color
spec:
  containers:
  - name: simple-webapp-color
    image: simple-webapp-color
    ports:
    - containerPort: 8080
    envFrom:
    - secretRef:
        name: app-secret

envFrom.secretRef.name에 secret이름을 적어주면 된다. secret이 환경변수로 제공된다.

다음은 secret에 있는 특정 data만 가져오는 방법이다.

  • pod-definition.yaml
apiVersion: v1
kind: Pod
metadata:
  name: simple-webapp-color
spec:
  containers:
  - name: simple-webapp-color
    image: simple-webapp-color
    ports:
    - containerPort: 8080
    env:
    - name: DB_Password
      valueFrom:
        secretKeyRef:
          name: app-secret
          key: DB_password

마지막으로 file로 secret을 가져오는 방법으로 volume을 이용한다.

apiVersion: v1
kind: Pod
metadata:
  name: simple-webapp-color
spec:
  containers:
  - name: simple-webapp-color
    image: simple-webapp-color
    ports:
    - containerPort: 8080
  volumes:
  - name: app-secret-volume
    secret:
      secretName: app-secret

secret을 volume을 통해 배포하게 된다면 pod안에 secret의 각 data들이 file로 존재하게 된다.

ls /opt/app-secret-volumes
DB_Host   DB_Password   DB_User

각 file에 value가 들어있는 것이다.

Secret에 민감한 data를 집어넣는다고 했지만, secret data는 사실 encrypted data를 넣는 곳이 아니다. encoded 데이터를 넣는 곳이다. 즉, 암호화되지 않는다는 것이다. 따라서 cluster에 접근하는 누군가라도 해당 정보를 볼 수 있다는 것이다.

secret data뿐만 아니라 secret자체도 etcd안에서 암호화되지 않는다.

0개의 댓글