본문 바로가기
Developing../MLOps:k8s

[3] 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커

by bents 2022. 6. 13.

# 쿠버네티스에 대하여...

[목차]
1. 사용이유
2. 사용방법 3가지
3. 구성요소
4. 오브젝트 : 특정 기능을 수행하는 구성요소
- 작업자 중심(4)
- 네트워트 중심(5)
- 기타 (6)

1. 사용이유

이전 블로그 링크

[1]컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커

1.컨테이너 인프란 환경  1-1. 컨테이너 인프라 환경 : 리눅스 운영 체제의 커널 하나에서 여러 컨테이너가 격리되어 (서로 영향주지 않으며) 실행되는 환경  1-2. 컨테이너 : 하나 이상의 목적을

bents.tistory.com

2. 사용방법

2-1. 관리형 : 아마존, 구글, 마소
2-2. 설치형
2-3. 구성형 : *kubeadam*, kubespary, kops, KRIB,

3. 구성요소

3-1. 파드배포로 구성요소보기
- 마스터 플레인
0) kubectl : 클러스터에 binary로 바로 명령을 내림. 주로 api server와 통신함.
1) api server : 클러스터 통신의 중추 통로. 주로 etcd와 통신하지만, 다른 요소들도 api server를 통해 통신함.
2) *etcd : 구성 요소들의 상태값을 저장하는 곳. etc+distubuted의 약어로 복제 및 분산저장은 필수.
3) *controller manager : 클러스터의 오브젝트 상태를 관리함
- Node controller : worker node 통신 상태 체크, 상태 복구
- ReplicaSet controller : pod 개수 유지
- Endpoint controller : Service와 Pod 연결
4) *scheduler : Pod를 조건에 맞는 Worker node에 지정하고, 할당 일정을 관리함.
+ Network Plugin : 클러스터 내 컨테이너 네트워크 통신을 지원함.
+ CoreDNS : 클러스터에서 IP대신 도메인 이름으로 통신하기 위해 쓰는 DNS 서버

- 워커노드
5) kubelet : API SERVER에서 받은 "Pods의 구성내용(PodSpec)"을 CRI로 전달함. 파드 내 컨테이너 작동상태 모니터링
6) 컨테이너 런타임(CRI;Container Runtime Interface) : 파드 내 컨테이너 실행
7) Pod : 하나의 목적의 일을 맡는 단위로 1개 이상의 컨테이너를 가짐.

3-2. 파드 생명주기 흐름 보기
1) kubectl을 통해 api server 에 pod생성 요청하기
2) api sever : 새로 전달된 상태값 있는지 점검; if yes then write it to etcd
3) controller manager : api sever에 새로 전달된 요청 있는지 점검; if yes then create pods and return status
4) scheduler : api server에 새로 전달된 요청값이 완료상태인지 점검; if yes then scan , ask a worker node to take pods and confirm the result thru kubelet
5) kubelet : container runtime에게 pod 생성 요청함. return status
*api-server가 각 과정의 결과를 감시(수신)하고 있지만, 감시대상들도 계속 요청상태를 수신중이다.

