k8s/concept

configMap

부엉이사장 2023. 12. 21. 15:54

# 개념

configMap은 머랄까.. 객체같은거다. 자바스크립트에서 그냥 객체..

키 값 쌍의 데이터가 여러개 묶음으로 관리되는 그런거라고 보면된다.

이런 객체 데이터들을 configMap으로 만들어두고 pod나 이런 리소스들에서 갖다 쓰는거다.

뭐 환경변수나 이런걸로 쓰게되면, 여러 pod들에 모두 적용되는 특정 환경변수, 예를들어 db접근정보라던지.. 이런게 변경되었을경우 모든 pod에서 일일히 수정&적용해줘야하는데, configMap으로 관리하게 된다면 configMap에서만 변경해주면 이에 연결된 모든 pod들에 해당 변경사항이 적용이 될거라 생각했는데.. env는 안된다.

pod를 삭제하고 다시만들어줘야 적용이 되더라..

대신 volume mount는 되고 참,..

암튼

 

 

 

# configMap yaml양식

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  # property-like keys; each key maps to a simple value
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

  # file-like keys
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

공식문서에 있는 yaml양식인데, 뭐사실 좀 게임?같은거 만드는데 쓰이는거같음.

암튼 이렇게 yaml형식으로 만들 수 있다. 사실 파일은 잘 모르겠음.

 

 

# cli 명령어로 configMap만들기

kubectl create configmap <configMap이름!> --from-literal=<키>=<값>

리터럴로 키 값을 넣는거다. 예를들어보면, 

kubectl create configmap babo-config --from-literal=id=muzzi

babo-config라는 configMap을 만들거고, 리터럴로 id는 muzzi라는 값을 넣을거다.

configMap을 describe로 보자.

kubectl describe configmap babo-config

id가 muzzi라는 데이터가 잘 들어간 것을 볼 수 있다.

 

중복은 될까?

kubectl create configmap babo-config --from-literal=id=muzzi --from-literal=pw=dori
kubectl describe configmaps babo-config

아까 id=muzzi라는거에다가 pw=dori를 추가했다. 그냥 옆에 --from-literal로 치니까 잘 되더라.

 

 

# cli명령어로 파일째로 넣어버리기.

kubectl create configmap <configMap이름> --from-file=<파일경로>

이러면 파일이름이 키, 파일내용이 값으로 configMap이 생성된다.

현재 경로에다가 text라는 이름, 내용은 hello muzzi world로 파일을 만들어봤다.

그리고 이 파일로 configMap을 생성해보면,

kubectl create configmap babo-config --from-file=text
kubectl describe configmaps babo-config

text라는 키값에, hello muzzi world라는 파일내용이 configMap데이터로 저장이 되었다.

 

 

 

파일이름을 키값으로 하기 싫으면 직접 지정해줄수도 있다.

kubectl create configmap babo-config --from-file=muzzi-data=text

파일기반으로 configMap을 만들건데, 파일이름을 키로 안쓰고, muzzi-data로 만들고 파일내용을 값으로 넣겠다는거다.

describe를 쳐보면,

 

 

++

kubectl create configmap babo-config --from-literal=id=muzzi --from-file=text

파일과 리터럴 둘다 동시에 넣어서 만들 수도 있다.

 

 

 

 

 

 

# 그럼 이렇게 만든 configMap을 어떻게 써야하는걸까?

1. 환경변수로 사용해보자.

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: nginx
    env:
    - name: dog
      valueFrom:
        configMapKeyRef:
          name: muzzi-config
          key: babo

테스트용으로 만들 pod의 yaml파일이고 환경변수에 dog라는 환경변수 키값에 muzzi-config라는 configMap에서 babo키값에 있는 값을 매칭시킬거다.

일단 위에 있는 pod를 한번 생성해봤는데,

kubectl create -f test-env-pod.yaml

configError가 떠버렸다. 참조할 muzzi-config를 만들어놓지 않았기 때문인듯..?

그래서 만들었다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: muzzi-config
data:
  babo: "muzzi"

yaml로 configMap을 만들었다. 아까 babo라는 키에 매칭되는 값이 pod에서 dog라는 키에 매칭될거니 babo : muzzi라는 데이터를 만들어줬다,

그러니까 아까 configError띄우고 running이 안되던 pod가 상태가 running으로 바뀌었다,

 

이제 pod의 컨테이너 안에서 환경변수를 확인하기 위해 exec로 들어가보자.

kubectl exec -it test-env-pod -- /bin/bash

이렇게 잘 만들어졌고 잘 쓸수 있게 되었다.

 

 

 

 

2. 파일대 파일로 마운트 해주기.

yaml로 파일내용 가져와서 값으로 넣어주는건 사실 잘 모르겠다. 일단 cli로 만들어보자.

