0513_Kubernetes_k8s 구성요소, 설치, 클러스터 생성

HYOJU DO·2022년 5월 15일
0

Kubernetes

목록 보기
1/13
post-thumbnail

Kubernetes(k8s)


💡Cloud Native
Kubernetes가 포함 된 컨테이너 생태계
관련 소프트웨어 확인

💡참고 : 쿠버네티스 다큐멘터리 1
💡참고 : 쿠버네티스 다큐멘터리 2

쿠버네티스는 Borg의 GO 오픈소스 버전
➕ 3개월에 1번씩 업데이트
CNCF 재단 (리눅스 하위 재단)에서 코드 관리


쿠버네티스 개요

Immutable service 위한 Stateless Infrastructure 에 최적화 -> 위함
Kubernetes == PaaS
대부분의 정보를 yaml 이라는 데이터 포멧으로 제공

➕ Immutable Infrastructure
바로 서버를 구축한 이후에는 변경이나 업데이트를 할 수 없고 만약 변경이 필요한 경우에는 아예 새로운 서버를 구축하는 방법

쿠버네티스가 제공하는 서비스

  • 서비스 디스커버리 / 로드 밸런싱
  • 스토리지 오케스트레이션
  • 자동화된 롤아웃 / 롤백
  • 자동화된 바이너리 패킹(bin packing)
  • 자동화된 복구 ➜ Docker restart 기능
  • 시크릿과 구성 관리

쿠버네티스가 제공하지 않는 서비스

  • 지원하는 애플리케이션의 유형 제약 X (Stateless)
    컨테이너에서 구동 가능 == 쿠버네티스에서 구동 가능
  • 소스 코드 배포 X, 애플리케이션 빌드 X ➜ 별도 구성
  • 애플리케이션 레벨 서비스 제공 X ➜ Paas
  • 로깅, 모니터링, 경보 솔루션을 포함 X ➜ 별도 구성
  • 기본 설정 언어/시스템 X ➜ yaml (데이터 포멧)
  • 머신 설정, 유지보수, 관리, 자동 복구 시스템 제공 X

🌟 k8s 핵심
1. PaaS
2. Logging / Monitoring 기능 x
3. 소스코드 Build / Deploy 기능 x



쿠버네티스 구성요소


🌟 해당 그림 이해 및 암기 필수

클러스터(Cluster)

물리적, 논리적 개념의 여러 개의 소프트웨어(리소스)를 모아서 사용
➜ 한꺼번에 관리하기 위함

  • Control Plane
  • Node

보통 각각 VM으로 사용
각 VM은 Controll Plane과 Node로 역할 나뉘고,
Node(worker or minions)가 컨테이너 실행

Node

실질적인 어플리케이션 실행

파드(Pod) 를 사용하여 컨테이너를 객체로 관리
동작 중인 파드를 유지시키고 쿠버네티스 런타임 환경을 제공하며, 모든 노드 상에서 동작
Node에는 Docker, Podman, Cri-o 등 CRI(container runtime interface) + 표준 인터페이스 containerd 설치되어 있어야 함
어플리케이션 동작 수준에 따라 갯수 변경

Kubelet (큐블렛)

컨테이너 담당

컨테이너를 대신 관리해주는 에이전트

Docker는 컨테이너를 직접 관리하지는 않음
컨테이너를 만들어달라는 요청이 API Controller에 접수되면 API Controller는 Kublet에게 요청하여 컨테이너 생성

Kube-proxy

네트워크 담당

네트워크 정책을 어떻게 setting 할 것인지 결정

Kubelet과 Kube-proxy 는 Control Plane에도 존재
➜ control plane도 결국에 컨테이너들로 이루어져있기 때문
(위 그림에서는 보이지 x)


Control Plane

Node를 관리해주는 시스템

➕ 여러 개의 Control Plane도 Cluster라고 부름 (위의 Cluster과 다른 개념)

🎈 Control Plane 서버 구성 시, 주의 사항
각 역할마다 컨테이너 3대 이상 씩 배치 (SPOF 방지)
➜ 똑같은 VM 여러 대 중복 구성
➜ 반드시 홀수 개로 구성 (Split Brain 방지)

💡Split Brain
VM들은 클러스터 내에서 같은 네트워크로 연결되어있고, 과반수 정책(정족수)을 따름
네트워크 스플릿(네트워크 끊어짐)이 발생하여 VM 2대 장애 발생
문제 : 둘 중 어떤 VM 집합을 종료시킬 것인가


API 서버

모든 쿠버네티스 관련 통신은 반드시 API 서버를 통해야함 (절대 다이렉트 통신 없음)
🎈 kubectl (쿠베씨티엘, 큐브씨티엘) ➜ api 서버에게 통신을 거는 명령어
🌟 쿠버네티스는 api 서버가 죽으면 끝

