쿠버네티스 교과서 1
Kubernetes
k3
k3 설치
1
2
3
curl -sfl https://get.k3s.io | sh -s - --docker -disable=traefix --write-kubeconfig-mode=644
쿠버네티스는 컨테이너로 애플리케이션을 실행합니다. 모든 컨테이너는 파드에 속합니다. 쿠버네티스는 컨테이너를 또 다른 가상 환경인 파드로 감쌉니다. 파드는 컴퓨팅의 단위로, 클러스터를 이루는 노드 중 하나에서 실행됩니다.
파드는 쿠버네티스로 관리되는 자신만의 가상 IP 주소를 가집니다. 하나의 파드에 여러 컨테이너가 있다면, localhost 만을 이용해서 서로 통신할 수도 있습니다.
쿠버네티스가 직접 컨테이너를 실행하지는 않습니다. 컨테이너를 생성할 책임을 해당 노드에 설치된 컨테이너 런타임에 맡기는 형태입니다. 이 컨테이너 런타임은 도커가 될 수도 있습니다. 파드는 쿠버네티스가 관리하는 리소스고, 컨테이너는 쿠버네티스 외부에서 관리됩니다.
kubectl
1
2
3
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
파드의 컨테이너 개수가 0이 되자마자 쿠버네티스가 즉각적으로 대체 컨테이너를 생성하여 파드를 복원합니다. 쿠버네티스는 컨테이너를 파드로 추상화합니다. 이상을 일으킨 컨테이너는 일시적인 문제이며, 파드는 그대로 있으므로 새로운 컨테이너를 추가하여 파드 상태를 복원하면 됩니다.
1
2
3
4
5
6
7
docker container ls -q --fiter label=io.kubernetes.container.name=hello-kiamo1
// 컨테이너 식별
docker container rm ...
// 컨테이너 삭제
파드의 상세 정보에서 삭제한 컨테이너가 동작 중임을 확인할 수 있습니다. 식별자가 다른데, 이는 쿠버네티스가 새로운 컨테이너로 파드를 복원했기 때문입니다. kubectl 에는 네트워크 트래픽을 노드에서 파드로 전달할 수 있는 기능이 있습니다. 이 기능을 사용하면 간편하게 클러스터 외부에서 파드와 통신할 수 있습니다.
1
2
3
kubectl port-forwad pod/hello-kiamol 8080:80
컨트롤러 객체
파드는 직접 사용하기에는 너무 단순합니다. 파드는 고립된 한 벌의 애플리케이션으로 각 파드는 서로 다른 노드에 배정됩니다. 컨트롤러 객체는 다른 리소스를 관리하는 쿠버네티스 리소스를 의미합니다.
컨트롤러는 쿠버네티스 API 와 연동하며 시스템의 현재 상태를 감시하다가 ‘바람직한 상태’와 차이가 생기면 필요에 따라 그 차이를 바로잡습니다. 쿠버네티스에서 파드를 관리하는 컨트롤러 객체는 디플로이먼라고 부릅니다.
디플로이먼트를 정의할 때 우리에게 필요한 파드가 무엇인지 기술만 하면, 디플로이먼트는 쿠버네티스 api 를 통해 동작하는 리소스를 확인하고 필요한 파드를 생성합니다.
모든 쿠버네티스 리소스는 키-값 쌍의 레이블을 가질 수 있습니다. 디플로이먼트에 release 라는 레이블을 추가하면 배포 버전을 식별할 수 있습니다. 컨트롤러가 자신이 관리하는 리소스 목록을 직접 유지하지 않아도, 레이블 셀렉터가 컨트롤러 객체의 정의에 포함되어 있다면 컨트롤러 객체가 언제라도 쿠버네티스 API 를 통해 자신이 관장하는 리소스를 찾아볼 수 있습니다.
디플로이먼트가 생성한 파드의 레이블을 수정하면, 디플로이먼트는 해당 레이블을 가진 새로운 파드를 만듭니다. 예를 들어 release 0.0.1 -> 0.0.2 로 업데이트 되는 것입니다.
이 방법은 디버깅에 유용하다. 원하는 파드를 컨트롤러 객체의 관리에서 제외하고 직접 접속해서 문제가 무엇인지 확인할 수 있기 때문이다.
디플로이먼트의 관리를 벗어난 파드의 레이블을 원래대로 수정하면, 디플로이먼트는 레이블 셀렉터의 파드 개수가 자신이 관리하는 개수보다 증가한 것을 확인하여, 삭제 규칙에 의해 결정된 쪽을 삭제합니다. 따라서 상태를 원복할 수 있습니다.
애플리케이션 매니페스트
애플리케이션 매니패스트를 통해서 배포 결과를 지정할 수 있습니다. pod.yaml 의 예시는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 매니페스트 스크립트는 쿠버네티스 API 의 버전과
# 정의하려는 리소스의 유형을 밝히며 시작한다.
apiVersion: v1
kind: Pod
# 리소스의 메타데이터에는 이름(필수 요소)과
# 레이블(비필수 요소)이 있다.
metadata:
name: hello-kiamol-3
# 스펙은 리소스의 실제 정의 내용이다.
# 파드의 경우 실행할 컨테이너를 정의해야 한다
# 컨테이너는 이름과 이미지로 정의된다.
spec:
containers:
- name: web
image: kiamol/ch02-hello-kiamol
이런 형식을 선언적 스크립트 방식이라고 합니다. 최종 결과를 알려주고, 그 과정을 따지지 않는 방식입니다.
1
2
3
4
5
6
7
# 매니페스트 파일로 애플리케이션 배포
kubectl apply -f pod.yaml
# 실행 중인 파드 목록 확인
kubectl get pods
yaml 포맷으로 디플로이먼트도 적용할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 디플로이먼트는 API 버전 1에 속한다.
appVersion: apps/v1
kind: Deployment
# 디플로이먼트의 이름을 정해야 한다.
metadata:
name: hello-kiamol-4
# 디플로이먼트가 자신의 관리 대상을 결정하는
# 레이블 셀렉터가 정의된다.
# 여기에서는 app 레이블을 사용하는데, 레이블은 임의의 키-값 쌍이다.
spec:
selector:
matchLabels:
app: hello-kiamol-4
# 이 템플릿은 디플로이먼트가 파드를 만들 때 쓰인다.
template:
# 디플로이먼트 정의 속 파드의 정의에는 이름이 없다
# 그 대신 레이블 셀렉터와 일치하는 레이블을 지정해야 한다.
metadata:
labels:
app: hello-kiamol-4
# 파드의 정의에는 컨테이너 이름과 이미지 이름을 지정한다.
spec:
containers:
-name : web
image: kiamol/ch02-hello-kiamol
디플로이먼트의 매니페스트로 애플리케이션을 실행할 수 있습니다.
1
2
3
4
5
6
7
# 디플로이먼트의 매니페스트로 애플리케이션 실행
kubectl apply -f deployment.yaml
# 새로운 디플로이먼트가 만든 파드 찾기
kubectl get pods -l app=hello-kiamol-4
kubectl 을 사용하면 파드 안에 있는 컨테이너에 접근할 방법이 있습니다. 파드 속 컨테이너에 대화형 셸을 연결하면 파드 속 상황을 확인할 수 있습니다.
1
2
3
4
# 파드 내부와 연결할 대화형 셸 실행
kubectl exec -it hello-kiamol sh
쿠버네티스를 통해 컨테이너의 최근 로그를 출력할 수 있습니다.
1
2
3
kubectl logs --tail=2 hello-kiamol
컨트롤러 객체가 관리하는 리소스를 삭제하려면 해당 컨트롤러 객체를 삭제해야 합니다. 컨트롤러 객체는 삭제될 때 자신이 관리하던 리소스를 말끔히 제거하고 삭제됩니다.