티스토리 뷰

⚠️ 해당 글을 읽기전 유의 사항

  • 본 글은 관리형 쿠버네티스 서비스(EKS, GKE)를 사용하지 않고 VM 또는 온프레미스의 offline(폐쇄망)환경에서 쿠버네티스를 구축하기 위한 내용으로 구성되어 있습니다.
  • 전체 설치되는 과정은 root가 아닌 일반 사용자 권한으로 진행했습니다.
  • 본 글에서 사용하는 ‘자원’이라는 용어는 구동중인 VM을 의미합니다.
  • 본 글에서는 쿠버네티스 클러스터를 구축하기 위한 kubeadm init, kubeadm join, CNI 구축을 진행하는 내용을 포함하지 않습니다.



1. 기본 정보

개발환경 및 클러스터 정보

  • OS : Ubuntu 22.04.3 LTS (x86-64)
  • 쿠버네티스 버전 : v1.28.2
  • 배포 도구 : Kubeadm
  • 컨테이너 런타임 : CRI-O
  • 이미지 관리 : Podman
  • CNI 플러그인 : Calico
  • 노드 구성 : Master 2, Worker 6(총 8개의 VM 사용)

 

 

2. 기초 설정

기초 설정은 클러스터에 포함될 폐쇄망 환경의 모든 자원에 설정합니다.
해당 내용은 쿠버네티스 공식문서를 참고하여 진행했습니다.

 

브릿지 네트워크 설정

# 1.
$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

# 2.
$ sudo modprobe overlay
$ sudo modprobe br_netfilter


# 3.
$ 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

# 4. 재부팅하지 않고 sysctl 파라미터 적용하기
$ sudo sysctl --system

 

swap 메모리 해제

# swap 여부 확인
$ free -g

# swap이 활성화 되어 있을 경우 해제
$ swapoff -a

 

 

3. 컨테이너 런타임

쿠버네티스에서 주로 사용되는 컨테이너 런타임으로는 containerd와 CRI-O가 있습니다. 이번 쿠버네티스 구축 과정에서는 CRI-O를 컨테이너 런타임으로 채택하여 사용했습니다.

 

CRI-O 설치 및 설정

설치

⚠️ 폐쇄망(Offline) 환경의 경우 apt-get install 을 사용할 수 없기 때문에 온라인 환경(bastion)에서 apt downloadapt-cache depends -i ~ 명령어를 이용하여 관련 패키지를 모두 받고 폐쇄망 환경으로 다운 받은 패키지를 모두 넘겨 설치하는 방식으로 진행했습니다.

 

1. CRI-O 공식 문서(install.md)를 참고하여 패키지 및 의존 패키지 다운로드

# 1. 패키지 다운로드
bastion:~$ apt download cri-o
bastion:~$ apt download cri-o-runc

# 2. 패키지가 의존하는 패키지 설치
bastion:~$ apt-cache depends -i [패키지명] \ 
	| awk '/Depends:/ {print $2}' \
	| xargs apt download

# 3. 패키지 정상 설치 확인
# dependency 에러 발생시 해당 패키지명으로 '2'번 다시 실행
bastion:~$ dpkg -i *.deb
위의 명령어를 이용해 패키지를 다운 받을 경우 반드시 모든 패키지가 정상적으로 설치 되는지 확인 후 넘기는 것을 권장합니다. (의존패키지가 의존하는 또 다른 패키지까지 전부 다운 받지 못한 경우가 발생하기 때문입니다.😢)

cri-o , cri-o-runc 와 관련된 패키지를 모두 다운로드 한 상태

 

2. 패키지를 하나로 압축 후 폐쇄망 환경의 클러스터에 사용될 모든 자원에 전송

bastion:~$ for IP in 199 200 ...
do
	scp crio_install_pkg.tgz ubuntu@10.0.27.$IP:~/;
done

위 명령어로 진행시 별도의 설정이 없을 경우 각 자원별로 비밀번호를 입력해야 합니다. (ssh-key를 이용해 비밀번호 없이 scp 명령어 실행이 가능하지만 해당 내용은 생략하도록 하겠습니다.)

 

3. 각 클러스터 자원에서 전송된 압출파일을 해제 후 패키지 전체 설치 및 crio 활성화

# 패키지 전체 설치
master1:~/crio_install_pkg$ dpkg -i *.deb 

