# 컨테이너 하나를 담은 파드를 실행한다. kiamol/ch02-hello-kiamol 도커 이미지를 hello-kiamol 이라는 이름으로 파드를 생성한다.
kubectl run hello-kiamol --image=kiamol/ch02-hello-kiamol
# 파드가 준비 상태가 될 때까지 기다린다.
kubectl wait --for=condition=Ready pod hello-kiamol
# 클러스터에 있는 모든 파드의 목록을 출력한다.
kubectl get pods
# 파드의 상세 정보를 확인한다.
kubectl describe pod hello-kiamol
# 파드 하나의 기본 정보를 출력한다.
kubectl get pod hello-kiamol
# 특정 항목을 지정해서 출력한다.
kubectl get pod hello-kiamol --output custom-columns=NAME:metadata.name,NODE_IP:status.hostIP,POD_IP:status.podIP
# JSONPath로 복잡한 출력을 구성한다.
kubectl get pod hello-kiamol -o jsonpath='{.status.containerStatuses[0].containerID}'
# 로컬 컴퓨터의 8080 포트로 들어오는 트래픽을 파드의 80번 포트로 전달한다.
kubectl port-forward pod/hello-kiamol 8080:80
# 디플로이먼트 hello-kiamol-2를 생성한다.
kubectl create deploy hello-kiamol-2 --image=kiamol/ch02-hello-kiamol
hello-kiamol-2-787f8db75d-ctqwn
파드가 생성된다.NAME READY STATUS RESTARTS AGE
hello-kiamol 1/1 Running 1 (92m ago) 8d
hello-kiamol-2-787f8db75d-ctqwn 1/1 Running 0 2m40s
# 디플로이먼트가 부여한 파드의 레이블을 출력한다.
kubectl get deploy hello-kiamol-2 -o jsonpath='{.spec.template.metadata.labels}'
# 아래와 같이 출력된다.
{"app":"hello-kiamol-2"}
# app:hello-kiamol-2 레이블을 가진 파드 목록을 출력한다.
kubectl get pods -l app=hello-kiamol-2
# 아래와 같이 출력된다.
NAME READY STATUS RESTARTS AGE
hello-kiamol-2-787f8db75d-ctqwn 1/1 Running 0 24m
# 모든 파드 이름과 레이블을 출력한다.
kubectl get pods -o custom-columns=NAME:metadata.name,LABELS:metadata.labels
# app=hello-kiamol 레이블을 가진 파드의 app 레이블을 수정한다.
kubectl label pods -l app=hello-kiamol-2 --overwrite app=hello-kiamol-x
# 다시 파드 목록을 조회한다.
kubectl get pods -o custom-columns=NAME:metadata.name,LABELS:metadata.labels
# 아래와 같이 hello-kiamol-2 파드가 생성된다.
hello-kiamol map[run:hello-kiamol]
hello-kiamol-2-787f8db75d-4v7lk map[app:hello-kiamol-2 pod-template-hash:787f8db75d]
hello-kiamol-2-787f8db75d-ctqwn map[app:hello-kiamol-x pod-template-hash:787f8db75d]
# app 레이블이 부여된 모든 파드 이름과 레이블을 출력한다.
kubectl get pods -l app -o custom-columns=NAME:metadata.name,LABELS:metadata.labels
# app 레이블을 원래대로 수정한다.
kubectl label pods -l app=hello-kiamol-x --overwrite app=hello-kiamol-2
# 다시 파드 목록을 조회한다.
kubectl get pods -l app -o custom-columns=NAME:metadata.name,LABELS:metadata.labels
# 대체 파드로 생성되었던 hello-kiamol-2-787f8db75d-4v7lk 파드는 삭제되고 처음 생성된 파드가 다시 컨트롤러 객체에서 관리된다.
hello-kiamol-2-787f8db75d-ctqwn map[app:hello-kiamol-2 pod-template-hash:787f8db75d]
# 로컬 컴퓨터에서 디플로이먼트로 포드포워딩을 설정한다.
kubectl port-forward deploy/hello-kiamol-2 8080:80
kubectl run
또는 kubectl create
는 명령형이다.# 매니페스트 스크립트는 쿠버네티스 API 버전과 정의하려는 리소스의 유형을 정의하면서 시작한다.
apiVersion: v1
kind: Pod
# 리소스의 메타데이터에는 이름(필수)과 레이블(비필수)이 있다.
metadata:
name: hello-kiamol-3
# 리소스의 실제 정의 내용이다. 파드는 실행할 컨테이너를 정의한다. 컨테이너 이름과 이미지로 정의한다.
spec:
containers:
- name: web
image: kiamol/ch02-hello-kiamol
kubectl apply
명령어를 사용해 애플리케이션 매니페스트를 통해 애플리케이션을 배포한다.# 매니페스트 파일로 애플리케이션을 배포한다.
kubectl apply -f pod.yaml
# 파드 목록을 조회한다.
kubectl get pods
# 아래와 같이 hello-kiamol-3 파드가 실행된다.
NAME READY STATUS RESTARTS AGE
hello-kiamol 1/1 Running 1 (3d2h ago) 11d
hello-kiamol-2-787f8db75d-ctqwn 1/1 Running 0 3d
hello-kiamol-3 1/1 Running 0 2d23h
kubectl apply -f https://raw.githubusercontent.com/sixeyed/kiamol/master/ch02/pod.yaml
# 디플로이먼트 API 버전은 apps/v1 이다.
apiVersion: apps/v1
kind: Deployment
# 디플로이먼트 이름
metadata:
name: hello-kiamol-4
# 디플로이먼트가 자신의 관리 대상을 결정하는 레이블 셀렉터를 정의한다.
# app 레이블의 값이 hello-kiamol-4
spec:
selector:
matchLabels:
app: hello-kiamol-4
# 디플로이먼트가 파드를 만들 때 이 템플릿을 사용한다.
template:
metadata:
labels:
app: hello-kiamol-4
# 파드의 정의에 컨테이너 이름과 이미지 이름을 정의한다.
spec:
containers:
- name: web
image: kiamol/ch02-hello-kiamol
kubectl apply
명령어를 사용해 애플리케이션을 배포한다.kubectl apply -f deploy.yaml
# 레이블이 app=hello-kiamol-4인 파드 목록을 조회한다.
kubectl get pods -l app=hello-kiamol-4
# 레이블이 app=hello-kiamol-4인 파드 목록이 출력된다.
NAME READY STATUS RESTARTS AGE
hello-kiamol-4-568f7fbc88-ndbnh 1/1 Running 0 4m57s
kutectl apply
명령어를 수행하면 YAML에 정의된 리소스가 없으면 쿠버네티스가 생성한다.# 파드 IP 주소를 확인한다.
kubectl get pod hello-kiamol -o custom-columns=NAME:metadata.name,POD_IP:status.podIP
# 컨테이너 안에서 명령어를 실행한다. hello-kiamol 파드 내부의 쉘을 실행한다. -- 뒤에 컨테이너 안에서 실행할 명령어를 입력한다. 아래 명령어를 수행하면 컨테이너의 쉘이 현재 터미널에 연결된다.
kubectl exec hello-kiamol -it -- sh
# 컨테이너 안에서 명령어를 입력해 IP주소를 확인한다. 파드의 IP 주소와 같다.
hostname -i
--tail=2
옵션은 로그의 최근 두 줄만 출력하라는 의미이다.# 쿠버네티스를 통해 컨테이너의 최근 로그를 출력한다.
kubectl logs --tail=2 hello-kiamol
# 도커를 통해 컨테이너의 최근 로그를 출력한다. 쿠버네티스를 통한 로그와 일치한다.
docker logs --tail=2 $(docker container ls -q --filter label=io.kubernetes.container.name=hello-kiamol)
# 디플로이먼트가 생성한 파드 안에 들어있는 컨테이너에서 웹 애플리케이션을 호출한다.
kubectl exec deploy/hello-kiamol-4 -- sh -c 'wget -O - http://localhost > /dev/null'
# 위의 파드의 로그를 조회한다.
kubectl logs --tail=2 -l app=hello-kiamol-4
# 파드 안의 index.html을 로컬 컴퓨터의 현재 경로에 복사한다.
kubectl cp hello-kiamol:/usr/share/nginx/html/index.html ./index.html
# 복사된 파일 내용을 확인한다.
cat ./index.html
# 로컬 컴퓨터에 복사된 파일을 다시 파드 안의 /tmp 디렉토리 안에 복사한다.
kubectl cp ./index.html hello-kiamol:/tmp/
컨트롤러 객체가 관리하는 리소스를 직접 삭제하면 컨트롤러가 다시 해당 리소스를 생성한다.
예를 들어 모든 파드를 삭제하고 조회해보면 직접 생성한 파드는 삭제되고 디플로이먼트가 생성한 파드는 다시 생성된다.
# 모든 파드를 조회한다.
kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-kiamol 1/1 Running 1 (3d3h ago) 12d
hello-kiamol-2-787f8db75d-ctqwn 1/1 Running 0 3d1h
hello-kiamol-3 1/1 Running 0 3d
hello-kiamol-4-568f7fbc88-ndbnh 1/1 Running 0 46m
# 모든 파드를 삭제한다.
kubectl delete pods
pod "hello-kiamol" deleted
pod "hello-kiamol-2-787f8db75d-ctqwn" deleted
pod "hello-kiamol-3" deleted
pod "hello-kiamol-4-568f7fbc88-ndbnh" deleted
# 모든 파드를 조회한다.
kubectl get pods
# 디플로이먼트가 생성한 파드는 다시 생성된다.
NAME READY STATUS RESTARTS AGE
hello-kiamol-2-787f8db75d-z5fqb 1/1 Running 0 5s
hello-kiamol-4-568f7fbc88-b49b6 0/1 ContainerCreating 0 5s
정리하면 컨트롤러 객체 없이 생성된 리소스는 삭제시 바로 삭제된다. 컨트롤러 객체(예를 들면 디플로이먼트)로 생성된 파드는 삭제되어도 디플로이먼트가 파드가 사라진 것을 감지하고 대체 파드를 생성한다.
따라서 컨트롤러 객체가 관리하는 리소스를 삭제하려면 해당 컨트롤러 객체를 삭제해야한다. 컨트롤러 객체는 삭제될 때 자신이 관리하던 리소스를 제거하고 삭제된다.
# 디플로이먼트 목록을 확인한다.
kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
hello-kiamol-2 1/1 1 1 3d1h
hello-kiamol-4 1/1 1 1 50m
# 디플로이먼트를 모두 삭제한다.
kubectl delete deploy --all
deployment.apps "hello-kiamol-2" deleted
deployment.apps "hello-kiamol-4" deleted
# 파드 목록을 조회한다.
kubectl get pods
# 모두 삭제됭 리소스가 발견되지 않는다.
No resources found in default namespace.