Contents

Local Kubernetes Cluster

Multipass와 K3S를 이용한 Kubernetes Cluster 구축

Multipass를 이용하여 다수의 Virtual Machine을 만들고, K3S를 이용하여 다수의 Virtual Machine을 Kubernetes Cluster로 만드는 방법에 대해서 소개합니다.

Multipass

Multipass는 Ubuntu가 설치된 Virtual Machine을 만들어 주는 도구입니다. 간단한 명령어만 익히면 Ubuntu가 설치된 Virtual Machine을 빠르게 만드는 것을 할 수 있습니다.

Multipass 설치

Multipass 설치는 OS별로 다르기 때문에 아래의 링크를 참고바랍니다.

Multipass 소개

사용법이 간단하고, multipass --help를 확인하면 명령어 대부분이 잘 설명되어 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
multipass --help

Usage: multipass [options] <command>
Create, control and connect to Ubuntu instances.

This is a command line utility for multipass, a
service that manages Ubuntu instances.

Options:
  -h, --help     Display this help
  -v, --verbose  Increase logging verbosity. Repeat the 'v' in the short option
                 for more detail. Maximum verbosity is obtained with 4 (or more)
                 v's, i.e. -vvvv.

Available commands:
  delete    Delete instances
  exec      Run a command on an instance
  find      Display available images to create instances from
  get       Get a configuration setting
  help      Display help about a command
  info      Display information about instances
  launch    Create and start an Ubuntu instance
  list      List all available instances
  mount     Mount a local directory in the instance
  networks  List available network interfaces
  purge     Purge all deleted instances permanently
  recover   Recover deleted instances
  restart   Restart instances
  set       Set a configuration setting
  shell     Open a shell on a running instance
  start     Start instances
  stop      Stop running instances
  suspend   Suspend running instances
  transfer  Transfer files between the host and instances
  umount    Unmount a directory from an instance
  version   Show version details

launch

1개 CPU, 2GB Memory, 20G Disk를 가진 Ubuntu 20.04가 설치된 Virtual Machine을 생성하는 명령어입니다.

1
2
3
multipass launch --name test-vm --cpus 1 --mem 2048M --disk 20G 20.04

Launched: test-vm

info

생성한 Virtual Machine 정보를 확인할 수 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
multipass info test-vm

Name:           test-vm
State:          Running
IPv4:           192.168.64.6
Release:        Ubuntu 20.04.2 LTS
Image hash:     38b82727bfc1 (Ubuntu 20.04 LTS)
Load:           1.10 0.32 0.11
Disk usage:     1.3G out of 19.2G
Memory usage:   141.9M out of 1.9G

exec

동작중인 Virtual Machine에 명령어를 실행할 수 있습니다.

1
2
3
multipass exec test-vm -- uname -a

Linux test-vm 5.4.0-72-generic #80-Ubuntu SMP Mon Apr 12 17:35:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

shell

동작중인 Virtual Machine shell을 실행시키는 명령입니다. 마치 ssh으로 Machine을 접근할 때와 같은 화면을 확인 할 수 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
multipass shell test-vm

Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-72-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun Apr 18 20:54:12 KST 2021

  System load:  0.02              Processes:               118
  Usage of /:   6.6% of 19.21GB   Users logged in:         0
  Memory usage: 9%                IPv4 address for enp0s2: 192.168.64.6
  Swap usage:   0%


1 update can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable


Last login: Sun Apr 18 20:52:57 2021 from 192.168.64.1
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@test-vm:~$

stop

Virtual Machine을 사용하지 않을 때는 stop 명령으로 Host Machine의 Resource를 확보할 수 있습니다.

1
multipass stop test-vm

start

멈춘 Virtual Machine을 시작하는 명령입니다.

1
multipass start test-vm

delete

더 이상 필요없는 Virtual Machine을 삭제하는 명령입니다.

1
multipass delete -p test-vm

K3S

K3S는 Single Binary로 구성되어 있고 크기가 약 40MB으로 매우 가볍습니다. 그래서 Raspberry Pi와 같이 Resource가 비교적 작은 Node를 엮는 Kubernetes Cluster를 만들 때 사용할 수 있습니다.

Virtual Machine Setup

node1, node2, node3 이름을 가진 Virtual Machine 3개를 생성하는 명령입니다. 각 Virtual Machine은 1개 CPU, 2GB Memory, 20GB Disk 자원과 Ubuntu 20.04가 설치되어 있습니다.

1
2
3
4
5
for i in 'node1' 'node2' 'node3'; do multipass launch --name "${i}" --cpus 1 --mem 2048M --disk 20G 20.04; done

Launched: node1
Launched: node2
Launched: node3

K3S 설치

node1에 K3S를 설치합니다. node1에 설치된 K3S는 server type으로 Kubernetes에서 master node와 같은 역할입니다. K3S에서 기본으로 설치되는 Traefik대신 Ingress NGINX를, ServiceLB대신 MetalLB를, local-storage대신 Longhorn을 사용할 것입니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
multipass exec node1 -- bash -c "curl -sfL https://get.k3s.io | sh -s - server --disable traefik --disable servicelb --disable local-storage"

