본문 바로가기

Study/kubernetes

kubernetes 강의 #3

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/

 

API Reference

Production-Grade Container Orchestration

kubernetes.io

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/

 

Init Containers

This page provides an overview of init containers: specialized containers that run before app containers in a Pod. Init containers can contain utilities or setup scripts not present in an app image. You can specify init containers in the Pod specification

kubernetes.io

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/

 

Welcome to nginx!

Welcome to nginx! If you see this page, the nginx web server is successfully installed and working. Further configuration is required. For online documentation and support please refer to nginx.org. Commercial support is available at nginx.com. Thank you f

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