Kubernetes cluster 안에서 아래의 리소스를 연동하고 조합해서 Container 시스템을 구성할 수 있습니다.
Kubernetes cluster는 Kubernetes스의 여러 리소스를 관리하기 위한 집합체입니다.
Node
는 Container가 배치되는 대상으로 Kubernetes cluster 전체를 관리하는 서버인 Master Node
가 적어도 하나 있어야 합니다.
Cluster에 배치된 Node의 수, Node의 사양 등에 따라 배치할 수 있는 Container 수가 결정됩니다.
Component | Role |
---|---|
kube-apiserver | 쿠버네티스 API를 노출하는 kubectl로부터 리소스를 조작하라는 지시를 받습니다 |
etcd | 고가용성을 갖춘 분산 키-값 스토어로, 쿠버네티스 클러스터의 백킹 스토어로 쓰입니다 |
kube-scheduler | 노드를 모니터링하고 컨테이너를 배치할 적절한 노드를 선택합니다 |
kube-controller-manage | 리소스를 제어하는 컨트롤러를 실행합니다 |
Kubernetes안의 가상 Cluster를
namespace
라고 합니다.
namespace마다 권한을 설정할 수 있습니다.
'Pod는 Container가 모인 집합체의 단위'로, 하나 이상의 Container로 이뤄집니다.
Pod는 Node에 배치
해야하고, 하나의 Pod는 여러 Node에 걸쳐 배치될 수 없습니다.
Pod 생성은 kubectl로도 생성할 수 있지만, 버전 관리 관점에서 yaml파일로 관리하는 것이 좋습니다.
Kubernetes의 여러 리소스를 정의하는 파일을 manifest 파일이라고 합니다.
아래는 nginx + echo 2개의 Container로 구성된 Pod를 정의한 manifest 파일입니다.
apiVersion: v1
kind: Pod
metadata:
name: simple-echo
spec:
containers:
- name: nginx
image: gihyodocker/nginx:latest
env:
- name: BACKEND_HOST
value: localhost:8080
ports:
- containerPort: 80
- name: echo
image: gihyodocker/echo:latest
ports:
- containerPort: 8080
kind
: 파일에서 정의하는 Kubernetes 리소스의 유형을 지정합니다. kind의 속성에 따라 spec아래의 schema가 변경됩니다.
metadata
: 리소스에 부여되는 메타데이터입니다.
metadata.name
: 리소스의 이름을 설정합니다.
spec
: Pod를 구성하는 Container를 containers아래 정의합니다.
containers
: Container의 속성을 정의합니다.
containers.name
: Container 이름입니다.
containers.image
: 도커 허브에 저장된 이미지 태그 값입니다. 로컬에서 빌드한 Image도 지정할 수 있습니다.
container.ports
: Container가 노출시킬 포트를 의미합니다.
env
: 환경 변수를 열거할 수 있습니다.
$ kubectl apply -f simple-pod.yaml
pod/simple-echo created
위의 명령어로 Kubernetes cluster에 Pod를 배포
할 수 있습니다.
Pod에 접근하는 법은 아래의 service
에서 설명하도록 하겠습니다.
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
simple-echo 2/2 Running 0 3m37s
Pod의 목록을 확인할 수 있는 명령어입니다.
STATUS
: 'Running이면 Pod안의 모든 컨테이너가 실행중이다.'를 의미합니다.
READY
: 실행 상태의 Container 수 / Pod에 정의된 Container 수를 의미합니다.
$ kubectl exec -it simple-echo sh -c nginx
#
kubectl 명령어로 Container안에도 접근할 수 있습니다.
Container가 여러 개인 경우 -c 옵션에 Container명을 지정합니다.
$ kubectl logs -f simple-echo -c echo
2020/10/09 09:25:55 start server
kubectl log 명령으로 Pod안에 있는 Container의 표준 출력을 할 수 있습니다.
# 리소스 삭제
$ kubectl delete pod simple-echo
pod "simple-echo" deleted
# manifest 파일로 삭제
$ kubectl delete -f simple-pod.yaml
pod "simple-echo" deleted
사용이 끝난 리소스를 삭제할 때 위의 명령어를 사용하면 됩니다.
manifests 파일로 Pod를 삭제할 수도 있습니다. manifest에 작성된 리소스 전체가 삭제됩니다.
ReplicaSet는 똑같은 정의를 갖는 Pod를 여러 개 생성하고 관리하기 위한 리소스입니다.
manifest 파일로는 Pod를 하나밖에 생성할 수 없기 때문에, 여러 개의 Pod를 실행해 가용성을 확보해야할 경우 RelicaSet를 사용해야 합니다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: echo
labels:
app: echo
spec:
replicas: 3
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: nginx
image: gihyodocker/nginx:latest
env:
- name: BACKEND_HOST
value: localhost:8080
ports:
- containerPort: 80
- name: echo
image: gihyodocker/echo:latest
ports:
- containerPort: 8080
replicas
: ReplicaSet에서 만들 Pod의 복제본 수를 의미합니다.
template
: Pod정의와 같습니다.
$ kubectl apply -f simple-replicaset.yaml
replicaset.apps/echo created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
echo-6z2rf 2/2 Running 0 64s
echo-8lmq9 2/2 Running 0 64s
echo-9p8br 2/2 Running 0 64s
ReplicaSet를 배포하면 3개의 Pod가 생성된 것을 확인할 수 있습니다.
같은 Pod가 여러 개 복제된 것이라 Pod NAME에 echo-6z2rf처럼 무작위로 생성된 접미사가 붙습니다.
$ kubectl delete -f simple-replicaset.yaml
replicaset.apps "echo" deleted
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
echo-6z2rf 2/2 Terminating 0 4m36s
echo-8lmq9 2/2 Terminating 0 4m36s
echo-9p8br 2/2 Terminating 0 4m36s
ReplicaSet를 manifest 파일을 이용해 아래와 같이 삭제할 수 있습니다.
ReplicaSet는 Pod를 관리했다면, Deployment는 ReplicaSet를 관리하고 다루기 위한 리소스입니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo
labels:
app: echo
spec:
replicas: 3
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: nginx
image: gihyodocker/nginx:latest
env:
- name: BACKEND_HOST
value: localhost:8080
ports:
- containerPort: 80
- name: echo
image: gihyodocker/echo:latest
ports:
- containerPort: 8080
ReplicaSet 정의와 크게 다르지 않습니다. 차이점은 Deployment가 ReplicaSet의 Revision관리를 할 수 있다는 점입니다.
$ kubectl apply -f simple-deployment.yaml --record
pod/simple-echo created
$ kubectl get pod,replicaset,deployment --selector app=echo
NAME READY STATUS RESTARTS AGE
pod/echo-6968d87679-6rnmx 2/2 Running 0 6m22s
pod/echo-6968d87679-9b84s 2/2 Running 0 6m22s
pod/echo-6968d87679-rslrb 2/2 Running 0 6m22s
NAME DESIRED CURRENT READY AGE
replicaset.apps/echo-6968d87679 3 3 3 6m22s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/echo 3/3 3 3 6m22s
$ kubectl rollout history deployment echo
deployment.apps/echo
REVISION CHANGE-CAUSE
1 kubectl apply --filename=simple-deployment.yaml --record=true
첫 번째 명령어
에서는 어떤 명령을 실행했는지 기록하는 옵션 --record를 붙여 manifest 파일을 cluster에 반영했습니다.
두 번째 명령어
에서는 pod, replicaset, deployment가 잘 생성되었는지 확인했습니다.
세 번째 명령어
에서는 kubectl의 어떤 명령어가 실행됐는지 확인했습니다.
Deployment가 관리하는 Replicaset은 지정된 개수만큼 Pod를 확보하거나 새로운 버전으로 교체하는 등 중요한 역할을 합니다.
실제 운영에서는 Replicaset을 Deployment의 Manifest파일을 통해 다루기 때문에 Deployment안에서 Replicaset이 어떻게 동작하는지 알아야 합니다.
$ kubectl apply -f simple-deployment.yaml --record
deployment.apps/echo configured
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
echo-6968d87679-6rnmx 2/2 Running 0 16m
echo-6968d87679-9b84s 2/2 Running 0 16m
echo-6968d87679-rhfmm 0/2 ContainerCreating 0 7s
echo-6968d87679-rslrb 2/2 Running 0 16m
simple-deplyoment.yaml파일의 replicas값을 3에서 4로 변경하고 apply 했습니다.
기존 Pod는 유지되고, Container하나가 새로 생성됩니다.
$ kubectl apply -f simple-deployment.yaml --record
deployment.apps/echo configured
$ kubectl get pod --selector app=echo
NAME READY STATUS RESTARTS AGE
echo-54dbdb57c7-fx76c 0/2 ContainerCreating 0 9s
echo-54dbdb57c7-h6wqh 0/2 ContainerCreating 0 8s
echo-6968d87679-6rnmx 2/2 Running 0 20m
echo-6968d87679-9b84s 2/2 Running 0 20m
echo-6968d87679-rhfmm 2/2 Terminating 0 4m
echo-6968d87679-rslrb 2/2 Running 0 20m
simple-deployment.yaml의 echo:latest를 echo:patched로 변경했습니다.
새로운 Pod가 생성되고, 기존 Pod는 단계적으로 정지됨을 알 수 있습니다.
$ kubectl rollout history deployment echo --revision=1
deployment.apps/echo with revision #1
Pod Template:
Labels: app=echo
pod-template-hash=6968d87679
Annotations: kubernetes.io/change-cause: kubectl apply --filename=simple-deployment.yaml --record=true
Containers:
nginx:
Image: gihyodocker/nginx:latest
Port: 80/TCP
Host Port: 0/TCP
Environment:
BACKEND_HOST: localhost:8080
Mounts: <none>
echo:
Image: gihyodocker/echo:latest
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
$ kubectl rollout undo deployment echo
Deployment는 특정 Revision의 내용을 확인할 수 있고, undo
를 실해하면 Deployment가 바로 직전 Revision으로 Rollback합니다.