인프라 > 클라우드 > DevOps > MSA > AI

 

Chapter 1. 쿠버네티스 기본 지식

Kubernetes는 결국 Container를 관리하기 위한 Orchestration 기술이다.

 

컨테이너란?

- OS 가상화 기술

- 프로세스 격리

- 리눅스 커널은 공유

 

기존의 대체제로는 Virtual Machine 이 존재했다.

 

Virtual Machine 이전에는 Physical Machine 방식만 존재했다.

 

Service를 제공하려면 Server가 필요한데, 맨 처음의 Server는 곧 하나의 Physical Machine을 의미했다.

 

그러나 Service 마다, Physical Machine 마다 Server 구성하다보면 리소스 낭비가 너무 심하다.
(Service가 늘어날 때마다 OS 설치, 의존성 프로그램 설치, 네트워크 설정 등)

 

가상머신과 컨테이너 비교

1. 가상머신

- Hypervisor가 VM 마다 가상 메모리, CPU를 할당해주는 방식으로 존재

- VM마다 Guest OS가 존재하므로, 불필요한 파일도 생성되야 하므로 무겁다.

 

2. 컨테이너

- Guest OS가 없어, Host Machine의 OS만 공유하고 Linux의 컨테이너 격리 기술로, 별도 Container로 띄우는 방식이다.

- VM 대비 구동 시간이 빠르고, 가벼움

 

아키텍처의 변화

1. Monolytic Service

2. MicroService 아키텍처

- Container 기술에 따라, 기존보다 달성하기 쉬워짐

 

Docker 란?

- 컨테이너 엔진(컨테이너를 실행하고 관리하는 도구)

- 컨테이너 기반의 오픈소스 가상화 플랫폼

- 도커 허브라는 공개된 저장소 서버를 통해 컨테이너 자료들을 관리

(Image)

 

Dockerfile 이란?

- 컨테이너 이미지를 생성하기 위한 레시피 파일(설계도, 재설계)

- Docker file로 build를 하면 Image가 만들어지고, Image를 run 하면 Container가 생성된다.

- FROM, WORKDIR, RUN, CMD 등 용도에 따른 명령어 모음

 

Docker Image

- 서비스 운영에 필요한 프로그램, 소스코드, 라이브러리 등을 묶는 형태로, 일종의 Container 템플릿이다.

- Docker Image는 Dockerfile을 사용하여 커스텀 생성(build)

- Docker Image을 사용하여, 다수의 Container를 실행(Run)

- 무한정 실행할 수는 없다.(왜냐하면 Physical Machine의 CPU, RAM, Storage 의 한계가 있기 때문이다.)

 

Docker Image Naming Rule

- docker build -t <Namespace>/<ImageName>:<tag>

- Namespace란 저장소이다. (예 : 도커허브 : docker.io/library)

- Namespace가 없으면 dockerhub인 것으로, 약속되어 있음

- Tag가 없으면 latest인 것으로 약속되어 있음

 

Docker Private Image

- Private 이미지

 

대표 Docker Image 명령어

- Run : Image가 있거나, 없거나 Run을 수행하면 Container가 실행된다.(Image가 local docker에 없으면 pull 한 뒤에, 실행한다.)

- Pull : Image만 docker hub에서 download

- Build : Dockerfile로 custom Image 생성

- Push : docker hub로 공유 upload

 

 

컨테이너 오케스트레이션이란?

- docker 명령어만으로는 컨테이너가 너무 많을 때 관리하기가 힘들다.

- 다수의 컨테이너를 다수의 시스템에서, 각각의 목적에 따라, 배포 / 복제 / 장애복구 등 총괄적으로 관리

- 스케줄링 / 자동확장 및 축소(오토스케일링) / 장애복구(오토힐링) / 로깅 및 모니터링 / 검색 및 통신 / 업데이트 및 롤백

 

컨테이너 오케스트레이터

- Kubernetes, docker Swarm, AWS ECS, ...

 

컨테이너 오케스트레이터의 배포 위치

