[Kubernetes] EKS 다루기(1) - Pod, Replicaset, Deployment
안녕하세요, 달콤한달팽이입니다.🐌🙂
이번 시간에는 EKS에서 사용되는 용어를 알아보고,
지난 실습에서 생성한 EKS 클러스터를 사용하여 이를 구성하는 방법에 대하여 알아보겠습니다.
YAML이란?
YAML이란, 데이터 표현 양식의 한 종류입니다.
앞으로 진행되는 EKS의 실습은 대부분 YAML파일을 작성하고, 이를 적용시키는 방식으로 진행됩니다.
때문에 "EKS를 잘 다룬다"는 것은 EKS의 개념을 숙지하고, 이를 YAML파일로 녹여내는 것을 의미한다고해도 과언이 아닙니다.
앞으로 사용될 YAML 파일은 기본적으로 아래와 같은 구성을 가지고 있습니다.
1) apiVersion: 오브젝트 생성을 위해 사용중인 쿠버네티스 API 버전
2) kind: 오브젝트 종류 (ex. Pod, Namespace, Role 등..)
3) metadata: 오브젝트 구분을 위한 데이터 (ex. 이름, 네임스페이스 등..)
4) spec: 오브젝트 상태 (ex. 이미지 종류, 사용 포트 등..)
apiVersion: v1
kind:
metadata:
spec:
yaml 파일은 띄어쓰기로 인해 에러가 날수도 있을 정도로 예민하며,
앞으로의 실습은 리소스 단위로 분할하여 작성할수도, 파나의 파일로 합쳐 작성할수도 있다는점 참고바래요!
1) Pod
Pod란, 컨테이너를 하나 이상 모아놓은 것으로 쿠버네티스 애플리케이션의 최소 단위입니다.
쿠버네티스에서 컨테이너를 개별적으로 사용하는 것이 아닌, Pod 단위로 사용하는 데에는 Pod의 특징 때문입니다.
[Pod의 특징]
1) Pod 내부 컨테이너는 IP와 Port를 공유합니다.
- 하나의 Pod에서 배포된 A, B 컨테이너는 서로를 localhost:port로 호출이 가능합니다.
2) Pod 내부 컨테이너는 디스크 볼륨을 공유합니다.
- 애플리케이션과 로그 수집을 분리하여 타 컨테이너의 로그를 수집 및 분석이 가능합니다.
가장 기본적인 nginx 컨테이너를 사용하여 Pod을 생성하는 yaml 파일을 작성해봅시다.
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
이제 yaml파일을 적용시켜보도록 하겠습니다.
kubectl apply -f {yaml 파일명}
이후 Pod 목록을 확인하면 nginx-pod라는 이름의 신규 Pod이 생성되었습니다!
이제 exec 명령어를 통해 nginx도 제대로 올라와있는지 확인해주세요!
kubectl exec -it {pod 이름} -- /bin/bash
curl localhost
이제 delete 명령어를 사용해 pod를 삭제해주세요!
kubectl delete -f {yaml 파일명}
하지만 이렇게 Pod만 생성하는 방식은 큰 단점이 존재합니다.
바로 Pod에 문제가 생겨도 이를 알아차리고, 대응해주는 존재가 없다는 것입니다.
때문에 이를 보완하기 위해 Replicaset이라는 오브젝트를 사용하기 시작했습니다!
2) Replicaset
Replicaset이란, Pod의 실행을 안정적으로 유지하는데 목적을 갖춘 오브젝트입니다.
즉, 지정된 Pod의 개수만큼은 항상 실행될 수 있도록 관리를 돕는 오브젝트입니다.
만약 5개의 Pod를 항상 실행하도록 설정할 경우,
사고로 3개의 Pod가 삭제되도 다시 3개가 생성되어 5개가 유지될 수 있도록 도와줍니다.
이제 아래를 참조하여 replicaset.yaml 파일을 작성해봅시다.
# replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-pod
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
이제 yaml파일을 적용시켜보도록 하겠습니다.
kubectl apply -f {yaml 파일명}
이후 Pod 목록을 확인하면 nginx-pod라는 이름의 신규 Pod이 생성되었습니다!
이제 Replicaset을 통해 생성된 Pod 중 하나를 임의로 삭제해보겠습니다.
kubectl delete pod {pod 이름}
이후 다시 Pod 목록을 조회해보면 신규 Pod이 삭제한 Pod을 대체함을 확인할 수 있습니다.
그렇다면 Replicaset은 삭제된 것이 자신이 관리하는 Pod인지 어떻게 알고 대처하는걸까요?
바로 Replicaset의 Label Selector과 Pod의 Label을 비교하기 때문입니다.
Replicaset은 미리 지정한 키-값 형태의 Label을 가진 Pod을 감시하고 있다가,
문제가 발생할 경우 지정된 수만큼의 Pod을 유지하는 역할을 수행합니다.
Replicaset의 Yaml파일에는 총 3번 Label을 지정하는 탭이 있습니다.
1) 첫 번째는 Repliaset 자체에 대한 식별자입니다.
2) 두 번째는 Replicaset이 관리하는 Pod 그룹을 선택하기 위한 식별자입니다.
3) Replicaset을 통해 생성하는 Pod에 대한 식별자입니다.
이제 Replicaset을 삭제해주도록 합시다.
하지만 Replicaset 역시 몇 가지 단점이 존재합니다.
바로 배포시 버전관리가 불가하기 때문에 yaml파일이 점점 늘어난다는 것입니다.
때문에 이를 보완하기 위해 Deployment라는 오브젝트를 사용하기 시작했습니다!
3) Deployment
Deployment란, Replicaset과 같이 Pod의 항상성을 유지하며
애플리케이션의 업데이트와 배포에 대한 Revision을 남기는 오브젝트입니다.
때문에 Deployment는 Replicaset을, Replicaset은 Pod을 관리한다고 보시면 될 것 같습니다!
이제 아래를 참조하여 deployment.yaml 파일을 작성해봅시다.
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
name: nginx-test
template:
metadata:
labels:
name: nginx-test
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
yaml 파일을 유심히 보셨다면 알겠지만, 사실 replicaset.yaml파일과 kind만 다를 뿐 내용은 동일함을 알 수 있습니다.
이제 지금까지 생성되어있는 pod, replicaset, deployment를 출력해봅시다!
kubectl get pods,rs,deploy
이제 명령어를 수행해 Deployment의 버전을 확인해보도록 합시다.
kubectl rollout history deployment/{deployment 이름}
이제 set 명령어를 사용해 Deployment를 수정해보도록 합시다!
kubectl set image deployment/{deployment 이름} {사용중인 컨테이너 이름}=nginx:1.9.1
이후 Deployment 버전을 다시 확인해보면 REVISION 2가 생성된 것을 알 수 있습니다.
kubectl rollout history deployment/{deployment 이름}
undo 명령어에 revision 버전을 지정할 경우, 다시 롤백되게 됩니다!
kubectl rollout undo deploy {deployment 이름}--to-revision={버전}
지금까지 EKS를 사용하기 위해 기본적으로 사용되는
Pod, Replicaset, Deployment에 대해 알아보고 실습해보았습니다.
하지만 이번 실습에서는 Pod 정상 여부 체크를 위해 exec 명령어만을 사용했습니다!
(즉, 현재까지의 애플리케이션은 외부 노출이 불가했습니다.)
다음 실습에서는 이러한 애플리케이션을 외부로 노출 하는 방법에 대하여 알아보겠습니다.
감사합니다!