용찬호. 「 시작하세요! 도커/쿠버네티스」. 위키북스 를 읽으며, 학습한 내용을 정리하는 글입니다.
→ 본문의 내용은 모두 책의 내용에 대한 직/간접적 인용임을 밝힙니다.
→ 포드의 데이터를 영속적으로 저장하기 위한 방법이 필요!
→ 어느 노드에서도 접근해 사용할 수 있는 퍼시스턴트 볼륨(Persistent Volume)을 사용하는 것이 일반적!
[ 퍼시스턴트 볼륨 ]
hostPath
: 호스트와 볼륨을 공유하기 위해서 사용emptyDir
: 포드의 컨테이너 간에 볼륨을 공유하기 위해서 사용apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: my-container
image: busybox
args: ["tail", "-f", "/dev/null" ]
volumeMounts:
- name: my-hostpath-volume
mountPath: /etc/data
volumes:
- name: my-hostpath-volume
hostPath:
path: /tmp
→ 호스트의 /tmp를 포드의 /etc/data에 마운트
** 바람직한 방식은 아님!
emptyDir
이름처럼, 비어있는 상태로 생성되고, 포드가 삭제되면 emptyDir
에 저장돼 있던 데이터도 함께 삭제apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
spec:
containers:
- name: content-creator
image: alicek106/alpine-wget:latest
args: ["tail", "-f", "/dev/null"]
volumeMounts:
- name: my-emptydir-volume
mountPath: /data # 1. 이 컨테이너가 /data에 파일을 생성하면
- name: apache-webserver
image: httpd:2
volumeMounts:
- name: my-emptydir-volume
mountPath: /usr/local/apache2/htdocs. # 2. 아파치 웹서버에서 접근 가능
volumes:
- name: my-emptydir-volume
emptyDir: {}. # 포드 내에서 파일을 공유하는 emptyDir
→ 이러한 문제를 해결하기 위해, 퍼시스턴트 볼륨(PV)와, 퍼시스턴트 볼륨 클레임(PVC)를 사용!
포드가 볼륨의 세부 사항을 몰라도 볼륨을 사용할 수 있도록 추상화해 준다.
즉, 포드를 생성하는 YAML은 네트워크 볼륨이 NFS인지, AWS의 EBS인지 상관없이 볼륨 사용 가능!
사용자는 디플로이먼트의 YAML 파일에 볼륨의 상세한 스펙을 정의하지 않는다.
[ AWS에서 EBS를 퍼시스턴트 볼륨으로 사용하기 ]
1. EBS 생성
export VOLUME_ID=$(aws ec2 create-volume --size 5 \
--region ap-northeast-2 \
--availability-zone ap-northeast-2a \
--volume-type gp2 \
--tag-specifications \
'ResourceType=volume, Tags=[{Key=KubernetesCluster, Value=mycluster.k8s.local}]' \
| jp '.VolumeId' -r)
apiVersion: v1
kind: PersistentVolume
metadata:
name: ebs-pv
spec:
capacity:
storage: 5Gi # 이 볼륨의 크기는 5G
accessModes:
- ReadWriteOnce #하나의 포드(또는 인스턴스)에 의해서만 마운트될 수 있다.
awsElasticBlockStore:
fsType: ext4
volumeID: <VOLUME_ID>
[ 퍼시스턴트 볼륨 클레임과 포드를 함께 생성 ]
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-ebs-pvc #1. my-ebs-pvc라는 이름의 pvc를 생성
spec:
storageClassName: ""
accessModes:
- ReadWriteOnce #2.1 속성이 ReadWriteOnce인 퍼시스턴트 볼륨과 연결
resources:
requests:
storage: 5Gi. #2. 볼륨 크기가 최소 5Gi인 퍼시스턴트 볼륨과 연결
---
apiVersion: v1
kind: Pod
metadata:
name: ebs-mount-container
spec:
containers:
- name: ebs-mount-container
image: busybox
args: ["tail", "-f", "/dev/null" ]
volumeMounts:
- name: ebs-volume
mountPath: /mnt
volumes:
- name: ebs-volume
persistentVolumeClaim:
claimName: my-ebs-pvc. # 3. my-ebs-pvc라는 이름의 pvc를 사용
AccessMode
, 볼륨의 크기 등이 이러한 조건에 해당!accessMode
및 볼륨 크기 속성이 부합해야, 쿠버네티스는 두 리소스를 매칭해 바인드한다. [ 퍼시스턴트 볼륨의 STATUS ]
Available
: 퍼시스턴트 볼륨이 사용 가능한 상태Bound
: 퍼시스턴트 볼륨 클레임을 새로 생성해, 바인드.Released
: 퍼시스턴트 볼륨과 연결된 퍼시스턴트 볼륨 클레임 삭제 상황 Released
상태의 퍼시스턴트 볼륨을 다시 사용할 수 없음. [ Reclaim Policy ]
< Reclaim Policy의 종류 >
Retain
: 연결된 퍼시스턴트 볼륨 클레임 삭제 후에 Released
전환, 실제 데이터는 보존Delete
: 퍼시스턴트 볼륨 사용 종료 이후 자동적으로 삭제됨Recycle
: 퍼시스턴트 볼륨 클레임 삭제시, 퍼시스턴트 볼륨의 모든 데이터를 삭제 후 Available
로 전환 Deprecated
된 기능.[ kubectl 명령어를 사용해 쿠버네티스 기능 실행 시, 일어나는 일들 ]
1. HTTP 핸들러 : kubectl
명령어가 쿠버네티스 API 서버의 HTTP 핸들러에 요청을 전송
2. Authentication & Authorization : API 서버는 해당 클라이언트가 쿠버네티스의 사용자가 맞는지 (인증), 해당 기능을 실행할 권한이 있는지 (인가) 확인
3. 어드미션 컨트롤러 단계를 거친 뒤, 요청받은 기능을 수행
→ kubectl 사용시, 이런 과정을 신경쓰지 않았던 것은
설치 도구가 자동으로 kubectl이 관리자 권한을 갖도록 설정하기 때문
→ ~/.kube/config 파일에서 확인!
[ Role 사용하기 ]
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: service-reader
rules:
- apiGroups: [""] #1. 대상이 될 오브젝트의 API 그룹
resources: ["services"] #2. 대상이 될 오브젝트의 이름
verbs: ["get", "list"] #3. 어떠한 동작을 허용할 것인지 명시
apiGroups
: 어떠한 API 그룹에 속하는 오브젝트에 대해 권한을 지정할지 설정. API 그룹은 쿠버네티스의 오브젝트가 가지는 목적에 따라 분류되는, 일종의 카테고리resources
: 어떠한 쿠버네티스 오브젝트에 대해 권한을 정의할 것인지 입력verbs
: 이 롤을 부여받은 대상이 resources에 지정된 오브젝트들에 대해 어떤 동작을 수행할 수 있는지 정의→ 코어 API 그룹("")에 속하는 서비스 리소스에 대해 get과 list를 실행할 수 있다.
[ ex. 서비스 어카운트에 롤에 정의된 권한 부여하기 ]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: service-reader-rolebinding
namespace: default
subjects:
- kind: ServiceAccount # 권한을 부여할 대상이 ServiceAccount
name: alicek106 # alicek106이라는 이름의 서비스 어카운트에 권한을 부여
namespace: default
roleRef:
kind: Role #Role에 정의된 권한을 부여합니다.
name: service-reader # service-reader라는 이름의 Role을 대상(subjects)에 연결
apiGroup: rbac.authorization.k8s.io
→ 롤 바인딩과 롤, 서비스 어카운트는 모두 1 : 1 관계가 아님!
→ 하나의 롤은 여러 개의 롤 바인딩에 의해 참조될 수 있고, 하나의 서비스 어카운트는 여러 개의 롤 바인딩에 의해 권한을 부여받을 수 있다.
롤은 권한을 부여하기 위한 일종의 템플릿, 롤 바인딩은 롤과 서비스 어카운트를 연결하기 위한 중간 다리
[ 클러스터 롤 ]
쿠버네티스 클러스터 내부 애플리케이션은 어떻게 API 서버에 접근하고 인증을 수행하는가?
→ 이를 위해 쿠버네티스는 클러스터 내부에서 API 서버에 접근할 수 있는 서비스 리소스를 미리 생성!
→ 기본적으로 존재하는 kubernetes
서비스가 그것이다.
쿠버네티스는 포드를 생성할 때 자동으로 서비스 어카운트의 시크릿을 포드 내부에 마운트한다.
ServiceAccount
대신 User
나 Group
도 사용 가능!