# cri-o 활성화
master1:~$ sudo systemctl enable crio --now
master1:~$ sudo systemctl status crio

 

설정

cgroup driver 설정이 필요하며 쿠버네티스 클러스터가 구축되는 자원에서 systemd를 사용하기에 별도의 설정 없이 진행하였습니다. (자세한 내용은  공식문서를 통해 확인 가능합니다.)

cgroup과 cgroup driver 의미는 아래 더보기를 참고해주세요.

더보기

cgroup은 호스트 리소스 자원에 대한 권한을 제한하고 격리시키는 것을 의미하며, cgroup driver는 cgroup을 관리하는 모듈을 의미합니다. cgroupfs driver는 파일 시스템 기반의 접근 방식을 사용하여 cgroup을 관리하며, 사용자가 직접적으로 더 많은 제어를 가능하게 합니다. systemd driver는 cgroup과 시스템의 서비스 및 프로세스를 함께 관리하며, cgroupfs에 비하여 조금 더 통합적이고 자동화된 관리를 제공합니다.

 

 

4. 쿠버네티스 필수 패키지 설치

본문에서 쿠버네티스 공식문서를 기반으로 이전 cri-o 설치 과정과 동일하게 패키지 다운로드 방식을 대입하여 진행했습니다.

2024년 3월 18일 기준, 공식문서의 방식을 따라서 설치를 진행할 경우 apt-get update시 '리포지터리에 릴리즈가 존재하지 않는다.'는 에러가 발생하고 있습니다.  공식문서에서 구글 클라우드의 공개 사이닝 키를 통한 apt 리포지터리를 추가하는 절차의 내용이 최신 사항으로 업데이트되지 않아 발생하는 문제임으로 링크를 참고하여 설치 진행하시면 됩니다.

 

Kubelet

  • 노드에 배포되는 에이전트.
  • 마스터의 API서버와 통신을 하며 노드가 수행해야 할 명령을 받아서 수행하고 노드의 상태 등을 마스터로 전달하는 역할을 합니다.
    (API 서버란 명령을 주고 받기 위해 쿠버네티스의 중심이 되는 서버를 의미합니다.)

Kubeadm

  • 쿠버네티스 클러스터 구축을 위한 기본적인 도구
  • 마스터 노드 생성 및 워커 노드 조인 등 클러스터를 구축하기 위한 기본적인 명령어들을 제공합니다.

Kubectl

  • 구축된 쿠버네티스 클러스터에 대해 명령어를 실행하는 도구
  • 애플리케이션 배포, 클러스터 리소스 검사 및 관리, 로그 조회 등 전반적인 클러스터 관리 작업을 수행하기 위한 명령어들을 제공합니다.

 

쿠버네티스 클러스터를 구성하는 모든 자원에 상기 패키지들을 복제하여 설치를 진행했습니다.

 

 

5. Local Registry 구축

쿠버네티스 클러스터를 구축 시 필요한 Docker image들이 몇가지 있습니다. 온라인 환경에서는 Docker hub와 같은 개방된 레지스트리를 통해 바로 pull 하여 실행 가능하지만 폐쇄망 환경에서는 불가능합니다. 이를 위해 별도의 private registry 구축이 필요하며 이번 설치 과정에서는 podman을 이용한 간단한 Local registry를 구축해보았습니다.

  • docker를 대신하여 podman을 사용한 이유는 docker가 보유한 기본 기능을 제공하면서 docker와는 다르게 데몬을 이용하지 않아 컨테이너들을 훨씬 더 안정적으로 실행할 수 있기 때문입니다. 자세한 내용 참고

 

Podman 설치

1. 이전 cri-o 설치 과정과 동일하게 온라인 환경에서 podman 패키지 및 의존 패키지를 다운로드

 

2. 다운로드 받은 패키지를 모든 마스터 노드에 전송해서 설치

 

3. 설치 상태 확인

master1:~$ sudo systemctl status podman

 

4. insecure 설정

모든 자원에 private registry를 실행시킬 마스터의 ip 주소를 insecure 로 설정하여 http 통신을 가능하게 합니다.