3-3. 구성요소 실습
1) 모든 namespace의 pods 목록보기
> kubectl get pods --all-namesapces
2) pods 이름으로 모든 namespace의 pods 목록 검색하기
> kubectl get pods --all-namesapces | grep kube-proxy
3) kubectl : 접속정보를 바탕으로 명령을 내리는 프로토콜.
> kubectl get nodes
-- master node에 있는 api server 접속정보가 필요함.
> scp root@192.000.0.00:/etc/kubernetes/admin.conf ./
> kubectl get nodes --kuberconfig admin.conf
4) kubelet : worker node에서 발생하는 job을 통신하는 역할(없으면 아무것도 안됨)
-- master node에서 pod 배포하기(f : filenmae)
> kubectl create -f ~/nginx-pod.yaml
> kubectl get pods -o wide
-- workder node에서 kubelet 중단하기
> systemctl stop kubelet
-- master node에서 pod 삭제하기
> kubectl get pod
> kubectl delete pod nginx-pod
> kubectl get pod
-- workder node에서 kubelet 실행하기
> systemctl start kubelet
5) kube-proxy
-- master node
> kubectl create -f ~/nginx-pod.yaml
> kubectl get pod -o wide
> curl 172.16.103.130
-- worker (r:remove - br_netfilter module)
> modprobe -r br_netfilter
> systemstl restart network
-- master (Connection time out error)
> curl 172.16.103.130
> kubectl get pod -o wide
-- worker (**reboot >>> restart network )
> modprobe br_netfilter
> reboot
-- master
> kubectl get pod -o wide
> curl 172.16.103.131
> kubectl delete -f ~/nginx-pod.yaml
6) pod 생성하는 방법
-- run vs. create deployment**t
> kubectl run nginx-pod --image=nginx
> kubectl create deployment dpy-nginx --image=[account_name]/[image_name]
> kubectl apply -f ~/nginx-dpy.yaml

4. 쿠버네티스 오브젝트 : 파드 생성+관리 중심

4-1.오브젝트
: 파드와 디플로이먼트 등 개별 기능의 그룹, 또는 이를 셈하는 단위
- 기본 오브젝트
1) 파드 : 독립적인 공간과 ip를 가지는 서비스의 최소 단위
2) 네임스페이스 : 리소스 그룹. default, kube-system, metallb-system 등이 있음
3) 볼륨 : 저장보존이 가능한 directory
4) 서비스 : 파드 접속을 안정적으로 유지하기 위한 클러스터 내외부 연결장치
- 디플로이먼트
1) 정의 : 기본 오브젝트에 추가적인 기능을 조합해 구현한 관리 그룹
2) 특성 : 파드에 기반함. 레플리카셋 오브젝트의 결합 형태
> kubectl scale deployment dpy-nginx --replicas=3
* pod는 replicaSet을 적용할 수 없다.
- 기타 오브젝트
1) 데몬셋
2) 컨피그맵
3) PV, PVC
4) 스테이트풀셋
5) ETC

* 파드와 디플로이먼트는 spec과 status를 가짐

-오브젝트 스펙으로 파드만들기
1) api version 찾기
> kubectl api-versions
2) yaml 파일 작성하기
*apiVersion
*kind
*metadata[name/label]
*spec[replicas/selector/template]
3) yaml 파일 수정하기 (sed ; streamlined editor, i; inplace, s/ ; change pattern)
> sed -i 's/replicas: 3/replicas: 6/' ~/echo-dpy.yaml
> cat ~/echo-dpy.yaml | grep replicas
> kubectl apply -f ~/echo-dpy.yaml

4-2. 오브젝트 생성 관리
* ad-hoc(일회용)으로 오브젝트를 생성할 때 : create
* 수정가능한 오브젝트를 생성할 때 : yaml 파일 작성후 apply

1) container 자동복구(self-healing) : 내재화된 기능임.
-- pod container의 bash sheell 접속(i;stdin, t;teletypewriter)
> kubectl exec -it nginx-pod -- /bin/bash
> [bash] cat /run/nginx.pid
> [bash] ls -l /run/nginx.pid
-- master node의 job 실행을 위해 container가 죽어도 다시 복구되어 job 실행함.
> i=1;while true; do sleep 1; echo $((i++)) 'curl --silent 172.00.000.000 | grep title'; done
> [bash] kill 1

2) 파드 동작 보증 : deployment 있는 파드 만들면 됨.
-- deployment에 속하지 않은 독립/개별 pod는 컨트롤러가 관리하지 않음.
-- deloyment에 속한 pod를 삭제하면 replicaset이 새로운 파드 생성함.
> kubectl delete pods nginx-pod (run으로 생성된 pod 삭제 오래걸림)
> kubectl delete pods echo-dpy-5k1231-1241n (create으로 생성된 pod 삭제 안됨)
-- deployment를 삭제해야 함. 즉, replicaset을 줄이거나 모든 pod를 삭제해야 함.
> kubectl delete deployment echo-dpy

