파드 생성
컨테이너를 담을 파드를 생성합니다.
그런데 파드를 만드는 데는 2가지 방법이 있습니다. 먼저 첫 번째 방법입니다.
kubectl run [파드명] --image=[이미지명]
이렇게 해서 파드를 생성한 다음에 파드가 잘 생성되었는지 확인합니다.
kubectl get pods
다음 방법입니다. run이 아니라 create를 통해서 파드를 생성하는 것입니다.
kubectl create deployment [파드명] --image=[이미지명]
동일하게 파드 생성을 확인합니다.
kubectl get pods
그런데 둘은 동일하게 파드를 생성하는데 왜 명령어를 굳이 2개나 사용할까요?
디플로이먼트
둘의 차이는 바로 디플로이먼트입니다. run을 통해 생성한 파드는 디플로이먼트가 없으며, create deployment로 생성한 파드는 디플로이먼트가 있습니다.
디플로이먼트는 레플리카셋(레플리케이션 컨트롤러) 오브젝트를 합친 오브젝트입니다. 이 레플리카셋은 파드를 관리합니다. 파드를 원하는 개수를 미리 지정해놓으면 그만큼 파드를 생성·유지합니다.
파드는 생성과 소멸이 자유롭습니다. 그런데 run을 여러 번 하여 여러 개의 파드를 일일히 하나씩 만드는 것보다는 여러 개의 파드를 한 번에 만드는 것이 훨씬 효율적인 과정입니다. 그렇기 때문에 파드를 만들 때는 디플로이먼트 오브젝트를 통해 만드는 것이 좋습니다.
그러면 레플리카셋을 통해서 파드의 수를 조정해보겠습니다. 가상머신의 bash에서 아래 명령어를 입력합니다.
kubectl scale pod [파드명] --replicas=[파드 개수]
파드의 스케일을 조정하는 것입니다. 뒤에 있는 replicas의 값을 수정하여 파드를 몇 개로 관리할 것인지를 지정합니다. 이것은 디플로이먼트 오브젝트에 속한 파드만 가능합니다.
오브젝트 생성
일일히 디플로이먼트를 생성하고 레플리카셋을 설정하는 것 말고 애초에 생성과 설정을 같이하는 것이 더 편리합니다. 그렇기 때문에 오브젝트의 스펙을 작성합니다. 설정 파일은 .yaml 야믈 파일로 생성합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-hname
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: echo-hname
image: sysnet4admin/echo-hname
조훈님께서 작성하신 echo-hname 파일입니다.
- apiVersion: 오브젝트의 API 버전입니다.
- kind: apps/v1 API의 오브젝트를 선택합니다.
- metadata: data에 대한 설정입니다. 이름과 레이블 등을 설정합니다.
- spec: 스펙에 대한 설정입니다.
- replicas: 몇 개의 파드를 만들 것인지 설정합니다.
- selectors: 셀렉터의 레이블을 지정합니다.
- template: 템플릿의 설정입니다. 템플릿의 레이블과 스펙을 정할 수 있습니다.
- spec: 오브젝트 스펙입니다. containers로 파드의 이름과 그 파드에 쓰일 이미지를 지정합니다.
이제 파드의 스펙을 살펴보겠습니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
name: container-name
image: nginx
파드의 스펙을 보면 각 컨테이너의 이름과 그 이미지를 설정합니다. 이때, 앞선 디플로이먼트에서 파드에 쓰일 이미지를 sysnet4admin/echo-hname으로 설정했습니다. 그 이미지를 통해서 nginx 이미지를 파드에서 컨테이너에 사용합니다.
이제 Bash에서 yaml 파일을 불러옵니다.
kubectl create -f [yaml 파일 디렉터리 위치]
이를 통해 바로 파드를 3개 만들 수 있습니다.
오브젝트 생성 및 관리
그런데 디플로이먼트의 설정을 갑자기 바꾸고 싶어졌습니다. 그래서 바로 야믈파일을 수정하고 create 다시 야믈 파일을 불러오면 이미 존재하는 디플로이먼트이기 때문에 수정이 불가합니다. 이때 쿠버네티스의 apply 명령어를 통해 오브젝트를 관리할 수 있습니다.
먼저 레플리카셋을 6으로 수정합니다.
sed -i 's/replicas: 3/replicas: 6/' [yaml 파일 디렉터리 위치]
이후에 apply 명령으로 적용합니다. apply 명령어로 오브젝트를 생성한 것이 아니라 경고가 발생하는데 작동할 수는 있습니다. 그렇지만, 일관성 문제 때문에 변경이 발생할 수 있는 오브젝트는 apply 로 만드는 것이 좋습니다.
파드의 기능
1. 셀프 힐링
파드에서 컨테이너가 제대로 작동하지 않는다면 자동으로 복구하는 기능이 있습니다. 파드 컨테이너에 접속해서 프로세스를 종료하고 파드의 상태를 확인하면 다시 복구되는 것을 볼 수 있습니다.
컨테이너 셸에 접속하는 것은 아래와 같이 할 수 있습니다.
kubectl exec -it nginx-pod
보통 프로세서 식별자는 1이기 때문에 아래 명령어로 프로세서를 종료합니다.
kill 1
이후 파드 컨테이너의 프로세스를 확인하면 생성 시간이 달라져있는 것을 볼 수 있습니다.
2. 동작 보증
kubectl delete [파드명]
위 명령어로 파드를 제거해봅시다. 그 이후에 다시
kubectl get pods
를 통해서 파드 목록을 조회하면 제거한 파드가 보이지 않지만 새로운 파드가 그 자리를 대체하고 있습니다. 실제로 생성된 시간도 다른 디플로이먼트의 파드와 다릅니다.
레플리카셋이 파드의 개수를 맞추기 때문에 파드의 동작을 보증할 수 있게 됩니다.
노드 보호
노드에서 문제가 생기면 쿠버네티스에 알려 어떠한 대책을 강구해야 합니다. 이때는 cordon 기능을 사용합니다.
아래의 명령어로 노드에 cordon 명령을 실행합니다. 노드의 이름은 kubectl get nodes를 통해 확인할 수 있습니다.
kubectl cordon [노드 명]
cordon노드로 스케쥴을 할당하지 않도록 했다면 노드의 상태를 확인해봅시다.
kubectl get nodes
내가 지정한 노드의 STATUS를 보면 Ready 오른쪽에 SchedulingDisabled의 상태가 추가된 것이 보입니다.
이 상태에서 kubectl scale deployment [파드명] --replicas=[개수] 를 입력해주면, 스케쥴되지 않는 상태인 노드에서는 파드를 추가로 배포할 수 없기 때문에 해당 노드를 제외하고 나머지 워커 노드에서 고르게 파드가 분배되게 됩니다.
스케쥴할 수 있게 노드를 변경하기 위해서는 uncordon 명령을 실행하여 설정을 해제합니다.
노드 유지보수
노드를 잠시 휴식시키는 것보다 유지보수가 필요하게 된다면 노드의 파드를 임시로 옮긴 다음에 유지보수를 해야 합니다. 대청소를 하기 위해서 잠시 짐을 다른 방에 옮기는 것과 같은 과정입니다.
이때는 drain이라는 기능을 사용합니다.
kubectl drain [노드명]
하지만, drain은 파드를 삭제하고 다른 곳에 생성시키면서 파드를 옮기는 것입니다. 그런데 데몬셋이라는 노드에 하나 씩 존재하는 파드는 drain으로 삭제할 수 없기 때문에 ignore-daemonsets 옵션을 같이 사용합니다.
kubectl drain [노드명] --ignore-daemonsets
경고가 발생하며 모든 파드가 이동됩니다.
해당 노드는 스케쥴링 되지 않는 상태가 되므로 uncordon으로 다시 노드의 상태를 변경할 수 있습니다.
파드 수정
1. 파드 업데이트
apply를 통해 새롭게 파드를 배포합니다. 이때, --record 옵션을 설정하여 히스토리를 기록합니다.
이를 통해서 rollout 명령을 통해 record 옵션을 통해 기록된 것들을 확인할 수 있습니다.
kubectl rollout [history, status 등] deployment [파드명]
그 파드의 생성, 업데이트 등의 기록들을 확인할 수 있습니다.
이제 set image 명령으로 각 파드의 컨테이너 이미지를 변경합니다. 이때도 --record를 통해서 명령을 기록합니다.
kubectl set image deployment [파드명] [컨테이너 이름=컨테이너 버전] --record
이렇게 업데이트하면, 레플리카셋이 파드의 수를 줄인다음 늘려서 파드를 새로 생성합니다. 하나씩 순차적으로 업데이트되며 규모가 크면 여러 개의 파드가 동시에 업데이트 됩니다.
이제 rollout으로 상태를 확인합니다.
kubectl rollout status deployment [파드명]
2. 업데이트 실패
오타나 잘못된 기억으로 존재하지 않는 컨테이너를 업데이트 할 경우, 디플로이먼트 파드가 대기중에서 계속 머물러 있습니다.
이때 describe를 통해서 쿠버네티스 오브젝트의 상태를 확인할 수 있습니다.
kubectl describe [오브젝트] [오브젝트 이름]
이때 디플로이먼트의 상태를 확인해보면, 기록에서
NewReplicaSet: 레플리카 (1/1 replicas created)
를 확인할 수 있습니다. 이는 컨테이너 이미지를 찾지 못하여 배포가 실패했음을 알 수 있습니다.
우리가 포토샵이나 파워포인트에서 Ctrl-Z를 사용하는 것과 동일하게 쿠버네티스에서도 Undo 기능을 쓸 수 있습니다.
kubectl rollout undo deployment [파드명]
파드를 롤백할 수 있는 기능입니다. 상태를 되돌리면서 history에서 되돌린 revision이 삭제되며 새로운 revision이 최근 상태로 추가됩니다.
describe를 통해 확인하면 NewReplicaSet이 변경된 것을 확인할 수 있습니다.
3. 파드 복귀
--to-revision 옵션을 통해 특정 시점의 파드로 복귀할 수 있습니다.
kubectl rollout undo deployment [파드명] --to-revision=[revision]
이상으로 쿠버네티스 오브젝트인 디플로이먼트의 기능을 확인하고, 쿠버네티스의 안정적인 기능들을 알아봤습니다.
'데브옵스 & 인프라 > Kubernetes' 카테고리의 다른 글
minikube에서 파드로 서버 띄우고, 컨테이너 접근하기(MacOS docker driver 이슈) (1) | 2023.11.01 |
---|---|
[Kubernetes] 쿠버네티스 서비스 (책 실습) (0) | 2022.09.09 |
[Vagrant] 가상 머신 설정 및 네트워크 구성 (0) | 2022.09.04 |
[Infra Tools] 인프라 생성을 위한 도구 설치(버추얼박스, 베이그런트) (0) | 2022.08.31 |
[Cloud Infra] 서비스 인프라 환경과 클라우드 인프라 (0) | 2022.08.30 |