Lightweight Kubernetes
K3s is a highly available, certified Kubernetes distribution designed for production workloads in unattended, resource-constrained, remote locations or inside IoT appliances.
INFORMATION |
k3s 는 sqlite 를 사용하여 경량화를 시켰는데 최근 ETCD 를 적용할 수 있게 되었다. HA (고가용성) 을 위한 옵션 변경이 가능하다는 의미이다. 이 링크를 확인하여 자세히 살펴볼 수 있다. |
Categories
Secret
Volumes
Sidecar
Requirements
K3s는 매우 가볍지만 아래에 설명된 몇 가지 최소 요구 사항이 있습니다.
컨테이너에서 실행되도록 K3를 구성하든 기본 Linux 서비스로 실행하든 관계없이 K3를 실행하는 각 노드는 다음과 같은 최소 요구 사항을 충족해야 합니다.
이러한 요구 사항은 K3 및 해당 패키지 구성 요소의 기준이며 워크로드 자체에서 사용하는 리소스는 포함하지 않습니다.
Prerequisites
두 노드는 동일한 호스트 이름을 가질 수 없습니다.
여러 노드가 동일한 호스트 이름을 가지거나 자동화된 프로비저닝 시스템에서 호스트 이름을 재사용할 수 있는 경우 --with-node-id
옵션을 사용하여 각 노드에 임의의 접미사를 추가하거나,
클러스터에 추가하는 각 노드에 대해 --node-name
또는 $K3S_NODE_NAME
을 사용하여 전달할 고유한 이름을 고안하세요.
방화벽
방화벽 ufw는 꺼라.
Hardware
Spec | Minimum | Recommended |
CPU | 1 core | 2 cores |
RAM | 512 MB | 1 GB |
Networking
모든 노드에서 액세스하려면 k3s 서버에 포트 6443
가 필요.
- 노드는 Flannel VXLAN 백엔드를 사용할 때 UDP 포트
8472
를 통해, - Flannel WireGuard 백엔드를 사용할 때 UDP 포트
51820
(IPv6를 사용하는 경우51821
)을 통해 다른 노드에 연결할 수 있어야 합니다.
노드는 다른 포트에서 수신 대기해서는 안 됩니다.
K3s는 노드가 서버에 대한 아웃바운드 연결을 만들고 모든 kubelet 트래픽이 해당 터널을 통해 실행되도록 역방향 터널링을 사용합니다.
그러나 Flannel을 사용하지 않고 자체 사용자 정의 CNI를 제공하는 경우 Flannel에 필요한 포트는 K3에 필요하지 않습니다.
메트릭 서버를 활용하려면 모든 노드가 포트 10250
에서 서로 액세스할 수 있어야 합니다.
내장된 etcd를 사용하여 고가용성을 달성하려는 경우 서버 노드는 포트 2379
및 2380
에서 서로 액세스할 수 있어야 합니다.
INFORMATION |
노드의 VXLAN 포트는 누구나 액세스할 수 있도록 클러스터 네트워크를 개방하므로 외부에 노출되어서는 안 됩니다. 포트 |
WARNING |
Flannel은 Bridge CNI 플러그인을 사용하여 트래픽을 전환하는 L2 네트워크를 생성합니다. NET_RAW 기능을 갖춘 불량 포드는 해당 L2 네트워크를 악용하여 ARP 스푸핑과 같은 공격을 실행할 수 있습니다. 따라서 Kubernetes 문서에 설명된 대로 신뢰할 수 없는 포드에서 NET_RAW를 비활성화하는 제한된 프로필을 설정하십시오. |
Inbound Rules for K3s Nodes
Protocol | Port | Source | Destination | Description | 기본 옵션에서 필요 |
TCP | 2379-2380 | Servers | Servers | Required only for HA with embedded etcd | X |
TCP | 6443 | Agents | Servers | K3s supervisor and Kubernetes API Server | O |
UDP | 8472 | All nodes | All nodes | Required only for Flannel VXLAN | O |
TCP | 10250 | All nodes | All nodes | Kubelet metrics | [Optional] |
UDP | 51820 | All nodes | All nodes | Required only for Flannel Wireguard with IPv4 | X |
UDP | 51821 | All nodes | All nodes | Required only for Flannel Wireguard with IPv6 | X |
TCP | 5001 | All nodes | All nodes | Required only for embedded distributed registry (Spegel) | X |
TCP | 6443 | All nodes | All nodes | Required only for embedded distributed registry (Spegel) | X |
일반적으로 모든 아웃바운드 트래픽이 허용됩니다.
사용하는 OS에 따라 방화벽에 대한 추가 변경이 필요할 수 있습니다.
Requirements: Large Clusters
하드웨어 요구 사항은 K3s 클러스터의 크기에 따라 다릅니다. 프로덕션 및 대규모 클러스터의 경우 외부 데이터베이스와 함께 고가용성 설정을 사용하는 것이 좋습니다. 프로덕션 환경의 외부 데이터베이스에는 다음 옵션이 권장됩니다.
CPU and Memory
다음은 고가용성 K3s 서버 노드의 최소 CPU 및 메모리 요구 사항입니다.
Deployment Size | Nodes | VCPUS | RAM |
Small | Up to 10 | 2 | 4 GB |
Medium | Up to 100 | 4 | 8 GB |
Large | Up to 250 | 8 | 16 GB |
X-Large | Up to 500 | 16 | 32 GB |
XX-Large | 500+ | 32 | 64 GB |
Disk
클러스터 성능은 데이터베이스 성능에 따라 달라집니다. 최적의 속도를 보장하려면 항상 SSD 디스크를 사용하여 K3s 클러스터를 백업하는 것이 좋습니다. 클라우드 공급자에서는 최대 IOPS를 허용하는 최소 크기를 사용하는 것이 좋습니다.
Network
Pod의 IP가 부족해지지 않도록 클러스터 CIDR의 서브넷 크기를 늘리는 것을 고려해야 합니다. 시작 시 --cluster-cidr
옵션을 K3s 서버에 전달하면 됩니다.
Database
K3s는 MySQL, PostgreSQL, MariaDB 및 etcd를 포함한 다양한 데이터베이스를 지원합니다. 자세한 내용은 클러스터 데이터 저장소를 참조하세요.
다음은 대규모 클러스터를 실행하는 데 필요한 데이터베이스 리소스의 크기 조정 가이드입니다.
Deployment Size | Nodes | VCPUS | RAM |
Small | Up to 10 | 1 | 2 GB |
Medium | Up to 100 | 2 | 8 GB |
Large | Up to 250 | 4 | 16 GB |
X-Large | Up to 500 | 8 | 32 GB |
XX-Large | 500+ | 16 | 64 GB |
Installation
# 기본 설치
curl -sfL https://get.k3s.io | sh -
# 권한 설치
curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
이 설치를 실행한 후 다음을 수행합니다.
- 노드가 재부팅되거나 프로세스가 충돌 또는 중지된 경우 K3s 서비스가 자동으로 다시 시작되도록 구성됩니다.
- kubectl, crictl, ctr,
k3s-killall.sh
,k3s-uninstall.sh
등 추가 유틸리티가 설치될 예정입니다. - kubeconfig 파일이
/etc/rancher/k3s/k3s.yaml
에 기록되고 K3s에 의해 설치된 kubectl이 자동으로 사용합니다.
서비스는 k3s server ...
로 실행된다.
- 서비스 파일
/etc/systemd/system/k3s.service
- 환경변수 파일
/etc/systemd/system/k3s.service.env
작업자 노드로 설치
- Add new worker node on an existing k3s cluster
- Unable to setup cluster with 1 server and 1 agent · Issue #4839 · k3s-io/k3s
작업자 노드에 설치하고 클러스터에 추가하려면 K3S_URL
및 K3S_TOKEN
환경 변수를 사용하여 설치 스크립트를 실행하십시오. 다음은 작업자 노드에 가입하는 방법을 보여주는 예입니다.
WARNING |
설치시 |
파라미터를 설정하면 K3s가 worker 모드로 실행됩니다. (서비스는 k3s agent ...
로 실행된다.)
K3s 에이전트는 제공된 URL에서 수신 대기 중인 K3s 서버에 등록됩니다.
K3S_TOKEN
에 사용할 값은 서버 노드의 /var/lib/rancher/k3s/server/node-token
에 저장됩니다.
INFORMATION |
컴퓨터마다 고유한 호스트 이름이 있어야 합니다. 시스템에 고유한 호스트 이름이 없으면 |
- 서비스 파일
/etc/systemd/system/k3s-agent.service
- 환경변수 파일
/etc/systemd/system/k3s-agent.service.env
- 설치제거 파일은
/usr/local/bin/k3s-agent-uninstall.sh
에 저장된다.
마스터 노드에서 kubectl get nodes
명령을 치면 다음과 같이 추가된 노드를 확인할 수 있다:
NAME STATUS ROLES AGE VERSION
api-your-run Ready control-plane,master 11m v1.29.4+k3s1
answerver Ready <none> 13s v1.29.4+k3s1
High Availability Embedded etcd
이 모드에서 K3를 실행하려면 홀수의 서버 노드가 있어야 합니다. 세 개의 노드로 시작하는 것이 좋습니다.
시작하려면 먼저 클러스터링을 활성화하는 --cluster-init
플래그와 클러스터에 추가 서버를 연결하기 위한 공유 비밀로 사용될 토큰을 사용하여 서버 노드를 시작합니다.
- Network related flags:
--cluster-dns
,--cluster-domain
,--cluster-cidr
,--service-cidr
- Flags controlling the deployment of certain components:
--disable-helm-controller
,--disable-kube-proxy
,--disable-network-policy
and any component passed to--disable
- Feature related flags:
--secrets-encryption
나의 경우
Blackhole#k3s 항목 참조.
Configuration Options
에이전트 노드 등록 작동 방식
에이전트 노드는 k3s agent 프로세스에 의해 시작된 웹소켓 연결로 등록되며, 에이전트 프로세스의 일부로 실행되는 클라이언트 측 로드밸런서에 의해 연결이 유지됩니다. 이 로드 밸런서는 클러스터의 모든 서버에 대한 안정적인 연결을 유지하여 개별 서버의 중단을 허용하는 에이전시 서버에 대한 연결을 제공합니다.
에이전트는 노드 클러스터 시크릿과 노드에 대해 무작위로 생성된 비밀번호를 사용하여 서버에 등록하며, 이 비밀번호는 /etc/rancher/node/password
에 저장됩니다. 서버는 개별 노드의 비밀번호를 쿠버네티스 시크릿으로 저장하며, 이후 모든 시도는 동일한 비밀번호를 사용해야 합니다. 노드 패스워드 시크릿은 <host>.node-password.k3s
템플릿을 사용하는 이름으로 kube-system
네임스페이스에 저장됩니다. 이는 노드 ID의 무결성을 보호하기 위해 수행됩니다.
에이전트의 /etc/rancher/node
디렉터리가 제거되거나 기존 이름을 사용하여 노드에 다시 가입하려는 경우, 클러스터에서 노드를 삭제해야 합니다. 이렇게 하면 이전 노드 항목과 노드 비밀번호 시크릿이 모두 정리되고 노드가 클러스터에 (재)조인할 수 있습니다. 비고
INFORMATION |
K3s v1.20.2 이전 서버는 |
호스트 이름을 자주 재사용하지만 노드 암호 시크릿을 제거할 수 없는 경우, --with-node-id
플래그를 사용하여 K3s 서버 또는 에이전트를 시작하면 호스트 이름에 고유 노드 ID를 자동으로 추가할 수 있습니다. 활성화하면 노드 ID는 /etc/rancher/node/
에도 저장됩니다.
Features
K3s는 다음과 같은 향상된 기능을 갖춘 완전히 호환되는 Kubernetes 배포판입니다.
- 단일 바이너리로 패키징됩니다.
- 기본 스토리지 메커니즘으로 sqlite3를 기반으로 하는 경량 스토리지 백엔드. etcd3, MySQL, Postgres도 사용할 수 있습니다.
- TLS 및 옵션의 많은 복잡성을 처리하는 간단한 시작 프로그램에 포함되어 있습니다.
- 경량 환경을 위한 합리적인 기본값으로 기본적으로 보호됩니다.
- 다음과 같이 단순하지만 강력한 "배터리 포함" 기능이 추가되었습니다.
기본 설치 패키지
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
- completion - Install shell completion script
- help - Shows a list of commands or help for one command
Remove
Cluster Datastore
K3s에서는 두가지 타입이 존재합니다.
- control plane을 포함하고있는 K3s server
- control plane 없이 worker node 역할만하는 K3s agent 가 있습니다.
K3s_architecture.png
K3s 클러스터를구성하는 방법에는 3가지 방법이 존재합니다.
- #Embedded DB를 이용한 Single K3s server 구성
- #Embedded DB를 이용한 Multiple K3s server 구성
- #External DB를 이용한 Multiple K3s server 구성
Embedded DB를 이용한 Single K3s server 구성
아래 그림은 하나의 K3s server를 이용해서 클러스터를 구성하는 방법입니다.
control plane은 하나의 single node만 동작하고 K3s agent(worker)들을 구성하는 방법입니다.
유저는 오로지 K3s server 하나의 엔드포인트만을 이용하여 클러스터에 접근할 수 있게 됩니다.
K3s_Embedded_DB_Single_K3s_server.png
누구든 예상하기 쉽게, Single로 Control plane을 구성하면, 고가용성에 큰 문제가 있습니다.
K3s server가 죽게된다면 해당 클러스터에 접근을 할 수 없고 관리가 되지 않기때문에 pod scheduling과 같은 동작들이 멈추게 될 것입니다.
이를 해결하기 위해서는 당연히 Multiple K3s server를 구성함으로써 문제를 해결 할 수 있습니다.
Multiple K3s server를 구성하는데는 내부 Embedded DB를 이용하는 구성과, K3s만의 특별한 외부 DB를 이용한 구성 둘 다 가능합니다.
Embedded DB를 이용한 Multiple K3s server 구성
앞서 서술한 문제들을 해결하기 위해서 Multiple K3s server를 구성할 수 있는데, 먼저 Embedded db를 이용한 구성에 대해 설명하고자 합니다.
클러스터를 구성하기 위해선 기본적으로 3개 이상의 홀수 대수의 서버로 구성을 해야합니다. 해당 서버들은 control plane과 Kubernetes API Server를 제공합니다.
Embedded DB 방식은 Single node에서는 sqlite를 이용하지만, multiple node에서는 etcd를 사용합니다.
K3s_Embedded_DB_Multiple_K3s_server.png
External DB를 이용한 Multiple K3s server 구성
Embedded DB구성과 다르게 external DB를 이용하면 K3s server 외부에 존재하는 DB를 이용하여 cluster를 구성합니다.
MySQL, PostgreSQL, 외부 etcd를 이용할 수 있습니다.
K3s_External_DB_Multiple_K3s_server.png
설치된 상태 확인
클러스터 상태 확인
kubectl을 사용하여 확인. (kubectl은 k3s 설치 시 사용 가능)
외부에서 kubectl로 클러스터에 접근하기
/etc/rancher/k3s/k3s.yaml
파일을 클러스터 외부에 위치한 머신의 ~/.kube/config
로 복사합니다.
그런 다음 server 필드의 값을 K3s 서버의 IP 또는 이름으로 바꿉니다. 이제 kubectl이 K3s 클러스터를 관리할 수 있습니다.
클러스터 접근
Kubectl#클러스터 접근 항목 참조.
로컬환경에서 쿠버네티스 원격 접속
# 클러스터의 인증서 및 사용자 비밀번호 등 인증하는데 필요한 정보
cat /etc/rancher/k3s/k3s.yaml
# 해당 내용을 복사하여 로컬 ~/.kube/<클러스터 이름>로 붙여넣기
# 단, name 및 ip 주소를 해당 서버의 고정 ip로 변경할 것!
# 환경변수 설정
export KUBECONFIG=$HOME/.kube/config-k3s:$HOME/.kube/config:$KUBECONFIG
# 변경한 config 적용
kubectl config use-context <name>
도커 로그인
기존의 도커 자격 증명을 기반으로 시크릿 생성하기
kubectl create secret generic regcred \
--from-file=.dockerconfigjson=/home/ubuntu/.docker/config.json \
--type=kubernetes.io/dockerconfigjson
시크릿을 사용하는 파드 생성하기
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: <your-private-image>
imagePullSecrets:
- name: regcred
NVIDIA 컨테이너 런타임 지원
K3s는 K3s 시작 시 NVIDIA 컨테이너 런타임이 있으면 자동으로 감지하여 설정합니다.
- 아래의 안내에 따라 노드에 엔비디아 컨테이너 패키지 리포지토리를 설치합니다: https://nvidia.github.io/libnvidia-container/
- 엔비디아 컨테이너 런타임 패키지를 설치합니다. 예시:
apt install -y nvidia-container-runtime cuda-drivers-fabricmanager-515 nvidia-headless-515-server
- K3s를 설치하거나 이미 설치되어 있는 경우 다시 시작합니다:
curl -ksL get.k3s.io | sh -
- k3s가 엔비디아 컨테이너 런타임을 찾았는지 확인합니다:
grep nvidia /var/lib/rancher/k3s/agent/etc/containerd/config.toml
이렇게 하면 발견된 런타임 실행 파일에 따라 컨테이너 설정에 nvidia
및/또는 nvidia-experimental
런타임이 자동으로 추가됩니다.
여전히 클러스터에 런타임클래스 정의를 추가하고, 파드 스펙에서 runtimeClassName: nvidia
를 설정하여 적절한 런타임을 명시적으로 요청하는 파드를 배포해야 합니다:
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: nvidia
handler: nvidia
---
apiVersion: v1
kind: Pod
metadata:
name: nbody-gpu-benchmark
namespace: default
spec:
restartPolicy: OnFailure
runtimeClassName: nvidia
containers:
- name: cuda-container
image: nvcr.io/nvidia/k8s/cuda-sample:nbody
args: ["nbody", "-gpu", "-benchmark"]
resources:
limits:
nvidia.com/gpu: 1
env:
- name: NVIDIA_VISIBLE_DEVICES
value: all
- name: NVIDIA_DRIVER_CAPABILITIES
value: all
엔비디아 컨테이너 런타임은 엔비디아 디바이스 플러그인 및 GPU 기능 검색과 함께 자주 사용되며, 위에서 언급한 것처럼 파드 사양에 runtimeClassName: nvidia
가 포함되도록 수정하여 별도로 설치해야 한다는 점에 유의하세요.
containerd에서 gpu가 정상적으로 인식되는지 확인한다.
sudo ctr image pull docker.io/nvidia/cuda:11.0.3-base-ubuntu20.04
sudo ctr run --rm -t \
--runc-binary=/usr/bin/nvidia-container-runtime \
--env NVIDIA_VISIBLE_DEVICES=all \
docker.io/nvidia/cuda:11.0.3-base-ubuntu20.04 \
cuda-11.0.3-base-ubuntu20.04 nvidia-smi
k3s로 HTTPS 웹 서비스 돌리기
- k3s로 싱글 노드 쿠버네티스 구축해보기 - k3s로 싱글 노드 쿠버네티스 구축하고 Traefik으로 포트 오픈 및 배포
- k3s 시리즈 - Kubernetes에서 쉽게 HTTPS 웹 서비스 돌리기 | si.mpli.st
- HTTPS using Letsencrypt and Traefik with k3s
다음 내용을 알아야 한다:
Tutorial
Kubernetes:Basic 을 참고하여 차근차근 해보자.
Single Node
- K3s single-node cluster for noobs | Logan Marchione
- Single Node Cluster Kubernetes 구축(K3S Server 설치)
Swap 메모리 지원 여부
K3s는 항상 스왑을 지원해 왔습니다. 다만 누군가는 kubelet에서 문제가 된듯?
curl -sL get.k3s.io | sh -s - server --kubelet-arg=feature-gates=NodeSwap=true,CloudDualStackNodeIPs=true
Troubleshooting
tls: failed to verify certificate
Kubectl#tls: failed to verify certificate 항목 참조.
k3s 에서는 서버의 서비스 파일(/etc/systemd/system/k3s.service
)에 ExeStart 에 --tls-san api.your.run
과 같이 도메인을 추가하자:
참고로 플래그 명에 붙은 --tls-san
는 아래와 같은 약자이다. (스캔(SCAN) 이 아니다 스캔이)
- TLS - 전송 계층 보안 (Transport Layer Security)
- SAN - 주체 대체 이름 (Subject Alternative Name)
Agent 노드 설치 실패
journalctl -u k3s
으로 확인했을 때 다음과 같은 에러가 발생된다면:
Dec 25 18:11:38 ocvm-a1-1 k3s[8221]: time="2021-12-25T18:11:38Z" level=error msg="unable to verify hash for node 'ocvm-a1-2': hash does not match"
에이전트 등록시 사용된 비밀번호를 제거해보자:
자세한 내용은 #에이전트 노드 등록 작동 방식 항목 참조.
Waiting to retrieve kube-proxy configuration; server is not ready: failed to get CA certs: Get https://127.0.0.1:6444/cacerts
k3s agent 등록이 실패했을 때 journalctl -u k3s
으로 다음과 같은 에러 확인:
May 23 16:17:51 server k3s[2139]: time="2024-05-23T16:17:51+09:00" level=info msg="Waiting to retrieve kube-proxy configuration; server is not ready: failed to get CA certs: Get \"https://127.0.0.1:6444/cacerts\": EOF"
...
서버가 살아있는지 확인해 보고자 sudo netstat -l -n -p -t | grep 6444
를 날림:
살아있네... curl -v -k
https://127.0.0.1:6444/
로 HTTP 접속 확인:
* Trying 127.0.0.1:6444...
* Connected to 127.0.0.1 (127.0.0.1) port 6444 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.0 (OUT), TLS header, Unknown (21):
* TLSv1.3 (OUT), TLS alert, decode error (562):
* error:0A000126:SSL routines::unexpected eof while reading
* Closing connection 0
curl: (35) error:0A000126:SSL routines::unexpected eof while reading
OpenSSL#error:0A000126:SSL routines::unexpected eof while reading 항목 확인.
Ubuntu 22.04 가 문제인가? ... Ubuntu 20.04 로 다운시켜서 확인해보자.
See also
Favorite site
Beginner's guide
- (Kubernetes) k3s를 이용해 multi node 쿠버네티스 클러스터 구축하기
- [추천] k3s 시리즈 - 간단하게 Kubernetes 환경 구축하기 | si.mpli.st
- k3s로 싱글 노드 쿠버네티스 구축해보기
- k3s 시리즈 - Kubernetes에서 쉽게 HTTPS 웹 서비스 돌리기 | si.mpli.st
Guide
- Local Kubernetes Cluster - Byungchan's Blog - Multipass와 K3S를 이용한 Kubernetes Cluster 구축
- (Kubernetes) k3s를 이용해 single node 쿠버네티스 클러스터 구축하기