공부하기싫어
article thumbnail

현재 진행중인 프로젝트에서 여러개의 작은 웹사이트를 배포하려고 한다.

프론트앤드 역할을 수행하는 POD만 모아서 따로 관리하고싶어서 한번 알아볼 겸 포스팅 해보려고 한다.

 

테스트 목표

1. 같은 클러스터의 다른 Worker Node에서 각각 다른 2개의 웹호스팅 POD 배포 후 접속 테스트

2. 같은 클러스터의 같은 Worker Node에서 각각 다른 2개의 웹호스팅 POD 배포 후 접속 테스트

3. (1) , (2) 테스트 성공 시 로직 이해

4. (1) , (2) 테스트 성공 시 Route53 도메인에 연결 후 접속 테스트

 

테스트 환경

AWS Instance * 3 , k3s cluster

master * 1 , worker * 2

ubuntu 22.04 , t3a.small

 

https://docs.k3s.io/kr/installation

 

Installation | K3s

This section contains instructions for installing K3s in various environments. Please ensure you have met the Requirements before you begin installing K3s.

docs.k3s.io

 

ubuntu@master:~$ k get nodes
NAME      STATUS   ROLES                  AGE   VERSION
worker2   Ready    <none>                 60s   v1.28.7+k3s1
master    Ready    control-plane,master   9d    v1.28.7+k3s1
worker    Ready    <none>                 9d    v1.28.7+k3s1

ubuntu@master:~$
ubuntu@master:~$ k label nodes master nodenumber=master01
ubuntu@master:~$ k label nodes worker nodenumber=worker01
ubuntu@master:~$ k label nodes worker2 nodenumber=worker02

ubuntu@master:~$ k create namespace webserver1
namespace/webserver1 created
ubuntu@master:~$ k create namespace webserver2
namespace/webserver2 created


각 노드마다 라벨을 추가해줌
namespace webserver1과 webserver2 를 생성해줌

 

Test Directory

configmap 활용을 위해 2개의 다른 디렉토리를 만들고 각각 html 파일을 하나씩 생성해줬다.

ubuntu@master:~$ mkdir pod1
ubuntu@master:~$ mkdir pod2

 

chatgpt를 통해 2개의 각각 다른 html 파일을 생성했다.

pod1 - index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Coffee Shop Home</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            background-color: #f4f4f4;
        }
        .logo {
            margin-top: 20px;
        }
        .intro {
            margin: 20px;
            text-align: center;
        }
        .info {
            background-color: #fff;
            padding: 15px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }
    </style>
</head>
<body>
    <div class="logo">
        <img src="coffee_logo.png" alt="Coffee Shop Logo" width="100">
    </div>
    <div class="intro">
        <h1>Welcome to Our Coffee Shop</h1>
        <p>Enjoy the best coffee in town in a cozy atmosphere.</p>
    </div>
    <div class="info">
        <h2>Location & Hours</h2>
        <p>123 Coffee Lane, Coffee City</p>
        <p>Monday - Friday: 7am - 7pm</p>
        <p>Saturday - Sunday: 8am - 8pm</p>
    </div>
</body>
</html>

 

pod2 - index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tech Blog Home</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #eaeaea;
        }
        header {
            background-color: #333;
            color: #fff;
            padding: 20px;
            text-align: center;
        }
        .posts {
            margin: 20px;
            padding: 20px;
            background-color: #fff;
            border-radius: 8px;
        }
        article {
            margin-bottom: 20px;
            padding-bottom: 20px;
            border-bottom: 1px solid #ccc;
        }
        article:last-child {
            border-bottom: none;
        }
    </style>
</head>
<body>
    <header>
        <h1>Tech Blog</h1>
        <p>Insights and updates on the latest in technology</p>
    </header>
    <div class="posts">
        <article>
            <h2>Exploring the New Features of HTML5</h2>
            <p>Published on: January 10, 2024</p>
            <p>HTML5 introduces a wide array of new features that web developers will find useful...</p>
        </article>
        <article>
            <h2>The Future of Web Development: Trends to Watch</h2>
            <p>Published on: February 15, 2024</p>
            <p>As the web continues to evolve, several trends are emerging that developers should keep an eye on...</p>
        </article>
    </div>
</body>
</html>

 

Configmap

ubuntu@master:~$ k create configmap pod1-html --from-file=/home/ubuntu/pod1/index.html -n webserver1
configmap/pod1-html created
ubuntu@master:~$ k create configmap pod2-html --from-file=/home/ubuntu/pod2/index.html -n webserver2
configmap/pod2-html created
ubuntu@master:~$

1. 같은 클러스터, 다른 Worker Node

