본문 바로가기
Kubernetes

Kubernetes ConfigMap & volume

by 손영진 2023. 8. 9.
728x90

#1 ConfigMap

  • 비기밀 데이터 키-값 쌍으로 저장하기 위해 사용한 API 객체
  • 컨테이너에 필요한 환경설정 내용을 컨테이너와 분리해서 제공하기 위한 기능
  • 컨테이너는 클라우드 네이티브 환경에서 변하지 않는 자원
  • 다른 설정을 가지고 Pod를 실행해야 할 경우 사용
  • configmap.yaml
  • 더보기
    kind: ConfigMap
    metadata:
      name: configmap-dev
      namespace: configmap
    data:
      DB_URL: localhost
      DB_USER: myuser
      DB_PASS: mypass
      DEBUG_INFO: debug
<<configmap 소스 파일 생성>>
kubectl create ns configmap
kubens configmap

vim configmap.yaml	<더보기 참조>
kubectl apply -f configmap.yaml
kubectl get configmap		// 생성된 configmap의 이름 확인 (.yaml에서 설정)
kubectl describe configmap configmap-dev	// 세부정보 확인, 그림 확인

 

   1. configmap 사용 - configmap 설정 중 일부만 사용

  • deploy-config.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: configapp
      labels:
        app: configapp
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: configapp
      template:
        metadata:
          labels:
            app: configapp
        spec:
          containers:
          - name: configapp
            image: arisu1000/simple-container-app:latest
            ports:
            - containerPort: 8080
            env:
              - name: DEBUG_LEVEL
                valueFrom:
                  configMapKeyRef:
                    name: configmap-dev
                    key: DEBUG_INFO
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: configapp
      name: configapp-svc
      namespace: configmap
    spec:
      ports:
      - nodePort: 30800
        port: 8080
        protocol: TCP
        targetPort: 8080
      selector:
        app: configapp
      type: NodePort
vim deploy-config.yaml	<더보기 참조>
kubectl apply -f deploy-config.yaml
kubectl get deploy	// 생성한 deploy 확인
kubectl get svc		// 설정한 NodePort 번호 확인

 

   2. configmap 사용 - configmap 한꺼번에 사용

  • config-all.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: configapp
      labels:
        app: configapp
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: configapp
      template:
        metadata:
          labels:
            app: configapp
        spec:
          containers:
          - name: configapp
            image: arisu1000/simple-container-app:latest
            ports:
            - containerPort: 8080
            envFrom:
            - configMapRef:
              name: configmap-dev
vim config-all.yaml		<더보기 참조>
kubectl apply -f config-all.yaml

-> configmap-dev 전체를 보이도록 했기에 db내용이 다 나온다 <그림참조>

 

   3. configmap 사용 - configmap 볼륨으로 사용

  • config-volume.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: configapp
      labels:
        app: configapp
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: configapp
      template:
        metadata:
          labels:
            app: configapp
        spec:
          containers:
          - name: configapp
            image: arisu1000/simple-container-app:latest
            ports:
            - containerPort: 8080
            volumeMounts:
            - name: config-volume
              mountPath: /etc/config
          volumes:
          - name: config-volume
            configMap:
              name: configmap-dev
vim config-volume.yaml		<더보기 참조>
kubectl apply -f config-volume.yaml

<< pod 내부에서 확인 >>
kubectl get pods	// pod의 이름확인
kubectl exec -it [pod 이름] -- sh
> cd /etc/config
> ls -l		<그림참조>

 

#2 Secret

  • Password, Token, SSH key와 같은 민감한 정보들 저장
  • 컨테이너 내부에 저장하지 않고 별도 보관
  • configmap와 차이 : secret 저장 시 설정값 Base64로 인코딩해서 저장

 

   1. Secret 생성

kubectl create ns secret
kubens secret
echo -n 'alice' > ./username.txt
echo -n 'password' > ./password.txt

kubectl create secret generic user-pass-secret \
> --from-file=./username.txt --from-file=./password.txt

kubectl get secret		// opaque : 시크릿 구성 파일에서 누락된 경우의 기본 시크릿 타입
kubectl get secret user-pass-secret -o yaml	<그림 1>

echo [인코딩 된 username / password]| base64 --decode	<그림 2>

