Kubernetes

Kubernetes 정리

tpcable 2022. 6. 16. 22:39

컨테이너란?

- 호스트 OS상에서 논리적인 구획을 생성하고, 애플리케이션을 실행하는데 필요한 라이브러리, 애플리케이션 등을 하나로 모아 전용 서버 인 것 처럼 사용 가능한것(컨테이너 엔진 필요)

- 현재 쿠버네티스 기본값으로 되어 있는 것은 도커

 

외 다른 가상화

호스트가상화: Windows 10과 같은 Host OS에 별도의 가상화 소프트웨어를 설치 후 Guest OS실행(Virtual Box, VM Ware Player)

하이퍼바이저: HW상에 하이퍼바이저를 설치해 가상환경 제공(Windwos Hyper-V, 시트릭스 Hypervisior)

컨테이너를 통해 애플리케이션을 개발하게 된다면 애플리케이션 실행에 필요한 모든 파일과 디렉토리를 통째로 모두 컨테이너 이미지로 생성 가능하기에 개발, QA, 운영 동일한 환경으로 개발 가능

 

컨테이너 관련 도커 기본 명령어

- Build

애플리케이션 실행에 필요한 OS, 라이브러리, MW, 네트워크 설정 등을 하나로 모아 도커 이미지로 생성

-Run

도커 이미지를 기반으로한 컨테이너를 실행

 

쿠버네티스?

- 컨테이너를 통합 관리 할 수 있는 오케스트레이션 툴

- 비슷한 기능으로 도커swarm, 아파치 Mesos 가 있음

- 선언적인 시스템으로 추구하는 상태와 현재 상태를 맞추려고함

 

쿠버네티스를 활용한 개발 흐름

1. 개발 환경 준비

2. 컨테이너 이미지 작성, Docker는 Dockerfile에 해당 내용을 기술하고 빌드, 레포지토리에 공유

3. 인프라 구성(Seld Managed, AKS, EKS 등) 후 컨테이너 애플리케이션 실행