c-m (controller manager)

control plane(쿠버네티스 전체)를 control하는 컨테이너
Replica 및 네트워크 관리

  • 노드 컨트롤러: 노드 다운 및 생성 시 대응
  • 레플리케이션 컨트롤러: 적절한 수의 pod(파드) 유지
    ➜ 쿠버네티스의 핵심 : 컨테이너 복제 (replica)
    (pod가 곧 컨테이너는 X, 지금은 컨테이너라고 생각)
  • 엔드포인트 컨트롤러: 서비스와 파드 연결 (파드에 네트워크 제공)
    ➜ 서비스 == 네트워크
  • 서비스 어카운트 & 토큰 컨트롤러: 어카운트와 인증에 집중 된 컨트롤러

c-c-m (cloud controller manager)

(optional)
퍼블릭 클라우드와 쿠버네티스 VM 간의 통신 관리 (온프렘에서는 필요 x)
클라우드에서도 추상화 되어 볼 수 없음

Scheduller

pod 스케줄링 담당

pod(container)를 어디에 배치할 것인가
커널의 핵심 ➜ 리소스 사용량 결정

etcd(엣시디)

etc 데몬
key-value 스토리지 (nosql 형태 데이터베이스)
➕ 데이터베이스도 스토리지 개념에 포함

🌟 선언적
🌟Desired state 유지하게끔 해 줌
➜ Pod 생성 데이터(inspect 에서 확인할 수 있는 데이터)를 yaml 방식으로 선언

Control Plane의 다른 역할 컨테이너들은 stateless ➜ 장애가 발생 시 컨테이너 다시 실행
etcd는 stateless X ➜ 🌟 데이터 저장
이 데이터에 접근 못하면 아무것도 할 수 없음


➕ 각 클라우드 벤더의 관리형 쿠버네티스

➜ control plane을 관리 (추상화 되어있음)
➜ 요즘은 node까지 추상화

  • AWS : EKS
  • Azure : AKS
  • Google : GKE



Add-on

쿠버네티스가 구현하지 못하는 기능을 구현할 수 있게 해 줌 (플러그인 느낌..?)
추가 구성이지만 필수

🌟DNS add-on ( kube-dns )

필수!!

클러스터 DNS -> 서비스 디스커버리
클러스터 내부 에서 컨테이너를 어떻게 찾을 것이냐
➜ 외부에서 찾는 것과는 관련 X
coredns 라는 오픈 소스 사용

💡서비스 디스커버리 : 주소 체계를 가지고 서비스를 찾는 것
(ex. 어떤 VM이 어떤 디비나 VM을 찾는 것, 웹이 디비를 찾는 것)


컨테이너 리소스 모니터링 add-on

프로메테우스

프로메테우스는 쿠버네티스와 별개
(쿠버네티스용 X ➜ 베어메탈, VM 전부 연결 가능)


클러스터-레벨 로깅 add-on

오픈 소스 ELK(Elastic Search)

Docker에서 컨테이너 삭제 시 로그도 같이 삭제되어 다른 곳에 저장해야했음
로그를 저장을 하는데 사용하는 것이 ELK, EFK
(Elastic Search, Logstach, Kibana, Fluentd 의 약자)


➕ 웹UI add-on
➜ 사용 x (약한 인증으로 인해 보통 프로메테우스로 대체)



Kubernetes 설치


설치 방법

  1. Kubeadm (표준) ✔️
    자동화 x (관리할 것이 많음)
  2. Kubespray (Kubeadm + Ansible)
    자동화 (현업에서 많이 씀)
  3. minikube
    개발자들이 많이 씀
    멀티 플렛폼 제공 ➜ 로컬에 VM으로 k8s 설치 가능

k8s 소스코드



Kubeadm 설치

쿠버네티스 설치를 위한 도구
(쿠버네티스 아님)

현재 구현 조건 : 하나의 VM 생성
Control Plane과 Worker Node 역할 같이 해야 함
➕ Control Plane도 결국엔 Worker Node의 한 종류

Kubeadm 설치 전 런타임 설치 : 파드에서 컨테이너를 실행하기 위함
➜ Docker가 설치되어있으므로 넘어감

kubeadm, kubelet, kubectl 설치

➜ 모두 구글 저장소에 존재

  • kubeadm : 클러스터를 부트스트랩하는 명령
    ➕ 부트스트랩 : 한 번 시작되면 알아서 진행되는 일련의 과정
  • kubelet : 클러스터의 모든 머신에서 실행되고 포드 및 컨테이너 시작과 같은 작업을 수행하는 구성 요소
  • kubectl : 클러스터와 통신하기 위한 커맨드 라인 유틸리티

