kubectl run
명령을 실행하여 쉽게 파드를 생성할 수 있음
kubectl run niginx-pod --image=nginx
nginx-pod
: 파드 이름
--image=nginx
: 생성할 이미지 이름
kubectl create nginx --image=nginx
-> --image라는 옵션이 없다는 에러 메시지
create로 파드를 생성할 때는 deployment를 추가해서 실행해야 함
kubectl create deployment dpy-nginx --image=nginx
생성된 파드 확인
kubectl get pods -o wide
이름에서 dpy-nginx
를 제외한 나머지 부분은 무작위로 생성됨
run으로 생성하면 단일 파드 1개만 생성되고 관리됨
create deployment로 파드를 생성하면 디플로이먼트(Deployment)라는 관리 그룹 내에서 파드가 생성됨
파드와 디플로이먼트는 스펙(spec)과 상태(status) 등의 값을 가지고 있음
이 값을 가지고 있는 파드와 디플로이먼트를 개별 속성을 포함해 부르는 단위를 오브젝트(Object)라고 함
참고 링크 [쿠버네티스 공식 사이트]
파드(Pod)
: 쿠버네티스에서 실행되는 최소 단위
: 웹 서비스를 구동하는 데 필요한 최소 단위
: 독립적인 공간과 사용 가능한 IP를 가지고 있음
: 하나의 파드는 1개 이상의 컨테이너를 갖고 있음
; 여러 기능을 묶어 하나의 목적으로 사용할 수 있음
: 범용으로 사용할 때는 대부분 1개의 파드에 1개의 컨테이너를 적용함
네임스페이스(Namespaces)
: 쿠버네티스 클러스터에서 사용되는 리소스들을 구분해 관리하는 그룹
default
kube-system
metallb-system
볼륨(Volume)
: 파드가 사라지더라도 저장과 보존이 가능한 디렉터리를 생성하고 사용
: 파드는 영속되는 개념이 아니라서 제공되는 디렉터리도 임시로 사용됨
서비스(Service)
: 파드는 클러스터 내에서 유동적이기 때문에 접속 정보가 고정일 수 없음
: 파드 접속을 안정적으로 유지하도록 서비스를 통해 내/외부로 연결됨
: 새로 파드가 생성될 때 부여되는 새로운 IP를 기존에 제공하던 기능과 연결해 줌
: 쿠버네티스 외부에서 쿠버네티스 내부로 접속할 때 내부가 어떤 구조로 돼 있는지, 파드가 살았는지 죽었는지 신경 쓰지 않아도 이를 논리적으로 연곁하는 것
: 로드밸런서, 게이트웨이와 비슷한 역할
효율적으로 작동하도록 기능들을 조합하고 추가해 구현한 것
파드에 기반을 두고 있으며 레플리카셋 오브젝트를 합쳐 놓은 형태
API 서버와 컨트롤러 매니저는 파드 생성을 감시하는 것 뿐만 아니라 디플로이먼트처럼 레플리카셋을 포함하는 오브젝트의 생성을 감시함
이미지 경로 : sysnet4admin/echo-hname
(책 저자분 저장소)
디플로이먼트 생성
kubectl create deployment dpy-hname --image=sysnet4admin/echo-hname
생성된 디플로이먼트 확인
kubectl get pods
디플로이먼트 삭제
kubectl delete deployment dpy-hname
삭제되었는지 확인
kubectl get pods
쿠버네티스에서는 다수의 파드를 만드는 레플리카셋 오프젝트를 제공하고 있음
파드를 3개 만들 경우 레플리카셋에 선언하면 컨트롤러 매니저와 스케줄러가 워커 노드에 파드 3개를 만들도록 선언함
파드 수를 보장하는 기능만 제공함
-> 롤링 업데이트 기능 등이 추가된 디플로이먼트를 사용해 파드 수를 관리함
배포되 파드 상태 확인
kubectl get pods
nginx-pod를 3개로 증가
kubectl scale pod nginx-pod --replicas=3
--replicas=3
: 파드의 수를 3개로 맞추는 옵션
-> 리소스를 찾을 수 없다는 에러 메시지
-> 디플로이먼트 오브젝트가 아니라 파드라서 그럼
dpy-nginx를 3개로 증가
kubectl scale deployment dpy-nginx --replicas=3
파드 생성 확인
kubectl get pods
정상적으로 워커 노드에 적용되고 IP가 부여 되었는지 확인
kubectl get pods -o wide
생성한 디플로이먼트 삭제
kubectl delete deployment dpy-nginx
삭제 확인
kubectl get pods
디플로이먼트를 생성하면서 한꺼번에 여러 개의 파드를 만들기
-> 필요한 내용을 파일로 작성해야 함
-> 오브젝트 스펙(spec)
야믈(YAML) 문법으로 작성
야믈(YAML) : '또 다른 마크업 언어(Yet Another Markup Language)의 약어
-> '야믈은 단순히 마크업 언어가 아니다(YAML Ain't Markup Language)라고 다시 정의됨
~/_Book_k8sInfra/ch3/3.2.4 디렉터리의 예제 파일(echo-hname.yaml) 사용
apiVersion: apps/v1 # API 버전
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 # 사용되는 이미지
nginx-pod.yaml 파일과 디플로이먼트의 template
부분은 동일함
-> template
하위의 metadata
와 spec
이 nginx-pod.yaml에서 동일하게 사용됨
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: container-name
image: nginx
echo-hname.yaml 파일로 디플로이먼트 생성
kubectl create -f ~/_Book_k8sInfra/ch3/3.2.4/echo-hname.yaml
파드 3개 생성 확인
kubectl get pods
echo-hname.yaml 파일 수정하여 파드 6개로 늘리기
sed(streamlined editor)
명령으로 파일 replicas
값을 3에서 6으로 변경
sed -i 's/replicas: 3/replicas: 6/' ~/_Book_k8sInfra/ch3/3.2.4/echo-hname.yaml
-i
: --in-place
의 약어, 변경한 내용을 현재 파일에 바로 적용하겠다는 의미
s/
: 주어진 패턴을 원하는 패턴으로 변경하겠다는 의미
replicas값이 6으로 변경됐는지 확인
cat ~/_Book_k8sInfra/ch3/3.2.4/echo-hname.yaml | grep replicas
변경된 내용 적용
kubectl create -f ~/_Book_k8sInfra/ch3/3.2.4/echo-hname.yaml
-> echo-hname이 이미 존재한다는 에러 메시지
배포된 오브젝트의 스펙을 변경하고 싶을 때는 어떻게 해야하는가?
replicas를 6으로 수정한 echo-hname.yaml 파일을 kubectl apply 명령으로 적용
kubectl apply -f ~/_Book_k8sInfra/ch3/3.2.4/echo-hname.yaml
-> 오브젝트를 처음부터 apply로 생성한 것이 아니어서 경고가 뜸
6개로 늘어났는지 확인
kubectl get pods
create
: 명령 창 등에서 직접 애드혹(ad-hoc, 일회적 사용)으로 오브젝트를 생성할 때
apply
: 변경이 생길 가능성이 있는 복잡한 오브젝트는 파일로 작성한 후 적용
구분 | Run | Create | Apply |
---|---|---|---|
명령 실행 | 제한적임 | 가능함 | 안 됨 |
파일 실행 | 안 됨 | 가능함 | 가능함 |
변경 가능 | 안 됨 | 안 됨 | 가능함 |
실행 편의성 | 매우 좋음 | 매우 좋음 | 좋음 |
기능 유지 | 제한적임 | 지원됨 | 다양하게 지원됨 |
셀프 힐링(Self-Healing) : 파드의 자동 복구 기술
제대로 작동하지 않는 컨테이너를 다시 시작하거나 교체해 파드가 정상적으로 작도하게 함
파드의 IP를 알아야 접속할 수 있음
kubectl get pods -o wide
kubectl exec
명령으로 파드 컨테이너의 셸(shell)에 접속
nginx-pod에 /bin/bash를 실행해 컨테이너에서 배시(bash) 셸에 접속
kubectl exec -it nginx-pod -- /bin/bash
exec
: execute(실행)을 의미
i
: stdin(standard input, 표준 입력)
t
: tty(teletypewriter)
it
: 표준 입력을 명령줄 인터페이스로 작성한다는 의미
nginx의 PID 확인 -> nginx의 PID는 항상 1
cat /run/nginx.pid
ls -l
명령으로 프로세스가 생성된 시간 확인
ls -l /run/nginx.pid
슈퍼푸티에서 m-k8s 터미널을 1개 더 띄우고 nginx-pod의 IP에서 돌아가는 웹 페이지를 1초마다 한 번씩 요청하는 스크립트 실행
i=1; while true; do sleep 1; echo $((i++)) 'curl --silent 172.16.103.132 | grep title' ; done
배시 셸에서 nginx 프로세서인 PID 1번을 kill
명령으로 종료
kill 1
자동으로 복구되고 스크립트가 잘 작동됨
다시 nginx-pod에 접속하고 ls -l
로 생성 시간 확인
파드 자체에 문제가 발생하면 파드를 자동 복구해서 파드가 항상 동작하도록 보장하는 기능이 있음
파드에 문제가 발생하는 상황을 만들기 위해 생성한 파드를 삭제하기 전 파드 확인
kubectl get pods
nginx-pod 삭제
kubectl delete pods nginx-pod
동작을 보증하기 위해 필요한 조건 확인을 위해 비교할 다른 파드 삭제
kubectl delete pods echo-hname-~~
(이름 다름)
삭제 되었는지 확인
kubectl get pods
-> 아직 6개의 파드가 살아있고 하나는 최근에 생성됨
nginx-pod는 디플로이먼트에 속한 파드가 아니어서 어떤 컨트롤러도 이 파드를 관리하지 않음
-> nginx-pod는 바로 삭제되고 다시 생성되지 않음
echo-hname은 디플로이먼트에 속한 파드로 replicas를 6개로 선언함
선언한 수대로 유지하도록 파드의 수를 항상 확인하고 부족하면 새로운 파드를 만들어냄
디플로이먼트에 속한 파드는 상위 디플로이먼트를 삭제해야 파드가 삭제됨
kubectl delete deployment echo-hname
명령으로 디플로이먼트 삭제kubectl get pods
노드 : 쿠버네티스 스케줄러에서 파드를 할당받고 처리하는 역할
최근에 몇 차례 문제가 생긴 노드에 파드를 할당하면 문제가 생길 가능성이 높음
-> 어쩔 수 없이 해당 노드를 사용해야 한다면?
영향도가 적은 파드를 할당해 일정 기간 사용하면서 모니터링
-> 노드에 문제가 생기더라도 파드의 문제를 최소화
but, 쿠버네티스는 모든 노드에 균등하게 파드를 할당하려고 함
문제가 생길 가능성이 있는 노드라는 것을 쿠버네티스에 알려야 함 !
echo-hname.yaml을 적용(apply)하여 파드 생성
kubectl apply -f ~/_Book_k8sInfra/ch3/3.2.8/echo-hname.yaml
scale
명령으로 배포한 파드를 9개로 늘림
kubectl scale deployment echo-hname --replicas=9
배포된 파드 확인
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
-o
: output
custom-columns
: 사용자가 임의로 구성할 수 있는 열
NAME
, IP
, STATUS
, NODE
: 열의 제목
.metadata.name
, .status.podIP
, .status.phase
, .spec.nodeName
: 내용 값
scale로 파드의 수를 3개로 줄임
kubectl scale deployment echo-hname --replicas=3
각 노드에 파드가 1개씩만 남았는지 확인
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
w3-k8s 노드에서 문제가 자주 발생해 현재 상태를 보존
kubectl cordon w3-k8s
kubectl get nodes
명령으로 cordon 명령이 제대로 적용됐는지 확인
-> cordon 명령을 실행하면 노드에 파드가 할당되지 않게 스케줄되지 않는 상태(SchedulingDisabled)라는 표시를 함
파드 수를 9개로 늘림
kubectl scale deployment echo-hname --replicas=9
노드에 배포된 파드확인
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
-> w3-k8s는 파드 수가 여전히 1개
파드 수를 3개로 줄임
kubectl scale deployment echo-hname --replicas=3
각 노드에 할당된 파드 수가 공평하게 1개씩인지 확인
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
w3-k8s에 파드가 할당되지 않게 설정했던 것을 해제
kubectl uncordon w3-k8s
w3-k8s에 적용됐는지 확인
kubectl get nodes
정기 / 비정기적인 유지보수를 위해 노드를 꺼야하는 상황 발생
-> drain 기능 제공
지정된 노드의 파드를 전부 다른 곳으로 이동시켜 해당 노드를 유지보수할 수 있게 함
kubectl drain
명령으로 유지보수할 노드(w3-k8s)를 파드가 없는 상태로 만듬
kubectl drain w3-k8s
-> 데몬셋을 지울 수 없어서 명령을 수행할 수 없다고 나옴
-> drain은 노드에서 파드를 삭제하고 다른 곳에 다시 생성함
-> DaemonSet은 각 노드에 1개만 있는 파드라서 삭제할 수 없음
drain
명령과 ignore-daemonsets
옵션을 함께 사용하여 DaemonSet을 무시하고 진행
kubectl drain w3-k8s --ignore-daemonsets
w3-k8s에 파드가 없는지 확인
-> 옮긴 노드에 파드가 새로 생성되어 파드 이름과 IP가 부여됨
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
drain 명령이 수행된 w3-k8s 노드의 상태 확인
-> cordon
을 실행했을 때처럼 SchedulingDisable 상태
kubectl get nodes
w3-k8s에 uncordon
명령을 실행해 스케줄을 받을 수 있는 상태로 복귀
kubectl uncordon w3-k8s
다시 노드 상태 확인
kubectl get nodes
kubectl apply -f ~/_Book_k8sInfra/ch3/3.2.10/rollout-nginx.yaml --record
--record
: 배포한 정보의 히스토리 기록# <rollout-nginx.yaml>
apiVersion: apps/v1
kind: Deployment
metadata:
name: rollout-nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.12 # 중요 포인트 (컨테이너 버전 지정)
record
옵션으로 기록된 히스토리는 rollout history
명령으로 실행해 확인
kubectl rollout history deployment rollout-nginx
배포한 파드의 정보 확인
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
배포된 파드에 속해 있는 nginx 컨테이너 버전을 curl -I
(헤더 정보만 보여주는 옵션) 명령으로 확인
curl -I --silent 172.16.103.143 | grep Server
(IP 다를 수 있음)
set image
명령으로 파드의 nginx 컨테이너 버전을 1.16.0으로 업데이트
kubectl set image deployment rollout-nginx nginx=nginx:1.16.0 --record
업데이트 후 파드 상태 확인
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
-> 파드 이름과 IP가 변경됨
파드에 속한 nginx 컨테이너를 업데이트하는 가장 쉬운 방법
-> 파드를 관리하는 replicas 수를 줄였다가 늘려 파드를 새로 생성하는 것
-> 시스템 영향을 최소화하기 위해 replicas에 속한 파드를 하나씩 순차적으로 지우고 생성함
-> 파드 수가 많으면 하나씩이 아니라 다수의 파드가 업데이트 되기도 함
nginx 컨테이너가 모두 업데이트되면 Deployment 상태 확인
kubectl rollout status deployment rollout-nginx
rollout history
명령으로 rollout-nginx에 적용된 명령들 확인
kubectl rollout history deployment rollout-nginx
curl -I
명령으로 업데이트가 잘 됐는지 확인
curl -I --silent 172.16.132.10 | grep Server
(IP 다를 수 있음)
set image
명령으로 nginx 컨테이너 버전을 잘못되게 입력
kubectl set image deployment rollout-nginx nginx=nginx:1.17.23 --record
한참 지나도 파드가 삭제되지 않고 pending(대기 중) 상태에서 넘어가지 않음
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
문제 확인을 위해 rollout status
실행
kubectl rollout status deployment rollout-nginx
-> 새로운 replicas가 생성됐지만 배포하는 단계에서 대기 중(Waiting)
Deployment를 끝내 생성되지 않았다는 메시지 출력
describe
명령으로 쿠버네티스 상태 확인
kubectl describe deployment rollout-nginx
-> replicas가 새로 생기는 과정에서 멈춰있음 (1.17.23 버전의 컨테이너가 없어서)
-> 컨테이너 이미지를 찾을 수 없어서 배포되지 않음
-> 업데이트할 때 rollout
를 사용하고 --record
로 기록하는 이유!
정상적인 상태로 복구하기 위해 사용했던 명령 확인
kubectl rollout history deployment rollout-nginx
rollout undo
명령으로 실행 취소
kubectl rollout undo deployment rollout-nginx
파드 상태 확인
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
rollout history
로 실행된 명령 확인
kubectl rollout history deployment rollout-nginx
-> revision 4가 추가되고 revision 2가 삭제됨
배포된 컨테이너 버전 확인
curl -I --silent 172.16.132.10 | grep Server
(IP 다름 주의)
-> 버전이 1.16.0으로 상태가 되돌려짐
rollout status
명령으로 변경이 적용됐는지 확인
kubectl rollout status deployment rollout-nginx
describe
로 현재 디플로이먼트 상태를 세부적으로 점검
특정 시점으로 돌아가기 위해서는
--to-revision
옵션 사용
처음 상태로 돌아가기
kubectl rollout undo deployment rollout-nginx --to-revision=1
새로 생성된 파드들의 IP 확인
kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
curl -I
로 nginx 컨테이너 버전 확인
curl -I --silent 172.16.103.150 | grep Server
(IP 다름 주의)