컴퓨터/도커

4. 쿠버네티스설치 및 기본 개념

sidedoor 2024. 8. 8. 23:48

쿠버네티스의 개념

쿠버네티스(Kubernetes)는 컨테이너화된 애플리케이션의 자동 배포, 확장 및 관리를 위한 오픈소스 플랫폼이다. Kubernetes는 종종 K8s로 불리며, 이는 K와 s 사이에 8개의 글자가 있기 때문이다. 이 시스템은 여러 서버에서 작동하는 수많은 컨테이너를 효율적으로 관리할 수 있게 해준다.

서버 운영 시 여러 서버에서 실행되는 많은 컨테이너를 개별적으로 관리하기는 어렵다. 예를 들어, 100개의 컨테이너를 실행하려면 100번의 명령어를 입력해야 하고, 실행 중인 컨테이너에 문제가 생기면 각각의 서버에 대해 일일이 처리해야 한다. Kubernetes를 사용하면 이러한 문제를 해결하고 여러 컨테이너를 쉽게 생성하고 관리할 수 있다.

쿠버네티스의 구조

쿠버네티스 클러스터

쿠버네티스의 구조는 크게 마스터 노드와 워커 노드로 나눌 수 있다.

마스터 노드는 클러스터의 제어 및 관리를 담당하고 개발자가 주로 마스터 노드와 통신하여 애플리케이션 배포 및 관리 작업을 수행한다.

워커 노드는 실제 애플리케이션 컨테이너가 실행되는 곳으로 주로 사용자가 인터넷을 통해 워커 노드와 통신한다.

쿠버네티스 클러스터 이미지

이러한 것들을 위해 마스터 노드와 워커 노드 간의 유기적인 통신이 중요하다.

이를 위해 CNI(Container network interfaces)라는 개념이 사용된다.

이는 말 그대로 쿠버네티스 클러스터에 존재하는 컨테이너 간의 통신을 위해 필요한 인터페이스를 의미한다.

CNI를 사용하려고 쿠버네티스 너트워크 플러그인을 제공하는데 대표적인 플러그인은 Flannel과 calico이다.

여기서 Flannel는 단순하고 사용이 쉬운 오버레이 네트워크 솔루션이고, Calico는 네트워크 보안과 정책을 제공하는 고성능 네트워킹 솔루션이다.

 

컨트롤 플레인

쿠버네티스 컨트롤 플레인은 클러스터의 전반적인 작업을 관리하는 핵심 구성 요소로 이루어져 있다. 마스터 노드에서 컨트롤 플레인을 구성하는 주요 요소는 다음과 같다.

api서버

 

쿠버네티스의 작업은 kubectl 명령어를 통해 마스터 노드의 kube-apiserver에게 API 요청을 보냄으로써 이루어진다.

API 서버는 컨트롤 플레인의 프런트엔드 역할을 한다.

 

 

etcd

 

클러스터에 존재하는 모든 데이터를 저장하는 분산 키-값 저장소이다.

클러스터의 상태 정보를 영구적으로 저장한다.

 

 

스케줄러

 

파드(Pod)를 클러스터 내의 적절한 노드에 할당하는 역할을 한다.

새롭게 생성되는 파드를 어떤 노드에 실행시킬지 결정한다.

 

 

컨트롤 매니저

 

다양한 컨트롤러를 통해 리소스를 관리하고 제어하는 역할을 한다.

여기서 사용하는 주요 컨트롤러는 디플로이먼트 컨트롤러 서비스 컨트롤러 레플리카셋 컨트롤러 등이 있다.

그리고 클러스터 상태를 모니터링하고 원하는 상태를 유지하기 위해 필요한 조치를 취한다.

노드

kubelet

클러스터를 구성하는 각 노드에서 실행되며, 파드 내부의 컨테이너 실행을 담당한다. 파드의 상태를 모니터링하고 상태 이상이 발생하면 해당 파드를 다시 배포한다.

 

kube-proxy

노드에서 네트워크 역할을 수행하며, 노드에 존재하는 파드들이 내부와 외부 네트워크와 통신할 수 있도록 한다.

 

컨테이너 런타임

컨테이너의 생명 주기를 관리한다.

 

파드

쿠버네티스에서는 컨테이너가 도커와 다르게 파드 내에서 실행된다. 파드는 한 개 혹은 여러 개의 컨테이너를 담을 수 있으며, 이는 컨테이너를 그룹화한 것이다. 다수의 파드는 여러 워커 노드에 분산되어 실행되지만, 하나의 파드에 속한 컨테이너들은 모두 같은 노드에서 실행된다. 하나의 파드에 속한 컨테이너들은 하나의 목적을 위해 구성된다.

워크로드

레플리카셋

파드의 복제를 관리하며, 클라이언트가 요구하는 복제본 개수만큼 파드를 복제하고 모니터링하며 관리한다.

 

디플로이먼트

애플리케이션의 배포와 스케일링을 관리한다.

 

스테이트풀셋

파드 사이에서 순서와 고유성이 보장되어야 하는 경우 사용한다.

 

데몬셋