🎈 마스터 노드 : Ubuntu (데비안 계열)

  1. 패키지 목록 업데이트 및 apt 레포지토리 사용하는 데 필요한 패키지 설치
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl
  1. 구글 클라우드의 공개 signing key 다운로드
$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
  1. 쿠버네티스 apt 레포지토리 추가
$ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
  1. 패키지 목록 업데이트
    레포지토리를 추가했기 때문에 update 한 번 더
$ sudo apt-get update
  1. 사용 가능한 패키지 버전 확인
$ apt-cache madison kubeadm | grep 1.22.8
$ apt-cache madison kubelet | grep 1.22.8
$ apt-cache madison kubectl | grep 1.22.8
  1. kubelet, kubeadm, kubectl 1.22.8 버전 설치
    버전 명시 필수! 서버는 검증 된 버전 설치해야 함
    명시하지 않을 시, 최신 버전 패키지 설치
$ sudo apt-get install kubeadm=1.22.8-00 kubelet=1.22.8-00 kubectl=1.22.8-00 -y
  1. kubelet, kubeadm, kubectl 버전 고정
    쿠버네티스 자동 업데이트 잠금
$ sudo apt-mark hold kubelet kubeadm kubectl
  1. 설치 확인
    모두 버전이 동일해야 함
$ kubeadm version
$ kubectl version
$ kubelet --version



Kubeadm으로 쿠버네티스 클러스터 생성


🎈초기 설정 시 발생하는 오류

cgroup driver 오류

컨테이너 런타임에서는 systemd driver를 kubeadm 과 함께 사용하기를 권장
➕ cgroupfs 드라이버는 kubeadm과 함께 사용하는 것을 권장하지 X

기본으로 cgroups로 설정되어있음

$ docker info | grep 'Cgroup Driver'
WARNING: No swap limit support
Cgroup Driver: ✔️cgroupfs

Cgroups (control groups) Driver를 systemd 드라이버로 마이그레이션
/etc/docker/daemon.json

{
  "exec-opts": ["native.cgroupdriver=systemd"]
}

런타임(Docker) 재시작

sudo systemctl restart docker

확인

docker info | grep 'Cgroup Driver'

 Cgroup Driver: ✔️systemd

데몬 재시작하여 편집한 설정 반영 후, kublet 재시작

sudo systemctl daemon-reload && sudo systemctl restart kubelet

Control Plane 노드 초기화

kubeadm init

실제 이미지 받는 시간 때문에 약간 오래 걸림

$ sudo kubeadm init --control-plane-endpoint 192.168.100.100 --pod-network-cidr 172.16.0.0/16 --apiserver-advertise-address 192.168.100.100
I0513 16:09:12.618017   58549 version.go:255] remote version is much newer: v1.24.0; falling back to: stable-1.22
[init] Using Kubernetes version: v1.22.9
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster

...

