Kubeadm을 사용하여 쿠버네티스 구축해보기

Dierslair·2022년 5월 31일
0

kubernetes

목록 보기
2/5

kubeadm 을 사용하여 k8s 클러스터 구성을 실습해 보겠습니다.

실습 환경은 AWS Lightsail Linux Ubuntu 20.04 LTS 이며, 2CPU, 4Gi Memory 스펙을 가진 VM 3대(마스터1 - 워커2)를 사용합니다.

master 노드 구성

  • 메모리 스왑 기능을 비활성화합니다.
$ swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab
  • 호스트명이 Ip-[IP]이니 추후 운영할 때 식별하기가 헷갈리므로 호스트명을 변경해 줍니다.
$ sudo  vi /etc/cloud/cloud.cfg
...
# preserve_hostname 의 값을 true로 변경해 줍니다.
preserve_hostname: false
$ sudo hostnamectl set-hostname k8s-master-1
  • 필요한 모듈을 로드합니다.
$ sudo modprobe br_netfilter

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

$ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

$ sudo reboot
$ curl -fsL https://get.docker.com | sh -
$ sudo usermod -aG docker $USER
.. 이후 재 로그인
  • kubeadm을 설치합니다. 순서대로 입력합니다.
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl

$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

$ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl
  • kubeadm 을 사용하여 클러스터를 초기화합니다. CNI 플러그인으로는 kube-flannel을 사용할것이기 때문에 pod-network-cidrkube-flannel에서 제공해주는 기본값을 사용합니다.
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
  • unknown service runtime.v1alpha2.RuntimeService 과 같은 오류가 발생하게 되면 컨테이너 런타임에서 CRI 기능을 비활성화 한 경우이므로 다음 추가 작업을 진행합니다.
$ sudo vi /etc/containerd/config.toml
# 아래 줄을 주석 처리합니다.
disabled_plugins = ["cri"]

또는,

$ sudo rm /etc/containerd/config.toml

작업 후에는 컨테이너 서비스를 재시작 해 줍니다.

$ sudo systemctl restart containerd.service
  • 클러스터 초기화 후, 콘솔에 표시되는 join 명령어를 복사해 둡니다.
kubeadm join 172.26.8.85:6443 --token twfgx... \
--discovery-token-ca-cert-hash sha256:...
  • kubectl 명령어를 위한 설정을 진행합니다.
$ mkdir ~/.kube
$ sudo cp /etc/kubernetes/admin.conf ~/.kube/config
$ sudo chmod 644 ~/.kube/config
$ sudo chown $(id -u):$(id -g) ~/.kube/config
$ echo 'export KUBECONFIG="$HOME/.kube/config"' >> ~/.bashrc
  • 다음으로 CNI 플러그인을 설치하여야 합니다.
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

$ kubectl get pods --all-namespaces
===
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-6d4b75cb6d-grbrk             1/1     Running   0          1m
coredns-6d4b75cb6d-m74v4             1/1     Running   0          1m
etcd-k8s-master                      1/1     Running   0          1m
kube-apiserver-k8s-master            1/1     Running   0          1m
kube-controller-manager-k8s-master   1/1     Running   0          1m
kube-flannel-ds-9bjp6                1/1     Running   0          1m
kube-flannel-ds-fcw8g                1/1     Running   0          1m
kube-flannel-ds-k2qwt                1/1     Running   0          1m
kube-proxy-plvdb                     1/1     Running   0          1m
kube-proxy-v8rp5                     1/1     Running   0          1m
kube-proxy-wbr5w                     1/1     Running   0          1m
kube-scheduler-k8s-master            1/1     Running   0          1m
  • corednskube-flannel이 정상적으로 Running 상태가 되어야 합니다.

worker-1, worker-2 노드 구성

master 노드의 kubeadm init 명령어 이전까지는 같습니다.

  • master 노드를 구성했을 때 복사해 둔, join 명령어를 사용합니다.
$ sudo kubeadm join 172.26.8.85:6443 --token twfgx... \
--discovery-token-ca-cert-hash sha256:...
  • master 노드에서 연결 상태를 확인합니다.
$ kubectl get nodes
===
NAME           STATUS   ROLES           AGE   VERSION
k8s-master     Ready    control-plane    8m   v1.24.1
k8s-worker-1   Ready    <none>           3m   v1.24.1
k8s-worker-2   Ready    <none>           1m   v1.24.1

노드 레이블 설정하기

kubectl 명령어는 master 노드에서 실행하고, worker-1, worker-2 노드는 파드를 실행하기만 합니다. 이를 위해서는 어느 노드에서 파드를 구동할지를 정하기 위해서 레이블을 지정해 주어야 합니다.

# 노드의 타입을 worker 로 지정합니다.
$ kubectl label nodes k8s-worker-1 type=worker
$ kubectl label nodes k8s-worker-2 type=worker
$ kubectl get nodes --show-labels
===
NAME           STATUS   ROLES           AGE   VERSION   LABELS
k8s-master     Ready    control-plane   14m   v1.24.1   beta.kubernetes.io/arch=amd64,...
k8s-worker-1   Ready    <none>           9m   v1.24.1   ..,kubernetes.io/os=linux,type=worker
k8s-worker-2   Ready    <none>           7m   v1.24.1   ..,kubernetes.io/os=linux,type=worker

서비스 테스트

  • 테스트를 위해 nginx 서비스를 배포해 줍니다.
# nginx.yml
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: nginx

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          imagePullPolicy: Always
          ports:
            - containerPort: 80
      affinity:
        # 파드를 구동할 노드를 선택합니다.
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              # 레이블의 key가 type이고, value가 worker 인 노드
              - matchExpressions:
                  - key: type
                    operator: In
                    values:
                      - worker
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    values:
                      - nginx
                    operator: In
              # 호스트명은 각 노드에 고유하기 때문에 하나의 노드에는
              # 하나의 파드만 할당됩니다.
              topologyKey: kubernetes.io/hostname

# 스케일러 (옵셔널)
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  minReplicas: 2
  maxReplicas: 4
  targetCPUUtilizationPercentage: 50
$ kubectl apply -f nginx.yml
$ kubectl get pods -o wide
===
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
nginx-794b7556d9-pf7px   1/1     Running   0           4m   10.244.2.2   k8s-worker-2   <none>           <none>
nginx-794b7556d9-szf8v   1/1     Running   0           4m   10.244.1.2   k8s-worker-1   <none>           <none>

의도한 대로 각 worker 노드에서 잘 동작하고 있음을 확인할 수 있습니다.

profile
Java/Kotlin Backend Developer

0개의 댓글