Certification

[CKA] Udemy CKA 강의 Core Concepts01 - Cluster Architecture (Docker, ContainerD, ETCD, kube-apiserver, kube-controller-manager, kube-scheduler, kubelet, kube-proxy)

유자바 2024. 11. 7. 09:13

Cluster Architecture

  • 쿠버네티스의 목적
    • 자동화된 방식으로 애플리케이션을 컨테이너 형식으로 호스트
    • 요구에 따라 프로그램의 많은 인스턴스를 쉽게 배포할 수 있고, 다양한 서비스 간의 통신이 쉽게 가능해짐
  • 아키텍처
    • master node: 노드의 관리, 계획, 스케줄링, 모니터링 담당
      • etcd cluster: key-value 형식으로 데이터를 저장하는 데이터베이스
      • kube-scheduler: 컨테이너를 적재할 올바른 노드를 식별하고, 스케줄링함
        • 올바른 노드를 식별하기 위해 컨테이너 리소스 요구 사항, 워커 노드 용량, 다른 정책이나 제약 조건들, 테인트와 관용, 노드 친화성 규칙을 따짐
      • controller-manager
        • node-controller: 노드 관리
        • replication-controller: replication group 내에서 컨테이너 개수를 관리
      • kube-apiserver: 클러스터 내 모든 작업을 조정(orchestration), 주기적으로 kubelet에게 상태 보고서를 받음
    • worker node: 컨테이너 형식으로 응용 프로그램 호스트
      • kubelet: 각 노드에 존재하는 agent로 kube-apiserver와 통신
      • kube-proxy: 클러스터 내에서 서비스 간의 통신에 관여
    • 컨테이너 런타임 엔진: 클러스터 내 모든 노드에 다운로드 필요 (ex) docker, containerD, rocket

 

Docker vs ContainerD

  • 도커 외의 다른 런타임 엔진들도 쿠버네티스 생태계에 포함되고 싶어함
    • OCI(Open Container Initivative) 표준을 만족하면 쿠버네티스의 CRI(Container Runtime Interface)를 통해 통합 가능
  • 도커는 CRI 표준을 만족 못해서 dockershim을 통해 도커를 지속적으로 지원했으나 v1.24에서 dockershim이 없어짐
  • 도커는 cli, api, build, volumes, auth, security, containerd 등으로 구성
  • ContainerD는 CRI 표준을 지원해 도커와 별개로 쿠버네티스에서 사용 가능
    • ctr: 사용자 친화적 x, 디버깅 목적의 제한적 지원
    • nerdctl: 도커와 유사, 신규 기능까지 지원
    • crictl: CRI를 사용하는 컨테이너 런타임을 위한 cli 제공, 디버깅 목적

 

ETCD for Beginners

ETCD란?

distributed, reliable key-value store

 

key-value 저장소란?

  • 문서 혹은 페이지 형태로 정보를 저장
  • 각 개인마다 하나의 파일을 가져 한 문서의 수정이 다른 문서에 영향을 주지 않음
  • json, yaml 파일 형태

 

ETCD 설치하기

1. 바이너리 파일 다운로드: curl -L <깃허브 주소>

2. 파일 추출: tar xzvf <etcd 파일집>

3. ETCD 실행: ./etcd

 

ETCD는 어떻게 작동할까?

☁️ ETCD 명령어
- 실행: ./etcd
- 항목 생성
   - ./etcdctl set key1 value1 (v2.0)
   - ./etcdctl put key1 value1 (v3.0)  # 결과: OK
- 값 서치
   - ./etcdctl get key1 (v2.0) # 결과: value1 
   - ./etcdctl get key1 (v3.0) # 결과: key1 \n value1 
(v2.0)
- etcd version
   - 버전 확인: ./etcdctl --version
   - 버전 변경: ETCDCTL_API=3 ./etcdctl version
- 백업
   - etcdctl backup (v2.0)
   - etcdctl snapshot save (v3.0)
- 상태 체크
   - etcdctl cluster-health (v2.0)
   - etcdctl endpoint health (v3.0)

 


ETCD in Kubernetes

  • 모든 변경 정보가 ETCD 서버에 업데이트되고, kubectl get 명령어로 가져오는 정보는 모두 ETCD에서 가져옴
  • Deployment에 따라 ETCD 배포 방식이 달라짐
    • from scratch: wget -q --https-only <filename>
      • --advertise-clients-urls: 클라이언트의 IP와 ETCD의 포트(default: 2379)
      • kube-apiserver가 etcd 서버에 접근하려면 해당 url이 설정되어 있어야 함
    • kubeadm tool
      • etcd 서버가 파드의 형태로 배포됨: kubectl get pods -n kube-system
      • 모든 키들의 리스트 보고 싶으면: kubectl exec etcd-master -n kube-system etcdctl get / --prefix -keys-only
  • HA Environment
    • 클러스내 내에 여러 개의 마스터 노드가 있는 경우
    • 여러 개의 ETCD 인스턴스가 마스터 노드들에 존재
      • --initial-cluster에 인스턴스 명기해야 함

 

