새소식

Kubernetes

[Cloud Compute] Kubernetes 구축하기 - 2. 클러스터 구축

  • -

처음 쿠버네티스를 도입하며 가장 애먹었던 부분이 이 구축파트다.

분명히 이전에 했을 때는 잘됐는데 초기화하고 다시 해보니 안되는 경우도 많았다.

특히나 네트워크 플러그인....하...

수없이 구축하며 문제없이 진행되는 것을 매뉴얼로 구성해서 팀원들에게 배포도 했다(안보는게 문제...)

이 내용은 사실상 매뉴얼을 기초적인 형태로 풀어쓰는 것에 지나지 않지만 이것만으로도 새로 구축하려는 누군가에게 도움이 됐으면 한다.

 

1. AWS EC2 생성

여기서는 기본적인 AWS EC2의 기본적인 사용법을 알고 있다는 가정하에 진행할 것이다.

인스턴스는 공식문서에 따라 최소치로만 구현할 것이다.

 

  • 호환되는 리눅스 머신. 쿠버네티스 프로젝트는 데비안 기반 배포판, 레드햇 기반 배포판, 그리고 패키지 매니저를 사용하지 않는 경우에 대한 일반적인 가이드를 제공한다.
  • 2 GB 이상의 램을 장착한 머신. (이 보다 작으면 사용자의 앱을 위한 공간이 거의 남지 않음)
  • 2 이상의 CPU.
  • 클러스터의 모든 머신에 걸친 전체 네트워크 연결. (공용 또는 사설 네트워크면 괜찮음)
  • 모든 노드에 대해 고유한 호스트 이름, MAC 주소 및 product_uuid. 자세한 내용은 여기를 참고한다.
  • 컴퓨터의 특정 포트들 개방. 자세한 내용은 여기를 참고한다.
  • 스왑의 비활성화. kubelet이 제대로 작동하게 하려면 반드시 스왑을 사용하지 않도록 설정한다.

범용적인 인스턴스로 T3의 사양목록은 다음과 같다.

최소사양과 딱 맞는다

 

최소사양 2core, 2gb ram 에 맞춰 t3.small 로 2개의 인스턴스를 생성하자.

 

알기쉽게 인스턴스의 이름을 K8S로 지정하고 숫자를 붙였다

 

이제 인스턴스에 접속이 잘되는지 확인하고 다음단계로 넘어갈 것이다.

 

문제없이 접속이 되었으니 다음단계로 넘어가자.

 

접속에 문제가 있을 때를 적어놓지 않는 것은 몇가지가 있다.
1. 쿠버네티스 구축을 시도한다는 자체가 서버를 알고있기 때문이다.
2. 글의 목적은 쿠버네티스의 구축이고 EC2 인스턴스의 생성과 접속이 아니기 때문이다.

 

2. Docker와 Kubernetes설치하기

2-1. Docker 설치

1. 혹시 모를 구버전을 제거한다.

sudo apt-get remove docker docker-engine docker.io containerd runc

 

2. 필수 패키지를 설치한다.

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

 

3. apt에서 패키지를 인증하는데 사용되는 GPG키를 추가한다.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

 

4. apt에서 패키지를 설치하기 위해 레포지토리를 추가한다.

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

 

5. Docker를 설치한다.

sudo apt-get install docker-ce docker-ce-cli containerd.io

 

6. 설치된 Docker의 버전과 정보를 확인한다.

sudo docker version
sudo docker info

 

6-1. Docker의 data를 저장하는 디렉토디를 바꾼다면 다음과 같이 파일을 생성한다.

sudo vim /etc/docker/daemon.json
{
    "data-root":"/data/docker"
}

 

6-1. 디렉토리를 바꿨다면 재시작한다.

sudo systemctl daemon-reload
sudo systemctl restart docker

 

2-2. Kubernetes 설치하기

회사에 구축한 버전과 동일하게 진행하기 위해 Kubernetes의 버전은 1.24.1을 사용할 것이다.

 

