[주의] 개인 공부를 위해 쓴 글이기 때문에 주관적인 내용은 물론, 쓰여진 정보가 틀린 것일 수도 있습니다!
피드백 부탁드립니다. (- -)(_ _) 꾸벅
애플리케이션을 배포하다 보면 환경에 따라 다른 설정 값을 사용하는 경우가 있는데, 도커 이미지는 정적이므로 각 환경에 따라 유연하게 변경할 수 없다는 단점이 있다. 대안으로 Yaml를 작성할 때 env 필드에서 환경 변수들을 작성하는 방법이 있지만 이 역시 하드코딩이다.
이러한 YMAL 파일과 설정값을 분리할 수 있는 것이 컨피그맵(Configmap)과 시크릿(Secret)이다.
컨피그맵에는 설정값을, 시크릿에는 노출이 되어서는 안 되는 비밀 값을 저장하여 사용하며, 값을 Pod로 넘기는 방법은 크게 두 가지가 있다.
- Pod의 환경 변수 (Environment variable)로 넘기는 방법
- Pod의 디스크 볼륨으로 마운트 하는 방법
[ ConfigMap ]
컨피그맵도 마찬가지로 create로 생성할 수 있고, --from-literal 파라미터로 키-값 쌍을 저장할 수 있다.
$ kubectl create configmap test --from-literal player_initial_lives=3 \
> --from-literal ui_properties_file_name=user-interface.properties
configmap/test created
$ kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 88d
test 1 6s
$ kubectl describe cm test
Name: test
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
ui_properties_file_name:
----
user-interface.properties
player_initial_lives:
----
3
위에서 명령으로 컨피그맵을 만들었고 describe 명령을 통해 Data에 어떤 키-값 쌍이 있는지 확인할 수 있다.
또한 아래와 같이 data 필드를 활용하여 YAML 파일로 정의가 가능하다. (아래는 위에서 만든 컨피그맵을 YAML로 생성해봤다.) 절취 선 밑에 내용은 뒤에 예시를 위해 추가한건데, 파일과 비슷한 키 역할을 한다.
$ kubectl get cm test -o yaml > test.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test
namespace: default
data:
player_initial_lives: "3"
ui_properties_file_name: user-interface.properties
--- 아래는 제가 추가했습니다 ---
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
위 내용의 컨피그맵을 이용하여 아래에서 Pod를 생성할 때 사용할 수 있다.
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: alpine
command: ["sleep", "3600"]
env:
# 환경 변수 정의
- name: PLAYER_INITIAL_LIVES # 이 값은 해당 컨테이너에서 사용할 환경변수 이름
valueFrom:
configMapKeyRef:
name: test # 가져올 컨피그맵 이름.
key: player_initial_lives # 가져올 키.
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: test
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# 파드 레벨에서 볼륨을 설정한 다음, 해당 파드 내의 컨테이너에 마운트한다.
- name: config
configMap:
name: test # 마운트하려는 컨피그맵의 이름을 제공한다.
# 컨피그맵에서 파일로 생성할 키 배열
items:
- key: "game.properties"
path: "game.properties"
- key: "user-interface.properties"
path: "user-interface.properties"
위에 예시처럼 컨피그맵으로 Pod에 변수를 전달하는 방법은 2가지가 있다.
- env 구문을 이용하여 전달하는 방법
- 볼륨을 마운트하여 파일로 제공하는 방법
컨테이너에 env 필드에서 valueFrom: configMapKeyRef 필드를 통해 컨피그맵 키-값 쌍을 가져올 수 있다.
해당 컨테이너의 PLATER_INITIAL_LIVES라는 환경변수는 "3"으로 지정되게 되는 의미이다.
마찬가지로 Volume을 마운트하여 키-값 쌍을 파일로도 가져올 수 있는데, 위에서는 해당 컨테이너 /config 폴더에 총 두 가지 파일 /config/game.properties 와 /config/user-interface.properties 2개의 파일이 생성된다.
items 배열을 생략하면 완전히 test라는 컨피그맵의 모든 data들을 가져와 추가적으로 /config/player_initial_lives와 /config/ui_properties_file_name 4개의 파일이 생성된다. (키 값이 파일명이 되어 버린다)
[ 컨피그맵 실습 ]
Question : Expose Configuration settings
TASK :
All operations in this question should be performed in the < your namespace > Create ConfigMap called web-config that contains the following two entries
connection_string=localhost:80
external_url=cncf.io
Run a pod called web-pod with a single container running the nginx:1.19.8-alpine image, and expose these configuration settings as environment variables inside the container.
1. 컨피그 맵 생성
$ kubectl create cm web-config --from-literal=connection_string=localhost:80 --from-literal=external_url=cncf.io
configmap/web-config created
2. Pod Yaml 파일 추출 후 수정하여 env 구문 추가
$ kubectl run web-pod --image=nginx:1.19.8-alpine --dry-run=client -o yaml > cm.yaml
$ vi cm.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: web-pod
name: web-pod
spec:
containers:
- image: nginx:1.19.8-alpine
name: web-pod
resources: {}
###########추가###########
env:
- name: connection_string
valueFrom:
configMapKeyRef:
name: web-config
key: connection_string
- name: external_url
valueFrom:
configMapKeyRef:
name: web-config
key: external_url
###########추가###########
dnsPolicy: ClusterFirst
restartPolicy: Always
3. 확인
$ kubectl exec -it web-pod -- env
connection_string=localhost:80
external_url=cncf.io
...
[ Secret ]
시크릿은 비밀번호, OAuth 토큰, SSH 키 값 같은 민감한 정보들을 저장하고 활용하는 용도로 사용한다.
이런 값들은 컨테이너에 하드코드하여 사용하는 것보다 포드가 실행될 때 시크릿을 통해서 컨테이너에 제공하는 형태이다.
$ kubectl create secret generic super-secret --from-literal=password=secretpass
secret/super-secret created
$ kubectl get secret super-secret -o yaml
apiVersion: v1
data:
password: c2VjcmV0cGFzcw== # BASE64로 인코딩 되어있다 (암호화는 아님)
kind: Secret
metadata:
creationTimestamp: "2023-04-23T04:22:36Z"
name: super-secret
namespace: default
resourceVersion: "31896"
uid: e06f7b5b-0506-439a-9e16-8db8694d16fe
type: Opaque
https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod
위에는 Secret 파일을 Pod에서 사용하는 방법에 대한 글이다.
1. 볼륨 마운트를 통한 파일로 시크릿을 갖고오는 방법
$ sudo vi pod-secret-via-file.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: pod-secrets-via-file
name: pod-secrets-via-file
spec:
containers:
- image: redis
name: pod-secrets-via-file
volumeMounts:
- name : pod-secret
mountPath: "/secrets"
volumes:
- name: pod-secret
secret:
secretName: super-secret
$ sudo kubectl apply -f pod-secret-via-file.yaml
2. 환경변수로 가져오는 방법
$ sudo vi pod-secret-via-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secrets-via-env
spec:
containers:
- name: mycontainer
image: redis
env:
- name: PASSWORD
valueFrom:
secretKeyRef:
name: super-secret
key: password
$ sudo kubectl apply -f pod-secret-via-env.yaml
시크릿은 Base64 형태로 인코딩만 할 뿐 컨피그맵과 큰 차이가 없어서 간단히 작성한다
'클라우드 > 쿠버네티스' 카테고리의 다른 글
[Kubernetes] 17. 쿠버네티스 PV(Persistent Volume) 및 PVC(Persistent Volume Claim) (4) | 2023.04.23 |
---|---|
[Kubernetes] 16. 쿠버네티스 Ingress 인그레스 (0) | 2023.04.23 |
[Kubernetes] 14. 쿠버네티스 Node에 Pod 할당하기 (nodeSelector, Affinity, nodeName) (3) | 2023.03.09 |
[Kubernetes] 13. 쿠버네티스 사이드카 패턴(Sidecar pattern) 및 실습 (3) | 2023.03.05 |
CKA 정리 및 북마크 (0) | 2023.01.16 |