POD1 배포

apiVersion: v1
kind: Pod
metadata:
  name: pod1
  namespace: webserver1
  labels:
  	app: pod1
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html-volume
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html-volume
    configMap:
      name: pod1-html
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: nodenumber
            operator: In
            values:
            - worker01

 

POD2 배포

apiVersion: v1
kind: Pod
metadata:
  name: pod2
  namespace: webserver2
  labels:
  	app: pod2
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html-volume
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html-volume
    configMap:
      name: pod2-html
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: nodenumber
            operator: In
            values:
            - worker02

 

svc

apiVersion: v1
kind: Service
metadata:
  name: webserver1-service
  namespace: webserver1
spec:
  type: NodePort
  selector:
    app: pod1
  ports:
  - protocol: TCP
    port: 80
    nodePort: 30081

 

apiVersion: v1
kind: Service
metadata:
  name: webserver2-service
  namespace: webserver2
spec:
  type: NodePort
  selector:
    app: pod2
  ports:
  - protocol: TCP
    port: 80
    nodePort: 30082

 

 

 

접속 확인

ubuntu@master:~/2-diff-pod-deploy-test/diff-node$ k get all -n webserver1
NAME       READY   STATUS    RESTARTS   AGE
pod/pod1   1/1     Running   0          32s

NAME                         TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
service/webserver1-service   NodePort   10.43.33.9   <none>        80:30081/TCP   10m
ubuntu@master:~/2-diff-pod-deploy-test/diff-node$ 
ubuntu@master:~/2-diff-pod-deploy-test/diff-node$ k get all -n webserver2
NAME       READY   STATUS    RESTARTS   AGE
pod/pod2   1/1     Running   0          20s

NAME                         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/webserver2-service   NodePort   10.43.245.15   <none>        80:30082/TCP   10m

 

마스터노드의 public ip 를 통해 접속을 시도했을 때, 서로 다른 웹사이트로 접속되는것을 확인했다!

 


2. 같은 클러스터, 같은 Worker Node

(1)이 성공해서 당연히 성공할 것 같지만 그래도 시도해보겠다.

namespace 는 다르게하고 pod2의 nodeaffinity sector 중 nodeselectorterms 의 values 를 worker01 로 바꾸고 pod를 재배포 하여 테스트를 진행했다.

 

buntu@master:~/2-diff-pod-deploy-test/diff-node$ k get pods -o wide -A | grep webserver
webserver1    pod1                                      1/1     Running     0              6m30s   10.42.1.15   worker    <none>           <none>
webserver2    pod2                                      1/1     Running     0              113s    10.42.1.16   worker    <none>           <none>

두개의 pod 모두 worker1 에 배포되었다.

 

잘 접속된다

 


3. 테스트 결과 정리

devops gpts 를 사용하여 테스트에 대한 도움을 얻어서 이참에 요약도 시켜봤다.

 

GPTs : https://chat.openai.com/g/g-tXRU6PcBN-devops-gpt

 

ChatGPT - DevOps GPT

AI coding expert for all cloud operation needs. Responds concisely with cost efficient and secure practices.

chat.openai.com

 

이번 테스트는 AWS 인스턴스에서 구성된 k3s 클러스터를 사용하여, 서로 다른 네임스페이스에 배포된 두 개의 웹 서버 Pod의 외부 접근 가능성을 확인하는 과정을 포함했습니다. 테스트의 주요 목적은 서로 다른 네임스페이스로 구분된 두 개의 웹 호스팅 Pod가 외부에서 접근 가능한지, 그리고 이들이 서로 다른 워커 노드에 배치되었을 때와 같은 노드에 배치되었을 때의 접근성을 평가하는 것이었습니다.

 

테스트 환경

클러스터는 마스터 노드 1개와 워커 노드 2개로 구성되었습니다.
워커 노드에는 nodenumber 라벨이 worker01, worker02로 각각 추가되었습니다.
네임스페이스 webserver1과 webserver2가 생성되었습니다.
각 네임스페이스에는 pod1-html과 pod2-html ConfigMap을 사용하여, 각각 다른 index.html 파일을 가진 Nginx 웹 서버 Pod가 배포되었습니다.
NodePort 서비스를 통해 각 Pod에 외부 접근이 가능하도록 설정되었습니다.

 

테스트 절차 및 결과

서로 다른 노드에 Pod 배치: nodeAffinity 설정을 통해 pod1은 worker01에, pod2는 worker02에 각각 배치되었습니다. NodePort 서비스를 통해 각 Pod는 외부에서 접근 가능했습니다. 이는 클러스터의 노드 분리가 서비스의 외부 접근성에 영향을 주지 않음을 보여줍니다.