- 가상머신, 온프레미스, 클라우드 모두 가능

 

Kubernetes

- 컨테이너형 애플리케이션의 배포, 확장, 관리를 자동화하는 오픈소스 시스템, 그리스어로 선박 조종사를 의미한다.

- k8s라고 불린다.(k와 s 사이의 8글자가 존재하므로)

 

Kubernetes를 사용하는 이유

- 높은 확장성, 원활한 이동성(이식성)

- 여러 환경에 구축 가능

- 오픈 소스 도구의 장점

- 플러그인이 가능한 모듈 형식(Kubernetes의 여러 도구 모듈을 붙여서 사용 가능)

 

CNCF(Cloud Native Computing Foundation) 단체가 관리

- 클라우드 네이티브 오픈소스 기술들을 추진하고 관리하는 단체

- 대표적으로 Kubernetes와 Prometheus(모니터링 도구) 오픈소스 도구

 

Kubernetes 아키텍처

- Cluster(집합, 묶음) : Master Node(Control Plane)와 Worker Node(Date Plane)를 묶어서 Cluster라고 칭한다.

- Master Node

- Worker Node

 

마스터 노드의 구성요소

- API 서버 (6443 port) : Kubernetes API를 노출하는 구성요소, 명령, 통신을 담당 / 마스터 노드의 Frontend / 사용자가 컨테이너 수정*생성 명령을 API 서버에 요청함

- Scheduler 서버 : Pod의 생성 명령이 있을 경우, 어떤 Node에 배포할지 결정하여, API 서버에 예약 내역을 전달해줌

- Controller Managers : 클러스터의 상태를 조절하는 컨트롤러들을 생성, 배포

클러스터의 상태를 조절하는 역할을 컨트롤러라고 명령하고, 컨트롤러를 관리하는 것을 컨트롤러 매니저라고 한다.

클러스터의 현재 상태(Container 0개)를 원하는 상태(Container 5개)로 바꿔줄 수 있는 컨트롤러를 컨트롤러 매니저가 배치해준다.

컨트롤러에는 여러 종류가 있는데, Auto Healing Controller, Auto Scaling Controller 등이 있어서, 컨트롤러 매니저가 요청에 따라 Controller들을 적절하게 배치한다.

- etcd : 모든 클러스터의 구성 데이터를 저장하는 저장소

장애 복구 시, 해당 저장소에 저장된 데이터를 참고하여 수행한다. 다운 되지 않도록 backup 등이 필요하다.

 

Pod란? 단순히 Container를 감싸는 껍데기를 의미한다.

 

워커 노드의 구성요소

- kubelet : 각 Node의 Agent(팀장), Pod에서 Container가 확실하게 동작하도록 관리, Pod를 만들어 주는 것은 Kubernetes API

- Container Runtime : Pod에 컨테이너를 실행하고 노드에서 컨테이너 이미지를 관리

(Kubernetes에서 지원하는 containerd, cri-o만 지원하게 되었음, docker 제외됨)

- Kube-proxy : 각 노드의 네트워크 규칙 유지 관리

 

 

Addons

- Kubernetes 추가 기능

 

Chapter 2. 쿠버네티스 설치

 

All-in-One Single-Node 설치

- Node 하나에 Master + stcd , Worker 1, Worker 2

- 서비스 단계에서는 지양해야함

 

Single Node etcd, Single Master and Multi-Worker 설치

- Master Node만 한개, Worker Node는 여러개

 

Multi-Node etcd, Multi-Master and Multi-Worker 설치

- Master Node도 이중화

 

Kubernetes 설치도구

- kubeadm 도구로 설치함

 

Kubernetes 설치 순서

- Docker 설치

- Kubernetes 설치

- Master와 Worker 연동

 

# Master Node, Worker Node Setup 실습
init, join
3개의 노드에 필요한 설정과 k8s 설치 전에 해야할 설정을 