(Managed Kubernetes 서비스를 사용할 경우 다중화나 쿠버네티스 버전 업그레이드 등 불필요

 

쿠버네티스 핵심 세가지

1. Immutable Infrastructure

- 서버를 일회용 취급하는 개념(클라우드의 발전으로 인한)

 

2. 선언적

- 선언적으로 시스템이 유지되어야 할 모습을 정의

 

3. Self Healing

- 쿠버네티스는 애플리케이션 상태를 감시해서 차이가 발견되면 API를 통해 정의한 상태가 되도록 재시작 하거나 장애를 제거해서 시스템 복구

 

쿠버네티스 구성 요소

Control plane(Master)

  • API Server
    - 쿠버네티스의 리소스 정보를 관리하기 위한 프론트엔드 REST API
    - 각 컴포넌트로부터 리소스 정보를 받아 etcd에 저장하는 역할
    - kubectl 명령어를 통해 API Server를 원격으로 호출
  • Scheduler
    - Pod를 어떤 노드에서 배치시킬지 제어하는 백엔드 컴포넌트
  • Controller Manager
    - 쿠버네티스 클러스터의 상태를 감시하고 본래 되어야 할 상태를 유지하는 백엔드 컴포넌트
  • etcd
    - 클러스터 구성을 유지하는 분산 KVS
    - 어떤 Pod를 어떻게 배치할지 정보를 가지고 있어서 API Server가 이를 참조
    - 매니페스트의 내용이 저장
    - Master 서버에서 분리가능
    - Service Discovery(배포된 애플리케이션이 어디에 있는지 찾는 역할)

 

Worker node

  • kubelet
    - 각 노드마다 kubelet 에이전트가 동작(데몬), pod 매니페스트 파일에 따라 컨테이너를 실행하거나 스토리지를 마운트하는 기능
    - Status를 정기적으로 감시하는 기능이 있어 정기적으로 API Server에 전달(Pod 모니터링)
  • kube-proxy
    - 다양한 중계 및 변환을 수행하는 네트워크 프록시
    - 외부에서 들어오는 연결 리스닝(프리빌리지 권한 보유, iptabless 생성 요청)
  • 기타
    - 노드의 컨테이너 런타임은 기본적으로 도커

 

클러스터에 접근

kubectl 명령이 API Server과 안전하게 통신하려면 연결할 서버의 정보와 인증 정보 등이 필요

kubectl 명령은 ~/.kube/config에 기록되어 있는 정보를 바탕으로 클러스터에 연결 

 

~/.kube/config 파일 내용

- Cluster

kubectl 명령을 실행했을 때 연결 클러스터 정보를 설정

- Context

어떤 사용자가 어떤 클러스터에 연결할수 있는지 mapping 여러 사용자나 클러스터 전환가능 위에는 현재 3개의 정보가 있음

- Users

쿠버네티스 클러스터에 접근하는 사용자의 이름과 인증 키 등을 설정

 

쿠버네티스 리소스

애플리케이션 실행

  • Pod
    - 컨테이너의 집합, 애플리케이션 배포 단위
    - 컨테이너에서 가상 NIC을 공유하는 구성이라 컨테이너 끼리 localhost를 경유해 통신가능
  • ReplicaSet
    - 항상 지정된 수 Pod 유지
  • Deployment
    - 애플리케이션 배포 단위를 관리하는 것
    - Replica Set의 이력 관리 롤백이나 롤링업데이트 가능
  • Daemonset
    - log collector 와 같이 각각의 노드에 하나씩 배포하는 경우 사용
    - 클러스터 전체 노드에 Pod 하나 배포
    - ReplicaSet과 달리 수를 지정할 수는 없음
  • Statefulset
    - DB와 같이 영구 데이터와 연계되는 경우 사용, Pod의 고유성(기본적으로 stateless상태로 뭐든 랜덤으로 배정)

네트워크 관리

  • Service
    - 클러스터 안에 실행된 포드에 액세스 할 때, 쿠버네티스의 네트워크를 관리 하는 것
    - 서비스에 의해 할당되는 IP 주소는 Cluster IP(클러스터 내부 통신) / External IP(외부에 공개하는 주소)
    - Pod에서 Cluster IP로 나가는 패킷은 Proxy 가 받아 전달
  • Ingress
    - http/https 처리 등 L7역할

애플리케이션 설정 관리

- 환경변수를 변경할 때 마다 이미지를 새로 만들어야 하는데 해당 기능을 통해 설정 정보 관리 가능

  • ConfigMap
    - 애플리케이션의 설정 정보, 구성파일, 포트번호 등을 Pod에서 참조할 수 있도록 해주는 장치
    - ConfigMap의 정보는 마운트 가능하므로 보통의 파일 또는 환경변수로 취급 가능
  • Secret
    - DB Connection String이나 암호화된 정보를 관리할 때 사용
    - base64 encoding 하여 등록

 

배치 잡 관리

  • Job
    - 한 번만의 잡으로 처리가 끝나는 것에 이용, 실패 시 성공할 때 까지 Job 컨트롤러가 Pod생성
  • Cron Job
    - 반복할 Job실행에 사용

매니페스트 파일 구조

apiVersion: [API 버전 정보]

kind: [리소스 종류]

metadata:

     name: [리소스 이름]

spec:

[리소스 상세정보]

 

  • API 버전 정보
    - 호출할 API 버전 지정, 버전에 따라 안정성과 지원 레벨이 다름
    1) alpha
     예고 없이 호환성이 없는 방법으로 변경될 가능성이 있는 버전
    2)beta
    기능은 삭제되지 않지만 상세 내용이 변경될 수 있음
    3) 안정판
    v1과 같은 버전 번호가 붙음(실환경)

API Groups

  • Core API(apiVersion:v1)
    - CoreAPI는 group 작성 x, 
    - pod, service, pv, pvc, node, namespace 등
  • apps(apps/v1)
    - deployment, replicaset, statefulset 등

kubectl api-resource -o wide 명령어를 통해 api 그룹 확인

kubectl api-versions

YAML

- 쿠버네티스의 매니페스트 파일 작성할 때 권장하는 포맷(.yml .ymal)

  • 인덴트
    - 계층 구조를 인덴트로 나타낸다. 스페이스를 사용하며 탭은 사용불가
  • 플로, 블록
    - [], {} 등으로 데이터 구조를 나타내는 스타일을 블록스타일
    - 인덴트로 데이터 구조를 난타내면 플로스타일
  • 주석
    - 주석은 #로 한줄씩만 가능 
  • 데이터 형식을 자동으로 판별
    - 정수, 부동소수점, true/false, yes/no, null, yyyy-mm-dd, yyyy-mm-dd hh:mm:ss
    - 외 ' " 사이에 있는건 문자열 취급
  • 배열
    데이터 앞에 - 를 붙여서 배열을 나타냄 - 뒤에는 반드시 띄어쓰기 필요
  • 해시
    - key: vaule 와 같은 형식으로 입력 : 뒤에는 반드시 띄어쓰기 필요