[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!
...

--control-plane-endpoint
모든 Control Plane 노드에 대해 공유 endpoint를 설정하도록 지정
➜ 엔드포인트 : DNS 이름 or 로드 밸런서의 IP 주소
--pod-network-cidr
자신이 사용하는 네트워크 대역에 맞게 설정
apiserver-advertise-address
API 서버를 사용하기 위한 ip 지정

쿠버네티스 인증파일 생성
root가 아닌 사용자에 대해 kubectl이 작동하도록 하기 위함

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config # 이 파일 절대 노출되면 안 됨
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

제대로 권한 변경이 되었는지 확인


🎈 kubeadm init 실패시
reset 진행 후 kubeadm init 한 번 더 실행

sudo kubeadm reset



Network Add-on : Calico

노드 상태 확인

$ kubectl get nodes

NAME     STATUS     ROLES                  AGE    VERSION
docker   ✔️NotReady   control-plane,master   7m1s   v1.22.8

Ready 상태인 노드에서만 pod 예약 가능 ➜ pod의 (overlay) network add-on 설정 필요
Calico 사용

  • 성능, 확장성, 기능 모두 우수
  • VxLAN이라는 Tunneling Protocol 제공

Calico 설치

  1. 클러스터에 operator 설치
kubectl create -f https://projectcalico.docs.tigera.io/manifests/tigera-operator.yaml
  1. Calico 설치를 위한 리소스 다운
curl https://projectcalico.docs.tigera.io/manifests/custom-resources.yaml -O

파일 다운 후 사용자에 맞게 cidr 수정

custom-resources.yaml

# This section includes base Calico installation configuration.
...

spec:
  # Configures Calico networking.
  calicoNetwork:
    # Note: The ipPools section cannot be modified post-install.
    ipPools:
    - blockSize: 26
      ✔️cidr: 172.16.0.0/16  # 이 부분 수정 (우리가 지정한 cidr에 맞게)
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()
...
  1. Calico 설치를 위한 manifest 파일 생성
    ➕ manifest 파일 : 파일들의 그룹을 위한 메타데이터를 포함하는 파일
kubectl create -f custom-resources.yaml



클러스터 상태 확인

kubectl get pods
-A : all pods

파드 목록 실시간 확인

$ watch kubectl get pods -A
NAMESPACE         NAME                                       READY   STATUS              RESTARTS      AGE
calico-system     NAMEco-kube-controllers-5d74cd74bc-t9mqc   READY   STATUS    RESTARTS        AGE
calico-system     calico-kube-controllers-5d74cd74bc-t9mqc   1/1     Running   0               13m
calico-system     calico-node-xbvknf497c-sz6xx               1/1     Running   0               14m
calico-system     calico-typha-98dff497c-sz6xx               1/1     Running   0               14m
kube-system       coredns-78fcd69978-kc7vf                   1/1     Running   0               30m
kube-system       coredns-78fcd69978-ml6hn                   1/1     Running   0               30m
kube-system       etcd-dockerver-docker                      1/1     Running   1               30m
kube-system       kube-apiserver-dockerer-docker             1/1     Runninga  1               30m
kube-system       kube-controller-manager-docker             0/1     Running   5 (38s ago)     30m
kube-system       kube-proxy-kplzrocker                      1/1     Running   0(15m a         30m
kube-systemator   kube-scheduler-dockerf8fc7-vdghd           1/1     Running   5 (3m38s ago)   30m
tigera-operator   tigera-operator-7cf4df8fc7-vdghd           1/1     Running   5 (109s ago)    16m

노드 상태 확인

$ kubectl get nodes
NAME     STATUS   ROLES                  AGE   VERSION
docker   ✔️Ready    control-plane,master   31m   v1.22.8

Taint 설정

taint를 설정한 노드에는 파드가 부적절한 노드에 스케줄되지 않음
실행 이유 : 현재 Control Plane과 Worker Node VM 1대에 동시에 존재하기 때문

$ kubectl taint node docker node-role.kubernetes.io/master-

간단한 예제 - 어플리케이션 배포

  1. 이미지 받아와서 Deployment 리소스 생성
    kubectl create : 리소스 생성
    ➕ Deployment : 쿠버네티스가 애플리케이션의 인스턴스를 어떻게 생성하고 업데이트해야 하는지를 지시
$ kubectl create deployment myweb --image=ghcr.io/c1t1d0s7/go-myweb
  1. deployments, replicasets, pods 리소스 확인
    kubectl get : 리소스 확인
$ kubectl get deployments,replicasets,pods
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myweb   0/1     1            0           2m55s

NAME                              DESIRED   CURRENT   READY   AGE
replicaset.apps/myweb-97dbf5749   1         1         0       2m55s

NAME                        READY   STATUS    RESTARTS   AGE
pod/myweb-97dbf5749-5vzwd   1/1     Running   0          2m55s
  1. 외부에 서비스 노출
    kubectl expose : 레플리케이션 컨트롤러, 서비스(네트워크), 디플로이먼트 또는 파드를 가져와 쿠버네티스 서비스 노출
$ kubectl expose deployment myweb --port=80 --protocol=TCP --target-port=8080 --name myweb-svc --type=NodePort 
  1. 네트워크 관련 목록 확인
$ kubectl get services
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        37m
myweb-svc    NodePort    10.103.6.118   <none>        80:✔️30984/TCP   37s
  • myweb-svc ➜ LB 역할
  • 포트번호 확인 ➜ 사용자마다 다름
  1. 로드밸런싱 확인
$ curl 192.168.100.100:[포트번호]

🎈 Pod 복제

오토스케일링 자동으로 됨

$ kubectl scale deployment myweb --replicas=5   # 복제본 5개 생성

생성 된 Pod 확인

$ kubectl get pods

🎈 서비스 삭제 / Deployment 삭제

$ kubectl delete service myweb-svc
$ kubectl delete deployment myweb

🎈 지금은 하나하나 설정했지만 실제로는 yaml 파일 에 한 번에 정의 해서 실행



💡 TIP

쿠버네티스 어렵게 설치하는 방법
➜ 쿠버네티스의 본질 파악 가능

GitHub issues
오류 나면 바로 구글링 하지 말고 깃허브 들어가서 issues 검색해보기



profile
Be on CLOUD nine! ☁️ ( 수정 예정 == 📌)

0개의 댓글