본문 바로가기
CSP (Cloud Service Provider)/GCP

Kubernetes(GKE를 공부하기 위한)

by BTC_JGT 2022. 9. 7.

k8s Components

Control plane components

Control plane 컴포넌트는 일반적으로 하나의 노드에서 동작하지만, 고가용성 환경이나 대규모 클러스터에서는 여러 노드에 분산된 형태도 가능하다.

  • Api server : 쿠버네티스 REST API를 공개한다. 모든 데이터를 etcd 클러스터에 저장하므로 쉽게 수평 확장이 가능하다. API 서버는 쿠버네티스 control-plane을 구체화한 것이다.
  • etcd : 분산데이터 저장소, 쿠버네티스는 이것을 사용해 전체 클러스터의 상태를 저장한다. 규모가 작고 일시적인 클러스터의 경우에는 etcd 단일 인스턴스가 다른 마스터 컴포넌트와 함께 동일한 노드에서 동작할 수 있다. 하지만 대규모 클러스터의 경우 일반적으로 이중화와 고가용성을 위해 3개에서 많으면 5개 노드의 etcd 클러스터를 갖기도 한다.
  • controller manager : 컨트롤러 매니저는 API를 사용해 클러스터의 상태를 감시하고, 클러스터를 원하는 상태로 조정한다. 컨트롤러 매니저에는 replication controller, pod controller, service controller, endpoint controller 등이 포함된다.
  • scheduler : Kube scheduler는 node에 pod를 스케줄링하는 역할을 담당한다. 서비스의 리소스 요구사항, 서비스 요구사항, hardware와 software 정책 제약 사항등 여러 상호작용을 요인으로 고려해야하므로 사실상 매우 복잡한 작업이다.

Add-on Component

  • Dashboard
  • CNI(Container Network Interface Plugin)
  • Ingress
  • coreDNS

Worker Node Component

클러스터의 worker node가 클러스터 master components와 상호작용하고, 클러스터를 실행하고 업데이트하기 위한 워크로드를 받기 위해서는 몇 가지 관련 components가 필요하다.

  • kube-proxy
    • 각 node에서 저수준의 네트워크 관리 업무를 수행한다.
    • 쿠버네티스 서비스를 지역적으로 반영하고 TCP와 UDP 포워딩을 수행하며 환경변수나 DNS를 통해 클러스터 IP를 찾는다.
  • kubelet
    • kubelet은 쿠버네티스를 대표하는 node라고 할 수 있다.
    • kubelet은 마스터 컴포넌트와 통신을 수행하며 실행중인 pod를 관리 감독한다.
    • 구체적인 역할은 다음과 같다.
      • API 서버에서 pod secret 다운로드
      • 볼륨 마운트
      • pod의 컨테이너 실행
      • node와 각 pod의 상태 보고
      • 실행중인 컨테이너 활성 여부 조사

고가용성(HA) 클러스터

  • 쿠버네티스는 master node에 내부적으로 API-SERVER를 가지고 있어 master node를 통해 worker node로 통신이 전달된다.
  • 대량의 통신이 발생하게 되면 master node는 부하를 많이 받아 장애 발생 가능성이 커지게 되는데 master node 를 HA 클러스터로 운영하게 되면 통신량을 분산시킬 수 있고, 일부 master node에 장애가 발생되더라도 worker node의 운영환경에는 영향을 없을 수 있다.

핵심 기능

Automatic binpacking

  • 가용성에 대한 희생없이, 리소스 사용과 제약 사항을 기준으로 자동으로 컨테이너를 스케줄

Self-healing

  • 자동으로 문제가 발생한 node의 컨테이너를 대체(룰/정책에 따른 헬스 체크)

Horizontal scaling

  • CPU와 Memory 같은 리소스 사용에 따라 자동으로 애플리케이션을 확장, 경우에 따라서 사용자 정의 측정값을 기준으로 한 동적인 확장 가능

Service discovery and Load balancing

  • 컨테이너에 고유한 IP 부여. 여러 개의 컨테이너를 묶어 단일 서비스로 부여하는 경우 단일 name으로 접근하도록 로드 밸런싱 제공

Automatic rollouts and rollbacks

  • 다운타임 없이 애플리케이션의 새로운 버전 및 설정에 대한 롤아웃/롤백 가능

