Overview
오늘은 경량화된 Kubernetes 배포판인 K3s에 대해 알아보려고 한다.
K3s란?
K3s는 경량화된 Kubernetes 배포판으로, 특히 리소스가 제한된 환경이나 엣지 컴퓨팅 환경에서 사용하기 적합하게 설계되었다.
Rancher Labs에 의해 개발되었으며, Kubernetes의 기능을 완전히 지원하면서도 훨씬 작은 용량과 간소화된 설치 과정을 제공한다. K3s가 필수적인 기능만을 포함하고, 선택적인 부분은 제거하거나 가볍게 만들어진 결과이다.
예를 들어, 기본적으로 SQLite를 내장 데이터베이스로 사용하여, 별도의 etcd 클러스터 구성 없이도 작동할 수 있다.
ARM64 및 ARMv7 아키텍처를 지원하며, 이는 IoT 디바이스와 같은 ARM 기반 시스템에서의 사용을 가능하게 한다. 또한, 단일 바이너리로 제공되며, 이는 설치 및 운영을 매우 간단하게 만들어 준다. 단일 명령으로 설치가 가능하며, 필요한 모든 Kubernetes 구성 요소가 포함되어 있다.
표준 Kubernetes API를 제공하기 때문에, Kubernetes와 동일한 방식으로 애플리케이션을 배포하고 관리할 수 있다. 이는 기존 Kubernetes 사용자에게 친숙한 환경을 제공하며, Kubernetes 생태계의 툴과 플러그인을 K3s와 함께 사용할 수 있게 한다.
K3s는 특히 소규모 클러스터나 개발 환경, 제한된 리소스를 가진 환경에서의 Kubernetes 사용을 단순화하고자 하는 사용자에게 매력적인 선택이다.
K3s 설치를 위한 GCE(Google Compute Engine) 생성
Control Node 1대와 Worker Node 1대씩 총 2대의 VM을 생성한다.
OS는 `ubuntu-2004-lts` 이다.
Control Node
## test_server ##
resource "google_compute_address" "test_server_ip" {
name = var.test_server_ip
}
resource "google_compute_instance" "test_server" {
name = var.test_server
machine_type = "n2-standard-2"
labels = local.default_labels
zone = "${var.region}-a"
allow_stopping_for_update = true
tags = [var.kubernetes_server, var.kubernetes_client]
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2004-lts"
size = 10
}
}
metadata = {
ssh-keys = "somaz:${file("~/.ssh/id_rsa_somaz94.pub")}"
}
network_interface {
network = var.shared_vpc
subnetwork = "${var.subnet_share}-mgmt-a"
access_config {
## Include this section to give the VM an external ip ##
nat_ip = google_compute_address.test_server_ip.address
}
}
depends_on = [google_compute_address.test_server_ip]
}
# test
variable "test_server" {}
variable "test_server_ip" {}
variable "kubernetes_server" {}
variable "kubernetes_client" {}
test_server = "test-server"
test_server_ip = "test-server-ip"
kubernetes_server = "kubernetes-server"
kubernetes_client = "kubernetes-client"
Worker Node
## test_server_agent ##
resource "google_compute_address" "test_server_agent_ip" {
name = var.test_server_agent_ip
}
resource "google_compute_instance" "test_server_agent" {
name = var.test_server_agent
machine_type = "n2-standard-2"
labels = local.default_labels
zone = "${var.region}-a"
allow_stopping_for_update = true
tags = [var.kubernetes_server, var.kubernetes_client]
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2004-lts"
size = 10
}
}
metadata = {
ssh-keys = "somaz:${file("~/.ssh/id_rsa_somaz94.pub")}"
}
network_interface {
network = var.shared_vpc
subnetwork = "${var.subnet_share}-mgmt-a"
access_config {
## Include this section to give the VM an external ip ##
nat_ip = google_compute_address.test_server_agent_ip.address
}
}
depends_on = [google_compute_address.test_server_agent_ip]
}
# test_agent
variable "test_server_agent" {}
variable "test_server_agent_ip" {}
test_server_agent = "test-server-agent"
test_server_agent_ip = "test-server-agent-ip"
VM 생성 완료
K3s 설치
Control Node를 설치한 후에 Work Node 조인을 진행해준다.
Control Node 설치
명령어 한줄로 간단하게 설치가 가능하다.
curl -sfL <https://get.k3s.io> | sh -
[INFO] Finding release for channel stable
[INFO] Using v1.28.5+k3s1 as release
[INFO] Downloading hash <https://github.com/k3s-io/k3s/releases/download/v1.28.5+k3s1/sha256sum-amd64.txt>
[INFO] Downloading binary <https://github.com/k3s-io/k3s/releases/download/v1.28.5+k3s1/k3s>
[INFO] Verifying binary download
[INFO] Installing k3s to /usr/local/bin/k3s
[INFO] Skipping installation of SELinux RPM
[INFO] Creating /usr/local/bin/kubectl symlink to k3s
[INFO] Creating /usr/local/bin/crictl symlink to k3s
[INFO] Creating /usr/local/bin/ctr symlink to k3s
[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
상태를 확인해본다.
# service 상태 확인
service k3s status
● k3s.service - Lightweight Kubernetes
Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-11-06 02:03:16 UTC; 27s ago
Docs: <https://k3s.io>
Process: 1705 ExecStartPre=/bin/sh -xc ! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service (code=exited, status=0/SUCCESS)
Process: 1707 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
Process: 1710 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 1711 (k3s-server)
Tasks: 95
Memory: 1.0G
CGroup: /system.slice/k3s.service
├─1711 /usr/local/bin/k3s server
├─1729 containerd
├─2333 /var/lib/rancher/k3s/data/e82313669fe2739df53b3870076163d1fe7785336a68b4771685219e51c9785d/bin/containerd-shim-runc-v2 -namespace k8s.io -id 85663aeeb9166f3bb70889b598>
├─2341 /var/lib/rancher/k3s/data/e82313669fe2739df53b3870076163d1fe7785336a68b4771685219e51c9785d/bin/containerd-shim-runc-v2 -namespace k8s.io -id 4c19c8abd9ec834c423ddd4971>
├─2360 /var/lib/rancher/k3s/data/e82313669fe2739df53b3870076163d1fe7785336a68b4771685219e51c9785d/bin/containerd-shim-runc-v2 -namespace k8s.io -id 2933071c52aafac8e47c162310>
├─2378 /var/lib/rancher/k3s/data/e82313669fe2739df53b3870076163d1fe7785336a68b4771685219e51c9785d/bin/containerd-shim-runc-v2 -namespace k8s.io -id f2ec82b89471879636bee64bb6>
├─2379 /var/lib/rancher/k3s/data/e82313669fe2739df53b3870076163d1fe7785336a68b4771685219e51c9785d/bin/containerd-shim-runc-v2 -namespace k8s.io -id bbcd89004e03da6341c9486122>
└─2780 /var/lib/rancher/k3s/data/e82313669fe2739df53b3870076163d1fe7785336a68b4771685219e51c9785d/bin/unpigz -d -c
# cluster-info 확인
kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/https:metrics-server:https/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
`~/.bashrc` 설정
# kubectl
source <(kubectl completion bash)
alias k=kubectl
complete -F __start_kubectl k
# bashrc 적용
source ~/.bashrc
- kubectl 자동완성과 alias 설정이다.
`sudo` 제거
sudo kubectl get nodes
NAME STATUS ROLES AGE VERSION
test-server Ready control-plane,master 62s v1.27.7+k3s1
sudo chmod +r /etc/rancher/k3s/k3s.yaml
k get nodes
NAME STATUS ROLES AGE VERSION
test-server Ready control-plane,master 4m v1.27.7+k3s1
설치가 완료 되었으니 간단한 디플로이먼트를 배포해본다.
kubectl apply -f - <<EOT
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
EOT
deployment.apps/nginx-deployment created
배포한 디플로이트를 확인해본다.
kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-deployment-57d84f57dc-vb26g 1/1 Running 0 20s 10.42.0.9 test-server <none> <none>
pod/nginx-deployment-57d84f57dc-xwkfk 1/1 Running 0 20s 10.42.0.11 test-server <none> <none>
pod/nginx-deployment-57d84f57dc-w5bdg 1/1 Running 0 20s 10.42.0.10 test-server <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 29m <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/nginx-deployment 3/3 3 3 20s nginx nginx:latest app=nginx
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/nginx-deployment-57d84f57dc 3 3 3 20s nginx nginx:latest app=nginx,pod-template-hash=57d84f57dc
curl 테스트를 진행해본다.
curl 10.42.0.9
curl 10.42.0.9
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Auto Healing 테스트를 해본다.
k delete po nginx-deployment-57d84f57dc-vb26g
pod "nginx-deployment-57d84f57dc-vb26g" deleted
kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-deployment-57d84f57dc-xwkfk 1/1 Running 0 105s 10.42.0.11 test-server <none> <none>
pod/nginx-deployment-57d84f57dc-w5bdg 1/1 Running 0 105s 10.42.0.10 test-server <none> <none>
pod/nginx-deployment-57d84f57dc-5k4n2 1/1 Running 0 11s 10.42.0.12 test-server <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 30m <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/nginx-deployment 3/3 3 3 105s nginx nginx:latest app=nginx
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/nginx-deployment-57d84f57dc 3 3 3 105s nginx nginx:latest app=nginx,pod-template-hash=57d84f57dc
리소스를 삭제해준다.
k delete deploy nginx-deployment
Worker Node 설치
Control Node에서 token을 확인한다.
# Control Node
sudo cat /var/lib/rancher/k3s/server/node-token
K104dc7b746049cae8546d7d70086267166ca68ac8df373c581c63663e1d10aa87e::server:1b17f371f468c07ac90685f7e16f78cb
Worker Node에서 변수를 설정한다.
# Worker Node
export K3S_TOKEN=K104dc7b746049cae8546d7d70086267166ca68ac8df373c581c63663e1d10aa87e::server:1b17f371f468c07ac90685f7e16f78cb
export K3S_URL=https://10.77.101.40:6443 # Master Node IP
Worker Node 조인을 진행한다.
# Worker Node
curl -sfL <https://get.k3s.io> | sh -
[INFO] Finding release for channel stable
[INFO] Using v1.28.5+k3s1 as release
[INFO] Downloading hash <https://github.com/k3s-io/k3s/releases/download/v1.28.5+k3s1/sha256sum-amd64.txt>
[INFO] Downloading binary <https://github.com/k3s-io/k3s/releases/download/v1.28.5+k3s1/k3s>
[INFO] Verifying binary download
[INFO] Installing k3s to /usr/local/bin/k3s
[INFO] Skipping installation of SELinux RPM
[INFO] Creating /usr/local/bin/kubectl symlink to k3s
[INFO] Creating /usr/local/bin/crictl symlink to k3s
[INFO] Creating /usr/local/bin/ctr symlink to k3s
[INFO] Creating killall script /usr/local/bin/k3s-killall.sh
[INFO] Creating uninstall script /usr/local/bin/k3s-agent-uninstall.sh
[INFO] env: Creating environment file /etc/systemd/system/k3s-agent.service.env
[INFO] systemd: Creating service file /etc/systemd/system/k3s-agent.service
[INFO] systemd: Enabling k3s-agent unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s-agent.service → /etc/systemd/system/k3s-agent.service.
[INFO] systemd: Starting k3s-agent
Worker Node 조인을 확인한다.
# Worker Node
k get nodes
NAME STATUS ROLES AGE VERSION
test-server Ready control-plane,master 41m v1.27.7+k3s1
test-server-agent Ready <none> 46s v1.27.7+k3s1
K3s 삭제
# Control Node에서 k3s 삭제
/usr/local/bin/k3s-uninstall.sh
# Worker Node에서 k3s 삭제
/usr/local/bin/k3s-agent-uninstall.sh
k3sup 이란?
k3sup은 OpenFaaS ® 및 인렛 의 창립자 인 Alex Ellis 가 만들었다. ketchup 이라고 불려진다.
k3sup은 로컬 또는 원격 VM에서 k3를 사용하여 0에서KUBECONFIG로 이동하는 경량 유틸리티이다.
필요한 것은 ssh액세스 권한과 즉시 액세스 k3sup할 수 있는 바이너리뿐이다.
Go로 작성되었으며 Linux, Windows, MacOS 및 Raspberry Pi용으로 크로스 컴파일되었다.
k3sup 을 이용하면 좀더 쉽게 k3s 를 설치할 수 있다.
토큰을 획득 하거나 IP 를 찾는 등의 과정을 생략할 수 있기 때문이다.
VM은 동일한 방법으로 생성하였고 IP는 다음과 같다.
# Control Node
Public IP : 34.64.58.187 / Private IP : 10.77.101.53
# Worker Node
Public IP : 34.22.89.209 / Private IP : 10.77.101.38
k3sup 설치
동일하게 Control Node 설치 후 Worker Node를 조인해준다.
k3sup 다운로드
curl -sLS <https://get.k3sup.dev> | sh
sudo install k3sup /usr/local/bin/
Control Node에 K3s 설치
`$MASTER_IP` 만으로 설치가 가능하다.
export MASTER_IP=10.77.101.53
export CONTEXT=somaz-k3s
# error
k3sup install --ip $MASTER_IP --context $CONTEXT --user somaz
Running: k3sup install
2024/01/05 02:41:36 10.77.101.53
Public IP: 10.77.101.53
Error: unable to load the ssh key with path "/home/somaz/.ssh/id_rsa": unable to read file: /home/somaz/.ssh/id_rsa, open /home/somaz/.ssh/id_rsa: no such file or directory
# solution1
ssh-keygen
# error2
k3sup install --ip $MASTER_IP --context $CONTEXT --user somaz
Running: k3sup install
2024/01/05 02:36:00 10.77.101.53
Public IP: 10.77.101.53
Error: unable to connect to 34.22.89.209:22 over ssh: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
# solution2
rm -rf ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
에러가 해결되지 않는다? 그 이유는 다음과 같다.
GCE를 생성해서 Compute Engine 생성을 진행했다.
따라서 GCE를 생성한 Terraform 파일을 보면 로컬의 Public Key를 가지고 있다.
로컬에서 SSH를 통해, GCE에서 접속을 하기 위함이다.
## test_server ##
resource "google_compute_address" "test_server_ip" {
name = var.test_server_ip
}
resource "google_compute_instance" "test_server" {
name = var.test_server
machine_type = "n2-standard-2"
labels = local.default_labels
zone = "${var.region}-a"
allow_stopping_for_update = true
tags = [var.kubernetes_server, var.kubernetes_client]
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2004-lts"
size = 10
}
}
# 해당 부분에 보면 User를 somaz로 지정하였고 local의 pub키를 전달해주었다.
metadata = {
ssh-keys = "somaz:${file("~/.ssh/id_rsa_somaz94.pub")}"
}
...
}
따라서 k3sup을 진행하려면 로컬 Private Key도 GCE에 복사해 줘야 한다.
somaz@test-server:~/.ssh$ ls
# authorized_keys가 pub 키이다. 따라서 id_rsa 파일을 만들어주었고 private key를 저장해주었다.
authorized_keys id_rsa
다시 설치를 진행해준다. 성공적으로 설치가 된 모습이다.
k3sup install --ip $MASTER_IP --context $CONTEXT --user somaz
Running: k3sup install
2024/01/05 02:53:33 10.77.101.53
Public IP: 10.77.101.53
...
Saving file to: /home/somaz/kubeconfig
# Test your cluster with:
export KUBECONFIG=/home/somaz/kubeconfig
kubectl config use-context default
kubectl get node -o wide
🚀 Speed up GitHub Actions/GitLab CI + reduce costs: <https://actuated.dev>
조회해본다.
sudo kubectl get nodes
NAME STATUS ROLES AGE VERSION
test-server Ready control-plane,master 9m59s v1.28.5+k3s1
k3s 의 컨텍스트를 로컬의 $HOME/.kube/config 에 다운로드 할 수 있다.
- 주의할점은 CSP(ex. AWS,GCP,Azure) 사용시 Public IP를 지정해줘야 한다.
# 로컬 PC에 k3s 다운로드
curl -sLS <https://get.k3sup.dev> | sh
sudo install k3sup /usr/local/bin/
export MASTER_IP=34.64.58.187
export USER=somaz
export CONTEXT=somaz-k3s
k3sup install \\
--ip $MASTER_IP \\
--user $USER \\
--merge \\
--local-path $HOME/.kube/config \\
--context $CONTEXT \\
--ssh-key $HOME/.ssh/id_rsa_somaz94
- 명령을 실행하면 로컬의 `$HOME/.kube/config`에 병합해서 파일을 생성한다.
아래와 같이 Config를 사용해서 조회가 가능하다.
# 조회
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@cluster.local cluster.local kubernetes-admin
somaz-k3s somaz-k3s somaz-k3s
# 변경
kubectl config use-context somaz-k3s
Switched to context "somaz-k3s".
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
kubernetes-admin@cluster.local cluster.local kubernetes-admin
* somaz-k3s somaz-k3s somaz-k3s
# 삭제
k config delete-context somaz-k3s
deleted context somaz-k3s from /home/somaz/.kube/config
kubectx를 사용하면 쉽게 조회가 가능하다. 아래의 블로그를 참고하여 설치해보길 바란다.
# 조회
kubectx
kubernetes-admin@cluster.local
somaz-k3s
# 변경
kubectx somaz-k3s
Switched to context "somaz-k3s".
# 삭제
kubectx -d somaz-k3s
Deleting context "somaz-k3s"...
deleted context somaz-k3s from /home/somaz/.kube/config
로컬에서 조회
# error
k get nodes
Unable to connect to the server: dial tcp 34.22.89.209:6443: i/o timeout
# gcp firewall 설정
resource "google_compute_firewall" "server_ssh_kubernetes" {
name = "allow-ssh-kubernetes-server"
network = var.shared_vpc
allow {
protocol = "tcp"
ports = ["22", "6443"]
}
source_ranges = ["${var.public_ip}/32"]
target_tags = [var.kubernetes_server, var.kubernetes_client]
depends_on = [module.vpc]
}
# confirm
kubectl get nodes
NAME STATUS ROLES AGE VERSION
test-server Ready control-plane,master 10m v1.28.5+k3s1
Worker Node에 k3s 설치
# Master Server에서 진행
export WORKER_IP=10.77.101.38
export MASTER_IP=10.77.101.53
export USER=somaz
k3sup join --ip $WORKER_IP --user somaz --server-ip $MASTER_IP --server-user $USER
Running: k3sup join
Joining 10.77.101.38 => 10.77.101.53
Received node-token from 10.77.101.53.. ok.
...
[INFO] systemd: Creating service file /etc/systemd/system/k3s-agent.service
[INFO] systemd: Enabling k3s-agent unit
[INFO] systemd: Starting k3s-agent
🚀 Speed up GitHub Actions/GitLab CI + reduce costs: <https://actuated.dev>
마무리
`~/.bashrc` 설정
# kubectl
source <(kubectl completion bash)
alias k=kubectl
complete -F __start_kubectl k
- kubectl 자동완성과 alias 설정이다.
`sudo` 제거
sudo chown $(whoami):$(whoami) /etc/rancher/k3s/k3s.yaml
k get nodes
NAME STATUS ROLES AGE VERSION
test-server-agent Ready <none> 22m v1.28.5+k3s1
test-server Ready control-plane,master 37m v1.28.5+k3s1
서버 확인 / 로컬 확인
# 서버
k get nodes
NAME STATUS ROLES AGE VERSION
test-server-agent Ready <none> 108s v1.28.5+k3s1
test-server Ready control-plane,master 17m v1.28.5+k3s1
# 로컬
k get nodes
NAME STATUS ROLES AGE VERSION
test-server-agent Ready <none> 114s v1.28.5+k3s1
test-server Ready control-plane,master 17m v1.28.5+k3s1
Reference
https://m.blog.naver.com/dogenius01/222832268320
'Container Orchestration > Kubernetes' 카테고리의 다른 글
k3d(k3s in docker)란? (2) | 2024.01.14 |
---|---|
kind(Kubernetes in Docker)란? (2) | 2024.01.13 |
Flux란? / Flux + Kustomize (2) | 2023.10.16 |
2. Kustomize + ArgoCD ApplicationSet (2) | 2023.10.14 |
1. Kustomize란? (0) | 2023.10.12 |