# Master Node에서 kubeadm init 명령어 시작
kubeadm init --pod-network-cidr=172.16.0.0/16 --apiserver-advertise-address=<Master IP>
출력결과(kubeadm join 이하 명령어)를 잘 저장해둡니다. 3~5분 소요됩니다.


# Master 노드 설정 (Master Node 만 진행)

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf

# Calico 네트워크 플러그인 설치 (Master Node 만 진행)
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/calico.yaml

# kubectl 자동완성 적용 (Master Node 만 진행)
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
source /etc/bash_completion
echo alias k=kubectl >> ~/.bashrc
source ~/.bashrc
complete -F __start_kubectl k

# Worker 노드와 Master 노드 연동 (Worker Node 만 진행)
<kubeadm join 으로 시작하는 2번과정에서 저장해 두었던 명령어>

# 연동 확인 (Master 노드에서 확인)
kubectl get nodes

 

 

Chapter 3. 컨테이너 배포 - Pod, Replicaset, Deployment

 

Kubernetes Object

- 클러스터의 상태를 나타내기 위해 오브젝트를 이용

- 가장 기본적인 오브젝트(Pod, Service, Volume, Namespace)

- 오브젝트의 Spec(정의된 상태), Status(현재 상태) 필드

 

Kubernetes Controller

- 클러스터의 상태를 관찰하고, 필요한 경우에 오브젝트를 생성, 변경을 요청하는 역할

- 각 컨트롤러는 현재 상태를 정의된 상태에 가깝게 유지하려는 특징

- 기본 컨트롤러로는 Replicaset(자동 복구), Deployment(Pod 배포) 등이 있다.

 

Controller 동작 Cycle

- 관찰 -> 상태 변경 -> 조치

 

Controller 기능

- Auto Healing

- Auto Scaling (HPA Controller) : 부하 여부에 따라 Pod 수 조정

- Update & Rollback (Deployment Controller)

- Job : 1회성 Job을 수행하는 Container을 띄웠다가 내려주는 컨트롤러도 존재

 

YAML 파일

- Object는 Yaml 스펙으로 정의하고, docker run하듯이 kubectl create 등으로 사용한다.

- Object Model:

  - apiVersion : 연결할 API server의 버전

  - kind : Object의 유형

  - metadata : Object의 기본 정보를 갖고 있는 필드

     - name, label, namespace 등

  - spec : 배포되는 Object의 원하는 상태

 

 

 

Kubectl

- Kubernetes에 명령을 내리는 CLI

- kubectl 명령 구조 : 

  - kubectl [Command] [Type] [Name] [Flags]

- 오브젝트와 컨트롤러를 생성, 수정, 삭제

 

# 현재 kubernetes가 관리 중인 node 목록 보기
kubectl get node

# 상세 node 정보 보기
kubectl describe node <node명>

# 전체 명령어 목록 보기
kubectl -h

 

Kubernetes Object - Pod

- k8s에서 컨테이너를 배포하는 가장 작은 최소 단위 Object, 

- 하나 이상의 컨테이너 그룹

- Kubernetes에서 컨테이너를 배포하려면 반드시 Pod에 담아서 배포된다.

- 네트워크와 볼륨을 공유

- Pod 하나의 여러개의 컨테이너를 올릴 수 있지만, 여러개의 독립 서비스를 올린다기 보다, main 서비스와 monitoring 서비스 정도 같이 올라가는 것을 권장한다.

 

Pod - Kubecttl

- yaml 파일을 사용하여, Pod를 생성하는 명령어

```

kubectl create -f pod.yaml (-f(file)옵션이 yaml로 pod로 만들겠다는 옵션)

```

- kubectl 명령으로 Pod를 생성하는 명령어

```

kubectl run pod --image=nginx:1.14.0 --port=80

kubectl run <pod명> --image=<이미지명:버전> --port=<포트번호>

run은 이미 "create pod"와 동일한 의미이다.

docker run <이미지명> 과 비슷하다고 볼 수 있다.

```

 

Pod 예시

- Web(Frontend, nginx) Pod - Was(Backend, fastapi) Pod - DB(Postgresql) Pod

 