Secret and configuration management

  • 애플리케이션의 secret과 configuration 정보를 이미지와 독립적으로 구분하여 별도의 이미지 재생성 없이 관리

Storage and orchestration

  • 소프트웨어 정의 저장장치를 기반으로 로컬, 외부 및 저장소 솔루션 등을 동일한 방법으로 컨테이너에 마운트 하라 수 있음

Batch execution

  • CI 워크로드와 같은 Batch성 작업 지원, crontab 형식으로 스케줄링도 가능

k8s node

  • 컨테이너를 포함한 모든 Pod는 node에서 실행된다.
  • node는 물리머신이거나 가상머신이다.
  • node는 control-plane에 의해 관리되며 pod를 실행하는데 필요한 서비스를 포함한다.

 

 

node 정보 보기

  • 노드 정보 확인(get)
$ kubectl get nodes
$ kubectl get nodes -o wide

k8s node 관리

node 스케줄링 중단 및 허용

  • 노드 스케줄링 중단(cordon)
$ kubectl cordon node_name
  • 노드 스케줄링 허용(uncordon)
$ kubectl uncordon node_name
  • 노드 비우기(drain) : 특정 노드에서 동작중인 모든 pod를 제거
$ kubectl drain node [options]
--ignore-daemonsets : daemmonset-managed pod들은 모두 ignore
--force=false : rc, rs, job, daemonset 또는 statefulset에서 관리하지 않는 pod를 까지 제거
  • 노드 삭제(delete) 및 추가(join)
$ kubectl delete node node_name
$ kubectl join MASTER_IP --token XXX --discovery-token-ca-cert-hash XXXX

 

 

pod 란?

  • 컨테이너를 표현하는 k8s API의 최소 단위
  • 하나 또는 여러 개의 컨테이너의 그룹
    • 스토리지 및 네트워크를 공유
    • 해당 컨테이너를 구동하는 방식에 대한 명세를 가진다.

Pod 생성하기

  • 포드에서 특정 이미지를 생성하고 실행
$ kubectl run NAME --image=iamge [--env="key=value"] [--port=port] [--dry-run=server|client] [--overrides=inline-json] [--command] [args....]
  • 동작 중인 pod 확인
$ kubectl get pods
$ kubectl get pods -o wide

Pod Template으로 Pod 실행

  • 파드 템플릿은 파드를 생성하기 위한 명세이다.
  • 파드 템플릿은 yaml 형식이나 json 형식을 가진다.
  • 파드 템플릿을 사용하여 실제 파드가 동작된다.
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx:1.14
    name: nginx
    ports:
    - containerPort: 80

dry-run : 실제 pod를 실행하지 않고 실행 여부를 화면에 출력

-o yaml : 실제 pod를 실행하지 않고 실행 여부를 확인하고 pod API를 yaml 파일 포맷으로 출력

$ kubectl run nginx --image=nginx:1.14 --port=80 --dry-run=client -o yaml > pod-nginx.yaml

Pod 관리 Commands

  • 동작중인 pod 정보 보기
$ kubectl get pods
$ kubectl describe pod nginx
  • 동작중인 pod 수정
$ kubectl edit pod nginx
  • 동작중인 pod 삭제
$ kubectl delete pod nginx
  • pod 내 컨테이너 log 보기
$ kubectl logs nginx
  • 동작중인 pod로 연결
$ kubectl exec -it nginx -- /bin/bash

Pod expose

  • Deployment로 여러 개의 웹서버 실행
    • 동일한 애플리케이션을 여러 개 실행 가능
$ kubectl create deployment webserver --image=nginx:1.14 --replicas=2 --port=80
  • 동작 중인 pod 확인
$ kubectl get deployments.apps
$ kubectl get pods
$ kubectl get pods -o wide
  • 단일 진입점 만들기 : expose
$ kubectl expose deployment webserver --port=80
$ kubectl get service

multiple-container Pod

  • 하나의 pod에는 여러개의 컨테이너가 포함될 수 있다.
  • 하나의 Pod에 여러 개의 컨테이너를 포함하는 경우 모든 컨테이너가 항상 단일 Node에서 실행된다.
  • 보통 multiple-container pod에 포함된 컨테이너들은 밀접하게 관련된 프로세스를 함께 실행하거나 동일한 IP 및 Port를 사용한다.
apiVersion: v1
kind: Pod
metadata:
  name: multiple-pod