* etcdctl api version과 인증 파일의 path를 구체화하기 위한 명령어

kubectl exec etcd-master -n kube-system -- sh -c "ETCDCTL_API=3 
etcdctl get / --prefix --keys-only --limit=10 --cacert 
/etc/kubernetes/pki/etcd/ca.crt --cert 
/etc/kubernetes/pki/etcd/server.crt  --key 
/etc/kubernetes/pki/etcd/server.key"

 


 

Kube-API Server

  • 쿠버네티스의 주요 관리 구성 요소로 kube-apiserver의 역할은 다음과 같다.
    • 1. authenticate user
    • 2. validate request
    • 3. retrieve data
    • 4. update etcd
    • 5. scheduler
    • 6. kubelet
  • kubectl 명령을 실행하면
    • (ex) kubectl get nodes
      • kube-apiserver에 도달해서 관리자가 요청을 인증(1. authenticate)하고 유효성을 인증(2. validate request)
      • 인증되면 etcd 클러스터에서 데이터를 가져와 요청된 정보로 응답(3. retrieve data)
  • kubectl 명령어를 사용하지 않아도 post request를 통해 api를 직접 호출하는 것도 가능
    • (ex) curl -X POST /api/v1/namespaces/default/pods ...
      • api 서버는 노드에 할당하지 않고 포드 개체를 생성
      • kube-scheduler는 지속적으로 api서버를 모니터링해서 노드가 할당되지 않은 포드를 식별하고, kube-apiserver와 통신해 etcd 클러스터에 업데이트함
      • api 서버는 이 정보를 적절한 worker node의 kubelet에게 전달
      • kubelet은 노드에 포드를 생성하고 컨테이너 런타임 엔진에 지시해 앱 이미지를 배포
      • 완료되면 kubelet은 api 서버에 상태를 업데이트하고 
      • apiserver는 etcd 클러스터에 업데이트된 정보를 저장
      • 클러스터의 변경을 위해 수행하는 모든 작업의 중심에 있음
  • 요약하자면 요청의 인증과 유효성을 확인하고, etcd에 데이터를 검색하고 업데이트함 사실 etcd와 상호작용하는 유일한 요소
  • 여기서 다루는 모든 컴포넌트들은 연결된 인증서를 가지고 있음!

 

명령어

  • kubeadmin 툴로 설정하면 kubeadmin은 마스터 노드의 kube-syption 네임스페이스에 포드로서 kube-apiserver를 배포
  • kubeadm으로 설치 시 api-server 확인
kubectl get pods -n kube-system
  • kubeadm으로 설치 시 api-server 옵션 확인
cat /etc/kubernetes/manifests/kube-apiserver.yaml
  • kubeadm으로 미설치 시 api-server 옵션 확인
cat /etc/systemd/system/kube-apiserver.service
  • 실행 중인 프로세스에서 옵션 확인
ps -aux | grep kube-apiserver

 


 

Kube Controller Manager

  • 쿠버네티스의 다양한 컨트롤러 관리
  • 역할
    • watch status: 워커 노드의 상태 살피기
    • Remediate situation: 상황을 재조정하기 위해 필요한 조치 취하기
    • 시스템 내의 다영한 구성요소 상태를 지속적으로 모니터링하고 시스템 전체를 원하는 기능 상태로 만드는 것
      • node controller: kube-apiserver를 통해 노드의 상태를 모니터링하고 애플리케이션이 계속 실행되도록 액션을 함
        • kubectl get nodes
        • 5초마다 노드를 모니터링하고, 노드가 멈추면 노드의 상태는 not ready로 변하는데 40초 후에야 신호가 잡힘
        • 다시 틀때까지 5분이 걸림
      • replication controller: 복제본의 상태를 모니터링하고 원하는 수의 파드가 항상 사용 가능하도록 함
        • 파드가 죽으면 다른 파드를 만듦
  • 위의 두 가지 외에도 많은 컨트롤러가 kube-controller-manager에 하나의 프로세스로 패키지화되어 있음

 

installing kube-controller-manager

  • kube-controller-manager 다운로드하기
wget .../kube-controller-manager
  • kube-controller-manager.service에서 option의 형태로 제공
    • --node-monitor-period
    • --node-monitor-grace-period
    • --pod-eviction-timeout 
    • 어떤 컨트롤러를 활성화할지 선택할 수 있음

 

kubeadm으로 kube-controller-manager 설정하기

  • kubeadm으로 설치 시 kube-controller-manager 확인하기
    • 마스터 노드의 kube-system 네임스페이스에 파드로 kube-controller-manager-master를 배포
