Offline 환경에서 K3S 세팅하기

Offline 환경에서 K3S 세팅하기
Offline 환경에 표류된 K3S...

K3S?

많은 서비스에서 컨테이너 기반의 클러스터 구축 도구로 Kubernetes(이하 K8s)를 활용하고 있습니다. 최근 ML분야에서 사용되고 있는 K8s 기반의 MLOps 도구들(e.g. Kubeflow, Seldon Core)이 한 예시입니다.

그러나 Native K8s는 굉장히 무겁기 때문에 작은 규모의 인프라와 서비스에서는 적합하지 않습니다. 조금 더 가벼운 버전의 K8s 도구는 없을까요?

K3S는 사이트의 메인에도 나와 있듯이 "Lightweight Kubernetes"를 지향하는 도구입니다. IoT 서비스나 Edge 장비에서도 구축할 수 있을 정도로 기존 K8s에 비해 가벼운 도구입니다.

쉽고 빠른 K3S 설치, 그러나...

K3S Quick-Start Guide를 참고하면 쉽게 K3S를 설치하여 클러스터를 구축해 볼 수 있습니다. 무려 명령어 한 줄 이면 바로 클러스터가 생성됩니다!

물론, 설치하기 위한 System Requirements는 만족해야합니다.
curl -sfL https://get.k3s.io | sh -
K3s 클러스터 생성
[INFO]  Finding release for channel stable
[INFO]  Using v1.25.4+k3s1 as release
[INFO]  Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.25.4+k3s1/sha256sum-amd64.txt
[INFO]  Downloading binary https://github.com/k3s-io/k3s/releases/download/v1.25.4+k3s1/k3s
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Skipping installation of SELinux RPM
[INFO]  Skipping /usr/local/bin/kubectl symlink to k3s, already exists
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Skipping /usr/local/bin/ctr symlink to k3s, command exists in PATH at /usr/bin/ctr
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s
K3S 설치 결과

그런데 명령어를 보면 문제가 하나 있습니다. 바로 curl 명령어가 쓰이고 있다는 점입니다. curl 을 사용하여 외부 저장소에 있는 install script를 실행시키는 것으로 보이는데, 만약 인터넷이 연결되지 않는 환경이라면 위 명령어로 설치를 할 수 없습니다!

현업에서 서비스를 제공하다 보면 비즈니스 모델에 따라 외부 인터넷에 접속할 수 없고 내부망으로만 구성된 환경에 On-premise 서버나 Edge 장비를 납품해야 될 수도 있습니다.

해결 방법으로 인터넷이 연결되는 환경에서 장비에 K3s 클러스터를 구축하고 현장에 바로 납품하는 방법을 생각할 수 있습니다. 그러나 실제로는 납품 과정에서 네트워크 설정 등 예측할 수 없는 다양한 문제가 발생할 수 있기 때문에 현장에서의 설정이 필수적입니다.

내부망으로만 구성된 환경에서는 K3S를 사용할 수 없는 걸까요?

Offline 환경에서 K3S 구축해보기

K3S 공식문서의 Air-gap Install 이라는 문서에 Offline 환경에서 K3S를 구축할 수 있는 방법을 알려줍니다. 이 포스트에서는 이 문서를 기반으로 Offline 환경에서 K3S를 구축하는 방법과 발생하는 이슈의 해결 방법을 소개하려 합니다.

Air-gap enviornment?
물리적으로 네트워크가 연결되지 않은 상태를 말합니다. 컴퓨터 보안 용어로 사용되고 있으며, 이 포스트에서는 더 이해하기 편한 Offline 환경이라는 용어를 사용하겠습니다.

Prerequisites

이 포스트에서는 Ubuntu OS 장비에서 K3S 클러스터를 구축하려 합니다. 각 버전은 아래와 같습니다.

  • Ubuntu: 20.04.5 LTS
  • K3S: v1.23.6+k3s1