[INFO]  Finding release for channel stable
[INFO]  Using v1.20.6+k3s1 as release
[INFO]  Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.20.6+k3s1/sha256sum-amd64.txt
[INFO]  Downloading binary https://github.com/k3s-io/k3s/releases/download/v1.20.6+k3s1/k3s
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[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

TOKEN 환경변수를 node1/var/lib/rancher/k3s/server/node-token값으로 설정합니다. IP 환경변수를 node1 ip로 설정합니다.

1
2
TOKEN=$(multipass exec node1 sudo cat /var/lib/rancher/k3s/server/node-token)
IP=$(multipass info node1 | grep IPv4 | awk '{print $2}')

node2node3에 K3S를 설차합니다. node2node3에 설치된 K3S는 agnet type으로 Kubernetes의 worker node와 같은 역할입니다.

1
2
multipass exec node2 -- bash -c "curl -sfL https://get.k3s.io | K3S_URL=\"https://$IP:6443\" K3S_TOKEN=\"$TOKEN\" sh -"
multipass exec node3 -- bash -c "curl -sfL https://get.k3s.io | K3S_URL=\"https://$IP:6443\" K3S_TOKEN=\"$TOKEN\" sh -"

node1에서 kubeconfig를 가져와서 IP설정하고 KUBECONFIG환경변수를 설정합니다.

1
2
3
multipass exec node1 sudo cat /etc/rancher/k3s/k3s.yaml > k3s.yaml
sed -i "s/127.0.0.1/$IP/" k3s.yaml
export KUBECONFIG=$(pwd)/k3s.yaml

kubectl으로 node를 확인합니다.

1
2
3
4
5
6
kubectl get nodes

NAME    STATUS   ROLES                  AGE     VERSION
node1   Ready    control-plane,master   14m     v1.20.6+k3s1
node3   Ready    <none>                 3m30s   v1.20.6+k3s1
node2   Ready    <none>                 6m3s    v1.20.6+k3s1

MetalLB

공식문서를 참고하였습니다.

1
2
3
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.6/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.6/manifests/metallb.yaml
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"

IP대역을 확인합니다. 현재 환경에서 IP대역은 192.168.64.x입니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
multipass list

Name                    State             IPv4             Image
node1                   Running           192.168.64.3     Ubuntu 20.04 LTS
                                          10.42.0.0
                                          10.42.0.1
node2                   Running           192.168.64.4     Ubuntu 20.04 LTS
                                          10.42.1.0
                                          10.42.1.1
node3                   Running           192.168.64.5     Ubuntu 20.04 LTS
                                          10.42.2.0
                                          10.42.2.1
addresses에는 환경에 맞는 IP대역으로 설정해야 합니다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
    namespace: metallb-system
    name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.64.240-192.168.64.250
EOF

Ingress NGINX

공식문서를 참고하였습니다. Helm을 사용하여 설치합니다.

1
2
3
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx/ingress-nginx -g -n ingress-nginx --create-namespace

Longhorn

공식문서Github Issue를 참고하였습니다. Helm을 사용하여 설치합니다.

1
2
3
helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn longhorn/longhorn --namespace longhorn-system --set csi.kubeletRootDir=/var/lib/kubelet --create-namespace
1
2
USER=admin; PASSWORD=adminadmin; echo "${USER}:$(openssl passwd -stdin -apr1 <<< ${PASSWORD})" >> auth
kubectl -n longhorn-system create secret generic basic-auth --from-file=auth
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: longhorn-ingress
  namespace: longhorn-system
  annotations:
    ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
    # type of authentication
    nginx.ingress.kubernetes.io/auth-type: basic
    # prevent the controller from redirecting (308) to HTTPS
    nginx.ingress.kubernetes.io/ssl-redirect: 'false'
    # name of the secret that contains the user/password definitions
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    # message to display with an appropriate context why the authentication is required
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required '
    # custom max body size for file uploading like backing image uploading
    nginx.ingress.kubernetes.io/proxy-body-size: 10000m
spec:
  rules:
  - host: longhorn.k3s.cluster.local
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: longhorn-frontend
            port:
              number: 80
EOF

동작확인

Ingress IP를 확인합니다.

1
kubectl -n ingress-nginx get svc -o jsonpath='{.items[*].status.loadBalancer.ingress[*].ip}'

Longhorn UI를 확인하는 것으로 MetalLB, Ingress NGINX, Longhorn 정상적인 설치를 확인할 수 있습니다. DNS로 접근하기 위해서 /etc/hosts에 Ingress IP와 Domain Name을 추가합니다.

1
sudo sh -c "echo '192.168.64.240 longhorn.k3s.cluster.local' >> /etc/hosts"

Browser에서 http://longhorn.k3s.cluster.local/주소로 접속합니다. 위에서 설정한 id/password는 다음과 같습니다.

Info
ID: admin
Password: adminadmin

정리

K3S와 Raspberry Pi 여러개를 이용해서 Kubernetes Cluster를 만들어 보기전에 연습을 위한 용도로 Multipass와 K3S를 사용해 보았습니다.