Kubernetes 리소스 ConfigMap에 대해 이해하고 실습해보기

Bakumando·2022년 5월 25일
1

Kubernetes

목록 보기
9/17

들어가기에 앞서...

  • 본 글은 쿠버네티스 시리즈 중의 하나로, kubernetes 실습을 위한 기본 환경 세팅이 이루어져 있지 않은 분은 시리즈 1편을 확인해주시길 바란다.
  • 쿠버네티스 실습 시리즈는 아래 학습 자료를 참고하고 있다.

0. 블로깅 목적

  • ConfigMap 정의, 적용 방식을 이해한다.
  • ConfigMap 리소스의 사용방법을 이해하고 실습한다.
  • kubectl ConfigMap 생성 명령어를 이해하고 실습한다.

1. ConfigMap 정의, 적용 방식을 이해한다.

1) ConfigMap?

(1) ConfigMap 리소스 정의

  • 애플리케이션의 설정 값을 컨테이너에 주입하고 싶을 때 사용하는 리소스이다.
  • Pod에서 직접 환경변수를 관리하지 않고, ConfigMap을 분리하여 목적에 따라 설정 데이터를 다르게 주입할 수 있다.
    • 해석: Pod를 관리는 yml파일에 직접 환경변수를 하드코딩할 수도 있지만, 그럼 재사용성이 급감하게 된다. 운영관점에서 볼 때 애플리케이션을 실행시키는 코드와 애플리케이션에 주입하는 설정 코드를 분리할 수 있다면 훨씬 재사용성을 높일 수 있다.
    • 예시: 그림에서 볼 수 있듯이, DEV, TEST, PROD 환경에 맞는 설정 파일과, 아래에 있는 Pod yml 파일을 따로 분리하여 목적에 맞게 적용할 수 있도록 하는 게 ConfigMap 리소스이다.


(2) ConfigMap 리소스 적용 방식

  • ConfigMap은 설정 정보를 환경변수 혹은 볼륨의 형태로 Pod에 전달한다.
    • ConfigMap의 값을 컨테이너의 환경변수로 사용
    • ConfigMap의 값을 Pod 볼륨으로 마운트하여 사용

2. ConfigMap 리소스의 사용방법을 이해하고 실습한다.

1) ConfigMap 첫번째 실습

  • 일단 디렉토리를 실습별로 나눠준다. ex) configmap/1
  • 1번 실습은 ConfigMap으로 설정을 분리하는 게 아닌 그냥 하드코딩 하는 방식이다. 비교를 위해 먼저 이를 실습한다.
  • 먼저 yml 파일을 준비한다.

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      name: mysql
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mariadb:10.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: bakumando
        - name: MYSQL_DATABASE
          value: kubernetes
        ports:
        - name: http
          containerPort: 3306
          protocol: TCP
  • mysql이라는 이름의 Deployment이고, image는 mariadb:10.7버전을 사용한다. 그리고 환경변수가 세팅되어 있다.
  • mysql은 이상하게 imagePull 에러가 발생하여 mariadb로 대체하였다.

  • kubectl apply -f deployment.yml
    • 우선 apply해준다.

  • watch kubectl get pod
    • watch 모드를 새로운 터미널에 띄워준다.

  • kubectl exec -it deploy/mysql bash
  • echo $MYSQL_ROOT_PASSWORD
    • exec 키워드로 mysql deployment에 접속한다.
    • 그리고 환경변수로 저장해둔 MySQL 비밀번호를 확인한다.

  • mysql -h localhost -u root -p
    • mysql(mariadb) 환경으로 접속되었다.

  • show databases;
    • 만들어둔 데이터베이스가 존재하는지 확인한다.
    • kubernetes DB가 확인된다.

  • exit로 종료하고 kubectl delete -f deployment.yml로 마무리한다.


2) ConfigMap 두번째 실습

  • 일단 디렉토리를 만든다. ex) configmap/2
  • 2번 실습은 ConfigMap으로 env 설정을 분리하고, deployment에선 env 전체를 참조하는 방식이다.
  • yml 파일을 준비한다.

configmap.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  MYSQL_ROOT_PASSWORD: bakumando
  MYSQL_DATABASE: kubernetes
  • ConfigMap 메니페스트 파일은 간단하다.
  • 버젼은 api 그룹에 대한 명세 없이 그냥 v1이고, metadata에 이름은 잘 지어주면 된다.
  • 다른 리소스 yml파일과는 다르게 spec이 아닌 data라는 영역이 들어가는 점이 독특한 점이다. data 아래에는 configmap 객체가 가지는 key-value 형식의 데이터들을 확인할 수 있다. 이런 식으로 환경변수가 적용되어 있는 것이다.

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      name: mysql
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mariadb:10.7
        envFrom:
        - configMapRef:
            name: mysql-config
  • env가 아닌 envFrom을 활용한다.
  • configMapRef라는 옵션이 있어서 configmap을 참조해라 라는 형태의 항목을 정의할 수 있다.
  • 참조할 ConfigMap의 이름을 줄 수도 있다. 여기선 mysql-config로 설정하였다.

  • kubectl apply -f configmap.yml
  • kubectl apply -f deployment.yml
    • 두 yml 파일을 위 순서로 빠르게 적용해준다.
    • deployment.yml에는 env 설정이 없고 envFrom이 있는데, 이미 적용되어 있던 configmap.yml로부터 환경변수를 가져온 것이라고 할 수 있다.

  • kubectl api-resources | grep configmap
  • kubectl get cm
    • api-resources 중에 grep을 사용해 configmap 키워드만 검색하여 축약어를 알아낸뒤, 조회해보았다. mysql-confing 가 확인된다.

  • kubectl describe cm mysql-config
    • describe로 환경변수도 확인할 수 있다.

  • kubectl exec -it deploy/mysql bash
    • exec으로 mysql deployment에 접속하고, 역시 그 안에서 환경변수를 한번더 체크해본다.

  • mysql -u root -p
  • show databases;
    • 환경변수에서 확인한 비번을 이용해 mysql 환경에 접속하고, db를 확인해본다. kubernetes db가 잘 확인된다.

  • 마지막으로 kubectl delete -f deployment.yml를 적용하고 2번 실습을 마무리 한다.


3) ConfigMap 세번째 실습

  • 일단 디렉토리를 만든다. ex) configmap/3
  • 3번 실습은 ConfigMap에 있는 env 전체를 참조하는 게 아니라, env에서 key만 참조하는 방식의 실습이다.
  • yml 파일을 준비한다.

configmap.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  MYSQL_ROOT_PASSWORD: bakumando
  MYSQL_DATABASE: kubernetes
  • 2번 실습의 configmap.yml과 동일 하다.

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      name: mysql
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mariadb:10.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            configMapKeyRef:
              name: mysql-config
              key: MYSQL_ROOT_PASSWORD
  • envFrom이 없고, env와 그 아래 name이 있는데, name은 1번 실습과 동일하다. 다만 그 아래 value가 없고 valueFrom이 있다.
  • valueFrom의 값으로는 configMapKeyRef가 있는데, configmap을 참조하겠다는 게 아니라 configmap의 key를 참조하여 그 key-value를 적용하겠다는 의미다.
  • 그 아래 name으로는 configmap의 이름이 오게 되고, 그 아래 참조하고 싶은 configmap의 key가 들어간다.

  • kubectl apply -f deployment.yml
    • 새로운 deployment.yml을 apply한다.

  • kubectl exec -it deploy/mysql bash
  • echo $MYSQL_ROOT_PASSWORD
    • mysql deployment에 접속하고, 환경변수로 mysql 패스워드를 확인한다.

  • mysql -u root -p
  • show databases;
    • mysql 환경에 접속하여 db 목록을 확인했다.
    • kubernetes란 이름의 db가 없다. 이유는 이번에 적용된 deployment는 configmap을 모두 참조한 게 아니라 configmap의 key만 참조하도록 정의되어있기 때문이다.