spec:
  containers:
  - name: nginx-container
    image: ningx:1.14
    ports:
    - containerPort: 80
  - name: centos-container
    image: centos:7
    command:
    - sleep
    - "10000"

Label

  • Label은 Pod와 같은 오브젝트에 첨부된 Key와 Value의 쌍이다.
  • Label은 오브젝트의 특성을 식별하는데 사용되어 사용자에게 중요하지만, 코어 시스템에 직접적인 의미는 없다.
  • Label로 오브젝트의 하위 집합을 선택하고, 구성하는데 사용할 수 있다.
  • Label은 오브젝트를 생성할 떄에 붙이거나 생성 이후에 붙이거나 언제든지 수정이 가능하다.
  • 오브젝트마다 key와 value로 Label을 정의할 수 있다. 오브젝트의 key는 고유한 값이어야 한다.

Label Selector

  • name과 UID와 다르게 label은 고유하지 않다.
  • Label Selector를 통해 클라이언트와 사용자는 오브젝트를 식별할 수 있다.
  • 집합성 기준 레이블 요건에 따라 값 집합을 키로 필터링할 수 있다.
    (in, notin, exists)
- Label

matadat:
  label:
    rel: stable
    name: mainui

- Selector

selector:
  matchLabels:
    key: value
  matchExpressions:
  - {key: name, operator: In, values: [mainui]}
  - {key: rel, operator: NotIn, values: ["beta", "canary"]}

Label Template

  • pod label definition
apiVersion: v1  
kind: Pod 
metatdata:
  name: appjs-pod
  labels:
    apps: web
    release: stable
spec:
  containers:
    name: appjs-container
    image: smlinux/appjs
    ports:
      containerPort: 80

label 관리

  • label 보기
$ kubectl get pods --show-labels
$ kubectl get pods -L <label_name>
  • label 관리 : kubectl label --help
    • label 생성, 변경, 확인, 제거
$ kubectl label pod <name> key=value
$ kubectl label pod <name> key=value --overwrite
$ kubectl label pod <name> --show-labes
$ kubectl label pod <name> key-

annotation

  • Label과 동일하게 key-value를 통해 리소스의 특성을 기록
  • Kubernetes에게 특정 정보 전달할 용도로 사용
  • 관리를 위해 필요할 정보를 기록할 용도로 사용
  • 릴리즈, 로깅, 모니터링에 필요한 정보들을 기록
  • Label과 달리 오브젝트를 식별하여 select하지 않음
apiVersion: v1
kind: Pod
metadata:
  name: anon-pod
  annotation:
    imageregistry: "http://hub.docker.com/"
spec:
  containers:
    name: nginx
    image: nginx:1.14

Node Label

  • Worker node에 할당된 label을 이용해 node를 선택
  • Node Label 설정
$ kubectl label nodes <node 이름> <label key>=<label value>
$ kubectl label nodes node1.example.com gpu=true
$ kubectl get nodes -L gpu

node label 관리 명령

  • worker node를 구분할 용도로 label 할당
$ kubectl label nodes <node 이름> key=value
  • node에 할당된 label 보기
$ kubectl get nodes --show-labels
$ kubectl get nodes -L <label name>
  • node label 생성, 변경, 제거
$ kubectl label nodes <name> key=value
$ kubectl label nodes <name> key=value --overwrite
$ kubectl label nodes <name> key-
  • node Selector : label이 할당된 node는 nodeSelector를 통해 선택된다.
apiVersion: v1
kind: Pod
metadata:
  name: testpod
spec:
  containers:
    name: nginx
    image: ngnix:1.14
  nodeSlector:
    type: ssh

Pod Resource 제한 및 관리

  • Pod Resource 요청 및 제한
  • Resource Requests
    • pod를 실행하기 위한 최소 리소스 양을 지정
  • Resource Limits
    • Pod가 사용할 수 있는 최대 리소스 양을 지정
  • Pod Resources 단위
    • 1000m(milicores) = 1 core = 1 CPU = 1 AWS vCPU = 1 GCP Core
apiVersion: v1
kind: Pod
metadata:
  name: pod
spec:
  containers:
    name: nginx-container
    image: nginx:1.14
    resources:
      requests:
        cpu: 100m
        memory: 250Mi
      limits:
        cpu: 500m
        memory: 500Mi

댓글