3) 노드 자원 보호
> kubectl apply -f ~/echo-dpy.yaml
> kubectl scale deployment echo-dpy --replicas=9
-- -o wide말고 원하는 컬럼만 가져오기
> kubectl get pods -o=custom-columns=NAME:.metadata.name, IP:.status.podIP, STATUS:.status.phase, NODE:.spec.nodeName
-- 특정 파드의 세부 값 확인하기
> kubectl get pod echo-dpy-3dd333-52ddh -o yaml > pod1.yaml
> vi pod1.yaml
-- 특정 노드만 파드 할당되지 않게 막기
> kubectl scale deployment echo-dpy --replicas=3
> kubectl cordon w3-k8s
> kubectl get nodes
> kubectl scale deployment echo-dpy --replicas=9
> kubectl scale deployment echo-dpy --replicas=3
-- 노드 자원 할당 제한 풀기
> kubectl uncordon w3-k8s

4) 노드 유지 보수
-- 특정 노드의 파드를 다른 노드로 옮기고, 해당 노드는 파드없는 상태로 만들기
> kubectl drain w3-k8s --ignore-daemonsets
> kubectl get nodes
> kubectl uncordon w3-k8s

5) 파드 업데이트(=rollout)
-- 명령을 기록하라 (record)
> kubectl apply -f ~/rollout-nginx.yaml --record
-- 모든 명령의 이력을 보여라 (rollout history)
> kubectl rollout history deployment rollout-nginx
> kubectl get pods -o=custom-columns=NAME:.metadata.name, IP:.status.podIP, STATUS:.status.phase, NODE:.spec.nodeName
-- I:header 정보만 보여주기
> curl -I --silent 172.00.000.000 | grep Server
-- spec의 image version을 수정하라(set image)
> kubectl set image deployment rollout-nginx nginx=nginx:1.16.0 --record
> kubectl get pods -o wide
-- deployment의 상태를 확인하라
> kubectl rollout status deployment rollout-nginx
> kubectl rollout history deployment rollout-nginx
> curl -I --silent 172.00.000.00 | grep Server

6) 파드 복구
> kubectl set image deployment rollout-nginx nginx=nginx:1.17.23 --record
> kubectl get pods -o wide
-- pending이 존재한다면? 자세하게 문제를 확인하자
> kubectl rollout status deployment rollout-nginx
> kubectl describe deployment rollout-nginx
-- 마지막 명령 취소하기 (이전 상태를 신규 상태로 입력하면서 이전 상태 삭제)
> kubectl rollout history deployment rollout-nginx
> kubectl rollout undo deployment rollout-nginx
> kubectl rollout history deployment rollout-nginx
-- 특정 시점으로 복구하기
> kubectl rollout undo deployment rollout-nginx --to-revision=1

5. 쿠버네티스 오브젝트 : 네트워크 중심

5-1. 서비스
: 클러스터 외부에서 쿠버네티스 클러스터 내부(pod)에 접속하는 기능(방법)
*targetPort<--port<--nodeport
5-2. NODEPORT
- 1개 deployment에 1 nodeport 적용하기
- 사용자가 개별 워커 노드의 포트로 직접 접근하기 / 서비스가 각 노드의 파드 연결함.
1) 외부에서 접속하기
-- deployment pod 생성
> kubectl create deployment np-pods --image=[account]/[image]
> kubectl get pods
-- nodeport service 생성 (cluter ip 칼럼: private ip in cluster )
> kubectl create -f ~/nodeport.yaml
> kubectl get services
> kubectl get nodes -o wide

2) 부하 분산 테스트하기 (내부기능 pass)

3) expose로 nodeport 생성하기
> kubectl expose deployment np-pods --type=NodePort --name=np-svc-v2 --port=80
> kubectl get services