Label

- 버전, 애플리케이션 이름, 환경 등 쿠버네티스 리소스를 식별하기 위해 임의의 정보를 정의하는 것 

  • Label 확인
    k get po --show-labels

  • Label 변경
    - yaml 파일 변경 후 apply -f 하면된다.

Label 활용

  • -selector 옵션을 통해 지정한 조건에 해당하는 것 만 선택 가능 ,를 통해 and 조건
    k get po -l key=value

  • label을 통해서 kubernetes 리소스 들을 연결 

Namespace

- 네임스페이스를 통해 필요한 액세스 권한을 설정하여 이용할 수 있는 사용자를 제한 가능

default namespace 지정 안했을 때 기본 값
kubectl-public 모든 사용자가 이용 가능한 컨피그맵 같은 리소스
kube-system 시스템 리소스

- 아래와 같이 namespace에 속한 pod 확인 가능

 

Pod 매니페스트 파일

[1] 기본항목
apiVersion: v1                                                   -- API 버전 

kind: pod                                                           -- 리소스 종류

metadata:                                                          -- Pod 이름이나 Label 같은 메타데이터

     name: test-pod # Pod 이름

     labels:

         app: testapp
         env: prod

[2] Pod 스펙: 이미지 위치, 이름, 포트 번호 등

spec:                                                                  -- Pod 상세 정보 설정

containers(배열) Pod에 속하는 컨테이너 목록
imagePullSecrets(배열) 컨테이너 이미지를 사용하기 위한 인증정보
initContainers(배열) 초기화 처리 하는 컨테이너, 장애 발생한 경우 restartPolicy에 따라 재시작
nodeName(문자열) 특정 node에 Pod를 배치할 때 사용
nodeSelector(Object) 지정한 label을 가진 node에 pod를 스케쥴링 하고 싶을 때
priority(상수) Pod 우선순위(클수록 높음)
restartPolicy(문자열) container restart policy, Always(dafault), OnFailure, Never
volumes(배열) Pod 안 컨테이너가 마운트할 수 있는 볼륨 리스트

[3] 컨테이너 사양                                                     --Pod 안에 움직이는 컨테이너 애플리케이션 세부 정보 설정

 containers:

  - images: test.azurecr.io/image:v1

     name: testapp-container

     ports:

     - containerPort: 80

args(배열) 컨테이너에 송신할 인수
env(배열) 컨테이너에 설정할 환경변수
images(문자열) 컨테이너 이미지
imagePullPolicy(문자열) Always, Never, IfNotPresent(dafault)
livenessProbe 임계값 동안 응답이 없으면 Pod 재시작
readnessProbe 트래픽을 수용할 준비가 되었을 때만 LB에 추가되도록하는 
name 컨테이너 이름. 클러스터 내부에서 DNS_LABEL로 사용
ports 컨테이너 오픈 포트
resoureces 컨테이너에 필요한 CPU, 메모리와 같은 컴퓨팅 자원
volumeMounts 마운트 할 볼륨
workingDir 컨테이너 작업 Directory

 

Pod status

Pending Pod 작성 대기 중
Running Pod 가동 중
Succeeded Pod 안의 모든 컨테이너가 정상 종료
Failed Pod 안 컨테이너 중 적어도 하나의 컨테이너가 실패하여 종료된 상태
Unknown Pod와 통신이 불가능한 상태

 

Pod 배포 과정

- API Server를 경유해 etcd의 상태를 감시하고 변경사항 적용 후 API Server를 통해 etcd 업데이트

1. kubectlAPI Server에 Pod 생성 요청

2. API Serveretcd에 할당되지 않은 Pod가 있음을 업데이트(=신규 Pod가 작성되었다는 정보)

3. Scheduleretc 변경사항을 API Server를 통해 감시

4. Pod를 배포할 Node를 선택해 API Server로 전달

5. API가 etc에 Pod 정보에 배치 노드 업데이트

6. kubelet도 API Server를 감시

7. 변경을 감지하면 kubelet은 runtime(Docker)에 pod작성 지시

 

Node의 CPU, Memory 확인

kubectl describe node [node name]

 

  • Capacity: Node가 사용가능한 리소스 
  • Allocatable: Pod가 사용가능한 리소스 

1CPU = 1000m

 

Resource Request 를 통해 Pod 리소스 선언