kubectl get pods -n kube-system
  • kubeadm으로 설치 시 kube-controller-manager options 확인
cat /etc/kubernetes/manifests/kube-controller-manager.yaml
  • kubeadm으로 미설치 시 kube-controller-manager options 확인
cat /etc/systemd/system/kube-controller-manager.service
  • 실행 중인 프로세스에서 options 확인
ps -aux | grep kube-controller-manager

 


Kube Scheduler

  • node에 pod를 스케줄링하는 역할
  • Pod를 node에 위치하시키는건 kubelet이고, 어디에 스케줄링할지만 정하는게 kube-scheduler의 역할
  • pod에 가장 적합한 node를 위치하기 위해 거치는 2가지 단계
    • 1. filter nodes
    • 2. rank nodes

 

명령어

  • kube-scheduler 다운로드: wget .../kube-scheduler
  • kubeadm으로 설치 시 kube-scheduler option 확인: cat /etc/kubernetes/manifests/kube-scheduler.yaml
  • 실행 중인 프로세스를 통해 option 확인: ps -aux | grep kube-scheduler

 

Kubelet

  • 작업자 노드가 쿠버네티스의 클러스터로 노드를 등록
  • 노드에 컨테이나 포드를 로드하라는 지시를 받으면 컨테이너 런타임 엔진을 요청
  • 포드 상태와 컨테ㅣㅇ너를 계속 모니터링하고 kube apiserver에 보고

 

명령어

  • kubelet 다운로드
    • kubeadm은 kubelet을 deploy하지 않음
      • 다른 구성요소들과의 차이점으로 항상 수동으로 설치해야함
      • wget .../kubelet
  • 실행 중인 프로세스를 통해 option 확인: ps -aux | grep kubelet

 

Kube-proxy

  • 모든 파드가 다른 파드랑 소통할 수 있음
    • pod 네트워크는 내부, 가상 네트워크로 모든 포드가 연결되는 클러스터 내 모든 노드에 걸쳐있음
    • 이 네트워크로 서로 통신할 수 있음
    • 웹 앱은 파드의 ip를 이용해 데이터베이스에 도달할 수 있는데 데베 파드의 ip가 같을 보장이 없음
      • 서비스를 사용해 데베에 액세스하는 방법이 더 유용 -> 클러스터 전체에 데베 애플리케이션을 노출할 서비스 만들기
      • 서비스는 쿠버네티스 메모리 상 존재하는 가상의 요소라 파드 네트워크에 참여할 수 없음
    • 파드가 ip나 이름을 이용해 서비스에 도달하려 할 때 트래픽을 백엔드 포드(데베 파드)로 전달
    • but, 서비스는 파드 네트워크에 조인할 수 없음 (실제것이 아니라서, 파드같은 컨테이너가 아니라 프로세스도 인터페이스도 없음, 쿠버네티스 메모리에만 존재하는 가상 컴포넌트)
      • 서비스가 클러스터의 노드에 접근가능해야 할 때 kube-proxy가 이 역할을 해줌
        • 새 서비스가 생성될때마다 규칙을 만들어 그 서비스로 트래픽을 전달 (백엔드 파드로)
        • iptables 규칙을 만들어 서비스의 ip로 향하는 트래픽을 만들게 됨
 웹 애플리케이션이 데이터베이스에 접근하는 더 나은 방법은 쿠버네티스 서비스를 사용하는 것입니다. 데이터베이스 파드의 IP는 변경될 수 있으므로, 서비스는 클러스터 내에서 데이터베이스에 고정된 주소(서비스 이름 DB)를 제공합니다. 이를 통해 웹 애플리케이션은 IP가 아닌 서비스 이름을 사용해 데이터베이스에 안정적으로 접근할 수 있습니다.
 서비스는 가상 컴포넌트로, 실제로 네트워크에 참여하거나 직접 통신을 담당하지 않습니다. 이 역할은 kube-proxy가 수행하며, 각 노드에서 실행되는 kube-proxy는 새로운 서비스가 생성될 때마다 해당 서비스의 트래픽을 백엔드 파드로 전달하는 규칙을 설정합니다. 예를 들어, iptables 규칙을 사용하여 서비스 IP(예: 10.96.0.12)로 들어오는 트래픽을 실제 데이터베이스 파드 IP(예: 10.32.0.15)로 전달합니다.

 

명령어

  • kube-proxy 다운로드: wget ..../kube-proxy
  • kubeadm을 통해 설치 시 kube-proxy 확인
    • kubectl get pods -n kube-system
    • kubectl get daemonset -n kube-system
      • 데몬셋으로 각 노드에 kube-proxy 파드를 배포함
      • 단일 파드는 항상 클러스터 내 각 노드에 배포