1. apt에서 패키지를 인증하는데 사용되는 GPG키를 추가한다.

sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

 

2. 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
sudo apt-get update

 

3. Kubernetes를 설치한다.

sudo apt-get install -y kubelet=1.24.1-00 kubeadm=1.24.1-00 kubectl=1.24.1-00

 

공식문서에 따르면 설치하는 각 패키지는 다음과 같은 역할을 수행한다.

  • kubeadm: 클러스터를 부트스트랩하는 명령이다.
  • kubelet: 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트이다.
  • kubectl: 클러스터와 통신하기 위한 커맨드 라인 유틸리티이다.

대부분의 제어는 kubectl 을 이용해 진행된다.

 

4. apt 버전고정(권고사항으로 따르지 않아도 된다)

sudo apt-mark hold kubelet kubeadm kubectl

 

여기까지 무사히 진행되었다면 다음 단계로 넘어간다.

 

3. 클러스터 만들기 

먼저 Master의 역할을 맡을 서버에서 클러스터의 초기화를 진행해야 한다.

테스트에서는 이름에 따라 K8S-1 서버를 Master로 잡아서 진행할 것이다.

 

1. 클러스터를 초기화한다.

kubeadm init --pod-network-cidr=192.168.0.0/16

 

여기서 pod-network-cidr 이라는 옵션이 있다

kubernetes상 내부 네트워크에 배포되는 각종 서비스의 ip 블록을 지정하는 옵션인데 익숙하게 192.168.0.0으로 지정했다.

그러면 내부 ip의 범위는 192.168.0.0 ~ 192.168.255.255 이 될 것이다.

 

1-1. 권한문제로 초기화 실패

[ERROR IsPrivilegedUser]: user is not running as root

 

위와 같은 문구가 보인다면 명령어를 실행하는 계정의 권한문제로 sudo 를 붙여서 실행해보자

 

1-2. CRI v1 runtime API is not implemented 초기화 실패

CRI v1 runtime API is not implemented: ~~~~

 

위와 같은 문구가 보인다면 아래명령어를 써보자

sudo rm /etc/containerd/config.toml
sudo systemctl restart containerd

 

위 명령어로 containerd를 재시작하면 containerd 설정과 kubernetes간 충돌문제를 해결할 수 있다.

 

2. config파일 옮겨서 kubectl 명령어 사용할 수 있게 하기.

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

4. CNI 내부망 구축하기

4-1. 방화벽 설정하기

각 노드가 통신을 할 때 중요한 것이 있다.

1편 개념파트에서 구조도를 보면 각종 서비스들이 통신으로 제어된다는 것을 알 수 있다.

이 말은 Slave 노드를 구축할 때도 통신으로 제어될 것이란걸 알 수 있다.

공식문서 "포트와 프로토콜"에서 방화벽에서 열어줘야 하는 포트를 확인해서 열어줘야 한다.

굳이 넘어가지 않겠다면 그냥 이걸로 보자

 

  • Master 혹은 컨트롤플레인
프로토콜 방향 포트 범위 용도 사용 주체
TCP 인바운드 6443 쿠버네티스 API 서버 전부
TCP 인바운드 2379-2380 etcd 서버 클라이언트 API kube-apiserver, etcd
TCP 인바운드 10250 Kubelet API Self, 컨트롤 플레인
TCP 인바운드 10259 kube-scheduler Self
TCP 인바운드 10257 kube-controller-manager Self

 

  • 워커노드(Slave 노드를 말한다)
프로토콜 방향 포트 범위 용도 사용 주체
TCP 인바운드 10250 Kubelet API Self, 컨트롤 플레인
TCP 인바운드 30000-32767 NodePort 서비스† 전부

 

4-2. 네트워크 플러그인 설치

방화벽도 열어줬다면 네트워크 플러그인을 설치해야 클러스터에 Slave노드를 추가할 수 있고 노드간 통신이 가능해지기 때문에 필수적인 작업이다.