5-3. INGRESS *비추*
- 정의 : 다음 기능의 묶음 ; 사용 목적별 다른 응답 제공, 트래픽에 대한 L4/L7 로드밸런서, 보완 인증서 처리.
- n개의 deployment를 m개의 nodeport에 연결할 경우
- 사용자가 개별 워커 노드의 포트로 직접 접근하기 / 사용목적 그룹별로 서비스가 각 파드를 연결함.
* ingress controller 는 nodeport 또는 loadbalancer를 통해 pod와 통신함.

* ingress-config, ingress, ingress-pod..이게 어떻게 돌아가는거야?
* selector는 무슨 역할 하는거야?

1) deployment의 pod 생성
> kubectl craete deployment ing-hname-pod --image=[account]/[image]
> kubectl craete deployment ing-ip-pod --image=[account]/[image]
> kubectl get pods

2) ingress controller의 pod 생성 (n; namespace)
> kubectl apply -f ~/ingress-nginx.yaml
> kubectl get pods -n ingress-nginx

3) ingress conig(경로, 서비스명, 작동포트) 정의 (worker nodeport -> nodeport service)
> kubectl apply -f ~/ingress-config.yaml
* kind;ingress
> kubectl get ingress
> kubectl get ingress -o yaml

4) nodeport를 사용해 ingress controller를 외부노출하기(ingress controller <- nodeport)
> kubectl apply f ~/ingress.yaml
> kubectl get services -n ingress-nginx

5) expose로 depoloyment를 인그레스로 노출하기(deployment<-ingress controller)
> kubectl expose deployment ing-hname-pod --name=hname-svc --port=80,443
> kubectl expose deployment ing-ip-pod --name=ip-svc --port=80,443

5-4. LoadBalancer *추천*
- 사용자가 개별 워커 노드의 포트로 직접 접근하지 못함/ 부하분산에 장점가짐

0) if not on-premise
> kubectl expose deployment ex-lb --type=LoadBalancer --name=ex-svc

5-4-1. MetalLB
: 내부에서 로드밸런서 서비스를 받아주는 구성을 지원하는 도구
: L2/L3 네트워크로 구성됨

1) deployment 생성
> kubectl create deployment lb-hname-pods --image=[]/[]
> kubectl scale deployment lb-hname-pods --replicas=3
> kubectl create deployment lb-ip-pods --image=[]/[]
> kubectl scale deployment lb-ip-pods --replicas=3
> kubectl get pods

2) metallb 구성하기
> kubectl apply -f ~/metallb.yaml
> kubectl get pods -n metallb-system -o wide

3) metallb 설정 / configmap !
> kubectl apply -f ~/metallb-l2config.yaml
* kind : confingMap
> kubectl get configmap -n metallb-system
> kubectl get configmap -n metallb-system -o yaml

4) expose로 deployment를 로드밸런서로 노출하기
-- deployment가 개별적인 ip를 받음.
> kubectl expose deployment lb-hname-pods --type=LoadBalancer --name=lb-hname-svc --port=80
> kubectl expose deployment lb-ip-pods --type=LoadBalancer --name=lb-ip-svc --port=80
> kubetctl get services

5-4-2. 부하분산하기
- HPA(horizontal pod AUTO SCALER!) : metallb 심화과정
- HPA는 부하량에 따라 Deployment의 pod 수를 유동적으로 증감하는 기능으로, metrics-server으로 부하량을 계측한다!
- HPA는 http:heapster를 통해 metric-server를 monitoring한다.

> kubectl create deployment hpa-hname-pods --image=0/0
> kubectl expose deployment hpa-hname-pods --type=LoadBalancer

-- TLS 인증, kubelet 내부주소 우선순위 설정..어떻게 함?
> kubectl create -f ~/metrics-server.yaml
> kubectl top pods