- 실제 리소스 사용율이 낮아 여유가 있는 노드가 있더라도 리소스를 확보할 수 없는 노드에는 Pod 배포하지 않음

- Pod에 들어가는 컨테이너의 합

 

kubectl describe node [node name]

메모리는 전체의 44% 확보

 

Node의 사양보다 높은 Pod를 정의 했을경우

할당노드: None

request Memory를 8Gi 요구 했으나 어떤 노드에도 할당 하지 못 함

Resource limtes 를 통해 Pod 리소스 제한설정

Pod에 오류가 발생 했을 경우

- Always: 항상 재시작(기본값)
- Onfailure: 오류인 경우만 재시작

- Never: 재시작하지 않음

 

Pod의 우선순위

- Pod에 대해 3개의 QoS 제공 QoS는 Resource Request, Resource Limits 조건을 바탕으로 우선순위가 정해짐

  • BestEffort: Pod안 어떤 컨테이너도 Resoure Request와 Resource Limits가 설정되어 있지 않을 때
  • Guaranteed: CPU와 메모리 모두 Resource Request와 Resource Limits가 설정되어 있는 경우 두 값이 똑같은 경우에 설정
  • Burstable: BestEffort Guaranteed 이외에 경우설정

k describe pod [podname] -n kube-system | findstr QoS 를 통해 QoS 확인 

- 우선순위(낮은순서대로 kill)

BestEffort

Burstable

Guaranteed(시스템이 메모리가 필요한 경우에만 kill)

 

 

Pod가 동작하는지 확인 하는 방법(kubectl describe 리소스 [리소스이름] 으로 로그확인)

- Liveness Probe: 애플리케이션이 응답하는지 아닌지 확인

  • HTTP Request 반환값 확인
    웹 애플리케이션의 경우 특정 URL에 http request / https status 값으로 판단
    livenessProbe에 httpGet 

  • TCP Socket 연결 가능한지 확인
    livenessProbe에 tcpSocket 

  • 명령 실행 결과 확인
    컨테이너 안에 임의의 명령 실행 후 그 결과로 Status 확인
    libenessProbe 에 exec

ReplicaSet(버전관리가 불가능하기에 상위 개념인 deployment 사용 권장) 

- ReplicaSet을 통해 항상 동일한 Pod 수 유지(Self-Healing)
- Label 조건에 따라 Pod 확인

ReplicaSet 매니패스트파일

[1] 기본항목
apiVersion: apps/v1                                                  -- API 버전 

kind: ReplicaSet                                                        -- 리소스 종류

metadata:                                                                  -- 레플리카 셋 이름이나 Label같은 메타데이터

     name: test-rs # ReplicaSet 이름

[2] ReplicaSet 스펙

spec:                                                                  -- ReplicaSet 상세 정보 설정

     replicas: 3        # Pod 수 

     selector:           # Pod Template 검색 조건, Pod Template에 설정된 라벨과 일치해야함

         matchLabels:

             apps: testrs
[3] Pod 템플릿

template:             -- 클러스터 안의 Pod수가 replicas 와 일치하지 않을 때 작성되는 Pod 템플릿

     metadata:       -- 템플릿 이름이나 Label 같은 메타데이터

         labels:

             app:testrs

             env:prod

[4] Pod 스펙

     spec:               -- Pod 상세 정보 설정

         containers:

             - image: ~~~~~~
                 name: ~~~~~

                 ports:

                     - containerPorts: 80

     

Kubernetes의 확장성

  • Pod
    - HPA(Horizontal Pod Autoscaler) 수평
    - VPA(Vertical Pod Autoscaler) 수직
  • Node
    - az aks scale

kubectl 명령어를 통한 pod HPA

k scale [object] [name] --replicas=수 / k scale --replicas=수 -f [파일명]

 

HPA

- HPA로 지정한 메트릭을 컨트롤러가 부하에 따라 필요한 pod수를 조절
- Deployment, ReplicaSet, Replication Controller, StatefulSet

 

HPA는 메트릭 서버를 통해 리소스의 사용량 수집

 

1. Auto Scale 하고싶은 ReplicaSet 작성

2. Pod Template에 Resource Request, Resource Limits 설정

3. HPA Yaml 작성

metrics: 오토스케일 메트릭 설정

scaleTargetRef: 오토스케일 리소스 설정

 

HPA 구조

- kubelet의 cAdvisor agent가 메트릭 수집
- cAdvisor은 kubelet 바이너리에 통합된 오픈소스로 CPU, Memory, Network, FileSystem 등의 컨테이너 메트릭 수집(Node 단)

