📍 해당 글은 Udemy의 Certified Kubernetes Administrator (CKA) with Practice Tests 강의를 듣고 정리했습니다.
Kubelet
은 Master Node와의 유일한 접점으로, 스케줄러가 지시한 대로 컨테이너와 포드를 Worker Node에 적재 및 삭제한다.
컨테이너 또는 파드를 load하라는 명령을 받으면, 도커와 같은 Container Runtime Engine
에게 필요한 이미지를 pull해 달라고 요청하고, 인스턴스를 실행한다.
kubelet은 파드와 파드 안의 컨테이너 들의 상태를 계속 모니터링하고, kube-apiserver에 필요시 보고
한다.
지금까지 컴포넌트들은 kubeadm
툴을 사용하여 클러스터를 배포할 수 있었지만, kubelet
은 자동으로 배포되지 않아 항상 수동으로 설치해주어야 한다.
wget https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubelet
⚠️ Kubeadm does not deploy Kubelets !
kubelet 프로세스와 적용된 옵션은 다음 명령어를 통해 확인가능하다.
세션의 뒷 부분에서 kubelet 구성 방법, 인증서 생성, TLS Bootstrap에 대해 살펴볼 것이다.
ps -aux | gerp kubelet
쿠버네티스 내의 모든 pod는 다른 pod와 소통할 수 있다.
POD Network는 모든 노드에 거쳐, 모든 파드에 연결되어 있는 internal virtual network이다.
먼저 Service
는 쿠버네티스 메모리에 존재하는 가상 컴포넌트이다. 서비스는 어떠한 실물이 아니라 POD Network
에 조인할 수 없고, 컨테이너도 아니고 listening 프로세스도 없다.
→ 여기서 kube-proxy
가 등장한다.
kube-proxy
는 각 노드에서 실행되는 프로세스이다. 새로운 서비스를 찾고, 새롱운 서비스가 생성될 때마다 각 노드에 해당하는 서비스에 대한 트래픽을 뒤쪽의 파드로 전달하기 위해 적절한 규칙을 생성한다. 규칙을 생성하는 방법 중 하나는 iptables rule
을 사용하는 것이다. iptables rule은 실제 파드의 IP를 서비스의 IP로 변경하여** 각 노드가 서비스로 트래픽을 전달하도록 한다.
kubeadm
툴은 kube-proxy를 각 노드의 파드로 배포한다. 실제로는 DaemonSet
이라는 이름으로 배포되고, 항상 각 노드에서 단일 파드로 배포된다.
kubectl get pods -n kube-system
쿠버네티스의 궁극적인 목표는 클러스터에서 워커 노드로 구성된 컨테이너 형태로 애플리케이션을 배포하는 것이다. 그러나 쿠버네티스는 컨테이너를 워커 노드에서 직접 배포하지 않는다. 컨테이너들은 Pod
라는 쿠버네티스 오브젝트로 캡슐화되어 있다.
애플리케이션의 단일 인스턴스로, 쿠버네티스에서 가장 작은 오브젝트이다.
만약 애플리케이션을 확장해야한다면, 컨테이너 인스턴스를 추가하여 load를 분산할 수 있다.
이때, 한 파드 안에서 컨테이너 인스턴스를 추가하지 않고 새 인스턴스와 함께 새로운 파드를 만든다. 만약 사용자의 수가 더 많아져서 노드에 충분한 공간이 없다면 새 노드를 만들어서 추가로 파드를 배포할 수 있다.
결론적으로, 확장하려면 새로운 Pod를 만들고, 축소하려면 기존 Pod를 삭제한다.
💡 Pod는 일반적으로 컨테이너와 1:1 관계를 가진다.
💡 클러스터의 물리적 용량 확장을 위해선 새 노드를 추가한다.
쿠버네티스가 한 Pod에서 하나의 컨테이너만 가질 수 있게 제한해둔 것은 아니다.
한 파드는 같은 종류의 컨테이너가 아니라면, 여러 컨테이너를 가질 수 있다.
만약, 위의 경우처럼 애플리케이션을 확장해야하는 상황에서는 같은 종류의 컨테이너를 추가해야 하는 것이므로 파드를 추가적으로 생성해야하는 것이다.
동일한 파드 안에 있는 두 컨테이너는 동일한 network space를 공유하기때문에 서로를 localhost
로 참조하여 직접 소통할 수 있다. 또한 동일한 저장 공간을 쉽게 공유할 수도 있다.
동일한 파드의 컨테이너들을 함께 생성되고 함께 파괴된다. 이렇게 파드를 생성하는 것이 애플리케이션 아키텍처가 변경되거나 확장될 때를 대비하여 장기적으로 유리하다.
하지만, 멀티 컨테이너 파드는 드문 사례이기 때문에 세션에서는 파드 당 컨테이너가 하나 있다고 가정하고 설명하도록 한다.
kubectl run nginx --image nginx
명령을 이용해 Nginx pod를 배포했다. 하지만 아직은 사용자가 nginx 웹 서버에 접근할 수 없다. 외부 사용자가 웹 서버에 접근할 수 있도록 해주어야하는데 이 내용은 네트워킹과 서비스를 배운 이후에 공부한다.
쿠버네티스에서는 YAML 파일을 이용하여 파드, 레플리카, 배포, 서비스 등과 같은 오브젝트를 생성할 수 있다.
definition file의 최상위 레벨에는 항상 아래 4가지가 포함된다. (필수 !)
apiVersion
, kind
, metadata
, spec
apiVersion:
kind:
metadata:
spec:
💡 공백에 주의하자
공백을 기준으로 sibling 항목인지 child 항목인지 구분된다.
name
과 image
가 key인 dictionary를 가진다.# pod-definition.yml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
imgae: nginx
파일을 다 작성하였으면 아래 명령을 이용하여 Pod를 생성할 수 있다
kubectl create -f pod-definition.yml
OR
kubectl apply -f pod-definition.yml
💡 definition file을 작성하고자하면 일단 최상위 레벨에
apiVersion
,kind
,metadata
,spec
이 4가지를 적고 시작하자
# yaml 파일 작성 후
kubectl apply -f pod.yaml
# Pod 생성 확인
kubectl get pods
# Pod에 대한 더 자세한 정보
kubectl describe pod [파드 이름]
# default 네임스페이스에서 pod 갯수 확인
kubectl get pods
# nginx 이미지로 pod 생성
kubectl run nginx --image=nginx
# pod에 대한 자세한 설명보기 (이미지, 상태, 상태에 대한 로그, 배포된 노드 등)
kubectl describe pod [파드명]
# pod가 배포된 node 확인
1. kubectl get pods -o wide
2. kubectl describe pod [파드명] 에서 Node 필드 확인
# pod 삭제
kubectl delete pod [파드명]
# yaml로 redis 파드 생성
kubectl run redis --image=redis --dry-run -o yaml > redis.yaml