ConfigMap 이란?
애플리케이션에서 필요한 환경 변수나 설정 파일들을 관리 할 때 사용되는 리소스 입니다.
ConfigMap을 사용하면, 애플리케이션 배포 시 환경 설정이나 구성 값을 쉽게 적용하고 수정할 수 있습니다.
Secret 이란?
ConfigMap 처럼 애플리케이션에서 필요한 환경 변수나 설정 파일들을
관리 할 때 사용되는 리소스 이지만, 민감한 정보를 안전하게 관리하기 위해
사용되는 리소스 입니다.기본적으로 Base64로 인코딩 됩니다.
또한, Secret은 Secret에 접근하는 POD가 있는 노드에서만 생성이 됩니다.
노드 자체적으로도 시크릿을 항상 메모리에만 저장하고
물리 저장소에 기록되지 않도록 합니다.
ConfigMap | Secret |
민감하지 않고 일반 설정 데이터는 ConfigMap을 사용 | 민감한 데이터는 Secret을 사용하여 키 아래에 보관해서 사용 |
실습을 통해 좀 더 자세히 알아보겠습니다.
ConfigMap
apiVersion: v1 kind: ConfigMap metadata: name: fortune-config data: sleep-interval: "25"
- ConfigMap에서 변수 지정은 data 아래에 key:value 형태로 지정해줍니다.
- 위 yaml에서는 sleep-interval:25 변수 지정을 해주었습니다.
이제 생성한 ConfigMap을 활용하여 POD를 생성해보겠습니다.
POD
apiVersion: v1 kind: Pod metadata: name: fortune-args-from-configmap spec: containers: - image: luksa/fortune:args env: - name: INTERVAL # 1번 valueFrom: configMapKeyRef: name: fortune-config # 2번 key: sleep-interval # 3번 args: ["$(INTERVAL)"] # 4번 name: html-generator volumeMounts: - name: html mountPath: /var/htdocs - image: nginx:alpine name: web-server volumeMounts: - name: html mountPath: /usr/share/nginx/html readOnly: true ports: - containerPort: 80 protocol: TCP volumes: - name: html emptyDir: {}
- 1번: luksa/fortune:args 이미지로 생성될 컨테이너 내에서 사용될 환경 변수 이름 지정
- 2번: 앞서 생성한 ConfigMap의 이름 지정
- 3번: 앞서 생성한 ConfigMap의 변수 key 값 지정
- 4번: 컨테이너 내에서 변수가 사용되도록 args에서 spec.container.env.name 값으로 지정
즉, ConfigMap에 있는 sleep-interval 값을 INTERVAL 환경 변수에 넣고, 그 변수를 args에서 사용할 수 있도록 설정
그래서 Pod 에 접속하여 변수를 확인하면,
앞서 ConfigMap에서 설정한 interval 값 25가 설정이 되어 있습니다.
이젠 ConfigMap 볼륨에 대해 알아보겠습니다.
앞서 확인한 것 처럼 간단한 환경 변수나 설정 값들은 ConfigMap 리소스로
사용을 하면 되지만,
예를 들어, nginx.conf, prometheus.yml 등의 대형 설정 파일들을
ConfigMap으로 사용하려면 ConfigMap 볼륨을 사용해야 한다.
실습을 통해 좀 더 자세히 알아보겠습니다.
ConfigMap 볼륨으로 사용될 환경 변수 값을 정의한 파일과 nginx.conf 파일을 생성 해줍니다.
# mkdir configmap-files # cd configmap-files # vi nginx.conf ------------------------------------------------ server { listen 80; server_name www.kubia-example.com; gzip on; gzip_types text/plain application/xml; location / { root /usr/share/nginx/html; index index.html index.htm; } } ------------------------------------------------ # vi sleep-interval (환경 변수 값을 정의한 파일) ------------------------------------------------ 25 ------------------------------------------------
그리고 해당 폴더를 configMap으로 정의해주겠습니다.
# kubectl create configmap fortune-config --from-file configmap-files
생성된 ConfigMap을 보겠습니다.
# kubectl get configmap fortune-config -o yaml
그리고 ConfigMap을 볼륨으로 mount 해서 사용하는 POD를 생성 해줍니다.
apiVersion: v1 kind: Pod metadata: name: fortune-configmap-volume spec: containers: - image: luksa/fortune:env env: - name: INTERVAL # 1번 valueFrom: configMapKeyRef: name: fortune-config # 2번 key: sleep-interval # 3번 name: html-generator volumeMounts: - name: html # 4번 mountPath: /var/htdocs - image: nginx:alpine name: web-server volumeMounts: - name: html # 4번 mountPath: /usr/share/nginx/html readOnly: true - name: config # 5번 mountPath: /etc/nginx/conf.d readOnly: true - name: config # 5번 mountPath: /tmp/whole-fortune-config-volume readOnly: true ports: - containerPort: 80 name: http protocol: TCP volumes: - name: html # 4번 emptyDir: {} # - name: config # 5번 configMap: name: fortune-config
- 1번: html-generator 컨테이너에서 사용되는 INTERVAL이란 환경변수 정의
- 2번: 앞서 생성한 ConfigMap 의 이름
- 3번: 앞서 생성한 ConfigMap의 sleep-interval key 지정
- 4번: luksa/fortune:env, nginx:alpine 해당 두 이미지로 만든 컨테이너에서 볼륨을 공유하도록 설정
- 5번: volumeMount를 configMap 타입으로 설정
여기서 알고자 하는 핵심은 5번 volumeMount를 configMap으로 하는 것 입니다.
이렇게 되면 볼륨을 사용할 때 앞서 정의한 ConfigMap을 사용할 수 있도록 할 수 있습니다.
실제로 fortune-configmap-volume POD의 web-server 컨테이너에서
/etc/nginx/conf.d 디렉터리에 있는 파일을 확인 하면
앞서 ConfigMap으로 지정했던 nginx.conf와 환경변수 파일이 존재합니다.
# kubectl exec fortune-configmap-volume -c web-server -- ls /etc/nginx/conf.d
그리고 볼륨에서 특정 컨피그맵만 사용하도록 하려면, 아래와 같이 설정을 하면 됩니다.
volumes: - name: config configMap: name: fortune-config items: - key: my-nginx-config.conf path: gzip.conf
ConfigMap에 관련된 실습은 여기까지 입니다.
Secret에 대해 자세히 알아보도록 하겠습니다.
Secret 리소스를 생성하여 해당 Secret 리소스를 사용하여
Nginx 컨테이너가 HTTPS 트래픽을 제공할 수 있도록
Secret에 인증서와 개인 키를 넣어서 정상적으로 동작하도록 해보겠습니다.그러기 위해선, 먼저 Secret 생성 하기 위해, 인증서와 개인 키를 생성하겠습니다.
# openssl genrsa -out https.key 2048 # openssl req -new -x509 -key https.key -out https.cert -days 3650 -subj /CN=www.kubia-example.com
그리고 foo 라는 더미 파일도 생성을 해줍니다.
# echo bar > foo
이제 위에서 생성한 3가지 파일로 Secret을 생성 해보도록 하겠습니다.
# kubectl create secret generic fortune-https --from-file=https.key --from-file=https.cert --from-file=foo => generic 옵션은 Secret을 생성할 때, local file이나 directory를 사용하여 생성한다는 의미 입니다.
여기서 configMap과 Secret의 차이점을 보면 아래와 같습니다.
Secret ------------------------------------------- # kubectl get secret fortune-https -o yaml apiVersion: v1 data: foo: YmFyCg== https.cert: LS0tLS1CRUdJTiBDRVJUSUZJ.... https.key: LS0tLS1CRUdJTiBSU0EgUFJJV.... kind: Secret metadata: creationTimestamp: "2024-11-26T05:56:28Z" name: fortune-https namespace: test resourceVersion: "7274018" uid: f6191fd0-747f-4731-8f9c-5f108f1f6106 type: Opaque ------------------------------------------- configMap ------------------------------------------- apiVersion: v1 data: my-nginx-config.conf: | server { listen 80; server_name www.kubia-example.com; gzip on; gzip_types text/plain application/xml; location / { root /usr/share/nginx/html; index index.html index.htm; } } sleep-interval: | 25 kind: ConfigMap metadata: creationTimestamp: "2024-11-22T05:04:56Z" name: fortune-config namespace: test resourceVersion: "6087705" uid: 0dca5890-f8df-4d82-ae54-d36874a45628 -------------------------------------------
Secret과 ConfigMap의 차이는 data 부분에서 암호화가 가장 큰 차이점 입니다.이제 생성한 Secret 사용하도록 설정을 해주겠습니다.
앞서 생성한 configMap에서 SSL 인증서를 사용하도록 수정해보겠습니다.
# kubectl edit configmap fortune-config --------------------------- apiVersion: v1 data: my-nginx-config.conf: | server { listen 80; listen 443 ssl; # 해당 부분 추가 server_name www.kubia-example.com; # 해당 부분 추가 ssl_certificate certs/https.cert; # 해당 부분 추가 ssl_certificate_key certs/https.key; # 해당 부분 추가 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 해당 부분 추가 ssl_ciphers HIGH:!aNULL:!MD5; # 해당 부분 추가 gzip on; gzip_types text/plain application/xml; location / { root /usr/share/nginx/html; index index.html index.htm; } } sleep-interval: | 25 kind: ConfigMap metadata: creationTimestamp: "2024-11-22T05:04:56Z" name: fortune-config ... ---------------------------
configMap 설정 변경을 완료하였으면,
이제 해당 ConfigMap과 Secret을 사용하는 POD를 생성해보도록 하겠습니다.앞서 ConfigMap을 사용하도록 생성했던 POD의 내용과 비슷하지만,
Volume에 Secret 설정이 추가 되었습니다.
apiVersion: v1 kind: Pod metadata: name: fortune-https spec: containers: - image: luksa/fortune:env name: html-generator env: - name: INTERVAL valueFrom: configMapKeyRef: name: fortune-config key: sleep-interval volumeMounts: - name: html mountPath: /var/htdocs - image: nginx:alpine name: web-server volumeMounts: - name: html mountPath: /usr/share/nginx/html readOnly: true - name: config mountPath: /etc/nginx/conf.d readOnly: true - name: certs # 1번 mountPath: /etc/nginx/certs/ readOnly: true ports: - containerPort: 80 - containerPort: 443 # 2번 volumes: - name: html emptyDir: {} - name: config configMap: name: fortune-config items: - key: my-nginx-config.conf path: https.conf - name: certs # 3번 secret: secretName: fortune-https
- 1번: nginx:alpine 이미지를 사용하는 web-server 컨테이너에서 앞서 생성한 certs 파일을 사용하기 위해 /etc/nginx/certs 경로에 마운트 진행해줍니다.
- 2번: https를 사용하기 위해 443 포트도 사용해줍니다.
- 3번: web-server 컨테이너에서 사용하기 위한 secret 리소스를 정의 해줍니다.
정상적으로 Secret 리소스가 마운트 되었는지 확인해줍니다.
# kubectl exec fortune-https -c web-server -- ls /etc/nginx/certs
이제 인증서가 정상적으로 적용이 되었는지도 확인해줍니다.
# kubectl port-forward fortune-https 8443:443 # curl https://localhost:8443 -k -v
정상적으로 확인이 완료되었습니다.추가적으로, Secret을 환경변수로 사용할 수 도 있습니다.
간단하게 알아보면 앞서 configMap을 환경변수로 사용했던 것 처럼
secret도 아래와 같이 환경변수로 사용 할 수 있습니다.
env: - name: TEST_SECRET valueFrom: secretKeyRef: name: fortune-https # 생성한 Secret의 이름 key: foo # Secret에서 정의한 Key의 이름
이상 입니다.
출처
Kubernetes-in-action 책을 보고 정리한 내용 입니다.
'쿠버네티스 > 이론' 카테고리의 다른 글
쿠버네티스 Deployment 란 ? (0) | 2024.12.04 |
---|---|
쿠버네티스 Downward API 란? (2) | 2024.11.28 |
쿠버네티스 퍼시스턴트볼륨(PV) 퍼시스턴트볼륨 클레임(PVC) 이란? (0) | 2024.11.12 |
쿠버네티스 Volume 이란? (0) | 2024.11.11 |
쿠버네티스 Ingress 란? (0) | 2024.11.04 |