오브젝트는 Kubernetes 에서 템플릿 등을 이용해 자원에 대한 Desired State (사용자가 원하는 상태) 를 설명하는 리소스 입니다.
Kubernetes 에서 생성하고 관리할 수 있는 가장 작은 단위의 배포 가능 컴퓨팅 단위입니다. Pod 는 하나 이상의 컨테이너로 이루어져 있으며, Pod 내 컨테이너는 네트워크, 스토리지를 공유하며 항상 같이 배치, 스케줄 됩니다.
Pod 는 Linux Namespace, cgroup (컨트롤 그룹), 컨테이너 격리 등의 기술로 격리되어 있어 Pod 의 컨텍스트 내의 동작은 외부의 영향을 받거나 주지 않습니다.
아래는 Pod를 단독으로 생성할 때 사용하는 예제입니다. 일반적인 상황에서는 사용될 일이 매우 적습니다.
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
Pause Container 는 Pod 내부의 컨테이너들을 위한 일종의 '부모 컨테이너' 와 같은 역할을 수행합니다.
PID Namespace
대상 프로세스들을 다른 Namespace 의 프로세스들과 격리
Network Namespace
대상 프로세스들의 네트워크를 다른 네트워크와 격리, 같은 네임스페이스 내의 프로세스들과 포트 중복 불가 (같은 인터페이스를 공유하기 때문)
UTS Namespace
컨테이너마다 고유의 Hostname 을 부여 (프로세스의 Hostname을 격리)
좀비 프로세스
부모 프로세스와 자식 프로세스가 있다고 할 때, 부모 프로세스가 자식 프로세스보다 먼저 종료되면 자식 프로세스는 종료되지 못하게 됨. 이를 좀비 프로세스 라고 부름.
리눅스에서는 이러한 좀비 프로세스를 PID 1번을 가진 프로세스 (Init Process) 에 할당해주며, 이 1번 프로세스는 좀비 프로세스를 종료시켜줌.
컨테이너의 프로세스 생성 방식
컨테이너는 기본적으로 외부와 단절된 단일 프로세스로 구성되도록 설계 되어 있기 때문에, 컨테이너 내에선 기본적으로 시작 프로세스의 PID 가 1번으로 설정
그런데 만약 컨테이너 내의 프로세스가 하나만 실행되는 것이 아닌 여러 프로세스가 실행된다면 위에서 언급한 좀비 프로세스 문제가 발생할 수 있는데, 문제는 시작 프로세스가 부모 프로세스이면서 1번 PID 를 가지게 되어 있기 때문에 자식 프로세스는 1번 프로세스가 죽으면 그대로 좀비 프로세스로서 계속 시스템에 남게 됨
이를 해결하기 위해 Pod 에선 PID Namespace 기능을 이용해 Pod 내의 컨테이너가 1번 PID 로 Pause Container 를 사용하게 해 Pause Container 의 프로세스가 좀비 프로세스를 죽이도록 함
네트워킹 문서 내 Service Object 항목 참조
Pod 에 연결 할 수 있는 저장소 입니다. Docker 에서 저장소를 매핑하지 않고 실행하면 임시 저장소가 할당 되듯이 Kubernetes 에서도 임시 저장소가 할당 되며, 별도로 설정하지 않으면 자료가 유실되기 때문에 이를 막기 위해 설정합니다.
Volume 은 지정된 특정 Pod 의 라이프사이클을 따라가기 때문에 사용되는 Volume 이나 설정에 따라 Pod 가 생성될 때 생성되고 삭제될 때 같이 삭제됩니다.
emptyDir
기본적으로 생성되는 임시 저장소이며, Pod 가 삭제되지 않고 단순히 컨테이너만 재생성 혹은 재시작 한다면 저장소는 지워지지 않습니다.
hostPath
호스트가 되는 Node 의 특정 경로를 매핑하는 저장소이며, Pod 가 삭제되어도 데이터가 삭제되지는 않습니다. 하지만 Node 에 의존적이기 때문에 Pod 가 다른 Node 로 이전되면 저장소에 접근이 불가합니다.
apiVersion: v1
kind: Pod
metadata:
name: hostpath
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: volumepath
mountPath: /usr/share/nginx/html
# 볼륨 매핑
volumes:
- name : volumepath
hostPath:
path: /imsi
type: Directory
gitRepo
특정 Git 에 있는 Repository 를 Clone 하여 매핑해 사용하는 저장소이며, 물리적으로는 emptyDir 타입의 저장소이기 때문에 동일한 특성을 가져갑니다.
Volume 을 사용하려면 개발자가 Pod 등에 볼륨을 지정 할 때마다 입력 할 물리적인 정보를 잘 알고 있어야 하기 때문에 사용하기 까다롭습니다.
Persistent Volume (PV) 와 Persistent Volume Claim (PVC) 는 디스크를 추상화 하여 개발자가 손쉽게 필요한 Volume를 사용할 수 있게 하며, NFS, iSCSI, cephFS 등의 범용 Network Storage 뿐만 아니라 Amazon EBS, Azure Disk, GCE Persistent Disk 등의 클라우드 스토리지를 사용 할 수 있습니다. 또한 플러그인 형태로 새로운 Volume Type 을 사용할 수도 있습니다.
시스템 관리자가 사용될 디스크를 PV로서 Kubernetes에 등록하면, 개발자는 Pod를 생성할때 Volume에 PVC를 지정하여 관리자가 생성한 PV를 Provision 받아 사용합니다.
이렇게 발급 받은 볼륨은 Pod 의 라이프사이클에 관계 없이 자신만의 라이프사이클을 가지기 때문에 Pod 가 삭제되어도 볼륨이 삭제되지 않습니다, 만약 Pod 를 삭제해 볼륨이 필요 없어졌다면 별도로 PVC 를 삭제해주어야 합니다. 다만, 설정으로 PVC 가 삭제되었을 때 볼륨이 같이 삭제될 지, 아니면 재사용 가능하도록 할당을 해제하지 않을지 등의 동작 선택이 가능합니다.
또한 볼륨을 다른 Pod 에서 재사용 할 수 있으며, 재사용시 저장된 데이터를 유지할 지, 아니면 데이터를 비울지를 설정할 수 있습니다.
정적 생성
관리자가 미리 적절한 설정을 통해 PV를 생성하면 추후 사용자가 PVC를 생성해 Claim 하는 방식입니다.
만약 관리자가 생성한 PV가 100GB 인데 PVC가 요청한 PV가 150GB 면 생성에 실패해 사용하지 못합니다.
동적 생성
미리 PV를 만들지 않고, 사용자가 PVC를 생성해 요청한 시점에 PV를 생성해서 제공해 주는 방식입니다. Kubernetes 클러스터를 위해 1TB 짜리 스토리지를 준비해 뒀다고 하면 사용자가 필요할 때 스토리지 용량 한도 내에서 원하는 용량만큼 생성해 사용할 수 있습니다.
동적 프로비저닝을 위해서 PVC는 StorageClass를 사용합니다. StorageClass를 이용해서 원하는 스토리지에 PV를 생성합니다.
# PV 생성
apiVersion: v1
kind: PersistentVolume
metadata:
name: dev-pv
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
storageClassName: slow
persistentVolumeReclaimPolicy: Delete
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp/log_backup
server: 172.17.0.2
Capacity
볼륨의 용량을 정의한다.
StorageClassName
사용할 Storage Class 의 이름을 지정한다. 만약 사용자가 PVC에 지정한 Storage Class 와 동일하고 디스크의 용량이 충분하다면 PV를 동적 생성 하지 않고 정적 생성한 디스크를 할당받는다.
VolumeMode
VolumeMode는 Filesystem (기본값)또는 Block 으로 설정할 수 있다. Filesystem 은 해당 Pod의 디렉토리에 마운트 되는 방식이며, Block 은 블록 장치로서 하드디스크를 붙인 것 처럼 제공된다.
Reclaim Policy
PV는 연결된 PVC가 삭제된 후 다시 다른 PVC에 의해서 재사용이 가능한데, 재사용시에 디스크의 내용을 지울지 유지할지에 대한 정책을 Reclaim Policy를 이용하여 설정이 가능하다.
Reclaim Policy은 모든 디스크에 적용이 가능한것이 아니라, 디스크의 특성에 따라서 적용이 가능한 Policy가 있고, 적용이 불가능한 Policy 가 있다.
AccessMode
AccessMode는 PV에 대한 동시에 Pod에서 접근할 수 있는 정책을 정의한다.
여러개의 모드가 있지만, 모든 디스크에 사용이 가능한것은 아니고 디스크의 특성에 따라서 선택적으로 지원된다.
보통 클라우드 스토리지는 디스크 용량의 제한이 없거나 크며 용량보다는 속도에 따른 Disk Tier 가 나누어져 있는데, 어떤 클라우드 스토리지의 어떤 Tier 의 스토리지를 할당받아 사용할 것인지 등을 지정하기 위해 StorageClass 리소스를 생성해 설정한다.
# AWS EBS 의 예제
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
# 이곳에 지정된 이름이 PV, PVC 에서 사용된다
name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
# Storage 의 Tier 나 옵션 등을 지정한다
type: io1
zones: eu-west-1a, eu-west-1b
iopsPerGB: "10"
fsType: ext4
디스크를 할당받기 위해 PVC를 생성한다.
지정된 StorageClass에 속한 PV를 찾고, 없으면 동적으로 PV를 생성하여 할당받는다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: slowclaim
labels:
app: nginx
spec:
storageClassName: slow
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
# 만약 Selector 를 사용하면 이미 생성된 PV 중 해당 Selector 를 만족하는 PV를 찾아 할당한다
selector:
matchLabels:
release: "stable"
이후 Pod 등의 자원 선언에서 PVC를 이름을 지정해 연결한다.
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
# 할당할 볼륨 정보 선언
volumeMounts:
- name: redispath
mountPath: /data/shared
volumes:
- name : redispath
persistentVolumeClaim:
claimName: slowclaim
Kubernetes 내에 생성할 수 있는 일종의 가상 클러스터로서 여러 팀이나 여러 프로젝트가 존재하는 상황에서 혼돈을 줄이고 특정 자원을 찾기 쉽게 하기 위해 도입되었다.
이외에도 Namespace 별로 Quota를 설정하여 사용량을 제한할 수도 있다.
기본 생성되는 Namespace는 아래와 같다
default
기본 Namespace이다. 쿠버네티스에서 별도의 Namespace를 지정하는 명령어를 입력하지 않는이상 default Namespace에 적용한다.
kube-system
쿠버네티스 시스템에서 관리하는 Namespace로 관리용 파드나 설정이 있다.
kube-public
클러스터 안 모든 사용자가 읽을 수 있는 Namespace스이다.
⇒ 모두가 볼 수 있기 때문에 클러스터 사용량 같은 정보를 이곳에서 관리한다.
kube-node-lease
각 노드의 임대 오브젝트(Lease Object)들을 관리하는 Namespace이다
Namespace 에는 어떠한 자원이든 추가가 가능하며, 조회시 해당 Namespace 를 조건으로 조회하여야 한다.
# 네임스페이스 생성
kubectl create namespace {네임스페이스 이름}
# 모든 네임스페이스 조회
kubectl get namespace
# 네임스페이스 내 모든 자원 조회
kubectl get all -n {네임스페이스 이름}
# 모든 네임스페이스의 모든 Pod 를 표시
kubectl get pods --all-namespaces
# 네임스페이스 삭제
kubectl delete namespace {네임스페이스 이름}