초안

inception-of-things part 2

vagrant
k8s
argoCD
gitlab
42 seoul

Intro

Part 1에 이어서 진행해보겠습니다.

개념 설명

Part 1 구조

Part 1에서 클러스터가 여러 노드들을 논리적으로 묶어주는 기술임을 설명했습니다.

그렇다면 구체적으로 각각의 노드들이 어떻게 협업을 한다는 것일까요?

코드 설명

Provision

Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-24.04"
  config.vm.box_version = "202404.26.0"

  config.vm.define "hyunghkiS" do |control|
    control.vm.hostname = "hyunghkiS"
    control.vm.network "private_network", ip: "192.168.56.110"
    control.vm.provider "virtualbox" do |v|
      v.customize ["modifyvm", :id, "--name", "hyunghkiS"]
      v.memory = "8192"
      v.cpus = "5"
    end
    config.vm.synced_folder "confs", "/etc/vagrant/confs"
    control.vm.provision "shell", path: "scripts/server.sh"
  end
end

Vagrant 파일을 이용해서 가상머신을 생성해줍니다. 이번 파트에서는 k3s 클러스터 안에 하나의 노드만 provision하고 있는데, 이 경우 노드 하나가 master, worker 역할을 모두 수행합니다.

k3s config file

deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-one
  labels:
    app: app1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-two
  labels:
    app: app2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: app2
  template:
    metadata:
      labels:
        app: app2
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-three
  labels:
    app: app3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app3
  template:
    metadata:
      labels:
        app: app3
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
ing.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
spec:
  ingressClassName: traefik
  rules:
  - host: "app1.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: app-one
            port:
              number: 80
  - host: "app2.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: app-two
            port:
              number: 80
route.yml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: default-backend
spec:
  routes:
    - match: PathPrefix(`/`)
      kind: Rule
      services:
        - name: app-three
          port: 80
svc.yml
apiVersion: v1
kind: Service
metadata:
  name: app-one
spec:
  selector:
    app: app1
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app-two
spec:
  selector:
    app: app2
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app-three
spec:
  selector:
    app: app3
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

실행 스크립트

scripts/server.sh
#!/bin/bash

echo 'alias k=kubectl' >> /home/vagrant/.bashrc
source /home/vagrant/.bashrc
curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" sh -s - server
until kubectl get crd | grep -q 'ingressroutes.traefik.containo.us'; do
    echo 'waiting for CRD...'
    sleep 1
done

# 작성한 설정 파일을 적용해줍니다.
kubectl apply -f /etc/vagrant/confs

# pod이 정상적으로 올라올 때 까지 기다려줍니다.
until [ ! -z "$(kubectl get pods -o jsonpath='{.items[*].metadata.name}')" ]; do
    sleep 1
done
for pod in $(kubectl get pods -o jsonpath='{.items[*].metadata.name}'); do
    until kubectl get pods $pod | grep -q 'Running'; do
        sleep 1
    done
    app_name=$(kubectl get pods $pod -o jsonpath='{.metadata.labels.app}')

    # 과제에서 제시된 HTML 파일을 생성된 pod에 저장해줍니다.
    HTML=$(cat <<EOF
<!DOCTYPE html>
<html> 
<head> 
    <title>Hello Kubernetes!</title>
</head>
<body>

    <div class="main">
        <div class="content">
            <div id="message"> 
    Hello from ${app_name}.
</div>
<div id="info">
    <table> 
        <tr>
            <th>pod:</th> 
            <td>${pod}</td>
        </tr>
        <tr>
            <th>node:</th> 
            <td>$(uname -s) ($(uname -r))</td> 
        </tr> 
    </table>

</div> 
    </div> 
</div>
</body>
</html>
EOF
)
    echo $"${HTML}" > /home/vagrant/index.html
    kubectl cp /home/vagrant/index.html $pod:/usr/share/nginx/html/index.html > /dev/null
done

Provision이 완료되고 자동으로 실행되는 script를 작성해줍니다.

Outro

Part 3와 Bonus는 다음 포스팅에서 작성하겠습니다.

맨 위로