많이 쓰이는 플러그인으로 Flannel, Calico, Cilium, WeaveNet 등이 있는데 서로 성격이 다르기 때문에 팀 내부에서 회의를 해보고 잘 결정해보도록 하자.

테스트에서는 Cilium 을 사용할 것이고 다음 명령어로 설치할 수 있고 Helm이라는 패키지 매니저를 통해 설치할 수 있지만 나중에 알아보자....

curl -LO https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz
cilium install

 

아래와 같이 보이면 무사히 설치된것이다.

다행히 한번에 성공했다

다음 명령어를 그냥 따라해보자.

kubectl get pod -n kube-system

 

그대로 따라했고 아무것도 설치되지 않은 지금 다음과 똑같이 보일 것이다.

NAME READY STATUS     RESTARTS AGE
cilium-cwq9w 1/1 Running 0 3m 3s
cilium-operator-74c4bc768c-4d9k6 1/1 Running 0 3m 3s
coredns-6d4b75cb6d-jhjhj 1/1 Running 0 25m
coredns-6d4b75cb6d-km7b5 1/1 Running 0 25m
etcd-ip-172-31-33-228 1/1 Running 0 26m
kube-apiserver-ip-172-31-33-228 1/1 Running 0 26m
kube-controller-manager-ip-172-31-33-228 1/1 Running 0 26m
kube-proxy-s4hnb 1/1 Running 0 26m
kube-scheduler-ip-172-31-33-228 1/1 Running 0 26m

위를 보면 cilium-cwq9w, cilium-operator-74c4bc768c-4d9k6 2개가 딱봐도 별 문제없이 돌아가고 있다는 것을 알 수 있다.

 

4-3. 네트워크 플러그인(CNI)이 제대로 설치되지 않아 노드간 통신이 안될때

1. 모든 노드에서 초기화를 진행

kubeadm reset​

 

2. 재부팅을 실행하여 라우팅 테이블 초기화

rm -r /etc/cni/net.d​

 

3. 재설치
pod-network-cidr 에 맞춰 CNI도 동일한 cidr를 사용하도록 옵션을 지정할 것
VPC 환경에서 설치될 경우, subnet의 cidr과 겹치지 않게 조심할 것

 

5. 클러스터에 Slave노드 추가하기

3-1번에서 초기화가 정상적으로 진행되었다면 마지막에 다음과 같은 명령어를 알려준다.

kubeadm join 172.31.33.228:6443 --token sknx54.knubyhpvvqtp4s9t \
        --discovery-token-ca-cert-hash sha256:9496ed455394a102de0ed6d7df58fad6a485366cc4f1e7ded11d5477efc50291

 

Master노드의 주소와 인증토큰으로 노드를 추가하는 명령어로 Sub노드가 되는 서버에서 실행하면 된다.

 

여기까지 잘 진행되었다면 다음 명령어를 Master노드에서 실행해보자.

kubectl get node

 

EC2에서 생성한 서버 2대가 클러스터에 노드로서 연결되었음을 확인할 수 있다.

 

이제 기본적인 구성으로 클러스터를 구축하는 것이 끝났다.

 

다음은 어플리케이션을 배포하는 것을 진행해보자.

 

이전글

 

[Cloud Compute] Kubernetes 구축하기 - 1. 개념과 기대하는 역할

1. Kubernetes의 개념이 뭘까? 솔직히 개념같은건 공식 홈페이지와 다른 수많은 국내/해외 블로그들이 너무 많이 다루고 있어서 내가 생각하는 한줄 요약을 적어본다면 "특정 역할을 수행할 컨테이

bateaux.tistory.com

 

다음글

 

[Cloud Compute] Kubernetes 구축하기 - 3. 어플리케이션 배포하기

지난 글에서 구축까지 진행해보았다. 이제는 어떻게 어플리케이션을 배포하고 통신을 할 수 있는지 알아보자. 0. 시작하기에 앞서 명령어 알아보기 지금까지는 그냥 따라왔다면 이제는 명령어

bateaux.tistory.com

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.