쿠버네티스를 구성하는 모든 노드가 파드의 복사본을 실행하도록 하여, 클러스터에 새로운 노드가 추가되면 파드 역시 추가된다. 주로 로깅, 모니터링, 스토리지 같은 시스템 수준의 서비스를 실행하는 데 사용한다.

 

잡과 크론잡

작업이 정상적으로 완료되고 종료되는 것을 담당한다. 파드가 정상적으로 종료되지 않으면 재실행시킨다. 잡은 작업이 한 번 종료되는 것을 담당하고, 크론잡은 동일한 작업이 일정에 따라 여러 번 수행되도록 한다.

네트워크

서비스

파드를 여러 개 묶어서 클러스터 외부로 노출시킬 수 있다. 서비스의 장점은 이미 실행 중인 파드를 외부로 노출시키기 위해 파드 내부를 수정할 필요가 없다는 것이다. 이렇게 실행 중인 파드를 수정하지 않고도 외부에 노출시켜 클라이언트와 통신이 가능하다.

 

인그레스

쿠버네티스 내부에 있는 서비스를 HTTP/HTTPS 루트를 통해 클러스터 외부로 라우팅하는 역할을 한다.

스토리지

컨테이너 내부에 존재하는 파일은 수명이 짧기 때문에 스토리지를 통해 파드의 상태와 상관없이 파일을 보관할 수 있다.

쿠버네티스 실습 환경 구축

이제 쿠버네티스 실습을 위한 환경 구축을 할 것이다.

 

가상머신 복제

쿠버네티스는 서버가 여러 대일 때 좀 더 효율적으로 운영할 수 있다.

따라서 이를 위해 여러개의 서버를 만들어 진행을 하겠다.

먼저 가상머신을 복제하면 호스트 이름이 기존과 동일하기 때문에 이를 고치기 위해 아래와 같이 진행하여 머신별로 이름을 다르게 한다.

 

가상머신 호스트 이름 변경

기존의 노드를 복제한 뒤에 이처럼 호스트 이름을 변경하여 다른 서버에 다른 이름을 만들어 준다.

그리고 이제 각각의 머신별로 IP주소를 변경하여 가상머신을 구분지을 수 있게 한다.

/etc/netplan/00-installer-config.yaml파일에 아래와 같이 입력을 해주면 해당 가상 머신 주소를 변경할 수 있다.

 

network:
  ethernets:
    enp0s3:
      addresses: [10.0.2.16/24] # 바꾸고 싶은 IP입력
      routes:
      - to: default
        via: 10.0.2.1
      nameservers:
        addresses: [8.8.8.8]
  version: 2

 

 

바뀐 ip주소 확인

이처럼 IP주소가 내가 원하는 번호로 바뀐 것을 볼 수 있다.

 

DNS설정

세 대의 가상머신을 활용해 쿠버네티스 클러스터를 구축하려면 서로 통신이 가능해야함으로 DNS를 설정해야한다.

/etc/hosts파일을 다음과 같이 수정한다.

DNS수정

이렇게 수정을 한 뒤 통신을 해보면 아래와 같이 통신이 잘 되는것을 볼 수 있다.

 

ping으로 통신 확인

그러면 이제 다른 머신에 ssh를 통해서 접속을 해보면 아래와 같이 다른 머신으로의 접속도 잘 되는 것을 볼 수 있다.

 

다른 머신 접속

 

네트워크 설정

 

# IPv4포워딩 
sudo -i 
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf #tee명령어를 쓰면 화면에 출력됨과 동시에 파일에 저장 
overlay 
br_netfilter 
EOF 

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf 
net.bridge.bridge-nf-call-iptables = 1 
net.bridge.bridge-nf-call-ip6tables = 1 
net.ipv4.ip_forward = 1 
EOF

 

여기서 overlay는 리눅스 커널의 네트워크 드라이버로, 서로 다른 호스트에 존재하는 파드 간의 네트워크 연결을 가능하게 한다. 독립적인 네트워크 레이어를 겹쳐서 하나로 연결된 네트워크를 생성하며, 이를 통해 서로 다른 호스트에 있는 파드들이 동일한 네트워크에 존재하는 것처럼 통신할 수 있게 한다.

by_netfilter는 네트워크 패킷 처리 관련 모듈로, iptables/netfilter 규칙이 적용되도록 한다. 이는 컨테이너와 호스트 간의 인터페이스 등에서 발생하는 트래픽에 대해 규칙을 적용하여 트래픽을 관리한다.

 

containerd설정

containerd는 도커 관련 작업을 할 때 사용하는데 이를 쿠버네티스에서 컨테이너 런타임으로 사용할 수 있도록 설정을 변경하겠다

 

# containerd 설정값 출력하고 config.toml파일 저장 
sudo mkdir -p /etc/containerd 
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null 

# 파일에서 SystemdCgroup수정 
sudo vim /etc/containerd/config.toml

 

 

config.toml파일 내부

위의 이미지처럼 config.toml파일 내부의 SystemdCgrup를 true로 수정해준다

 

