Gom3rye
Kubernetes- Volume API 본문
728x90
반응형
동적 시크릿 업데이트
- 볼륨 마운트를 사용한 시크릿에서는 일정 기간마다(kubelet의 Sync Loop 타이밍) kube apiserver로 변경을 확인하고 변경이 있을 경우 파일을 교체한다.
- Secret → yaml 파일을 이용해서 생성 But, 변경될 때마다 kubectl apply -f 하지 않아도 된다.
- 시크릿은 1분마다 api server에 변경 사항 있는지 물어보고 sync가 받는지 확인하면서 자동으로 변경 동기화한다.
- like Kafka : 매번 구독 신청하고 너 어디까지 받았니 어디까지 받았니~ 확인한다.
# Secret 생성을 위한 yaml 파일 작성(sample-db-auth.yaml)
apiVersion: v1
kind: Secret
metadata:
name: sample-db-auth
type: Opaque
stringData:
username: admin
password: rootpassword
# 확인
kubectl get service sample-db-auth -o yaml # username, password 잘 base64 인코딩 되어 들어갔다.
# secret을 파일로 저장해서 사용하기 위한 리소스 파일 생성(sample-secret-multi-volume.yaml)
apiVersion: v1
kind: Pod
metadata:
name: sample-secret-multi-volume
spec:
containers:
- name: secret-container
image: nginx:1.16
volumeMounts:
- name: config-volume
mountPath: /config
volumes: # ← containers 바깥, spec 아래에 위치해야 함
- name: config-volume
secret:
secretName: sample-db-auth
# 생성
kubectl apply -f sample-secret-multi-volume.yaml
# Secret이 잘 마운트되었는지 확인
kubectl exec -it sample-secret-multi-volume -- ls /config
password username
kubectl exec -it sample-secret-multi-volume -- cat /config/username # admin
kubectl exec -it sample-secret-multi-volume -- cat /config/password # rootpassword
# sample-db-auth.yaml 파일에서 password를 adminpassword로 수정하고 1분 정도 후에 파드를 다시 확인
# 기본적으로 파드가 볼륨 마운트 되어 있는 경우 그 내용을 1분마다 확인해서 변경된 내용이 있으면 다시 적용한다.
vi sample-db-auth.yaml
kubectl apply -f sample-db-auth.yaml
kubectl exec -it sample-secret-multi-volume -- cat /config/password
# adminpassword로 잘 바뀌어 있는 것을 확인할 수 있다. -> kubectl apply -f sample-secret-multi-volume.yaml 하지 않았음!!
→ 비밀(Secret), 설정(ConfigMap)을 VolumeMount로 마운트한 경우 굳이 apply 안 해도 알아서 변경 사항 반영해서 바뀌어준다.
어떨 때 Configmap을 쓰고 어떨 때 Secret을 쓰면 좋을까?
Secret과 ConfigMap
사용 구분
- 시크릿과 컨피그맵은 비슷한 리소스들이지만 가장 큰 차이점은 시크릿이 기밀 정보를 취급하기 위한 리소스라는 점이다.
- 시크릿 데이터는 쿠버네티스 마스터가 사용하는 분산 KVS(Key Value Store)의 etcd에 저장된다.
- 실제 시크릿을 사용하는 파드가 있는 경우에만 etcd에서 쿠버네티스 노드에 데이터를 전송한다.
- 이때 쿠버네티스 노드 상에 영구적으로 데이터가 남지 않도록 시크릿 데이터는 tmpfs(메모리 상에 구축된 임시 파일 시스템)에 저장된다.
- 매번 가져오지 않기 위해 VolumeMount를 쓰는 것
- 시크릿은 describe 일반 명령으로는 확인이 안되고 -o yaml 이나 -o json으로 확인을 하더라도 base64 인코딩해서 출력하기 때문에 화면에서 원래 문장을 읽어내기가 어렵다.
- 시크릿은 base64 인코딩만 되어 있기 때문에 그대로 깃 저장소 같은 곳에 업로드 하는 것은 피해야 하고 실제 운영 환경에서는 시크릿 자체를 암호화하는 OSS나 암호화 기능을 제공하는 Vault 같은 솔루션을 이용한다. (Vault는 오픈소스라서 그냥 가져다 쓰면 된다.)
컨피그맵과 시크릿의 데이터 마운트 시 퍼미션 변경
- 컨피그맵이나 시크릿에 스크립트를 저장하는 것이 가능하다.
- 컨피그맵 데이터에서 볼륨을 생성할 때 실행 권한을 부여할 수 있다.
실습 - 751(기타 사용자는 읽기만 하면 되니까) 많이 준다.
# sample-configmap-scripts.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-configmap-script
spec:
containers:
- name: configmap-container
image: nginx:1.16
command: ["/config/test.sh"]
volumeMounts:
- name: config-volume
mountPath: /config
volumes:
- name: config-volume
configMap:
name: sample-configmap
items:
- key: test.sh
path: test.sh
mode: 0755
시크릿이나 컨피그맵의 데이터 변경 여부
- 시크릿이나 컨피그맵을 여러 디플로이먼트에서 참조하는 경우 변경을 하게 되면 여러 애플리케이션에 영향을 준다.
- 수정이 안되도록 설정할 수 있는데 이때는 immutable이라는 키에 true를 설정하면 된다.
# Secret 생성을 위한 yaml 파일 작성(sample-secret-immutable.yaml)
apiVersion: v1
kind: Secret
metadata:
name: sample-secret-immutable
type: Opaque
stringData:
username: user00
password: rootpassword
immutable: true # 바꿀 수 없도록 만들고 싶으면
# 바꾸려고 하면 에러 난다.
kubectl apply -f sample-secret-immutable.yaml
# Forbidden: field is immutable when 'immutable' is set
Volume API
영구 볼륨 클레임
볼륨, 영구 볼륨, 영구 볼륨 클레임
- 볼륨은 미리 준비된 사용 가능한 볼륨(호스트 볼륨/nfs/iSCSI/Ceph)을 매니페스트에 직접 지정하여 사용할 수 있게 하는 것
- 사용자가 설정된 볼륨을 사용할 수 있지만 쿠버네티스에서 신규 볼륨을 생성하거나 기존 볼륨을 삭제하는 작업은 할 수 없다.
- 매니페스트에서 볼륨 리소스를 생성하는 것도 불가능하다. (일종의 Disk)
- 영구 볼륨은 외부 영구 볼륨을 제공하는 시스템과 연계하여 신규 볼륨을 생성하거나 기존 볼륨을 삭제하는 등의 작업이 가능하다.
- 매니페스트에서 영구 볼륨 리소스를 별도로 생성하는 형태
- 볼륨과 영구 볼륨은 같은 플러그인을 제공한다.
- GCP나 AWS 볼륨 서비스에서는 영구 볼륨 플러그인과 볼륨 플러그인 둘 다 제공한다.
- 영구 볼륨 플러그인에서는 볼륨 생성 및 삭제 같은 라이프사이클을 처리할 수 있지만(영구 볼륨 클레임을 사용하면 동적 프로비저닝도 가능하다.) 볼륨 플러그인에서는 기존에 있는 볼륨만 사용한다.
- 영구 볼륨 클레임은 생성된 영구 볼륨 리소스를 할당하는 리소스이다.
- 영구 볼륨은 클러스터에 볼륨을 등록만 하기 때문에 실제 파드에서 사용하려면 영구 볼륨 클레임을 정의하고 사용해야 한다.
- 동적 프로비저닝 기능을 사용한 경우에는 영구 볼륨 클레임이 사용된 시점에 영구 볼륨을 생성할 수 있다.
볼륨
- 쿠버네티스에서는 볼륨을 추상화하여 파드와 느슨하게 결합된 리소스로 정의한다.
- Secret과 ConfigMap도 볼륨 플러그인의 한 종류이다.
- 볼륨 플러그인의 종류
- emptyDir
- hostPath → 웬만해서는 쓰지 말아라 for 보안
- downwardAPI
- projectd
- nfs
- iscsi
- cephfs
emptyDir
"파드가 뜰 때, 빈 폴더 하나 만들어줄게. 네가 쓰다가 파드가 죽으면 폴더도 같이 지울게!”
- 파드용 임시 디스크 영역
- 파드가 삭제되면 같이 삭제된다.
- emptyDir 볼륨은 기본적으로 노드의 디스크에 저장된다.
# 볼륨을 마운트하는 파드 리소스 매니페스트 (sample-emptydir.yaml)
apiVersion: v1
kind: Pod
metadata:
name: sample-emptydir
spec:
containers:
- name: nginx-container
image: nginx:1.16
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
# 파드 생성
kubectl apply -f sample-emptydir.yaml
# 리소스를 확인해서 디스크 할당 여부(df -h) 확인 (/cache가 할당되었는지 확인)
kubectl exec -it sample-emptydir -- df -h
# /dev/mapper/ubuntu--vg-ubuntu--lv 19G 6.8G 11G 39% /cache
# 이 yaml 파일 configure 하고 싶다면 delete pod 후에 apply 하기!
- emptyDir.medium에 Memory를 설정하면 고속의 tmpfs 영역을 사용한다.
- tmpfs(Temporary File System) 영역을 사용하면 emptyDir.sizeLimit 속성을 이용해서 리소스 제한을 걸 수 있다.
- tmpfs on /cache → 메모리 기반 → sizeLimit이 적용됨
- /dev/... on /cache → 디스크 기반 → sizeLimit이 무시됨
# 볼륨을 마운트하는 파드 리소스 매니페스트 (sample-emptydir.yaml)
apiVersion: v1
kind: Pod
metadata:
name: sample-emptydir
spec:
containers:
- name: nginx-container
image: nginx:1.16
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
medium: Memory
sizeLimit: 128Mi
# 파드 지우고 yaml 파일 수정후 다시 생성
kubectl apply -f sample-emptydir.yaml
# 리소스를 확인해서 디스크 할당 여부(df -h) 확인 (/cache가 할당되었는지 확인)
kubectl exec -it sample-emptydir -- df -h
# tmpfs 128M 0 128M 0% /cache 로 잘 limit 된 걸 볼 수 있다.
# 디스크에 적용한 후 용량 이상의 파일을 생성 (파드 안에 0으로 채워진 200MB짜리 dummy 파일이 /cache 경로에 생성된다.)
kubectl exec -it sample-emptydir -- dd if=/dev/zero of=/cache/dummy bs=1M count=200
# emptyDir.sizeLimit이 제대로 적용되어 dd: writing to '/cache/dummy': No space left on device 에러가 뜬다.
- 사용할 때
- 여러 컨테이너가 공통 데이터를 공유해야 할 때
- 데이터를 잠깐만 저장하고 파드가 죽으면 자동으로 정리되길 원할 때
- 디스크 기반 캐시, 빌드 중간 산출물 저장 등
hostPath
노드의 진짜 파일 시스템을 파드에 연결해주는 것. (like "이 폴더를 저 컨테이너 안에서 보이게 해줘”)
- 쿠버네티스 노드 상의 영역을 컨테이너에 매핑하는 플러그인
- emptyDir과 다르게 호스트의 임의 영역을 마운트할 수 있기 때문에 사용할 때는 호스트의 어떤 영역을 사용할지 지정해야 한다.
- type은 Directory/DirectoryOrCreate/File/Socket/BlockDevice 등을 선택할 수 있다.
- Linux의 /etc 디렉토리를 파드의 /svc 에 연결
# sample-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-hostpath
spec:
containers:
- name: nginx-container
image: nginx:1.16
volumeMounts:
- mountPath: /srv
name: hostpath-sample
volumes:
- name: hostpath-sample
hostPath:
path: /etc
type: DirectoryOrCreate # 없으면 만들겠다.
# 리소스 생성
kubectl apply -f sample-hostpath.yaml
# 마운트 여부 확인 (/etc 에는 이미 파일이 존재하니까)
kubectl exec -it sample-hostpath -- ls /srv
# 이때 /etc 는 파드가 생성된 노드의 /etc다! (control plane의 /etc 가 아니라 workner node의 /etc)
- 🔸 emptyDir → 파드끼리 임시 파일 공유, 캐시용
- 🔸 hostPath → 노드의 로그, 설정파일, 시스템 자원 접근이 필요할 때 (hostPath는 주의해서 써야한다. 잘못하면 시스템 망가질 수 있으니)
downwardAPI
- 파드 정보 등을 파일로 배치하기 위한 API
- 파드를 확인할 때 -o json 이나 yaml로 확인한 내용은 fieldRef(파드 수준) 로 가져오고 resourceFieldRef(컨테이너 수준) 로는 limits.cpu, limits.memory, requests.cpu, requests.memory, requests.storage, status.allocatable.cpu, status.allocatable.memory 등이 있다.
# sample-downward-api.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-downward-api
spec:
containers:
- name: nginx-container
image: nginx:1.16
volumeMounts:
- mountPath: /srv
name: downward-api-volume
volumes:
- name: downward-api-volume
downwardAPI:
items:
- path: "podname"
fieldRef:
fieldPath: metadata.name
- path: "cpu-request"
resourceFieldRef:
containerName: nginx-container
resource: requests.cpu
# 확인
kubectl apply -f sample-downward-api.yaml
kubectl exec -it sample-downward-api -- ls /srv # cpu-request podname
kubectl exec -it sample-downward-api -- cat /srv/cpu-request # 0
kubectl exec -it sample-downward-api -- cat /srv/podname # sample-downward-api
projected
- secret/configmap/downwardAPI/serviceAccountToken의 볼륨 마운트를 하나의 디렉토리에 통합하는 플러그인 (다 때려박는 것)
- 시크릿 인증 정보와 컨피그맵 설정 파일을 하나의 디렉토리에 배치하고자 할 때 사용한다.
# secret 생성
kubectl apply -f sample-db-auth.yaml
# nginx.conf 파일로 configmap 생성
kubectl create configmap sample-configmap --from-file=nginx.conf
# projected를 사용하는 매니페스트 작성 (sample-projectdd.yaml)
apiVersion: v1
kind: Pod
metadata:
name: sample-projected
spec:
containers:
- name: nginx-container
image: nginx:1.16
volumeMounts:
- mountPath: /srv
name: projected-volume
volumes:
- name: projected-volume # pluggin 들어가고
projected:
sources:
- secret: # secret에서 sample-db-auth 가져온다.
name: sample-db-auth # secret의 안에 들어가야 한다.(들여쓰기 위치 주의)
items: # 다 가져올 건지 하나만 가져올 건지
- key: username
path: secret/username # 여기서 username만 가져와서 /srv에 저장한다.
- configMap: # configMap에서 sample-configmap 가져온다.
name: sample-configmap
items:
- key: nginx.conf
path: configmap/nginx.conf
- downwardAPI:
items:
- path: "podname" # 파일명
fieldRef:
fieldPath: metadata.name
# 확인
kubectl exec -it sample-projected -- ls /srv
## configmap podname secret
kubectl exec -it sample-projected -- cat /srv/secret # username
kubectl exec -it sample-projected -- ls /srv/configmap # nginx.conf
kubectl exec -it sample-projected -- cat /srv/podname # sample-projected
영구 볼륨 (Persistent Volume, PV)
- 영구 볼륨은 영속성 영역으로 확보된 볼륨
- 볼륨은 파드 정의 안에 직접 지정하는 형태로 연결하지만 영구 볼륨은 개별 리소스로 생성한 후 사용한다.
- 매니페스트를 사용하여 영구 볼륨 리소스를 생성한다.
- 컨피그나 스토리지 리소스가 아니라 클러스터 리소스이다.
- 종류
- 영구 볼륨은 기본적으로 네트워크를 통한 디스크를 attach 하는 개념이다.
- 단일 노드의 경우는 hostPath로 충분하지만 노드가 여러 개인 경우는 hostPath로는 불충분하다.
- 플러그인 종류
- GCE Persistant Disk → Public Cloud(백업 신경 안 써도 됨)
- AWS Elastic Block Store
- Azure File
- nfs
- iSCSI
- Ceph
- OpenStack Cinder → Private Cloud(내가 직접 백업 해야 함)
- GlusterFS
- Container Storage Interface(공통 인터페이스, 벤더와 관계 없이 표준화된 방식)
Container Storage Interface
- 컨테이너 오케스트레이션 엔진과 스토리지 시스템을 연결하는 인터페이스이다.
영구 볼륨 생성
- 영구 볼륨을 생성할 때 설정 가능한 항목이 있다.
- 레이블
- 용량
- 접근 모드
- Reclaim Policy
- 마운트 옵션
- 스토리지 클래스
- 각 플러그인 특유의 설정
- 구글 클라우드 볼륨을 사용하는 실습: 구글 클라우드에 할당을 하지 않으면 에러가 난다.
# sample-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: sample-pv
labels:
type: gce-pv
environment: stg
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
# 플러그인별 설정
gcePersistentDisk:
pdName: sample-gce-pv
fsType: ext4
# 리소스 생성
kubectl apply -f sample-pv.yaml
kubectl get persistentvolume
##
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
sample-pv 10Gi RWO Retain Available manual <unset> 32s
-----------------------
# 영구 볼륨을 사용하는 파드를 생성하는 리소스 매니페스트 파일 작성
# sample-pv-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-pv-readonlymany # 볼륨 연결할거라 labels 필요 x
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.16
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-pvc
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: sample-pvc
readOnly: true # 읽기만 가능
기본적으로 pod는 immutable이기 때문에 아래와 같은 상황에서는 delete pod 하고 apply 해야 한다.
- 컨테이너 이름 변경
- 볼륨 추가/변경
- 환경 변수 변경
- volumeMounts 변경
- command, args 변경
- 컨테이너 수 변경
728x90
반응형
'현대 오토에버 클라우드 스쿨' 카테고리의 다른 글
CI/CD (1) | 2025.07.14 |
---|---|
Kubernetes- Volume API, Requests, Limits (1) | 2025.07.11 |
Kubernetes- Config & Storage API (4) | 2025.07.09 |
Kubernetes- Session Affinity, Headless, ExternalName, None-Selector, Ingress (2) | 2025.07.08 |
Kubernetes Service의 type (1) | 2025.07.07 |