-- deployment에 scale 기준값 설정하기 (1000m=1cpu, #pod:min~max, cpu usage % )
> kubectl edit deployment hpa-hname-pods
> kubectl auto scale deployment hpa-hname-pods --min=1 --max=30 --cpu-percent=50
> kubectl top pods
> kubectl get hpa

6. 쿠버네트스 오브젝트 : 추가 기능을 구현한 기타 오브젝트

6-1. daemonset
노드의 단일 접속 지점으로 노드 외부와 통신함(kubectl-proxy, calico, metallb speaker)
파드 2개 이상 필요하지 않음

– worker node 최대치 설정 수정하고 새로 생성된 파드 설정 확인하기(데몬셋이라고 써 있음)
> kubectl get pods -n metallb-system -o wide
> kubectl get pods -n metallb-system -o wide -w
> kubectl get pods speaker-vnc2k -o yaml -n metallb-system

6-2. configmap
범용 설정 목적으로 사용하는 오브젝트
개별 오브젝트로 존재하지 않으면 configmap으로 오브젝트 설정함

– 로드밸런서 서비스 생성하기 (디플로이먼트 생성후 로드밸런서로 노출하기)
> kubectl create deployment cfgmap –image=sysnet4admin/echo-hname
> kubectl expose deployment cfgmap –type=LoadBalancer –name=cfgmap-svc –port=80
> kubectl get services
– ip주소 변경하기
> cat ~/metallb-l2config.yaml | grep 192.
> sed -i ‘s/11/21/;s/13/23/’ ~/metallb-l2config.yaml
> cat ~/metallb-l2config.yaml | grep 192.
> kubectl apply -f ~/metallb-l2config.yaml
– 파드 삭제후 재생성
> kubectl delete pods –all -n metallb-system
> kubectl get pods -n metallb-system
– 로드밸런서 서비스 삭제후 재생성
> kubectl delete service cfgmap-svc
> kubectl get services
– 삭제
> kubectl delete deployment cfgmap
> kubectl delete service cfgmap-svc

6-3. pv/pvc
;볼륨이 필요한 이유 : 공유된 볼륨[저장소]으로부터 공통된 설정을 가져오기(파드 생성기록보관, 동일 설정값 유지)

; 볼륨의 종류
임시볼륨 : emptyDir
로컬볼륨 : host path, local
원격볼륨 : nfs, pvc, fc, ..
* nfs란? network file system -> 확장 : nas / network attached storage
* 예제; [블로그 자료] https://jhnyang.tistory.com/279
특수볼륨 : downloadAPI, configMap, secret
클라우드볼륨 : aws, azure, gce
*nfs와 같은 일부 원격볼륨은 동적할당이 불가능함

; PV/PVC란?
*PV : 사용자가 사용할 볼륨(공간)을 준비하는 단계(생성)
*PVC : 준비된 볼륨에서 일정 공간을 할당받는 단계(전달)
* PV로 볼륨을 선언함. 볼륨 타입 : 원격볼륨+ 클라우드 볼륨 가능

1) nfs volume에 pv/pvc를 만들고 pod에 연결하기 [사용자-관리자 별개 시스템]
– nfs server를 master node에 구성 및 적용하기 (nfs-utils.x86_64 기설치)
> mkdir /nfs_shared
> echo ‘/nfs_shared 192.000.0.0/24(rw, sync, no_root_squash)’ >> /etc/
> systemctl enable —now nfs
– pv, pvc 생성하기 [ pv 상태 : available -> bound ]
> kubectl apply -f ~/nfs-pv.yaml
> kubectl get pv
> kubectl apply -f ~/nfc-pvc.yaml
> kubectl get pvc
> kubectl get pv
– pvc가 mount된 pod 생성하기 ( 접속~ mount status 확인 )
> kubectl apply -f ~/nfs-pvc-deploy.yaml
> kubectl get pods
> (접속) kubectl exec -it nfs-pvc-deploy-8*-3n – /bin/bash
8*-3n:/> df -h
– audit-trail container 기능 테스트 1단계 : 로드밸런서 생성하기
> kubectl expose deployment nfs-pvc-deploy –type=LoadBalancer –name=nfs-pvc-deploy-svc –port=80
> kubectl get services
– audit-trail container 기능 테스트 2단계 :브라우저 접속 & audit 기록 확인하기
8*-3n:/> ls /audit
8*-3n:/> cat /audit/audit_nfs-pvc-deploy-23mf33j3-qwwsm.log
– audit-trail container 기능 테스트 3단계 : 모든 파드의 audit에서 접속 기록 확인하기
> kubectl scale deployment nfs-pvc-deploy –replicas=8
> kubectl get pods
> (접속) kubectl exec -it nfs-pvc-deploy-7*-*rp – /bin/bash
7*-*rp> cat /audit/audit_nfs-pvc-deploy-7*-*rp-qwwsm.log
7*-*rp> (접속후) ls /audit
7*-*rp> cat /audit/audit_nfs-pvc-deploy-7*-*mt.log
7*-*9k> (다른 파드 ip로 접속) ls /audit