결과를 보면 작동이 되는 것을 볼 수 있다

 

swap메모리 비활성화

쿠버네티스는 많은 컨테이너를 동시에 관리하기 때문에 원활한 관리를 위해 swap메모리 영역을 비활성해야한다.

여기서 swap메모리는 RAM이 부족할 때 사용되는 디스크 공간이다. 운영 체제가 RAM을 모두 사용하고 추가 메모리가 필요할 때, 사용하지 않는 메모리 블록을 디스크의 swap 영역으로 이동시켜 메모리를 해제한다. 이는 시스템이 더 많은 프로세스를 처리할 수 있도록 돕지만, 디스크 I/O 속도가 RAM에 비해 훨씬 느리기 때문에 성능 저하를 초래할 수 있다.

 

swap메모리 해제

그리고 아래처럼 12번째 줄을 주석처리하여 재부팅 했을 때 swap 메모리가 다시 활성화 되는 것을 방지한다.

 

다시 실행되는 것 방지

 

쿠버네티스 설치

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

 

Installing kubeadm

This page shows how to install the kubeadm toolbox. For information on how to create a cluster with kubeadm once you have performed this installation process, see the Creating a cluster with kubeadm page. This installation guide is for Kubernetes v1.30. If

kubernetes.io

 

 

위 주소를 참고하여 쿠버네티스를 설치하면 된다.

 

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.26/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.26/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

 

위처럼 실행을 하면 아래와 같이 각각 kubelet, kubeadm, kubectl이 설치가 잘 되었음을 볼 수 있다.

 

쿠버네티스 설치 완료

 

마스터 노드 설정

이제 myserver01을 마스터 노드로 설정하고 다른 노드를 워커 노드로 설정하겠다.

연제 아래와 같이 인증을 보면 아직 아무것도 인증이 되지 않은 것을 볼 수 있다.

 

인증 현황

이제 kubeadm에서 사용할 수 있는 이미지의 리스트를 뽑아보면 아래와 같다.

 

사용할 수 있는 이미지 리스트

 

sudo -i

# 쿠버네티스 설치에 필요한 이미지를 다운로드 한다
kubeadm config images pull
kubeadm init --apiserver-advertise-address=10.0.2.15 --pod-network-cidr=192.168.0.0/16 --cri-socket /run/containerd/containerd.sock

 

--apiserver-advertise-address=[master노드 IP]: API 서버가 클러스터 내에서 통신할 때 사용할 IP 주소를 지정한다.

--pod-network-cidr=192.168.0.0/16: 파드 네트워크의 클래스리스 도메인 경로 지정범위를 지정한다. 이 범위는 파드 간 통신을 위한 네트워크 주소 공간을 정의하는데 calic0를 사용할 경우 192.168.0.0/16을 입력하고, flannel을 사용하는 경우 10.244.0.0/16을 입력한다.

 

실행결과는 아래와 같이 나오는데 이 결과는 이후에 사용됨으로 따로 저장을 해둬야한다.

 

실행 결과

이제 다시 인증서 상태를 보면 아까와 다르게 인증이 되어 있는 것을 볼 수 있다.

 

인증 완료

이제 루트 권한이 아니라 사용자 권한으로도 쿠버네티스를 사용할 수 있게 설정하겠다.

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config # 기존 파일 복사
sudo chown $(id -u):$(id -g) $HOME/.kube/config # 설정 디렉토리의 소유자와 그룹을 변경해 사용자가 사용할 수 있도록 변경

 

 

# calico설치 위해 yaml파일 실행
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.3/manifests/tigera-operator.yaml

# calico설치 위해 필요한 커스텀 리소스 설치
curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.3/manifests/custom-resources.yaml -O

# calico설치
kubectl create -f custom-resources.yaml

 

코드를 실행하면 아래와 같이 calico에 대한 파드가 실행중임을 볼 수 있다.

 

calico 실행

워커 노드 설정

먼저 마스터 노드에서 설정 파일을 그대로 가져온다.

아래의 이미지처럼 마스터 노드의 IP주소를 이용해서 워커 노드의 특정 위치로 파일을 가져올 수 있다.

 

워커 노드로 파일 가져오기

그 후 위에서 실행결과로 얻었던 쿠버네티스 클러스터에 노드를 추가하는 명령어를 입력하고 추가로 --cri-socket /run/containerd/containerd.sock을 입력해서 노드를 마스터와 연계시킨다.

 

scp -p eevee@10.0.2.15:~/.kube/config ~/.kube/config

kubeadm join 10.0.2.15:6443 --token zvtolk.yvfx1awmgnijc5qi \
        --discovery-token-ca-cert-hash sha256:4093d4f96437152538031b9059ac696c4e8a01b14756ff479cafc1d0856bcaae --cri-socket /run/containerd/containerd.sock

 

이렇게 하면 아래와 같이 워커 노드가 추가된 것을 볼 수 있다.

 

워커 노드 추가

이제 쿠버네티스 설치를 끝냈으니 간단하게 hello world를 입력해보면 아래와 같이 결과가 나온다

 

쿠버네티스 hello world실행