목차
쿠버네티스는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장가능한 오픈소스 플랫폼이다. 쿠버네티스는 선언적 구성과 자동화를 모두 용이하게 해준다. 쿠버네티스는 크고, 빠르게 성장하는 생태계를 가지고 있다. 쿠버네티스 서비스, 기술 지원 및 도구는 어디서나 쉽게 이용할 수 있다.
쿠버네티스란 명칭은 키잡이(helmsman)나 파일럿을 뜻하는 그리스어에서 유래했다. K8s라는 표기는 “K”와 “s”와 그 사이에 있는 8글자를 나타내는 약식 표기이다. 구글이 2014년에 쿠버네티스 프로젝트를 오픈소스화했다. 쿠버네티스는 프로덕션 워크로드를 대규모로 운영하는 15년 이상의 구글 경험과 커뮤니티의 최고의 아이디어와 적용 사례가 결합되어 있다.
즉, 쿠버네티스(k8s)는 컨테이너 오케스트레이션 도구의 일종으로 여러 개의 컨테이너(서버)를 관리하는 도구
클러스터 - 마스터 노드와 워커 노드
쿠버네티스는 도커 엔진등의 컨테이너 엔진과는 별개의 소프트웨어로 쿠버네티스 소프트웨어와 CNI(가상 네트워크 드라이버)를 설치 해야한다.
마스터 노드(Master Node)
- 전체적인 제어를 담당
- 마스터 노드에는 컨테이너 등의 상태를 관리하기 위해
etcd라는 데이터베이스가 설치되고, 마스터 노드를 설정하는 관리자 컴퓨터에는kubectl을 설치하여 초기 설정 및 조정이 가능하다.
워커 노드(Worker Node)
- 실제 도커 컨테이너의 동작을 담당
- 워커노드에는 도커 엔진과 같은 컨테이너 엔진이 필요하다
컨트롤 플레인(제어판)과 kube-let
마스터 노드는 컨트롤 플레인을 통해 워커노드를 관리한다.
| 항목 | 내용 |
|---|---|
| kube-apiserver | 외부와 통신하는 프로세스, kubectl로 부터 명령을 전달받아 실행 |
| kube-controller-manager | 컨트롤러를 통합 관리, 실행 |
| kube-scheduler | 파드를 워커 노드에 할당 |
| cloud-controller-manager | 클라우드 서비스와 연동해 서비스를 생성 |
| etcd | 클러스터와 관련된 정보 전반을 관리하는 데이터베이스 |
워커노드는 kube-let과 kube-proxy가 동작하며, kube-let 은 마스터 노드의 kube-scheduler와 연동하며 워커 노드에 컨테이너 또는 볼륨을 배치하고 실행한다.
| 항목 | 내용 |
|---|---|
| kubelet | 마스터 노드에 있는 kube-scheduler와 연동하며 워커 노드에 파드를 배치하고 실행한다. 또 실행 중인 파드의 상태를 정기적으로 모니터링하며 kube-scheduler에 통지한다 |
| kube-proxy | 네트워크 통신 라우팅 알고리즘 |
쿠버네티스 대시보드 탭
| 리소스 | 용도 |
|---|---|
| 노드 (Node) | 쿠버네티스 클러스터에서 실행되는 컨테이너 배포 서버 |
| 네임스페이스(Namespace) | 쿠버네티스 클러스터 내부에서 생성하는 가상 클러스터 |
| 파드(Pod) | 컨테이너 집합체 단위로 컨테이너 실행 방법을 정의 |
| 레플리카셋(Replicaset) | 동일한 스펙의 여러 파드를 생성, 관리 |
| 디플로이먼트(Deployment) | 레플리카셋의 세대 관리 |
| 서비스 (Service) | 파드 집합에 액세스하기 위한 경로 정의 |
| 인그레스(Ingress) | 서비스를 쿠버네티스 클러스터 외부에 공개 |
| 컨피그 맵configMap | 설정 정보 정의, 파드에 공급 |
| 퍼시스턴트 볼륨(PersistentVolume) | 파드가 사용하는 스토리지의 크기와 유형을 정의 |
| 퍼시스턴트 볼륨 클레임(PersistentvolumeClaim) | 퍼시스턴트 볼륨을 동적으로 확보 |
| 스토리지 클래스 (StorageClass) | 퍼시스턴트 볼륨이 확보한 스토리지 유형 정의 |
| 스테이트풀셋 (StatefulSet) | 같은 스펙으로 고유성이 있는 여러 파드를 생성, 관리 |
| 데몬셋 (DaemonSet) | 모든 Worker Node에서 단일 파드를 생성, 관리 |
| 잡 (Job) | 상주 목적이 아닌 여러 파드를 생성하고 정상 종료 보장 |
| 크론 잡 (CronJob) | cron 기법으로 스케줄링하여 실행되는 잡 |
| 시크릿 (Secret) | 인증 정보 등 보안 데이터 정의 |
| 롤(Role) | 네임스페이스 내부에서 조작할 수 있는 쿠버네티스 리소스 규칙 정의 |
| 롤 바인딩 (RoleBinding) | Role과 쿠버네티스 리소스 사용 유저 연결 |
| 클러스터 롤 (ClusterRole) | Cluster 전체에서 조작할 수 있는 쿠버네티스 리소스 규칙 정의 |
| 클러스터 롤 바인딩 (ClusterRoleBinding) | ClusterRole과 쿠버네티스 리소스 사용 유저 연결 |
| 서비스 어카운트 (ServiceAccount) | 파드가 쿠버네티스 리소스를 조작할 때의 계정 |
${DASHBOARD_TOKEN}
네임스페이스(Namespace)
네임스페이스(Namespace) 단일 클러스터 내부를 논리적으로 분리해, 가상 클러스터처럼 사용할 수 있게 해주는 그룹 격리 메커니즘이다. 네임스페이스 내에서 유일해야 하며, 네임스페이스 간에서 유일할 필요는 없다
클러스터를 생성하면 기본적으로 default, kube-node-lease, kube-public, kube-system 네임스페이스가 생성되어 있다. 현재 클러스터에 존재하는 네임스페이스 목록은 kubectl get namespace 명령으로 확인할 수 있다.
일정규모 이상의 팀 개발에서 유용
파드(Pod)
파드(Pod) 는 쿠버네티스에서 생성하고 관리할 수 있는(컨테이너 집합 그룹) 배포 가능한 가장 작은 컴퓨팅 단위로, 적어도 하나의 컨테이너를 갖는다.
- 파드는 Worker Node에 배치
- 같은 Pod를 복수의 Node에 배치하거나 하나의 노드에 여러 개를 배치할 수 있다
- 동일한 파드 내부의 컨테이너는 모두 동일한 노드에 배치
- 하나의 파드 내부의 컨테이너는 여러 노드에 걸쳐 배치할 수 없다.
[파드의 사용]
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
[파드 템플릿]
apiVersion: batch/v1
kind: Job
metadata:
name: hello
spec:
template:
# 여기서부터 파드 템플릿이다
spec:
containers:
- name: hello
image: busybox:1.28
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
# 여기까지 파드 템플릿이다
[파드 반영]
kubectl apply -f pod.yaml
[파드 목록가져오기]
kubectl get pod
[파드 삭제]
kubectl delete pod nginx
레플리카셋(ReplicaSet)
파드를 정의한 매니페스트 파일은 하나의 파드만 만들 수 있다. 그러나 일정 규모 이상의 애플리케이션을 구축할 때느 동일한 파드를 복제하여 실행하면서 가용성을 높힐 때 레플리카셋(ReplicaSet)을 사용한다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# 케이스에 따라 레플리카를 수정한다.
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
[레플리카셋 반영]
kubectl apply -f replicaset.yaml
[현재 배포된 레플리카셋 확인]
kubectl get rs
[레플리카셋의 상태 확인]
kubectl describe rs/frontend
[레플리카셋 삭제]
kubectl delete -f replicaset.yaml
디플로이먼트(Deployment)
디플로이먼트는 애플리케이션 배포의 기본 단위가 되는 리소스로, 레플리카셋을 관리하고 조작하기 위해 제공되는 리소스이다.
- 파드와 레플리카셋에 대한 선언적 업데이트를 제공
flowchart LR D["Deployment"] --> |create| RS["ReplicaSet"] subgraph Pods["Pods (replicas)"] direction TB P1["Pod (nginx-1a)"] P2["Pod (nginx-2b)"] P3["Pod (nginx-3c)"] end RS --> |create| P1 RS --> |create| P2 RS --> |create| P3
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
[디플로이먼트 반영]
kubectl apply -f deployment.yaml
[디플로이먼트 확인]
kubectl get deployments
쿠버네티스는 디플로이먼트를 하나의 단위로 하여 애플리케이션을 배포한다.
실제 운영에서는 대부분 레플리카셋을 직접 사용하지 않고, 디플로이먼트의 매니페스트 파일을 루는 방식을 사용
서비스(Service)
쿠버네티스 클러스터 내에서 파드 집합(주로 레플리카셋)에 대한 경로와 서비스 디스커버리(Service Discovery)를 제공하기위한 리소스로 서비스 대상이 되는 파드와 서비스로 정의된 레이블 셀렉터에 의해 결정된다.
쿠버네티스는 파드에게 고유한 IP 주소와 파드 집합에 대한 단일 DNS 명을 부여하고, 그것들 간에 로드-밸런스를 수행할 수 있다.
Pod는 죽었다 살아나면 IP가 바뀔 수 있기 때문에 Pod 직접 붙으면 불안정 하므로, Service가 고정된 이름과 가상 IP를 제공해서 다른 Pod나 외부 트래픽을 안정적으로 접근하게 해준다.
서비스 종류
ClusterIP 서비스(기본값)
- 쿠버네티스 클러스터 내부 IP 주소로 서비스를 공개
- 한 Pod에서 다른 Pod 그룹에 대한 엑세스는 서비스를 통해 가능
- 서비스명으로 이름 분석도 가능
- 클러스터 외부에서 접근 불가
- 파드 그룹에 대한 엑세스 포인트로 IP 주소가 부여
[외부] -> Service(NodePort) -> Pod(Nginx)
[Deployment]
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
[Service]
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
Headless 서비스
-
서비스에 고유한 IP 주소를 설정하지 않는 구조
-
ClusterIP에 None을 지정
apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: ClusterIP clusterIP: None selector: app: nginx ports: - port: 80 targetPort: 80
NodePort 서비스
- 클러스터 외부에서 액세스 할 수 있는 서비스
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
LoadBalancer 서비스
- 주로 각 클라우드 플랫폼에서 제공되는 로드밸런서와 연동하기 위해 사용되며, 로컬 쿠버네티스 환경에서 사용할 수 없는 서비스.(ELB 등)
ExternalName 서비스
- selector, port도 가지지 않는 서비스.
- 쿠버네티스 클러스터 내부에서 외부 호스트를 해결하기 위해 별칭을 제공
apiVersion: v1
kind: Service
metadata:
name: nginx-ext-service
spec:
type: ExternalName
externalName: ext-nginx.com
인그레스(Ingress)
쿠버네티스 클러스터 외부에 서비스를 공개하려면 NodePort로 공개해야 하지만, 이 방법은 L4계층까지로 한정되어 HTTP/HTTPS와 같이 경로 베이스로 대상 서비스를 전환하는 L7 계층의 제어는 불가하다.
그래서 인그레스(Ingress)를 사용하면 서비스를 쿠버네티스 클러스터 외부에 공개하고 VirtualHost와 경로 베이스의 고급 HTTP 라우팅을 제공.
정리
- Deployment: 몇 개의 Pod를 띄울지 관리
- Pod: 실제 앱 실행
- Service: 그 Pod들에 안정적으로 접근하게 해줌
flowchart LR
U[User] --> ING[Ingress]
subgraph K8S[Kubernetes Cluster]
subgraph APP[Namespace: task-app]
subgraph WEB[web]
W_DEP[Deployment]
W_RS[ReplicaSet]
W_P1[Pod]
W_P2[Pod]
W_SVC[Service]
W_DEP --> W_RS
W_RS --> W_P1
W_RS --> W_P2
W_SVC --> W_P1
W_SVC --> W_P2
end
subgraph API[api]
A_DEP[Deployment]
A_RS[ReplicaSet]
A_P1[Pod]
A_P2[Pod]
A_SVC[Service]
A_DEP --> A_RS
A_RS --> A_P1
A_RS --> A_P2
A_SVC --> A_P1
A_SVC --> A_P2
end
subgraph DB[mysql]
M_STS[StatefulSet]
M_P[Pod]
M_SVC[Service]
PVC[PVC]
M_STS --> M_P
M_SVC --> M_P
M_P --> PVC
end
ING --> W_SVC
W_P1 --> A_SVC
W_P2 --> A_SVC
A_P1 --> M_SVC
A_P2 --> M_SVC
end
end