Offline에서 K3S를 구축하기 위해서는 다음과 같은 준비물이 필요합니다. 아직까지는 외부 인터넷에 연결이 필요합니다.

  • K3S binary
  • 원하는 버전의 K3S Image
  • K3S install script: install.sh

K3S binary와 Image는 GitHub의 K3S Release 페이지에서 다운로드 받을 수 있습니다. 다양한 종류의 이미지 중 CPU 사양에 맞게 이미지를 선택합니다. 이 포스트에서는 amd64 이미지를 다운로드 받습니다.

  • k3s
  • k3s-airgap-images-amd64.tar

K3S install script는 링크에서 install.sh 라는 이름으로 다운로드합니다.

위 준비물을 외장 하드에 담아 K3S 클러스터를 구성할 장비에서 사용합니다. 저는 외장 하드에  아래와 같은 디렉토리 구조로 만들어 두었습니다.

.
├── install.sh
└── v1.23.6+k3s1
    ├── k3s
    └── k3s-airgap-images-amd64.tar
준비물의 디렉토리 구조

Install

이제 설치를 시작합니다. 먼저 외장 하드로 옮겨온 binary 파일과 image를 정해진 위치에 옮겨야합니다. bash 명령어로 옮겨봅시다.

cd <외장하드 경로>
sudo mkdir -p /var/lib/rancher/k3s/agent/images/
sudo cp ./v1.23.6+k3s1/k3s-airgap-images-amd64.tar /var/lib/rancher/k3s/agent/images/
sudo cp ./v1.23.6+k3s1/k3s /usr/local/bin/

sudo chmod 755 /usr/local/bin/k3s
binary와 image 이동

설치를 시작하기 전에 한 가지 주의할 점이 있습니다. 설치할 장비가 인터넷이 연결되어 있지 않더라도 반드시 LAN Port가 활성화되어 있어야합니다. K3S 에서 service daemon을 시작하려면 Network Interface Controller (NIC)가 활성화되어 있어야하기 때문입니다. 보통 클러스터를 구축한다면 내부망이라도 연결되어있을 가능성이 높지만, 그렇지 않다면 아무 LAN 선이라도 LAN Port에 연결 한 후 설치를 진행합시다.

install.sh 을 실행하여 설치를 시작합니다. 아래와 같이 명령어를 실행합니다.

export INSTALL_K3S_SKIP_DOWNLOAD=true
sh ./install.sh --docker
K3S install
[DEBUG]  INSTALL_K3S_EXEC=
[DEBUG]  @=--docker
[DEBUG]  Run setup_env()
[DEBUG]  1=--docker
[DEBUG]  @=--docker
[DEBUG]  CMD_K3S_EXEC=server \
	'--docker' \
[DEBUG]  SERVICE_K3S=k3s.service
[DEBUG]  HAS_SYSTEMD=true
[DEBUG]  HAS_OPENRC=
[DEBUG]  Run download_and_verify()
[DEBUG]  BIN_DIR=/usr/local/bin
[DEBUG]  can_skip_download_binary=[DEBUG]  INSTALL_K3S_SKIP_DOWNLOAD=true
[DEBUG]  INSTALL_K3S_SKIP_DOWNLOAD=true
[INFO]  Skipping k3s download and verify
[DEBUG]  package_installer=yum
[DEBUG]  rpm_site=rpm.rancher.io
[DEBUG]  rpm_channel=stable
[DEBUG]  rpm_site_infix=centos/8
[DEBUG]  rpm_target=el8
[DEBUG]  Run can_skip_download_selinux()
[INFO]  Skipping installation of SELinux RPM
[DEBUG]  cmd=
[INFO]  Skipping /usr/local/bin/kubectl symlink to k3s, already exists
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Skipping /usr/local/bin/ctr symlink to k3s, command exists in PATH at /usr/bin/ctr
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s
Install 결과

