운영자 입장의 kubernetes 주요 특징

Jerry(이정훈)
15 min readMay 12, 2021

--

뇌피셜이라 정확하지 않을 수 있으나 운영자 입장에서 제가 느낀 Kubernetes 개념과 특징을 정리해 보았습니다.

(운영자 입장) Kubernetes 핵심 개념

  1. 선언형 (declarative), 가장 핵심
    : Application 설치 시 기존 VM처럼 순차적으로 명령어를 실행하는 것이 아니고 원하는 상태를 Code로 선언합니다. 그러면 항상 자동으로 이 상태를 유지합니다. 예를 들어 NGINX 웹서버 설치하고 웹서버를 3개로 유지하라 등을 code로 선언 할 수 있습니다.
  2. 소스 코드 기반
    : kubernetes object는 명령어가 아닌 source code로 관리합니다. 흔히 YAML 지옥이라고도 합니다. (조금 지나니 명령어 외울 필요 없고 조금씩 수정만 하면 되니 이게 편했습니다.)
  3. immutable(변하지 않는), 죽으면 수정하지 않고 다른 멀쩡한 놈으로 교체
    : Application 문제가 발생하면 기존 Application의 문제점을 찾아서 변경하는 것이 아니라 새로운 버전 혹은 문제가 없었던 기존 버전으로 교체하는 것을 의미합니다.
  4. Application(=POD) 항상 죽을 수 있다.
    : Application down 된 이유를 찾지 말고 POD Down 되어도 이중화 구성을 해서 실 서비스에는 이상 없도록 구성해야 합니다. 실 서비스 오픈 전 반드시 HA, 부하 테스트를 수행 합니다.
    (편의상 POD와 application을 같은 개념으로 사용합니다.)

kube 주요 특징

선언형

: POD(= application, process) 나아가 물리 서버(node) down 되어도 자동으로 항상 선언된 상태(e.x pod 3개) 유지한다.

  • POD Down

: 강제로 POD를 삭제해 보겠습니다.

[spkr@erdia22 99. ETC (spkcluster:nginx)]$ k delete pod nginx01-58cf646cdb-2q6tp
pod "nginx01-58cf646cdb-2q6tp" deleted

강제로 삭제하여도 자동으로 신규 POD가 생성됩니다.

spkr@erdia22 tmp (spkcluster:nginx)]$ k get pod -w
(-w wait, 변경 사항을 자동으로 tracking 합니다.)
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx01-58cf646cdb-2q6tp 1/1 Running 0 2m2s 10.10.100.49 dia02 <none> <none>
nginx01-58cf646cdb-vx8bs 1/1 Running 0 2m2s 10.10.100.55 dia01 <none> <none>
nginx01-58cf646cdb-x7rgt 1/1 Running 0 2m2s 10.10.100.53 dia04 <none> <none>
nginx01-58cf646cdb-2q6tp 1/1 Terminating 0 2m13s 10.10.100.49 dia02 <none> <none>
nginx01-58cf646cdb-xtf92 0/1 Pending 0 0s <none> <none> <none> <none>
nginx01-58cf646cdb-xtf92 0/1 Pending 0 0s <none> dia02 <none> <none>
nginx01-58cf646cdb-xtf92 0/1 ContainerCreating 0 0s <none> dia02 <none> <none>
nginx01-58cf646cdb-2q6tp 0/1 Terminating 0 2m16s 10.10.100.49 dia02 <none> <none>
nginx01-58cf646cdb-xtf92 1/1 Running 0 8s 10.10.100.58 dia02 <none> <none>
nginx01-58cf646cdb-2q6tp 0/1 Terminating 0 2m22s 10.10.100.49 dia02 <none> <none>
nginx01-58cf646cdb-2q6tp 0/1 Terminating 0 2m22s 10.10.100.49 dia02 <none> <none>

위와 같이 기존 pod(nginx01–58cf646cdb-2q6tp) terminating 되고 신규 pod (nginx01–58cf646cdb-xtf92) 생성되어 최초 3개의 상태를 유지합니다. 이는 강제적으로 삭제하지 않고 시스템 문제 등으로 자동으로 POD가 삭제되는 경우에도 항상 3개의 상태가 자동으로 유지됩니다. (새벽에 전화받고 수동으로 올리지 않아도 됩니다.)

  • 노드 Down(node drain)
    POD 뿐만 아니라 물리 서버(node)가 down 되어도 항상 선언된 상태를 유지합니다.