그림 1
그림 2

 

   2. Secret 사용

  • 생성할 secret의 pod의 환경변수 제공 및 확인
  • user-pass.yaml
  • 더보기
    apiVersion: v1
    kind: Secret
    metadata:
      name: user-pass-secret2
    type: Opaque
    data:
      username: YWxpY2U=
      password: cGFzc3dvcmQ=
  • user-env.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: secretapp
      labels:
        app: secretapp
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: secretapp
      template:
        metadata:
          labels:
            app: secretapp
        spec:
          containers:
          - name: secretapp
            image: arisu1000/simple-container-app:latest
            ports:
            - containerPort: 8080
            env:
              - name: SECRET_USERNAME
                valueFrom:
                  secretKeyRef:
                    name: user-pass-secret2
                    key: username
              - name: SECRET_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: user-pass-secret2
                    key: password
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: secretapp
      name: secretapp-svc
      namespace: secret
    spec:
      ports:
      - nodePort: 30900
        port: 8080
        protocol: TCP
        targetPort: 8080
      selector:
        app: secretapp
      type: NodePort
<환경변수로 Pod에 Secret 제공>

vim user-pass.yaml	<더보기 참조>
kubectl apply -f user-pass.yaml

vim user-env.yaml	<더보기 참조>
kubectl apply -f user-env.yaml
kubectl get svc -o wide		// 생성된 service의 포트번호 확인
kubectl get pods -o wide	// pods의 노드확인

-> 웹브라우저에 [pods의 노드의 공인ip]:[포트번호]

<볼륨으로 Pod에 Secret 제공>
vim secret-volume.yaml
kubectl apply -f secret-volume.yaml
kubectl get svc -o wide

-> 웹브라우저에 [공인 ip]:30900/volume-config?path=/etc/volume-secret/password
-> <그림1>

<pod에서 확인>
kubectl get pods	// pods 이름 확인
kubectl exec -it [pod 이름] -- sh
> cd /etc/volume-secret/
> ls -l		<그림2>

그림 1
그림 2

 

   3. TLS 인증서 Secret으로 사용

  • https 인증서를 저장하는 용도로 사용
  • 여기서는 테스트 목적이므로 사설 인증서를 만들어 사용
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
> -keyout tls.key -out tls.crt -subj "/CN=foo.bar.com"

ls tls*		// 생성된 2개의 키 확인 (tls.crt / tls.key)

kubectl create secret tls secret-tls --key tls.key --cert tls.crt

kubectl get secret -o wide	<그림참조>

 

#3 volume

  • Pod에 종속 되는 디스크 - Pod 컨테이너에서 접근하는 스토리지 단위
  • 컨테이너 내부 디스크 파일은 임시용
  • Pod가 삭제된 후에 그 데이터 지속되지 않음
  • emptyDir
    • 개별적 Pod에 적용할 수 있는 volume
    • Pod 내 여러 컨테이너가 생성된 경우 하나의 emptyDir 공유
  • hostpath
    • 호스트 디렉터리 Pod와 공유해서 사용
    • Pod가 삭제되어도 hostpath에 젖아된 파일들은 host에 저장
  • Network Volume
    • PV(Persistent Volume)
      • 시스템 관리자가 실제 물리 디스크 생성 후 PV이름으로 쿠버네티스에 등록
    • PVC(Persistent Volume Claim)
      • Pod 생성 시, 볼륨을 정의하고 PVC 지정, 관리자가 생성한 PV와 연결

 

   1. emptyDir 볼륨 사용

  • 휘발성 데이터 저장 : Pod삭제 시 emptyDir 또한 삭제
  • volume-emptydir.yaml
  • 더보기
    apiVersion: v1
    kind: Pod
    metadata:
      name: shared-volumes 
    spec:
      containers:
      - name: redis
        image: redis
        volumeMounts:
        - name: shared-storage
          mountPath: /data/shared
      - name: nginx
        image: nginx
        volumeMounts:
        - name: shared-storage
          mountPath: /data/shared
      volumes:
      - name: shared-storage
        emptyDir: {}
kubectl create ns volume
kubens volume
vim volume-emptydir.yaml	<더보기 참조>
kubectl create -f volime-emptydir.yaml
kubectl describe pod shared-volumes
			// volumes의 type이 emptydir 인 것 확인


<< 컨테이너 공유 확인 >>

kubectl exec -it shared-volume --container redis --/bin/bash
> cd chared
> echo 'hello world' file.txt
> exit

kubectl exec -it shared-volume --container nginx -- /bin/bash
> cd data/shared/
> cat file.txt		<그림 참조>

 

   2. hostpath 볼륨 사용

  • dockerswarm의 호스트 볼륨 마운트와 비슷한 방식
  • pod가 삭제되도 hostpath에 저장된 파일들은 호스트에 저장
  • 그러나, 컨테이너 생성 시 특정 호스트를 nodeselector를 통해 지정하지 않으면 매번 다른 호스트에 할당
  • volume-hostpath.yaml
  • 더보기
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx-label
    spec:
      selector:
        matchLabels:
          app: nginx-label
      template:
        metadata:
          labels:
            app: nginx-label
        spec:
          containers:
          - name: nginx-container
            image: nginx
            volumeMounts:
            - mountPath: /mydata-container
              name: hostpath-volume
          volumes:
          - name: hostpath-volume
            hostPath:
              path: /mydata
              type: Directory