Kubernetes Object - Namespace

- 리소스를 논리적으로 구분하기 위한 공간 오브젝트

- 그룹핑(프로젝트의 느낌일까?)

  - 팀별, 프로젝트별로 리소스를 격리하고 싶을 때

  - 같은 이름의 리소스를 중복 없이 사용하고 싶을 때

  - 리소스 사용량을 제한하거나 모니터링 하고 싶을 때

기본적으로 default, kube-sys Namespace가 존재한다.

kube-sys namespace는 kubenetes 아키텍처에서 기본적인 pod 들(예시. master node Api server)이 포함된다.

 

# pod 생성, namespace 생성 실습
Pod 조회
kubectl get pods
kubectl get pod
kubectl get po

yaml 확인
cat pod.yaml

yaml 을 활용한 Pod 생성
kubectl create -f pod.yaml

Pod 조회 및 세부정보 확인
kubectl get po
kubectl describe po

Pod 삭제
kubectl delete po <Pod명>
kubectl delete po --all

Pod 조회
kubectl get pod

run 명령을 사용한 pod 생성
pod name : lab2-pod
container image : nginx
container port : 80
kubectl run lab2-pod --image=nginx --port=80

생성한 pod 조회
kubectl get po
kubectl describe po

생성한 pod 삭제
kubectl delete pod lab2-pod
kubectl delete pod --all

 

Kubernetes Controller - ReplicaSet

- ReplicaSet은 Pod의 개수를 유지

- Pod 개수를 유지해주는 Controller의 종류

- yaml 정의할 때, replicas를 3으로 지정하면 3개의 pod로 유지시켜준다.

 

 

Kubernetes Controller - Deployment

- Deployement는 ReplicaSet을 관리하며, 애플리케이션의 배포를 더욱 세밀하게 관리

- 초기 배포 이후에도 버전 업데이트, 이전 버전으로 Rollback도 가능

 

Deployment Update

- Pod 업데이트 방식

1. Recreate 방식

- 가장 먼저 기존 Pod를 지워주고, 다음 버전 Pod를 실행하는 방식 (Downtime이 발생함) 

2. Rolling Update 방식

- 새로운 Pod를 먼저 만들고, 구버전 Pod를 지움

- 새로운 Pod가 추가로 올라갈만한 리소스 여유가 있어야 함

 

Deployement Rollback

- Deployment는 이전 버전의 ReplicaSet을 10개까지 기본 저장한다.

- revisionHistoryLimit을 통해 최근 몇개까지만 저장할 것인지 지정 가능하다.

 

Deployment - Kubectl

```

kubectl create -f deployment.yaml

```

 

그냥 단일 Pod만 만들면 죽으면 끝,

ReplicaSet을 통해 Pod를 만들면 죽어도 개수는 유지,

Deployment로 Pod를 생성하면 Pod 업데이트/롤백까지 가능하면서 자동으로 ReplicaSet이 하위에 만들어지기 때문에 보통 Deployment로 생성한다.

Replicaset - Replicaset 을 직접 생성/조회/삭제

# Replicaset 확인
kubectl get replicaset
kubectl get rs

# yaml 확인
cat rs1.yaml

# yaml 을 활용한 replicaset 생성
kubectl create -f rs1.yaml

# replicaset, pod 확인
kubectl get rs
kubectl get pod

# pod 1개 삭제
kubectl delete pod <pod명>

# pod 재배포 확인
kubectl get po

# replicaset 삭제
kubectl delete rs --all

# replicaset 삭제 확인
kubectl get rs
kubectl get pod

 

Deployment - deployment 을 생성, 조회, 업데이트, 롤백, 스케일링, 삭제

# Deployment 확인
kubectl get deployment
kubectl get deploy

# yaml 확인
cat dp1.yaml

# yaml 을 활용한 Deployment 생성
kubectl create -f dp1.yaml

# deployment, replicaset, pod 확인
kubectl get deploy
kubectl get rs
kubectl get pod

# pod 1개 삭제
kubectl delete pod <pod명>

# pod 재배포 확인
kubectl get po

# Deployment 삭제
kubectl delete deploy --all

# Deployment 삭제 확인
kubectl get deploy
kubectl get pod

# 터미널을 하나 더 오픈하여 모니터링용 터미널을 생성합니다.
watch -n 0.5 kubectl get pod

# create 명령으로 deployment 생성
-deployment 조건-
deployment name : dp2
container image : nginx:1.14.0
container port : 80
replicas : 3

kubectl create deploy dp2 --image=nginx:1.14.0 --port=80 --replicas=3

# 컨테이너 이미지 1.15.0으로 버전 업데이트
kubectl set image deployment/dp2 nginx=nginx:1.15.0 --record=true

# 이때 명령어 수행 직후 모니터링 터미널로 동작 확인
record=true 값으로 해야 히스토리 확인시 어떤 내용인지 확인 가능

# 업데이트 내역 확인
kubectl describe pod
kubectl describe deploy

# 업데이트 방식 변경
kubectl edit deploy dp2

strategy:
  rollingUpdate:
    maxSurge: 25%
    maxUnavailable: 25%
  type: RollingUpdate
를


Copy
strategy:
  type: Recreate
로 수정합니다.

vi 편집기 사용법과 동일합니다.

# 컨테이너 이미지 1.16.0 으로 버전 업데이트
kubectl set image deployment/dp2 nginx=nginx:1.16.0 --record=true

# 이때 명령어 수행 직후 모니터링 터미널로 동작 확인

# 업데이트 내역 확인
kubectl describe pod
kubectl describe deploy

# 롤 아웃 기록 확인
kubectl rollout history deploy/dp2

# 직전 버전으로 롤백
kubectl rollout undo deploy/dp2

# 버전 확인
kubectl describe deploy

# 리비전 지정하여 롤백
kubectl rollout undo deploy/dp2 --to-revision=1

# 버전 확인
kubectl describe deploy

# 스케일링
kubectl scale deploy/dp2 --replicas=5

# 결과 확인
kubectl get pod
kubectl describe deploy

# deployment 삭제
kubectl delete deploy --all

 

Chapter 4. 컨테이너 통신 - Service, Ingress

 

Kubernetes Object - Service

- Pod에 접근하기 위해 사용하는 Object

- Kubernetes 외부 또는 내부에서 Pod에 접근할 때 필요

- 고정된 주소를 이용하여 접근이 가능

- Pod에서 실행 중인 애플리케이션을 네트워크 서비스로 노출시키는 Object

Pod는 하나의 IP 주소를 가지는데, Recreate 또는 Rolling Update 되면서 새롭게 실행되면 Ip 주소가 바뀌어 버린다.

그렇기 때문에 Service 라는 Object를 통해 고정적인 Routing 정보로 Pod에 접근해야 문제가 없을 것이다.

- Pod 간 Traffic을 분산해주는 Load Balancer 기능도 해준다.

 

Service와 Pod와 연결하는 방식 

1. Yaml 안의 Label 항목

- Pod와 같은 Object에 첨부된 Key-value 쌍

2. Label Selector

- 특정 Label 값을 찾아 해당하는 Object만 관리할 수 있게 연결

3. TargetPort 설정

- Service 정의 시, 

 

Annotation

- yaml에 주석을 달아 줄 수 있다.

 

Service 유형

- ClusterIP 타입의 Service : ClusterIP가 Service의 고정 IP이고, Cluster의 IP가 내부 IP라 외부에서 접근은 불가능하다.

Cluster 단의 IP를 사용하겠다.

```

kubectl create service clusterip clip --tcp=5678:8080

kubectl expose deployment nginx --port=80 --target-port=8000 --type=ClusterIP

```

- NodePort 타입의 Service : type을 NodePort, nodePort 값을 지정해주면 사용자가 해당 포트값으로 접근 가능. 최소한 외부에서 접근 가능한 서비스를 만드려면 NodePort 타입을 사용한다.

Node 단까지 IP를 사용하겠다.

- LoadBalancer 타입의 Service : 공인 External IP를 발급 받아야 하므로, OnPremise & Vanila k8s는 쓸 수 없다.

AWS - EKS, Azure - AKS 와 같이 클라우드 기반의 Kubernetes를 적용하고 해당 Type을 사용하면 Cloud에서 공인해주는 외부 IP를 사용 가능하다.

ClusterIP < NodePort < LoadBalancer 순으로 상속받는다.

 

Kubernetes Object - Ingress

- 클러스터 내의 서비스에 대한 외부 접근을 관리하는 Object

- 일반적으로 HTTP를 관리

- 부하분산, SSL 인증서 처리, Service에 외부 URL 제공

- Service로의 트래픽 분산을 해줄 수 있음

- Ingress가 없이 Service를 LoadBalancer로 만들면, External IP가 여러개 생기므로 비용 비효율적

 

Ingress Controller

- Kubernetes에서 공식적으로 제공하는 Ingress Controller

- 대표적으로 nginx ingress controller를 사용한다.

- path별로 서비스를 매핑해줄 수 있다.

카나리 업그레이드

- Ingress 설정으로 가능하게 해준다. 

- Ingress 가중치 설정을 통해, version 1 pod service를 80%, version 2 pod service를 20% 로 가중치를 줄 수 있다. (미리 테스트)

Https 인증서 관리

- Ingress secret 항목으로 가능하게 해준다. 

- 인증서 관리 가능하게 해준다. (crt, pem 등록 가능하도록 해줌)

Chapter 5. Pod 데이터 관리 - Container 볼륨 설정 및 환경변수 설정

 

Volumne

- 일부 데이터를 저장하는 디렉토리

 

Volume 유형

- Emptydir : Pod가 생성될 때 함께 생성되고, 삭제될 때 함꼐 삭제되는 임시 Volume

데이터를 유지하는데 문제가 있는 방식

- hostPath : HostPath에 매핑되어, Pod의 종속성을 거두어낸 데이터 유지를 할 수 있는 Volume

데이터를 연결하는데 문제가 생길 수 있다.

- PV(Persistent Volume) & PVC(PersistentVolumeClaim) : Volume을 Cluster 내 Object 처럼 관리할 수 있음, PVC가 연결을 중계해줌. PV는 Local부터 AWS, Git Volume 다양하게 지정할 수 있음

AccessMode

- 각 모드 별로 제한을 두는 설정

  - ReadWriteOnce...

 

ConfigMap

- 컨테이너에서 필요한 환경설정을 컨테이너와 분리하여 제공하는 Object

- Pod와 환경변수 설정을 분리하는 방식

- ConfigMap은 환경설정 정보들을 저장해 놓는 저장소 역할

- 키/값 형태로 저장

- ConfigMap의 생성 방식

  - Literal : yaml 파일에 정의하거나 명령어 입력 통해 생성

  - File : Value에 들어갈 방법을 File에 저장

 

 

 

Secret

- ConfigMap과 유사하지만, 보안에 민감한 값들

- File로 값을 넣을 경우, Value에는 base64로 인코딩된 값을 넣어줘야 한다.

 

Pod env 적용 - ConfigMap & Secret

- envFrom 항목으로, Pod에 ConfigMap, Secret 전체를 주입할 수 있다.

- valueFrom 항목으로, 세부 항목만 주입할 수 있다.

 

Chapter 6. Container 관리

Kubectl top

- Default Namespace 내 Pod의 CPU, Memory 사용량을 파악할 수 있습니다.

 

Kubectl logs

 

로깅, 모니터링 도구

- Prometheus & Grafana[시각화 도구] (쿠버네티스의 모니터링 도구)

 

Kubernetes 대시보드

- 관리용 대시보드

- 로그 뷰어 제공

 

Trouble Shooting

- 명령어 오타 (자동완성 활용)

- yaml 들여쓰기 실수 (템플릿 활용)

 

 

 

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기