[spkr@erdia22 99. ETC (spkcluster:nginx)]$ k drain dia04 --delete-emptydir-data --ignore-daemonsets
(drain 명령어를 사용합니다.)
node/dia04 already cordoned
WARNING: ignoring DaemonSet-managed Pods: diamanti-system/collectd-v0.8-4bvcc, diamanti-system/csi-diamanti-driver-vlfml, diamanti-system/nfs-csi-diamanti-driver-7kkrv
evicting pod spektra-system/thanos-store-75cbbc5666-qrc2t
evicting pod diamanti-system/csi-external-snapshotter-6d7c748556-gcjsx
evicting pod default/nginx-test-c675f77c4-tqdth
(이하 생략)

dia04 node에서 실행중인 POD가 서버가 down되어 강제 Down 됩니다.

[spkr@erdia22 tmp (spkcluster:nginx)]$ kgpw
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx01-58cf646cdb-lngdj 1/1 Running 0 7m43s 10.10.100.50 dia04 <none> <none>
nginx01-58cf646cdb-nbljw 1/1 Running 0 7m43s 10.10.100.52 dia02 <none> <none>
nginx01-58cf646cdb-x7rgt 1/1 Running 0 7m43s 10.10.100.53 dia04 <none> <none>
nginx01-58cf646cdb-lngdj 1/1 Terminating 0 8m1s 10.10.100.50 dia04 <none> <none>
nginx01-58cf646cdb-ds6qx 0/1 Pending 0 0s <none> <none> <none> <none>
nginx01-58cf646cdb-ds6qx 0/1 Pending 0 0s <none> dia01 <none> <none>
nginx01-58cf646cdb-x7rgt 1/1 Terminating 0 8m3s 10.10.100.53 dia04 <none> <none>
nginx01-58cf646cdb-8gn2r 0/1 Pending 0 0s <none> <none> <none> <none>
nginx01-58cf646cdb-8gn2r 0/1 Pending 0 0s <none> dia02 <none> <none>
nginx01-58cf646cdb-ds6qx 0/1 ContainerCreating 0 3s <none> dia01 <none> <none>
nginx01-58cf646cdb-8gn2r 0/1 ContainerCreating 0 1s <none> dia02 <none>
<none>
nginx01-58cf646cdb-lngdj 0/1 Terminating 0 8m27s 10.10.100.50 dia04 <none> <none>
nginx01-58cf646cdb-lngdj 0/1 Terminating 0 8m31s 10.10.100.50 dia04 <none> <none>
nginx01-58cf646cdb-lngdj 0/1 Terminating 0 8m31s 10.10.100.50 dia04 <none> <none>
nginx01-58cf646cdb-x7rgt 0/1 Terminating 0 8m33s 10.10.100.53 dia04 <none> <none>
nginx01-58cf646cdb-x7rgt 0/1 Terminating 0 8m34s 10.10.100.53 dia04 <none> <none>
nginx01-58cf646cdb-x7rgt 0/1 Terminating 0 8m34s 10.10.100.53 dia04 <none> <none>
nginx01-58cf646cdb-ds6qx 1/1 Running 0 41s 10.10.100.62 dia01 <none> <none>
nginx01-58cf646cdb-8gn2r 1/1 Running 0 62s 10.10.100.64 dia02 <none> <none>

위와 같이 무려(?) 서버가 죽어도 자동으로 다른 노드(dia01, dia02)에서 신규 nginx pod가 생성됩니다.

service discovery
: Application 간 서로 지정이 필요한 경우(e.x web — db 호출) 시 IP 기반이 아닌 Domain Name 기반으로 통신합니다. 신규 POD 생성되면 IP가 변경될 수 있습니다.(pod는 수시로 죽을 수 있으므로) 하지만 Domain Name은 변경되지 않으므로 일관성 유지가 가능합니다.
: Load Balancer 기능을 지원하여 복수 POD로 balancing 됩니다.

  • NGINX 통신을 위한 Service 생성
    : Domain 기반 통신을 위해서는 Service 라는 Kubernetes Object를 사용합니다. 용어가 Service라는 웹서비스 등에서 사용하는 서비스와 혼동될 수 있으나 다른 개념입니다.
[spkr@erdia22 06.Deployment (spkcluster:nginx)]$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc ClusterIP 10.0.0.199 <none> 80/TCP 4m18s
  • centos POD 실행(접속)
[spkr@erdia22 06.Deployment (spkcluster:nginx)]$ k exec -it cent-tools-697fc7d5fc-2nv9z -- bash
[root@cent-tools-697fc7d5fc-2nv9z /]# curl nginx-svc
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
(이하 생략)
[root@cent-tools-75795cfbbb-49zjm /]# curl nginx-svc.nginx.svc.cluster.local