동일 노드에 Pod 배치: 선택적인 테스트로, 두 Pod 모두 같은 워커 노드에 배치되었을 경우의 외부 접근성도 확인되었습니다. 이 경우에도 NodePort 서비스를 통해 두 웹 서버에 성공적으로 접근할 수 있었습니다. 이는 한 노드가 다수의 Pod를 호스팅하고 외부에서 접근 가능함을 보여줍니다.

 

요약

이 테스트는 Kubernetes 클러스터에서 Pod의 배치 전략이 다양할 수 있음을 보여주며, NodePort 서비스를 사용하여 클러스터 외부에서 Pod에 성공적으로 접근할 수 있음을 입증했습니다. 또한, 네임스페이스를 사용하여 리소스를 논리적으로 분리하고 관리할 수 있음을 보여줍니다. 이는 Kubernetes의 유연성과 다양한 배포 시나리오를 지원하는 능력을 강조합니다.

 


성공적인 외부 접근 테스트는 클라우드 환경에서의 Kubernetes 사용 사례를 위한 중요한 기초를 마련합니다. 이러한 테스트는 더 복잡한 애플리케이션 배포 및 관리 전략을 설계할 때 중요한 참조점이 됩니다.

 


4. Route53 도메인 연결 확인

현재, 클러스터의 master node의 public ip의 30081, 30082 port 로의 접속에 성공했다.

이제 각 웹서버로의 접속을 route53을 통해 도메인 레코드와 매핑하는 것을 테스트해보려고 했는데,

route53에서 바로 불가능하고 프록시를 사용하거나 lb를 사용해야 하는 것 같다.

 

gpts : 

AWS Route 53을 사용할 때, DNS 레코드는 특정 도메인 이름을 IP 주소와 직접 매핑하는 데 사용됩니다. 그러나 DNS 자체는 포트 번호를 직접 지정하는 메커니즘을 제공하지 않습니다. 즉, Route 53 또는 다른 DNS 서비스를 통해 도메인 이름을 특정 IP의 특정 포트에 직접 매핑하는 것은 가능하지 않습니다. DNS 레코드는 호스트 이름을 IP 주소로 변환하는 역할만 하며, 트래픽을 특정 포트로 리디렉션하는 기능은 포함하지 않습니다.

하지만, 웹 트래픽을 특정 포트로 리디렉션하는 것은 다른 방법을 통해 달성할 수 있습니다:

 

1. 리버스 프록시 사용

가장 일반적인 방법 중 하나는 웹 서버 또는 리버스 프록시(예: Nginx, HAProxy)를 사용하여 도메인 또는 경로 기반의 트래픽을 특정 포트로 리디렉션하는 것입니다. 이 방법을 사용하면, 모든 트래픽을 표준 HTTP 또는 HTTPS 포트(80 또는 443)로 리디렉션한 다음, 리버스 프록시가 해당 트래픽을 클러스터 내의 적절한 서비스의 특정 포트로 전달하도록 구성할 수 있습니다.

 

2. Load Balancer를 통한 포트 매핑

AWS에서는 Application Load Balancer(ALB) 또는 Network Load Balancer(NLB)를 사용하여 도메인 이름을 로드 밸런서에 매핑하고, 로드 밸런서가 트래픽을 적절한 포트로 포워딩하도록 구성할 수 있습니다. ALB의 경우, 호스트 기반 라우팅 또는 경로 기반 라우팅 규칙을 설정하여 특정 도메인 또는 URL 경로에 따라 다른 타겟 그룹(포트가 다를 수 있음)으로 트래픽을 분배할 수 있습니다.

 

Route 53 설정 예

Route 53에서는 A 레코드(또는 CNAME 레코드, ALIAS 레코드를 사용할 경우)를 사용하여 도메인 이름을 로드 밸런서나 리버스 프록시 서버의 IP 주소에 매핑할 수 있습니다. 예를 들어, example.com 도메인을 로드 밸런서의 IP 주소에 매핑하고, 로드 밸런서 또는 리버스 프록시가 트래픽을 적절한 포트로 리디렉션하도록 설정할 수 있습니다.

결론적으로, 같은 IP의 다른 포트로의 직접적인 DNS 매핑은 불가능하지만, 리버스 프록시 또는 로드 밸런서를 사용하여 이를 우회하는 설정이 가능합니다. 이를 통해 다양한 웹 서비스를 한 클러스터 안에서 운영하면서, 각각에 대해 도메인 이름을 통한 접근을 구성할 수 있습니다

 

 

이 부분은 나중에 따로 테스트해봐야겠다.