<각 worker에서 실행>
mkdir /mydata

<master에서 실행>
vim volume-hostpath.yaml
kubectl create -f volume-hostpath.yaml
kubectl ger pods -o wide		// pod 이름 및 node 확인

kubectl exec -it [pode 이름] -- /bin/bash
> ls
> cd mydata-container/
> echo 'hostpaht volume test' > hostpath.txt

kubectl delete deploy nginx-deployment		// deploy를 삭제해도 각 worker에서 보이는지 확인

<각 worker에서 실행>
cat /myday/hostpath.txt

 

   3. PV & PVC 사용

  • PV는 볼륨 자체를 의미, 클러스터내에 리소스로 존재
    • Pod와 별도로 관리
  • PVC는 사용자가 PV에게 보내는 요청
<NFS 서버 구축하기>

apt install nfs-kernel-server
systemctl status nfs-server		// 잘 설치되었는지 확인. active 상태여야함

mkdir /volume-nfs
chown nobody:nogroup /volume-nfs/
chomod -R 777 /volume-nfs/
vim /etc/exports
> /volume-nfs	172.31.0.0/16(rw,sync,no_subtree_check)
			// 마지막 줄에 이거 추가
exportfs -a
exportfs		// 생성한 내용 확인
systemctl restart nfs-server

<maser와 각 worker에 실행>
ufw disable			// 방화벽 해제

<각 worekr>
mkdir /mnt/master
apt install nfs-common -y
mount 172.31.37.94:/volume-nfs /mnt/master/		// 각 master의 사설IP
touch /mnt/master/test1
echo 'nfs test' > /mnt/master/test1

<master>
cat /volume-nfs/test1
			// worker에서 생성한 파일 확인
  • PV & PVC생성 및 삭제
    • volume-nginx를 만들며 pvc는 html 디렉토리로 mount 된다.
    • pod가 삭제되어도 master노드의 NFS 서버가 제공 중인 디렉토리에 남아있는다.
    • 삭제 시 pvc 삭제 후 pv를 삭제 
    • volume-pv.yaml
    • 더보기
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: nfs-pv
      spec:
        capacity:
          storage: 3Gi
        accessModes:
        - ReadWriteMany
        persistentVolumeReclaimPolicy: Retain
        nfs:
          path: /volume-nfs
          server: 213.0.113.3
        readOnly: false
    • volume-pvc.yaml
    • 더보기
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: nfs-pvc
      spec:
        accessModes:
        - ReadWriteMany
        resources:
          requests:
            storage: 3Gi
    • volume-nginx.yaml
    • 더보기
      apiVersion: v1
      kind: Pod
      metadata:
        name: nginx-nfs
        labels:
          name: nginx-nfs
      spec:
        containers:
        - name: nginx-nfs
          image: fedora/nginx
          ports:
          - name: web
            containerPort: 80
          volumeMounts:
          - name: nfs-share
            mountPath: /usr/share/nginx/html
        volumes:
        - name: nfs-share
          persistentVolumeClaim:
            claimName: nfs-pvc
vim volume-pv.yaml	<더보기 참조>
kubectl apply -f volume-pv.yaml
kubectl get pv

vim volime-pvc.yaml	<더보기 참조>
kubectl apply -f volume-pvc.yaml
kubectl get pv
kubectl get pvc

<< PV와 PVC 연결 >>
vim volume-nginx.yaml
kubectl apply -f volume-nginx.yaml
kubectml get pods -o wide

<< Pod 디렉토리 데이터 생성>>
kubectl exec -it nginx-nfs -- /bin/bash
> cd /usr/share/nginx/html
> echo 'NFS pv test' > index.html
> exit
cat /volume-nfs/index.html	//위에서 생성한 index.html 내용확인

<< Pod 삭제 후 내용 확인 >>
kubectl delete pods nginx-nfs
cat /volume-nfs/index.html	//pod를 삭제해도 내용은 남아있다.

 

 

 

'Kubernetes' 카테고리의 다른 글

Kubernetes Scheduling  (0) 2023.08.15
Kubernetes Deploy & Service & Ingress  (0) 2023.08.08
Kubernetes 기본  (1) 2023.08.07