K3S 실행

설치가 완료되었습니다! 잘 설치되었는지 확인해보기 위해 한번 실행해봅시다.

k3s

NAME:
   k3s - Kubernetes, but small and simple

USAGE:
   k3s [global options] command [command options] [arguments...]

VERSION:
   v1.23.6+k3s1 (418c3fa8)

COMMANDS:
   server           Run management server
   agent            Run node agent
   kubectl          Run kubectl
   crictl           Run crictl
   ctr              Run ctr
   check-config     Run config check
   etcd-snapshot    Trigger an immediate etcd snapshot
   secrets-encrypt  Control secrets encryption and keys rotation
   certificate      Certificates management
   help, h          Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                     (logging) Turn on debug logs [$K3S_DEBUG]
   --data-dir value, -d value  (data) Folder to hold state default /var/lib/rancher/k3s or ${HOME}/.rancher/k3s if not root
   --help, -h                  show help
   --version, -v               print the version
k3s 명령어 실행

다음으로 K3S CLI를 통해 K8s의 명령어인 kubectl 도 실행해봅시다.


k3s kubectl

WARN[0000] Unable to read /etc/rancher/k3s/k3s.yaml, please start server with --write-kubeconfig-mode to modify kube config permissions
kubectl controls the Kubernetes cluster manager.

 Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/

Basic Commands (Beginner):
  create        Create a resource from a file or from stdin
  expose        Take a replication controller, service, deployment or pod and expose it as a new
Kubernetes service
  run           Run a particular image on the cluster
  set           Set specific features on objects

Basic Commands (Intermediate):
  explain       Get documentation for a resource
  get           Display one or many resources
  edit          Edit a resource on the server
  delete        Delete resources by file names, stdin, resources and names, or by resources and
label selector

Deploy Commands:
  rollout       Manage the rollout of a resource
  scale         Set a new size for a deployment, replica set, or replication controller
  autoscale     Auto-scale a deployment, replica set, stateful set, or replication controller

Cluster Management Commands:
  certificate   Modify certificate resources.
  cluster-info  Display cluster information
  top           Display resource (CPU/memory) usage
  cordon        Mark node as unschedulable
  uncordon      Mark node as schedulable
  drain         Drain node in preparation for maintenance
  taint         Update the taints on one or more nodes

Troubleshooting and Debugging Commands:
  describe      Show details of a specific resource or group of resources
  logs          Print the logs for a container in a pod
  attach        Attach to a running container
  exec          Execute a command in a container
  port-forward  Forward one or more local ports to a pod
  proxy         Run a proxy to the Kubernetes API server
  cp            Copy files and directories to and from containers
  auth          Inspect authorization
  debug         Create debugging sessions for troubleshooting workloads and nodes

Advanced Commands:
  diff          Diff the live version against a would-be applied version
  apply         Apply a configuration to a resource by file name or stdin
  patch         Update fields of a resource
  replace       Replace a resource by file name or stdin
  wait          Experimental: Wait for a specific condition on one or many resources
  kustomize     Build a kustomization target from a directory or URL.

Settings Commands:
  label         Update the labels on a resource
  annotate      Update the annotations on a resource
  completion    Output shell completion code for the specified shell (bash, zsh or fish)

Other Commands:
  alpha         Commands for features in alpha
  api-resources Print the supported API resources on the server
  api-versions  Print the supported API versions on the server, in the form of "group/version"
  config        Modify kubeconfig files
  plugin        Provides utilities for interacting with plugins
  version       Print the client and server version information

Usage:
  kubectl [flags] [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).
k3s kubectl 명령어 실행

마치며..

이 포스트에서는 Offline 환경에서 K3S 클러스터를 구축하는 방법에 대해서 알아보았습니다. 클라우드나 SaaS 기반의 서비스 뿐만 아니라 Air-gap 환경에서도 K3S로 구축한 클러스터를 사용해봅시다!