4) ConfigMap 네번째 실습

  • 일단 디렉토리를 만든다. ex) configmap/4
  • 4번 실습은 ConfigMap에 volume으로 mount하는 방법이다.
  • yml 파일을 준비한다. (configMap.yml은 이전과 같다.)

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      name: mysql
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mariadb:10.7
        envFrom:
        - configMapRef:
            name: mysql-config
        volumeMounts:
        - mountPath: /tmp/config
          name: mysql-config
      volumes:
      - name: mysql-config
        configMap:
          name: mysql-config
  • env을 없애고 envFrom을 넣는다. envFrom은 2번 실습과 동일하다.
  • containers하위에는 volumeMounts에 mount옵션이 정의되어있다.
    • 즉, mysql이라는 컨테이너는 volumeMounts옵션을 통해서, /tmp/config라는 디렉토리에다가 mysql-config라는 volume을 마운트해라 라고 정의되어 있기 때문에, volumes에 있는 목록이 참조되어 적용될 것이다.
  • 이렇게 spec 밑에 containers와 동일한 레벨에 정의되는 volumes는 각각의 컨테이너에서 마운트를 할 수 있게 된다.
    • volumes하위에는 해당 Pod가 사용하게 될 volume 목록이 정의되는데, 목록에는 name을 기본으로 + 이 volume이 사용하게 될 드라이버 옵션을 넣어준다. 여기서는 configMap을 사용한다. (다른 옵션으로는 secret, emptydirs(인메모리) 등이 있다.)
  • configMap.yml이 어떻게 마운트될 수 있을까?
    • 원리를 살펴보면, configMap의 data 키 아래에 있는 환경변수들이 file의 형태로 mountPath에 저장된다. key가 file이름이 되고, value는 데이터가 되는 것이다.

  • kubectl apply -f deployment.yml
    • 새로운 deployment.yml을 적용한다.

  • kubectl exec -it deploy/mysql bash
  • echo $MYSQL_ROOT_PASSWORD
    • mysql deployment에 접속하여 환경변수를 확인한다.

  • cd /tmp/config
  • ls
  • cat MYSQL_ROOT_PASSWORD
  • cat MYSQL_DATABASE
    • 마운트 경로가 생겼는지 확인하고, configMap.yml의 key-valuer가 파일로 잘 저장되었는지 확인한다. (정상적으로 저장된 게 확인)

  • mysql -u root -p
  • show databases;
    • 마지막으로 mysql 환경에 접속하여 db 목록을 살펴본다. (kubernetes db 존재)

3. kubectl ConfigMap 생성 명령어를 이해하고 실습한다.

1) kubectl ConfigMap 생성 명령어

  • 2번 챕터에서 활용한 configMap 커맨드는 선언형만 있었다면, 3번 챕터에서는 명령형 커맨드를 살펴본다.
  • 이유는 configMap의 경우 선언형으로만 명세하는 게 상당히 번거로운 일이 될 수 있어서다.
  • 그래서 효율적으로 선언형 yml 파일을 만들고 관리할 수 있도록 해주는, 보좌해주는(?) 느낌의 명령형 커맨드 기법에 대해 알아볼 필요가 있다.

다양한 방식으로 configmap yml 명세 파일을 만들어낼 수 있다.

$ kubectl create configmap {configmap 이름} --dry-run -o yaml
$ kubectl create configmap {configmap 이름} --from-file {파일명/파일경로} --dry-run -o yaml
$ kubectl create configmap {configmap 이름} --from-file {key}={파일명/파일경로} --dry-run -o yaml
$ kubectl create configmap {configmap 이름} --from-file {key}={파일명/파일경로} --dry-run -o yaml
$ kubectl create configmap {configmap 이름} --from-file {key}={파일명/파일경로} --dry-run -o yaml --from-literal {key}={value}
  • 핵심은 --dry-run -o yaml이다.
    • --dry-run: 가짜로 실행해라. 결과를 클러스터에 바로 반영하는 게 아니라 어떤 결과를 만들어낼지를 일단 확인해보기 위한 것.
    • -o yaml: 출력 결과를 yml 형태로 보려는 것.
  • 위 옵션을 없이 실행하면 그냥 바로 ConfigMap 오브젝트를 생성해버린다. 그래서 일단 위 옵션을 활용하여 어떤 명세가 될지를 살펴보고, 이후에 옵션을 지우고 적용을 하면 더 실수할 일이 적고 효율적일 수 있다.
  • 아니면 출력된 새로운 명세를 기존 yml에 덮어씌워주는 것도 좋은 방법일 것이다.

  • 이건 바로 실습으로 들어가서 살펴보는 게 이해가 잘된다.
  • kubectl create configmap my-config --dry-run -o yaml
    • my-config라는 이름의 ConfigMap yml 명세를 생성하였다.

  • kubectl create configmap my-config --from-file deployment.yml --dry-run -o yaml
    • 기존 deployment.yml이라는 파일을 바탕으로, 해당 파일명을 key로 하고, 파일 내용을 value로 하는 형태에다가 + ConfigMap 명세가 추가 된 yml 파일이 출력되었다.

  • kubectl create configmap my-config --from-file test=deployment.yml --dry-run -o yaml
    • key로는 test라는 이름을 주고, deployment.yml 파일의 내용만 value로 하는 형태에다가 + ConfigMap 명세가 추가 된 yml 파일이 출력되었다.

  • kubectl create configmap my-config --from-file test=deployment.yml --dry-run -o yaml --from-literal hello=world
    • 바로 위 실습 내용에 + hello라는 key와 world라는 value를 문자열 방식으로 만들어주는 yml 파일이 출력되었다.
profile
그렇게 바쿠만도는 개발에 퐁당 빠지고 말았답니다.

0개의 댓글