CKA 자격 시험 준비를 위한 Kubernetes 정리2-Volume,ConfigMap,Secret
오늘은 인프런 강의 대세는 쿠버네티스 강의 중 Volume, ConfigMap, Namespace 관련 내용을 실습해 보면서 정리 할 예정이다.
Volume - https://kubetm.github.io/k8s/03-beginner-basic-resource/volume/
ConfigMap,Secret - https://kubetm.github.io/k8s/03-beginner-basic-resource/ConfigMap/
Volume
1. emptyDir
2개의 Container가 있는 Pod를 생성하고 2개의 Container 내에서 파일을 공유하는지 확인. emptyDir volume은 pod가 삭제가 되면 volume내의 파일도 같이 삭제된다.
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-vol-01
spec:
containers:
- name: container01
image: coolguy239/p8080
volumeMounts:
- name: empty-dir
mountPath: /mount1
- name: container02
image: coolguy239/p8000
volumeMounts:
- name: empty-dir
mountPath: /mount2
volumes:
- name : empty-dir
emptyDir: {}
EOF
container1 내부로 들어가서 mount1 경로가 생성된 것을 확인 후 mount1 경로에 test.txt 파일을 생성한다.
$ kubectl exec -ti -c container01 pod-vol-01 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# ls
app.jar bin dev etc home lib lib64 media mnt mount1 opt proc root run sbin srv sys tmp usr var
# echo "this is test file" >> test.txt
container2 내부로 들어가서 mount2 경로가 생성된 것을 확인 후 mount2 경로에 test.txt 파일의 내용을 확인한다.
$ kubectl exec -ti -c container02 pod-vol-01 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# ls
app.jar bin dev etc home lib lib64 media mnt mount2 opt proc root run sbin srv sys tmp usr var
# cat /mount2/test.txt
this is test file
2. hostPath
spec.volumes.hostPath.type = DirectoryOrCreate 의 의미는 Node에 해당 경로가 없으면 생성하겠다는 의미이다.
hostPath 테스트 진행을 위해 k8s-worker1 노드에 동일한 Pod 두개를 생성한다.
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-vol-02
spec:
nodeSelector:
kubernetes.io/hostname: k8s-worker1
containers:
- name: container
image: coolguy239/init
volumeMounts:
- name: host-path
mountPath: /mount1
volumes:
- name : host-path
hostPath:
path: /node-v
type: DirectoryOrCreate
EOF
--
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-vol-03
spec:
nodeSelector:
kubernetes.io/hostname: k8s-worker1
containers:
- name: container
image: coolguy239/init
volumeMounts:
- name: host-path
mountPath: /mount1
volumes:
- name : host-path
hostPath:
path: /node-v
type: DirectoryOrCreate
EOF
pod-vol-02 파드에 접속 후 mount1 경로에 test.txt 파일 생성
$ kubectl exec -ti pod-vol-02 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# ls
app.jar bin boot dev etc home lib lib64 media mnt mount1 opt proc root run sbin srv sys tmp usr var
# cd mount1
# echo "this is test file" >> test.txt
pod-vol-03 파드에 접속 후 mount1 경로에 test.txt 파일 확인
$ kubectl exec -ti pod-vol-02 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# ls
app.jar bin boot dev etc home lib lib64 media mnt mount1 opt proc root run sbin srv sys tmp usr var
# cd mount1
# cat test.txt
this is test file
위의 결과로 hostPath를 통해 같은 Node 내의 Pod들이 Volume을 공유하는 것을 확인 할 수 있다.
k8s-worker1 노드의 /node-v 경로에 test.txt 파일 확인
$ ls
bin boot dev etc home lib lib64 media mnt node-v opt proc root run sbin srv swapfile sys tmp usr vagrant var
$ cat node-v/test.txt
this is test file
hostPath로 잡은 volume은 Node에 Directory가 생기는 것이기 때문에 Pod가 삭제되도 Volume의 파일이 삭제되지 않는다.
3. PVC / PV - storage, accessModes로 연결
Pod의 Volume을 영속적으로 사용하기 위한 방법이다.
3-1. PersistentVolume
PVC와 PV가 capacity, accessModes로 연결되는 예제로 capacity, accessModes를 조금씩 다르게 설정한다.
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-01
spec:
capacity:
storage: 1G
accessModes:
- ReadWriteOnce
local:
path: /node-v
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- {key: kubernetes.io/hostname, operator: In, values: [k8s-worker1]}
EOF
--
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-02
spec:
capacity:
storage: 1G
accessModes:
- ReadOnlyMany
local:
path: /node-v
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- {key: kubernetes.io/hostname, operator: In, values: [k8s-worker1]}
EOF
--
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-03
spec:
capacity:
storage: 2G
accessModes:
- ReadWriteOnce
local:
path: /node-v
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- {key: kubernetes.io/hostname, operator: In, values: [k8s-worker1]}
EOF
3-2. PersistentVolumeClaim
PVC 설정을 ReadWriteOnce, 1G로 설정하고 PVC를 생성하고 PV의 조회 결과를 보면 pv-01(1G, RWO)에 연결된 것을 확인 할 수 있다. PV보다 큰 PVC의 storage는 PV에 연결이 안되지만 작은 PVC는 accessModes만 일치한다면 연결이 가능하다.
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-01
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1G
storageClassName: ""
EOF
$ kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
pv-01 1G RWO Retain Bound default/pvc-01 5m35s Filesystem
pv-02 1G ROX Retain Available 4m54s Filesystem
pv-03 2G RWO Retain Available 2m58s Filesystem
---
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-02
spec:
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 1G
storageClassName: ""
EOF
$ kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
pv-01 1G RWO Retain Bound default/pvc-01 9m32s Filesystem
pv-02 1G ROX Retain Bound default/pvc-02 8m51s Filesystem
pv-03 2G RWO Retain Available 6m55s Filesystem
---
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-03
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1G
storageClassName: ""
EOF
$ kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
pv-01 1G RWO Retain Bound default/pvc-01 14m Filesystem
pv-02 1G ROX Retain Bound default/pvc-02 14m Filesystem
pv-03 2G RWO Retain Bound default/pvc-03 12m Filesystem
3-3. Pod
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-vol-04
spec:
containers:
- name: container
image: coolguy239/init
volumeMounts:
- name: pvc-pv
mountPath: /mount3
volumes:
- name : pvc-pv
persistentVolumeClaim:
claimName: pvc-01
EOF
$ kubectl exec -ti pod-vol-04 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# ls
app.jar bin boot dev etc home lib lib64 media mnt mount3 opt proc root run sbin srv sys tmp usr var
4. PVC / PV - label과 selector를 이용한 연결
이번 예제는 단순히 PVC와 PV만을 연결하기 위한 예제로 pod는 따로 생성하지 않는다.
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-04
labels:
pv: pv-04
spec:
capacity:
storage: 1G
accessModes:
- ReadWriteOnce
local:
path: /node-v
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- {key: kubernetes.io/hostname, operator: In, values: [k8s-worker1]}
EOF
---
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-04
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1G
storageClassName: ""
selector:
matchLabels:
pv: pv-04
EOF
---
$ kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
pv-01 1G RWO Retain Bound default/pvc-01 27m Filesystem
pv-02 1G ROX Retain Bound default/pvc-02 26m Filesystem
pv-03 2G RWO Retain Bound default/pvc-03 24m Filesystem
pv-04 1G RWO Retain Bound default/pvc-04 106s Filesystem
ConfingMap, Secret
1. Literal 방식
1-1. ConfigMap
ConfigMap 생성시 key,value 형태로 yaml을 생성한다. Boolean형은 싱글쿼테이션으로 감싸준다.
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-01
data:
data1: 'false'
data2: stringValue
EOF
1-2. Secret
Secret은 yaml파일 생성시 value 값을 base64 Encoding을 해서 생성한다.
$ echo -n '1111' | base64
MTExMQ==
$ echo -n '2222' | base64
MjIyMg==
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: sec-01
data:
pwd1: MTExMQ==
pwd2: MjIyMg==
EOF
1-3. Pod
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-01
spec:
containers:
- name: container
image: coolguy239/init
envFrom:
- configMapRef:
name: cm-01
- secretRef:
name: sec-01
EOF
1-4. Env 확인
pod-1 Container로 접속해서 env 환경변수를 확인한다.
$ kubectl exec -ti pod-01 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
$ env
...
pwd2=2222
pwd1=1111
...
data2=stringValue
...
daga1=false
...
2. File 방식
–form-file=[파일명] : 파일 이름과 동일한 시크릿 데이터 키를 사용해 파일에서 적재
–from-file=[키]=[파일명] : 명시적으로 지정된 시크릿 데이터 키를 사용해 파일에서 적재
–form-file=[디렉토리] : 파일이름이 수용할 수 있는 키 이름이 지정된 디렉토리의 모든 파일을 적재
–form-literal=[키]=[값] : 지정된 키/값 쌍으로 직접 사용
2-1. file로 ConfigMap, Secret 생성
$ echo "val" >> cm-data.txt
$ kubectl create configmap cm-02 --from-file=./cm-data.txt
$ kubectl get configmap cm-02 -o yaml
apiVersion: v1
data:
cm-data.txt: |
val
kind: ConfigMap
metadata:
creationTimestamp: "2021-09-07T19:52:42Z"
name: cm-02
namespace: default
resourceVersion: "61862"
uid: 3d36cfdd-ae83-4260-a318-62d7e519a385
$ echo "3333" >> sec-data.txt
$ kubectl create secret generic sec-02 --from-file=./sec-data.txt
$ kubectl get secret sec-02 -o yaml
apiVersion: v1
data:
sec-data.txt: MzMzMwo=
kind: Secret
metadata:
creationTimestamp: "2021-09-07T19:54:28Z"
name: sec-02
namespace: default
resourceVersion: "62005"
uid: dae91458-8874-44b7-9bc7-1fa51fb5360b
type: Opaque
2-2. Pod
spec.containers.env.name이 환경변수에서 사용하게 될 key값이 된다.
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-02
spec:
containers:
- name: container
image: coolguy239/init
env:
- name: env-key-cm-02
valueFrom:
configMapKeyRef:
name: cm-02
key: cm-data.txt
- name: env-key-sec-02
valueFrom:
secretKeyRef:
name: sec-02
key: sec-data.txt
EOF
pod/pod-02 created
2-3. Env 확인
spec.containers.env.name으로 설정한 env-key-cm-02, env-key-sec-02 값으로 key 값이 설정된 것을 확인.
$ kubectl exec -ti pod-02 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
$ env
env-key-cm-02=val
env-key-sec-02=3333
...
3. Volume Mount(File) 방식
File을 직접 ConfigMap을 설정했을 경우는 환경변수로 설정된 값이 변경이 되도 Pod가 재생성 되기 전까지는 변경이 없다. 하지만 Mount된 파일로 설정된 환경변수 값은 파일의 값을 변경하게 되면 환경변수에 바로 적용된다.
3-1. Pod
cm-02 ConfigMap을 Container에 Mount
$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-03
spec:
containers:
- name: container
image: coolguy239/init
volumeMounts:
- name: file-volume
mountPath: /mount
volumes:
- name: file-volume
configMap:
name: cm-02
EOF
3-2. ConfigMap 수정(cm-02)
값을 val에서 val1212로 변경
$ kubectl edit configmap cm-02
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
cm-data.txt: |
val1212
kind: ConfigMap
metadata:
creationTimestamp: "2021-09-07T19:52:42Z"
name: cm-02
namespace: default
resourceVersion: "61862"
uid: 3d36cfdd-ae83-4260-a318-62d7e519a385
3-2. File방식과 File Mount 방식 비교
# File 방식(pod-02)
$ kubectl exec -ti pod-02 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@pod-02:/# env
env-key-cm-02=val
env-key-sec-02=3333
# File Mount 방식(pod-03)
$ kubectl exec -ti pod-03 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
$ cat ./mount/cm-data.txt
val1212
참고
KUBETM BLOG
쿠버네티스 공식사이트-Configure a Pod to Use a ConfigMap
쿠버네티스 공식사이트-Distribute Credentials Securely Using Secrets
WEBNORI - Kubernetes