- Cluster 상의 리소스 메트릭을 모아서 집약하는 것은 Metric Server

- CPU 사용률의 경우 1분 평균 Pod에서 요구한 CPU로 계산

 

필요한 replica 수 = pod1 cpu + pod 2 cpu / targetAverageUtilization

 

k -n kube-system get po를 통해 Metrice Server 확인가능

Deployment

- deployment를 통해 pod rollout, rollback
- 배포방법, 배포 조건이나 속도 제어 애플리케이션 이력관리

아래의 순서로 네이밍 되어있는 것을 확인

Deployment

 Replica Set

  Pod1, Pod2, Pod3

k describe deployment [deployment name] 를 통해 이력 확인 가능

Annotations에 1 추가됨 deployment revision 될 때마다 증가

Deployment 상태는 condition

로그는 Event를 통해 확인

k get rs -o wide 를 통해 replica set 이력 확인 가능 / deployment를 삭제하면 관련된 Pod, replicaset까지 같이 삭제

 

Deployment 변경

- manifest 파일 spec, strategy, type에서 설정 / RollingUpdate(기본값) 또는 Recreate

  • Recreate
    - 오래된 Pod를 정지시키고 새로운 Pod를 재작성, 속도가 빠르지만 다운타임 발생
  • Rolling Update
    - 신규 Pod의 생성을 확인하면 하나씩 변경하는 방식

 

Rolling Update

- manifest 파일 spec, strategy, type에서 설정 / RollingUpdate(기본값) 또는 Recreate

- Rollback 경우 기존 이력에 있던 RS를 바탕으로 실행

- deployment yaml 파일 변경 결과 / deployment는 그대로 RS 추가됨 

- k rollout history [리소스] [리소스이름] --revison=[정수]를 통해 세부 롤아웃 히스토리 확인

Rolling Update 설정

  • maxUnavailable(기본값 25%)
    - 업데이트 중에 사용 못하는 Pod 퍼센트 지정
  • maxSurge
    - Rollout 할 때 추가 될 수 있는 리소스(기본값 25%)
    - 40%설정 시 기존Pod+신규Pod 합계가 140% 넘지 않음

Blue Green 배포

- Blue / Green 배포 후 Service yaml selector 변경을 통해 blue로 향하던 트래픽을 green으로 변경

 

ConfigMap

- 애플리케이션에서 사용하는 변수를 모아 관리 하는 것
- Manifest / config file Mount / kubectl 

 

  • Manifest 
    key:value 형태로 저장

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: app-config

    data:
      app.func: "home" 

  • Config file Mount
    파일에 통째로 환경변수 마운트 가능
    kubectl create configmap [config map name] --from-file=[파일 경로 및 파일명]

ConfigMap 참조

- 환경변수 / Volume Mount

  • 환경변수로 전달
    containers - env

    (위에 생성 정보참조)
    APP_ID가 app-config의 환경변수
    configmap: app-config
    k: app.func
    v: home

  • Volume Mount
    containers - volumeMounts
    앞에 설정한 configmap을 /etc/config에 마운트

 

kubectl exec -it [pod] /bin/bash pod 접속

 

Secret

- etcd안에 암호화된 상태로 관리

- Manifest / Mount

type에는 비밀 종류
type: Opaque                                                         일반적인 기밀 정보
type: kubernetes.io/tls                                         TLS 정보
type: kubernetes.io/docerconfigjson                Docker Registry 정보

type: kubernetes.io/service-account-token    Service Account 정보

data는 k v 형태로 지정하고 base64로 인코딩

  • Manifest
    apiVersion: v1
    kind: Secret
    metadata:
      name: apikey
    type: Opaque

    data:
      id: dXNlcg==
      key: 7JWU7Zi4

  • Mount
    파일 경로 및 파일명은 --from-file 옵션으로 지정
    kubectl create secret generic [name] --from-file=[PATH]

Secret 참조

  • 환경변수

  • Mount
    containers - volumeMounts

 

'Kubernetes' 카테고리의 다른 글

[K8S] 쿠버네티스 정리  (0) 2022.10.17
ACR(Azure Container Registry) 이미지 빌드 및 업로드  (0) 2022.03.28
[Kubernetes] Service 개체  (0) 2021.07.04
[kubernetes] 쿠버네티스 아키텍쳐  (0) 2021.07.04
docker 명령어  (0) 2021.01.17