2) nfs volume을 pod에 직접 mount하기 [사용자-관리자 단일 시스템]
– pvc 설정 대신 nfs ip 설정하기
> kubectl apply -f ~/nfs-ip.yaml
> kubectl get pods
> kubectl exec -it nfs-ip-*-* – /bin/bash
*-*> ls /audit
– 삭제하기
> kubectl delete deployment nfs-pvc-deploy
> kubectl delete deployment nfs-ip
> kubectl delete service nfs-pvc-deploy svc

3) volume 제한하기
– pvc가 pv에 요청하는 용량 제한하기
> kubectl apply -f ~/limits-pvc.yaml
> kubectl apply -f ~/nfs-pv.yaml
> kubectl apply -f ~/nfs-pvc.yaml
– *제한 해제!
> kubectl delete limitranges storagelimits

– storage resource로 총 누적 사용량 제한하기
> kubectl apply -f ~/quota-pvc.yaml
> kubectl get pv
> kubectl apply -f nfs-pvc.yaml
> kubectl apply -f nfs-pvc1.yaml
> kubectl apply -f nfs-pvc2.yaml
– *제한 해제!
> kubectl delete resourcequotas storagequota
> kubectl delete pvc nfs-pvc1
> kubectl delete pv nfs-pv2
> kubectl delete pv nfs-pv1

*pv, pvc도 pod처럼 replicaset 수 지정하면 알아서 생성됨?

6-4. statefulSet
- statefulSet이란? 이전 상태를 기억하는 세트(디플로이먼트 오브젝트)
- 왜 사용하나? pod의 이름과 순서에 일정한 규칙이 필요한 DB가 존재함(몽고, 카산드라, 주키퍼)
- 주요기능은?
1) volumeClaimTemplates 으로 PVC를 자동생성함
2) 각 pod가 순서대로 생성됨
3) 고정된 이름, 불륨,설정을 가짐

– serviceName, kind 가 있는 pvc 생성하기
> kubectl apply -f ~/nfs-pvc-sts.yaml
> kubectl get pods -w
– statefulset 외부에 노출하기(expose 못 씀)
> kubectl expose statefulset nfs-pvc-sts –type=LoadBalancer –name=nfs-pvc-sts-svc –port=80
> kubectl apply -f ~/nfs-pvc-sts-svc.yaml
> kubectl exec -it nfs-pvc-sts-0 – /bin/bash
– 삭제하기
> kubectl delete statefulset nfs-pvc-sts
> kubectl get pods -w

6-5. pvc,pv 동적할당하는 클라우드 스토리지!
– pvc 동적할당!
> kubectl apply -f ~/dynamic-pvc.yaml
> kubectl get pvc
> kubectl get pv
* 동적설정된 pv는 pvc의 요청에 따라 생성됨.
– deployment생성하기
> kubectl apply -f ~/dynamic-pvc-deploy.yaml
> kubectl get p
ods
– pod 내 /audit이 pvc크기다!
> kubectl exec -it dynamic-pvc-deploy-* – /bin/bash