# 설정파일 수정
$ sudo vi /etc/containers/registries.conf
.
.
.
# insecure = true
# # Given the above, a pull of example.com/foo/image:latest will try:
# # 1. example-mirror-0.local/mirror-for-foo/image:latest
# # 2. example-mirror-1.local/mirrors/foo/image:latest
# # 3. internal-registry-for-example.net/bar/image:latest
# # in order, and use the first one that exists.[registries.insecure]
[registries.insecure]
registries = ['10.0.27.199:5000']
# registries = ['[내부IP]:[포트번호]']

...

# cri-o 재시작 
$ systemctl restart crio

 

 

registry 실행

1. 온라인 환경에서 registry 이미지 tar 파일로 저장 후 마스터 노드에 전송

bastion:~$ sudo podman save -o registry.tar docker.io/library/registry:latest

bastion:~$ scp registry.tar ubuntu@10.0.27.199:~/;

 

2. 마스터 노드에서 전송된 이미지를 로드

master1:~$ sudo podman load -i registry.tar

master1:~$ sudo podman images
REPOSITORY                    TAG         IMAGE ID      CREATED        SIZE
docker.io/library/registry    latest      ff1857193a0b  2 months ago   26 MB

 

3. 이미지를 통해 registry 컨테이너 실행

master1:/$ sudo mkdir /registry

master1:/$ sudo podman run -it -d --name registry -p 10.0.27.199:5000:5000 --privileged -v /registry:/var/lib/registry registry
d1c34e4afc5673e86a09ae81985a4ca6f4127bf4e1516fc12c44c9a2cbc40583

master1:/$ sudo podman ps
CONTAINER ID  IMAGE                              COMMAND               CREATED         STATUS             PORTS                       NAMES
d1c34e4afc56  docker.io/library/registry:latest  /etc/docker/regis...  37 seconds ago  Up 37 seconds ago  10.0.27.199:5000->5000/tcp  registry

 

 

쿠버네티스 클러스터 구축 이미지 저장

1. 온라인 환경에서 클러스 구축에 필요한 이미지를 마스터로 전송

 

2. 마스터 노드에 전송된 이미지를 load, tag, push

# 이미지 로드
master1:~$ sudo podman load -i coredns.tgz
Getting image source signatures
...

# registry에 저장시키기 위해 이미지의 registry 주소를 local registry 주소로 변경하여 태그
master1:~$ sudo podman tag registry.k8s.io/coredns/coredns:v1.10.1 10.0.27.105:5000/coredns:v1.10.1
master1:~$ sudo podman images
REPOSITORY                                                     TAG         IMAGE ID      CREATED        SIZE
registry.k8s.io/coredns/coredns                                v1.10.1     ead0a4a53df8  11 months ago  53.6 MB
10.0.27.199:5000/coredns                                       v1.10.1     ead0a4a53df8  11 months ago  53.6 MB
## 'registry.k8s.io/coredns/'을 유지해서 태그해도 문제 없음
##  10.0.27.105:5000/registry.k8s.io/coredns/coredns:v1.10.1

# 태그한 이미지 푸시
master1:~$ sudo podman push 10.0.27.199:5000/coredns:v1.10.1
Getting image source signatures
Copying blob 6a4a177e62f3 done
Copying blob 398c9baff0ce done
Copying config ead0a4a53d done
Writing manifest to image destination
Storing signatures

# registry에 저장된 이미지 확인
master1:~$ curl -X GET 10.0.27.199:5000/v2/_catalog
{"repositories":["coredns"]}


## 나머지 이미지도 동일하게 수행
master1:~$ sudo podman load -i etcd.tgz
...

 

 

마무리

지금까지 offline 환경에서 쿠버네티스를 구축하기 위한 기본적인 세팅 방법에 대해 알아보았습니다.

본 글에서 다루었던 과정들을 마지막으로 요약하면 아래와 같습니다.

 

  • 네트워크 설정 및 swap 해제
  • 컨테이너 런타임 설치
  • 쿠버네티스 기본 패키지 설치
  • Local Registry 구축

 

저는 위 과정을 통해 마스터노드로 옮겨진 이미지를 이용하여 클러스터를 구축을 진행했습니다.

쿠버네티스 클러스터 구축과 관련된 게시글은 조금 더 내용을 보강하여 게시하도록 하겠습니다.

 

참고 자료

'Kubernetes' 카테고리의 다른 글

2024 CKA 자격증 취득 후기  (7) 2024.09.16
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday