섹션 0. 기초 다지기
-
최대한 서버 자원을 효율적으로 사용하기 위해 가상화 기술에 대해 관심이 많아짐
-
히스토리
-
1991. - 리눅스 자원 격리 기술(chroot, namespace, cgroup)
-
VM. 가상과 기술(VMWARE, KVM, …)
-
2010. 7 - 가상화 기술(openstack, rackspace, nasa)
-
2014. 6 - 컨테이너 가상화 기술(datCloud → docker 이름변경 후 오픈소스화)
-
오케스트레이터 도구가 만들어짐
-
2015. 7 - google kubernetes
-
다양한 회사에서 참여하면서 커짐
-
-
다양한 기업에서 kube를 활용하여 클라우드 서비스 제공
-
-
Kubernetes
-
User - Workloads, Service, Storage/Config, Metadata, Cluster
-
Admin: Installation, Architecture, Network, Monitoring, Plugins, Ecosystem
-
1. Why Kubernetes?
-
자원을 효율적으로 사용 - auto scaling
-
Failover - Auto Healing
-
Deployment - rolling update, recreate
VM vs Container
VM
-
layer
-
Host Server
-
Host OS
-
Hypervisor: VM을 가상화하기 위한 하이퍼바이저
-
Guest OS: 하나의 OS를 독립적올 사용
-
Container
-
layer
-
Host Server
-
Host OS
-
docker: 컨테이너 가상화하는 도구
-
cgroup: 자원 격리
-
namespace: 커널 관리
-
-
Overview
-
쿠베는 서버 한대는 마스터, 나머지는 노드라고해서 한 마스터에 여러 노드가 연결
-
이렇게 연결이 되면 하나의 클러스터라는 개념에 묶임
-
마스터는 컨트롤 하는 역할
-
노드는 자원
-
클러스터내에 네임스페이스라고 쿠베 오브젝트들을 독립된 공간으로 분리해줌
-
네임스페이스 안에 파드가 있고,
-
외부 연결해주는 서비스가 있고,
-
서로 다른 네임스페이스는 파드 끼리 연결 안됨
-
파드가 죽으면 데이터가 날라감
-
날라가는 문제를 해결하기 위해 볼륨을 만듬
-
네임스페이스에 ResourceQuota, LimitRange 설정을 통해 자원을 한정 시킬 수 있음
-
컨테이너안에 환경변수나 파일을 넣어줄 수 있는데 ConfigMap, Secret으로 함
-
컨트롤러가 파드들을 관리.
-
-
컨트롤러
-
Replication Controller
,ReplicaSet
-
Pod 죽으면 살리거나 스케일 인/아웃
-
-
Deployment
는 배포 후에 Pod들을 새 버전으로 업그레이드/롤백 -
DaemonSet
은 한 노드에 Pod가 하나씩 유지해주는 것 -
Job
은 특정 작업만 종료시켜야 할 때-
그런 Job들을 주기적으로 실행해야할 때
CronJob
-
-
섹션 2. 기본 오브젝트
Pod
Container
-
파드안에는 하나의 독립적인 서비스를 구동할 수 있는 컨테이너들이 있음
-
컨테이너들은 서비스가 연결될 수 있도록 포트를 가지고 있음.
-
한 컨테이너가 포트를 여러개 가질 수 있음
-
파드내에서 컨테이너들끼리 포트 중복 불가
-
한 호스트로 묶여있다고 봐야함
-
로컬호스트 8080으로 접근 가능
-
파드가 생성될 때 IP가 생성되는데 클러스내에서만 접근 가능(휘발성 IP)
Label
-
라벨은 파드뿐만 아니라 모든 오브젝트에 달 수 있음
-
목적에 따라 오브젝트 들을 분리하고 골라서 연결하기 위함
-
키/값이 한쌍으로 한 파드에 여러 라벨 설정 가능
Node Schedule
-
파드는 여러 노드중 한 노드에 올라가져야 함
-
직접 선택하려면 노드에 라벨을 달고 nodeSelector 설정
-
쿠베가 설정하려면 리소스를 설정
-
memory 설정을 초과시 파드 종료
-
cpu는 초과시 리소스를 낮추고 종료시키진 않음
-
Service
-
파드에는 클러스터내에 접근할 수 있는 아이피가 있음
-
하지만 파드는 재생성이 계속되므로 신뢰성이 떨어짐
-
그래서 파드와 서비스를 연결해두고 서비스 아이피를 활용
-
여러개 파드에 연결해주고 서비스가 분산해줌
-
ClientIp
-
클러스터내에서만 접근 가능한 IP
-
-
NodePort
-
내부망연결
-
-
LoadBalancer
-
외부시스템 노출할 때 사용
-
Volume
-
emptyDir
-
컨테이너들끼리 데이터를 공유하기 위해 볼륨 사용
-
최초 볼륨 사용시 비어있음
-
e.g. 두 웹서버가 파일을 주고받을 필요 없이 사용. 파드내에 생성되니 없어지면 제거. 즉 일시적인 사용으로..
-
-
hostPath
-
한 호스트, 즉 파드들이 올라가있는 노드들 사이에 사용
-
노드에 있는 데이터를 파드에서 쓰기위한 용도
-
파드가 노드가 바뀌어져 올라갔을 때 사용할 수 없음
-
직접 연결해주면 가능
-
-
PVC/PV
-
파드에 영속성있는 볼륨을 제공하기 위함
-
외부 볼륨도 사용 가능
-
파드는 PV에 바로 연결하기 않고 PVC로 연결함
-
PVC는 유저측, PV는 어드민측
-
어드민이 PV를 만들어두면 유저가 사용
-
ConfigMap, Secret
-
환경에 따라 변하는 값을 외부에서 관리하도록 도와주는 것
-
키와 벨류로 이뤄짐
-
ConfigMap
-
Secret
-
보안적인 관리가 필요한 값
-
value를 넣을 때 base64 인코딩해서 넣어야 함
-
pod에 주입될 때는 decoding 됨
-
ConfigMap은 디비에 저장되는데 Secret은 메모리에 저장됨
-
1 MB만 넣을 수 있음
-
메모리에 저장하니 많아지면 시스템 자원에 영향을 미침
-
-
상수나 파일을 넣을 수 있음
-
파일은 환경변수가 아닌 볼륨을 마운트해서 사용할 수 있음
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-dev
data:
SSH: False
User: dev
---
apiVersion: v1
kind: Secret
metadata:
name: sec-dev
data:
Key: MTs12==
---
apiVersion: v1
kind: Pod
metadata:
name: pod-1
spec:
containers:
- name: container
image: nginx
envFrom:
- configMapRef:
name: cm-dev
- secretRef:
name: sec-dev
-
파일을 통으로 ConfigMap에 넣을 수 있음
-
파일의 이름이 키가 됨
-
파일 ConfigMap
-
환경변수 방식은 한번 주입하면 끝
-
볼륨 마운트 방식은 원본이 변경되면 실제 파드에 마운트된 내용도 변하게 됨
-
Namespace, ResourceQuota, LimitRange
-
Namespace
-
쿠버네티스 클러스터 안에 여러 네임스페이스를 만들 수 있음
-
네임스페이스 안에 여러 파드는 만들 수 있음
-
한 네임스페이스 안에서 같은 파드의 오브젝트는 중복해서 만들수 없음
-
타 네임스페이스의 자원과 분리됨
-
노드나 PV와 같이 모든 네임스페이스에서 공용으로 사용되는 오브젝트도 있음
-
파드마다 IP가 있음. 분리되어 있지만 기본적으로 연결이 됨 → NetworkPolicy 오브젝트를 통해 가능
-
-
ResourceQuota: 네임스페이스의 리소스 한계 설정
-
LimitRange: 각각의 파드마나 네임스페이스에 들어올 수 있는지 설정
섹션 3. 컨트롤러
-
Auto Healing
-
파드에 장애가 오면 파드를 다른 노드에 생성해줌
-
-
Auto Scaling
-
파드는 분산해줌
-
-
Software Update
-
여러 파드를 한번에 업그레이드하거나 롤백해줌
-
-
Job
-
일시적인 파드의 경우 순간에만 만들고 제거
-
Replication Controller, ReplicaSet
-
Replication Controller: deprecated
-
ReplicaSet
-
selector
-
matchLabels: 키와 벨류가 같아야 연결
-
matchExpressions: 좀 더 디테일하게 설정
-
-
Deployment
-
현재 한 서비스가 운영중인데 업데이트해서 배포할 때 유용한 컴포넌트
-
Recreate
-
동작 방식
-
pod1 제거하고(이전 replicaSet의 replicas가 0이 됨)
-
pod2 생성해서 연결
-
-
다운타임이 발생하므로 일시정지 가능한 서비스에 사용
-
-
RollingUpdate
-
동작 방식
-
v2의 파드를 하나 만듬 - 자원 자용량 증가
-
v1과 v2에 모두 서비스중
-
v1의 파드 하나 삭제
-
-
배포 중간에 추가적인 자원을 요구하지만, 다운타임이 없음
-
다른 버전이 잠시 공존하게 됨
-
-
Blue/Green
-
서비스의 라벨을 스위칭해서 롤백 용이함
-
자원이 두배가 필요하다는 것
-
-
Canary
-
카나리는 심박수가 높고 유해한 공기를 확인하는데 사용하던 새
-
일산화 탄소를 감지하는데 사용했음
-
카나리같은 실험체를 사용하는 것
-
동작 방식
-
요청 흘리기 - 불특정 다수에 테스트할 때 사용함
-
모든 파드에 동일한 라벨이 있고, 하나의 서비스에 해당 라벨을 설정함
-
v2 파드 하나 생성하고 v2 파드에 흘려보냄(일부 요청을 v2로 테스트)
-
문제 발생하면 v2 의 컨트롤러의 replicas를 0으로 변경
-
-
Ingress Controller
-
v1, v2 각각의 서비스를 만듬
-
인그레스 컨트롤러를 만듬 - 유입되는 트래픽을 url path를 다르게 설정(/app, /v2/app)
-
-
-
DaemonSet, Job, CronJob
-
DaemonSet
-
레플리카셋은 노드의 자원에 맞게 스케줄링 되는 반면, 데몬셋은 모든 노드에 파드가 하나씩 생성된다.
-
성능 수집에 사용
-
로그 수집
-
노드들은 스토리지
-
nodeSelector를 통해 특정 노드에만 가능
-
-
Job, CronJob
-
파드가 삭제되는 것은 아니고 자원을 사용하지 않게 됨 - 로그 수집을 위해
-
activeDeadlineSeconds 옵션으로 실행시간을 지정할 수 있음
-
섹션 4. Pod
▼ Pod
┌──────────────────────────────────────────────────────────────────────────┐
│ Status: |
| ┌────────┬───────────────────────────────────────────────────────────┐ |
| | Phase | Pending, Running, Succeeded, Failed, Unknown | |
| └────────┴───────────────────────────────────────────────────────────┘ |
| Conditions: |
| ┌────────┬───────────────────────────────────────────────────────────┐ |
| | Type | Initialized, ContainerReady, PodScheduled, Ready | |
| ├────────┼───────────────────────────────────────────────────────────┤ |
| | Reason | ContainersNotReady, PodCompleted | |
| └────────┴───────────────────────────────────────────────────────────┘ |
├──────────────────────────────────────────────────────────────────────────┤
| ▼ Containers |
| ┌────────────────────────────────────────────────────────────────────┐ |
| | ContainerStatuses: |─┐ |
| | ┌────────┬───────────────────────────────────────────────────────┐ | | |
| | | State | Waiting, Running, Terminated | | | |
| | ├────────┼───────────────────────────────────────────────────────┤ | | |
| | | Reason | ContainerCreating, CrashLoopBackOff, Error, Completed | | | |
| | └────────┴───────────────────────────────────────────────────────┘ | | |
| └────────────────────────────────────────────────────────────────────┘ | |
| └─────────────────────────────────────────────────────────────────────┘ |
└──────────────────────────────────────────────────────────────────────────┘
-
Lifecycle
-
Pending: Pod의 최초 상태
-
initContainer
작업이 완료되면 Initialized 값이 true -
지정한 노드 혹은 쿠버네티스가 판단해서 노드 설정이 끝나면 PodScheduled 값이 true
-
컨테이너에 이미지를 다운로드
-
다운로드 중 컨테이너의 상태는 Waiting, 사유(reson)은 ContainerCreating
-
-
-
Running
-
정상적으로 컨테이너가 다 뜰 경우 Pod와 Container들의 상태는 Running
-
잘못된 경우 Container 상태는 Waiting, 사유는 CrashLoopBackOff
-
Running이여도 컨테이너의 상태가 실패일 수 있다는 것을 확인해야 한다.
-
-
-
Succeeded
-
Failed
-
-
ReadinessProbe
-
앱이 구동되는 순간에 요청 실패를 막아주는 방법
-
톰캣은 돌고 있지만 메모리 오버플로우나 문제가 생겼을 때
-
Pod 처음 기동시 정상 실행될 때까지 대기해야하는 경우 사용
-
실패시: 컨테이너를 대체하지 않고 기다림
-
e.g., l4 h/c
-
-
LivenessProbe
-
App에 대한 장애 상황을 파악하여 막아줌
-
실패시: Pod를 restart 함
-
e.g., l7 h/c(실패시 재시작)
-
-
QoS classes
-
다운되는 순서: BestEffort > Burstable > Guaranteed
-
컨테이너의 리소스 설정으로 결정됨
-
Guaranteed(보장, 개런티-드)
-
모든 컨테이너에 requests, limit 설정
-
request, limit의 memory, cpu 모두 설정
-
각 컨테이너의 request와 limit의 memory, cpu 값이 같음
-
-
Burstable(부스터블)
-
BestEffort: 어떤 컨테이너에도 request, limit 미설정
-
-
Node Scheduling
-
파드가 기본적으로 스케줄러에 할당되지만 다른 가능도 지원
-
Pod를 특정 노드에 할당되도록 선택 - NodeName, NodeSelector, NodeAffinity
-
NodeAffinity: 라벨 키값으로 구분 가능
-
required, preferred(선호) 옵션이 있음
-
-
-
Pod Affinity, Anti-Affinity
-
노드의 라벨이 아니라 파드의 라벨로 할당
-
특정 노드에 설정한 라벨의 파드가 있는지 없는지를 확인하여 스케줄링 함
-
노드별로 failover할 때 같은 노드에 설정되게끔 하면 안되므로 이 설정 사용
-
-
Toleration / Taint
-
Node 할당 제한
-
노드에 Taint 설정을 함
-
Toleration을 달고 와야지만 할당됨
-
-
섹션 5. 기본 오브젝트
Service
@startuml
ditaa
[Kubernetes Cluster] : [Internal Network] :
| |
[Pod Network] : Service Network | |
20.96.0.0/12 | 10.96.0.0/12 | |
| | |
+-------------+ | +-------------+ | +----------------+ |
| pod1 | | | service1 | | | Master | |
+-------------+ +-------------+ | (192.168.0.30) | |
| 20.109.5.11 +<-+->+ 10.111.4.10 +--+ +----------------+ |
+-------------+ | +-------------+ +--+ 3000(NodePort) | |
| +----------------+ |
+-------------+ | |
| pod2 | | : +----------------+ |
+-------------+ | | | Node1 | |
| 20.109.5.12 +<-+ | | (192.168.0.31) | |
+-------------+ | +----------------+ |
: | |
| | +----------------+ |
| | | Node2 | |
| | | (192.168.0.32) | |
| +----------------+ |
| |
@enduml
-
FQDN = Fully Qualified Domain Name
-
전체 도메인을 표기한 방식이며 kubernetes에서 Service 명에 사용된다. (외부에서 접근시)
-
규칙에 의해 만들어진 도메인
-
-
Service를 headless로 만들면 DNS를 통해 여러 Pod에 접근이 가능
-
Headless
-
Endpoint
-
라벨을 통해 연결하지만 이건 사용자 측면
-
실제로는 엔드포인트를 만들어 연결됨
-
-
ExternalName
-
Endpoint는 IP로 구분되지만 ExternalName은 DNS로 설정
-
Volume
-
On-Premise Solution: ceph(세프)
-
Dynamic Provisioning
-
자동으로 PV를 만들어주고…
-
StorageClass 오브젝트
-
StorageClassName에 이름 넣으면 자동으로 PV가 만들어짐
-
-
Status & ReclaimPolicy
-
최초 만들떄 Available
-
PVC와 연결이되면 Bound
-
아직 볼륨에 실제 만들어지지 않음
-
Pod가 PVC를 사용해서 구동될때 만들어짐
-
Pod가 삭제되더라도 데이터 유지
-
-
PVC를 삭제하면 연결이 끊어지면서 PV 상태는 Released
-
Accessing API
-
쿠베에 API로 접근하기
-
master 노드에 kube API server가 있음
-
kubectl이 이 API 서버에 접근해서 사용
-
User Account, Service Account
-
Authentication
-
CA key(발급기관 개인키) → CA csr(인증요청서) → CA crt(인증서)
-
Client key(클라이언트 개인키) → Client csr(인증요청서)
-
CA key + CA crt + Client csr → Client crt
-
-
Authorization
-
RBAC
-
클러스터내의 권한: ClusterRole, ClusterRoleBinding
-
네임스페이스내의 권한: Role, RoleBinding
-
-
섹션 6. 컨트롤러
StatefulSet
-
stateless, stateful
-
pod마다 각자의 역할을 저장하는 PVC가 붙음
Ingress
-
목적
-
Service LoadBalancing
-
url path별로 특정 서비스로 연결해줌
-
-
Canary Upgrade
-
90%, 10% 트래픽으로 서비스로 연결해줌
-
어노테이션으로 분리 가능(e.g. 지역, 국가)
-
-
HPA
-
autoscaler
-
HPA(Horizontal Pod Autoscaler): 파드의 갯수를 늘리는
-
VPA(Vertical Pod Autoscaler) : 파드의 리소스를 조정하는
-
CA(Cluster Autoscaler): 클러스터에 노드를 추가하는
-
-
HPA
-
장애시 사용(replicas 값 변경)
-
stateless 권장
-
기동이 빠르게 되는 APP
-
scale out: pod가 늘어난 것
-
scale in: pod가 줄어드는 것
-
-
VPA
-
stateful app
-
scale up: 리소스 증가
-
scale down: 리소스 감소
-
섹션 7. 쿠버네티스 설치
섹션 8. CKA 개요 및 시험 공부
섹션 9. 아키텍처편
Component
-
Master 노드
-
Etcd, kube-scheduler, kube-apiserver
-
Etcd: kube에서 여러 데이터들을 저장하는 데이터베이스 역할
-
-
Worker 노드
-
kubelet,
-
Network
-
IPVS: l4 LB
-
CIDR(사이더)
Storage
Logging
-
Core Pipeline
-
Service Pipeline
Note
kubectl create vs apply
Tip
|
Declarative? Imperative?
자주 언급되는 단어들 중, 선언적Declarative 및 명령적Imperative 동작이라는 것이 있다. Kubernetes는 선언적 및 명령적 동작을 모두 지원하지만, 가능하면 선언적인 동작을 사용하는 것이 권장되고 있다. 선언적 동작은 Desired-state 를 미리 정의한 뒤 Current-state가 Desired-state가 되도록 하는 것을 의미하며, Kubernetes의 Controller는 대표적인 선언적 동작의 예시라고 볼 수 있다.
|
-
create - 명령적 관리,
-
apply - 선언적 관리,
┌─────────┬───────────────────────┬────────────────────────┐
│ command │ object does not exist │ object already exists │
├─────────┼───────────────────────┼────────────────────────┤
│ create │ create new object │ ERROR │
│ │ │ │
│ apply │ create new object │ configure object │
│ │ (needs complete spec) │ (accepts partial spec) │
│ │ │ │
│ replace │ ERROR │ delete object │
│ │ │ create new object │
└─────────┴───────────────────────┴────────────────────────┘