현재 디렉토리에 index.html을 만들었다.

내용은 muzzi hellp pod라고 되어있다. 이걸 nodePort서비스에 연결된 deployment에 만들거다.

kubectl create configmap muzzi-config --from-file=index.html

이렇게 파일기반 configMap을 만들어주고..

 

아래 NodePort타입의 서비스와 deployment를 만들어줄거다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: muzzi-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: muzzi
  template:
    metadata:
      labels:
        app: muzzi
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        volumeMounts:
        - name: index
          mountPath: "/usr/share/nginx/html/"
          readOnly: true
      volumes:
      - name: index
        configMap:
          name: muzzi-config
          items:
          - key: index.html
            path: index.html
---
apiVersion: v1
kind: Service
metadata:
  name: muzzi-service
spec:
  type: NodePort
  selector:
    app: muzzi
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30007
kubectl create -f muzzi-web.yaml

이렇게 서비스와 deployment를 생성해주고

브라우저에서 vm아이피의 30007번 포트로 접속해주면..?

configMap에서 마운트해준 경로의 내용이 뜨게된다.

참고로 이 상태에서 index.html을 수정해준다고 내용이 바뀌진 않는다.

configMap을 생성할때 index.html파일을 참조하는거라 그렇다..

대신 만약 configMap에서 index.html의 내용을 수정해주면 반영된다.

kubectl edit configmap muzzi-config

modified를 붙여줌.

뭐된다..

 

 

 

 

 

3. configMap자체를 pod의 환경변수로.

apiVersion: v1
kind: Pod
metadata:
  name: test-env-pod
spec:
  containers:
  - name: mypod
    image: nginx
    envFrom:
    - configMapRef:
        name: muzzi-config

이렇게 envFrom에서 configMap을 쓸거다 해주면 된다.

중요한건 하나씩 환경변수로 꺼낼꺼였을땐 configMapKeyRef였는데 이젠 Key가 없다.

이러면 해당 pod의 컨테이너 내에서 configMap의 모든 데이터가 환경변수로 관리되게된다.

 

 

 

 

++ yaml에서 파일양식은..

그냥 |을 붙여주고 아래서 줄바꿈해도 상관없는 그런거인듯..

아예 파일자체를 마운트해주는게 아니라 configMap이 생성될때만 한번 반영하는거라 그런거 같다..

 

 

++configMap 마운트 해주는 방법 자세히.

apiVersion: v1
kind: Pod
metadata:
  name: config-pod
spec:
  containers:
  - name: mypod
    image: nginx
    volumeMounts:
    - name: index
      mountPath: "/usr/share/nginx/html/"
      readOnly: true
  volumes:
  - name: index
    configMap:
      name: muzzi-config
      items:
      - key: index.html
        path: index.html

위에껀 서비스, 디플로이먼트까지 해서 좀 복잡해보이는데 단순하게 pod에 연결되는 configMap을 설명해보자면,

volumeMounts부분에 mountPath에서 해당파일이 위치할 pod의 컨테이너 내에서의 경로를 적어주고,

여기서의 name과 아래 volumes에서 name을 이어진다고 생각하고 동일하게 적어준다.

그리고 volumes의 configMap에서 muzzi-config라는 configMap을 사용한다고 적어주고, 이 configMap에서의 원하는 자료의 키값을 items필드의 key에 적어주고, 

path는 위의 volumeMounts의 mountPath의 경로에 생길 파일이름으로 정해주면된다.

뭐시발 존나 복잡함

 

 

 

 

++

 

kubectl create configmap muzzi-config --from-file=index.html --dry-run=client -o yaml|kubectl apply -f -

파일내용으로 추가하려는걸 기존의 configmap에 추가하려면 이렇게 dry run으로 만들고 apply해주면 된다

명령어 참 복잡하게생겼다.

 

 

 

++ secret

configMap과 동작방식은 똑같은데 base64로 인코딩,디코딩해준다.

이걸 포스팅할까 생각해봤는데.. 사실 base64로 인코딩 디코딩이 된다는 사실을 알고 etcd에 접근권한이있다면 보안적인 목적이 불분명해진다..

따로 aws의 kms나 뭐 이것저것 갖다쓰면 보안상 이점이 있지만 k8s만으로는 보안상 이점이 그닥 없을것같아서 여까지 쓰겠다.

다만 private registry에 대한 접근권한으로 secret을 사용한다면 중요할것같은데 다시 레지스트리를 깔고뭐야해야해서.. 이건 나중에 보충을 해봐야겠다.

 

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

- Secret 정의, 종류를 이해한다. - kubectl Secret 생성 명령어를 이해하고 실습한다. - Secret의 선언적 관리 방법에 대해 이해한다.

velog.io