위와 같이 curl 실행을 IP 가 아닌 도메인(nginx-svc 또는 nginx-svc.nginx.cluster.local) 이름을 사용합니다. (nginx-svc는 Service 이름입니다.)

  • Load Balancing 테스트
    : POD 개수 변경(2개 -> 5개) 시 자동으로 해당 개수만큼 Load Balancing 됩니다.
[spkr@erdia22 99. ETC (spkcluster:nginx)]$ k get endpoints
NAME ENDPOINTS AGE
nginx-svc 10.10.100.52:80,10.10.100.62:80 51m

Service가 실제로 통신하는 POD는 endpoint object 으로 관리됩니다. domain name으로 호출할 때 실제 응답하는 POD가 endpoint 입니다.

[spkr@erdia22 99. ETC (spkcluster:nginx)]$ k scale deployment nginx01 --replicas=5
deployment.apps/nginx01 scaled

nginx POD 수 2개 -> 5개 증가

[spkr@erdia22 99. ETC (spkcluster:nginx)]$ k get endpoints
NAME ENDPOINTS AGE
nginx-svc 10.10.100.25:80,10.10.100.27:80,10.10.100.31:80 + 2 more... 53m

추가 설정 없이 자동으로 endpoint 개수 2개 -> 5개 증가되었습니다.

  • 외부에서 접속 시 아래와 같이 10.10.100.33, 10.10.100.43 등으로 분산(Load Balancing)하여 접속됩니다.

Label 기반 Kube Object 관리
: Kube 환경에서는 서로 다른 Object 간 선택을 해야 하는 경우가 많이 있습니다. 이 선택을 label(상표) 기반으로 지정합니다. 예를 들어 Service가 POD를 선택 시 아래와 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hello
# namespace: default
labels:
app: nginx-hello
spec:
replicas: 2
selector:
matchLabels:
app: nginx-hello
template:
metadata:
labels:
app: nginx-hello # Service 등에서 참조할 Label 이름
spec:
containers:
- name: nginx
image: nginxdemos/hello

label 이름이 app: nginx-hello 입니다.

Service에서 위 POD를 선택하려면 label을 맞추어 줍니다. 아래와 같이 selector (말 그대로 선택자)— app: nginx-hello 로 지정합니다.

apiVersion: v1
kind: Service
metadata:
name: nginxhello-svc
# namespace: default
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx-hello
sessionAffinity: None
type: LoadBalancer

Apply 하시면 Service에서 POD가 선택됩니다.

[spkr@erdia22 06.Deployment (spkn02:nginx)]$ k apply -f ../11.Service/nginx-LoadBalancer-svc.yml 
service/nginxhello-svc created
[spkr@erdia22 06.Deployment (spkn02:nginx)]$ k describe svc nginxhello-svc
Name: nginxhello-svc
Namespace: nginx
Labels: <none>
Annotations: <none>
Selector: app=nginx-hello
Type: LoadBalancer
IP Families: <none>
IP: 10.233.9.86
IPs: 10.233.9.86
LoadBalancer Ingress: 172.17.28.160
Port: http 80/TCP
TargetPort: 80/TCP
NodePort: http 32240/TCP
Endpoints: 10.233.92.47:80,10.233.96.64:80
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal IPAllocated 20s metallb-controller Assigned IP "172.17.28.160"
Normal nodeAssigned 20s metallb-speaker announcing from node "node3"

추가로 하면 아주 많이 많이 있지만 ^^ 다음 번에 하도록 하겠습니다.

컨테이너는 OS, VM 인 듯 아닌 듯

  • ssh 가 아닌 exec
  • curl, netstat, ping 등 안되는 명령어가 많다.

ephemeral-storage vs persistent volume

  • data를 저장하려면 PV로 저장

외부에서 POD 접속 방법

  • overlay vs sr-iov 환경

설정 파일 ConfigMap 관리

  • NGINX nginx.conf 파일

스케쥴링

  • pod 50개 생성 시 각 노드 별 균등 분배
  • Node 별 cpu/memory 사용량에 따라 분배
  • affinity 사용 시 특정 노드 분배

로그 파일 관리

  • 로그가 사라진다

--

--

Jerry(이정훈)
Jerry(이정훈)

Written by Jerry(이정훈)

DevOps/Automation Engineer 60살까지 콘솔 잡는 엔지니어를 목표로 느리게 생각하고 있습니다.

Responses (1)