Kubernetes key Feature
- Automatic binpacking
각 컨테이너가 필요로 하는 CPU와 메모리(RAM)를 쿠버네티스에게 요청하면, 쿠버네티스는 컨테이너를 노드에 맞추어서 자동으로 스케줄링
(각각의 콩자루 안에 얼마나 가질지 설정하는 것) - Self-healing
k8s는 실패한 노드에 대해, 컨테이너를 자동으로 교체하고, 재스케줄링하며, 또한 Health check에 반응하지 않는 컨테이너를 정해진 규칙에 따라 다시 시작 - Horizontal scaling
k8s는 CPU 및 메모리와 같은 리소스 사용량을 기반으로 애플리케이션을 자동으로 확장할 수 있으며, 메트릭을 기반으로 하는 동적 스케일링도 지원
(다른 워커노드에 해당 컨테이너를 복제해서 scale out (확장) 하는 것)
(예) resoure가 80%이면 2배 확장해 혹은 resource가 20%면 축소해라) - Service discovery and load balancing
자동으로 DNS 등록이 됨 - Automated rollouts and rollbacks
- Application, Configuration의 변경이 있을 경우 전체 인스턴스의 중단이 아닌 점진적으로 Container에 적용(rolling update) 가능
(roll out, roll update: 무중단 상태로 배포)
- Release reversion이 관리되고 새로운 버전의 배포시점에 문제가 발생할 경우, 자동으로 이전의 상태로 Rollback 진행 - Secret and configuration management
- Storage Orchestration
Local storage를 비롯해서
Persistant Volume 형태로 각자 원하는 Storage 설치 (k8s는 Storage가 없음)
Kubernetes Architeccture
- 하나 이상의 Master nodes
- 하나 이상의 Worker nodes
- etcd와 같은 distributed key-value store
Master는 하나만 있으면 되지만, 그 하나가 죽으면 안됨 (아무도 접속을 못함)
Master node는 H/A Cluster를 가져가고 m1, m2, m3 3개를 올려서 이중에 leader node가 선출돼서 하나의 노드만 동작
etcd(database)는 active 상태로 cluster 안에 있어야 함
-> 우리는 EKS Cluster 생성할 때 이미 설정한 부분
User가 접속하면 -- CLI/API/Dashboard --> Master node [api-server] -> Worker node
모든 k8s는 api-server를 접속을 통해 동작함
api-server한테 pods 생성 요청이 들어오면 Scheduler에게 전달해서
scheduler가 현재 worker node 들의 상태를 파악을 하고 가능한 worker node 정보를 다시 api-server에게 전달
선택된 worker node에게 pods 생성 요청 전달되면 worker node의 Kubelet에게 요청
pods에 대한 정보는 etcd (DB)에 저장된 key-value 값을 가져와서 조회함
etcd snap shot으로 back up 가능
Controller는 Pods를 모니터링하고 있음 desired state 상태가 되도록 모니터닝 진행
Worker node는 추가, 제거하는 것이 어렵지 않음
worker node는 cluster run time pod가 실행되고 있음
Kubelet은 master node의 api-server와 통신하므로 무조건 있어야 함
Kubelet이 CRI - init container에게 pods 생성을 요청해서 pods를 생성함
worker node안에 있는 pod로 가는 트래픽을 Proxy를 통해 전달 받음
Pod Creation Process
k8s는 컨테이너를 생성하는게 아니기 때문에, 컨테이너의 파드들을 바라보고 확인함
Kubernetes Core Concept: "Desired State"
- Imperative(명령적): action을 정의한다.
- Declarative(선언적): 원하는 상태(Desired State)를 정의한다.
Kubernetes Object, Controller and Kubectl
- Object: k8s의 상태를 나타내는 엔터티로 k8s API의 Endpoint
- 유형: Pod, Service, - Controller
yaml파일 4가지는 기본 요소
- apiVersion
- kind
- metadata
- spec
kubernetes.io/docs/reference/kubernetes-api/
Namespaces
- kubernetes는 동일 물리 클러스터를 기반으로 하는 복수의 가상 클러스터를 지원하는데 이런 가상 클러스터를 Namespace라고 한다.
- Namespace를 활용하면, 팀이나 프로젝트 단위로 클러스터 파티션을 나눌 수 있다.
- Namespace 내에 생성된 자원 객체는 고유하나, Namespace 사이에는 중복이 발생할 수 있다.
kube-pulic: 모든 접근이 가능한 namespace
기본 default namespace에서 hobi namespace로 변경
> kubectl config set-context --current --name=hobi
Pod: Kubernetes 최소 배포 단위
한개의 pod 안에는 contrainer를 하나 혹은 두개 이상 올릴 수 있으며 strictly 연결되어짐
init-container 는 CKA 시험에 나오는 예시
kubernetes.io/docs/concepts/workloads/pods/init-containers/
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
container 여러 개 선언됨
initContainers 를 통해서 container 정보 기입
- 한 Pod는 내부에 여러 컨테이너를 가질 수 있지만 대부분 1~2개의 컨테이너 가짐
- scailing이 컨테이너가 아닌 Pod 단위로 수행되기 때문에, Pod 내부에 다수의 컨테이너들이 타이트하게 묶여 있으면 스케일링이 쉽지 않거나 비효율적으로 이뤄지는 문제 - 1개의 Pod는 1개의 노드 위에서 실행
- Deployment에 의해서 배포된 Pod는 ReplicaSet Controller에 의해 복제 생성됨
- 이때 복수의 Pod는 Master의 Scheduler에 의해 여러 개의 Node에 걸쳐 실행 - Pod의 외부에서는 Service를 통해 Pod에 접근
- Service를 Pod에 연결했을 때 Pod의 특정 포트가 외부 expose
1) cluster ip형태: service end-point / LB와 동작하는 것과 비슷하지만 (service로 들어온 트래픽을 end-point로 전달되는 점)
2) Node Port
3) Load Balancer: 우리 네트워크 안에 LB가 꼭 있어야 함 - public cloud 한해서만 가능함
LB가 준 external ip를 줘서 이 ip를 통해 service 접속
deployment 생성하면
> kubectl create deployment hobi --image=nginx:1.16 --port=80
> kubectl get replicasets.apps
우리가 올린 pod를 모니터링하는 replicaSet Controller 가 생성
내 deployment replicas 2개로 변경
> k scale deployment hobi --replicas=2
- Type: ClusterIP
> k expose deployment hobi --type=ClusterIP
root@ip-10-0-1-47:~# k get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hobi ClusterIP 10.100.19.33 <none> 80/TCP 7s
- Type: NodePort
root@ip-10-0-1-47:~# k expose deployment hobi --type=NodePort
service/hobi exposed
root@ip-10-0-1-47:~# k get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hobi NodePort 10.100.98.190 <none> 80:32488/TCP 7s
worker node의 ip를 알아야지 사용 가능
- Type: LoadBalancer
> k expose deployment hobi --type=LoadBalancer
root@ip-10-0-1-47:~# root@ip-10-0-1-47:~# root@ip-10-0-1-47:~# k expose deployment hobi --type=LoadBalancer
root@ip-10-0-1-47:~#: command not found
root@ip-10-0-1-47:~# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
-bash: syntax error near unexpected token `('
root@ip-10-0-1-47:~# hobi LoadBalancer 10.100.67.176 a4c508ec0c3ea486793d611cc513186c-1829744781.ap-northeast-2.elb.amazonaws.com 80:32391/TCP 3s
hobi: command not found
root@ip-10-0-1-47:~#
root@ip-10-0-1-47:~#
root@ip-10-0-1-47:~#
root@ip-10-0-1-47:~# k run -i --tty --image busybox:1.28 dns-test --restart=Never --rm
If you don't see a command prompt, try pressing enter.
/ # nslookup 10.100.67.176
Server: 10.100.0.10
Address 1: 10.100.0.10 kube-dns.kube-system.svc.cluster.local
Name: 10.100.67.176
Address 1: 10.100.67.176 hobi.hobi.svc.cluster.local
a4c508ec0c3ea486793d611cc513186c-1829744781.ap-northeast-2.elb.amazonaws.com/
Kubernetes Object Model
무중단 배포
v1 가 이미 서비스 운영중이면
v2 도 서비스 배포를 진행하고, 배포 완료가 되면 v1 pod 삭제하면 무중단 배포 가능!
Zero-down time deployment
rolling update, rollback
(user 접속하는 ip 주소) service 와 pod에 대한 couple 연결을 제거 해야지 가능함
Kubernetes Object Model
- apiVersion
- kind
- metadata
- spec
- sepc.template.spec
Service - Deployment (end-point)- Pod
이들간의 연결은 label이 해준다!
root@ip-10-0-1-47:~# k get deployments.apps,pods,svc,ep --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/hobi 2/2 2 2 154m app=hobi
NAME READY STATUS RESTARTS AGE LABELS
pod/hobi-fd6b7c7fb-nzxxt 1/1 Running 0 60m app=hobi,pod-template-hash=fd6b7c7fb
pod/hobi-fd6b7c7fb-t5h8h 1/1 Running 0 60m app=hobi,pod-template-hash=fd6b7c7fb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
service/hobi LoadBalancer 10.100.67.176 a4c508ec0c3ea486793d611cc513186c-1829744781.ap-northeast-2.elb.amazonaws.com 80:32391/TCP 55m app=hobi
NAME ENDPOINTS AGE LABELS
endpoints/hobi 192.168.104.15:80,192.168.164.25:80 55m app=hobi
label을 바꾸면 새로운 pod가 만들어지고 새롭게 만들어진 pod
label은 selecting feature이고 연결해줌
기본적인 kubectl 명령어
자세한 사항은 kubernetes.io document 확인
root@ip-10-0-1-47:~# k create ns testns --dry-run --output yaml > newns.yaml
W0114 06:12:38.762256 17799 helpers.go:553] --dry-run is deprecated and can be replaced with --dry-run=client.
root@ip-10-0-1-47:~# cat newns.yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: null
name: testns
spec: {}
status: {}
--dry-run 실행하진 않고 지금 실행하는 파일만 만들기
declare하게 명령어 실행하기 위해서 진행
Labels
Annotations
- Label 처럼 식별 정보는 아닌 임의의 비 식별 메타 데이터를 객체에 key-value 형태로 추가
- 주로, 히스토리, 스케줄 정책, 부가 정보 등을 기술
- 배포 주석을 추가해 서비스를 Deploy하고, 이전 서비스로 롤백 시, 해당 정보를 활용해 롤백
k8s ingress controller 제공하는 nginx 에서 주는거 받아서 ingress 설정함
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
annotataions: kubernetes.io/change-cause=nginx:1.7.9
spec:
replicas: 3
selector: ………………………..
Deployments
- Deployment 객체는 Pods와 ReplicaSets에 대한 선언적 업데이터를 제공함
- Deployment Controller는 Master node 컨트롤 관리자의 일부로 Desired state가 항상 만족되는지를 확인한다.
- Deployment가 ReplicatSet을 만들고 ReplicaSet은 그 뒤에 주어진 조건만큼의 Pod들을 생성한다.
deploy - replicaset - pod
서로 label로 연결되어져 있음
Rolling update
Rollback
- 현재 실행중인 객체들을 확인
- 객체를 롤백 처리
revision을 명시하지 않으면 바로 이전 버전으로 rollback - 진행을 확인
service
항상 access point를 동일하게 하기 위해서 service가 있고 user가 접근했을 시app key의 value인 end-point로 이동되는 것!
service는 container가 아니고 config로서만 존재하는 것 (key:value)
kube-proxy
어느 worker node 위에 있는 pod인지 알아야지 됨
내 각각의 worker node에 있는 traffic을 pod로 연결해줌
pod 생성, 배포하는 방법
1. pod
: 어느 worker node에 pod를 띄우는 것
2. deployment
: replicaSet -> replicaSet=1 있어야 하고 어디서든 돌면 됨
pod hostname, ip, 예전에 내가 만들었던 pod의 정보, 상태를 기억하지 못함
3 deamontset kind
: node마다 하나씩 뜨게 됨 / node가 추가되면 deamonset이 알아서 pod 추가해줌
4. statefulset kind
: replicaSet 예전 pod 정보 기억해서 삭제됐을 시 똑같은 정보로 다시 만들어줌
ServiceType
Service 생성 시, IP주소 할당 방식과 서비스 연계 등에 따라 구분
- ClusterIP
: 외부에서 접속하기 위해서 worker node의 ip - NodePort
- LoadBalancer
: public에서만 제공이 됨
실습
'Study > kubernetes' 카테고리의 다른 글
kubernetes 강의 #4 (0) | 2021.01.15 |
---|---|
kubernetes 강의 #2 (0) | 2021.01.13 |
kubernetes 강의 #1 (1) | 2021.01.13 |