VMware Fusion 12 – vctl / KinD / MetalLB / Nginx deployment

몇 달 전에 VMware Fusion 12에서 KinD(Kubernetes in Docker) 서비스를 어떻게 제공하는지를 살펴보는 기사를 썼습니다. 간단히 말해, 이를 통해 VMware Photon OS를 기반으로 매우 가벼운 가상 머신(CRX)을 사용하는 Nautilus Container Engine을 사용하여 Kubernetes 환경을 매우 신속하게 구축할 수 있습니다. 이 게시물에서 저는 경험을 확장하고 간단한 Nginx 구축을 지원하는 방법을 시연하고 싶었습니다. 먼저 간단한 배치를 하겠습니다. 그런 다음 로드 밸런서 서비스(MetalLB 활용)를 사용하도록 확장할 것입니다.

이 게시물에는 이전 게시물에서 다루어지므로 이 게시물에서는 컨테이너 엔진 또는 KinD를 Fusion과 함께 시작하는 방법에 대해 다루지 않습니다. 대신 Nginx 웹 서버 배포에 초점을 맞추겠습니다. 먼저 Nginx 애플리케이션의 구축 및 서비스를 살펴보겠습니다. 다음은 2개의 개체, 즉 2개의 복제본이 있는 배포(Pod)와 서비스를 설명하는 간단한 매니페스트입니다. 이것들은 spec.selector.matchLabels을 통해 연결된다. 포트 80을 통해 웹 서비스를 제공하는 단일 컨테이너 이미지가 있습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      app: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    app: my-nginx
spec:
  ports:
    - port: 80
      protocol: TCP
  selector:
    app: my-nginx

VMware Fusion을 사용하여 Container Engine과 KinD를 다시 시작했다고 가정하면, MacOS 터미널을 통해 kubectl create 또는 kubectl apply를 통해 위의 매니페스트를 적용할 수 있습니다. 다음으로, 어떤 오브젝트가 만들어지는지 알아보겠습니다. 배포 환경, 두 개의 포드, 두 개의 엔드포인트 및 서비스를 확인해야 합니다.

% kubectl apply -f nginx.yaml
deployment.apps/my-nginx created
service/my-nginx created


% kubectl get deploy my-nginx
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
my-nginx   2/2     2            2           25s


% kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP            NODE                 NOMINATED NODE   READINESS GATES
my-nginx-74b6849986-glqbs   1/1     Running   0          45s   10.244.0.13   kind-control-plane   <none>           <none>
my-nginx-74b6849986-r4vf4   1/1     Running   0          45s   10.244.0.14   kind-control-plane   <none>           <none>


% kubectl get endpoints my-nginx
NAME       ENDPOINTS                       AGE
my-nginx   10.244.0.13:80,10.244.0.14:80   37s


% kubectl get svc my-nginx
NAME       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
my-nginx   ClusterIP   10.97.25.54   <none>        80/TCP    47s

보시는 바와 같이, 배포와 두 개의 Pod가 가동되어 실행되고 있습니다. 흥미로운 것은 네트워킹 구성입니다. 이 경우 Nginx 웹 서버인 서비스를 제공할 수 있는 여러 개의 Pod가 있을 수 있다는 것이 배치의 배경입니다. 포드 중 하나에 장애가 발생하면 다른 포드가 계속해서 기능을 제공합니다.

각 포드는 포드 네트워크 범위에서 자체 IP 주소(예: 10.244.0.13, 10.244.0.14)를 얻습니다. 이러한 IP 주소는 서비스에서 참조할 수 있는 엔드포인트에도 할당됩니다.

마찬가지로, 서비스를 생성하는 아이디어는 서비스 네트워크 범위에서 “프론트 엔드” 또는 “가상” IP 주소를 제공하여 배포에 액세스하는 것입니다(예: 10.97.25.54). 웹 서버의 클라이언트가 Pod IP/Endpoints를 사용하지 않도록 고유한 IP 주소를 가져옵니다. 클라이언트가 Pod IP 주소를 사용하는 경우, 해당 Pod가 실패하면 애플리케이션(예: 웹 서버)에 대한 연결이 끊어집니다. 서비스를 통해 연결이 이루어진 경우, 서비스가 다른 Pod IP 주소/종점으로 연결을 리디렉션하므로 Pod에 장애가 발생하더라도 연결이 손실되지 않습니다.

서비스가 생성되면 일반적으로 (1) 가상 IP 주소, (2) DNS 항목 및 (3) 실제로 서비스를 제공하는 Pod/Endpoint로 네트워크 트래픽을 ‘프록시’하거나 리디렉션하는 네트워킹 규칙을 가져옵니다. 가상 IP 주소가 트래픽을 수신하면 트래픽이 올바른 백엔드 포드/엔드 포인트로 리디렉션됩니다.

배포를 테스트해보고 웹 서비스가 실행 중인지 확인할 수 있는지 알아보겠습니다. 현재 MacOS에서 Pod 네트워크(10.244.0.0) 또는 서비스 네트워크(10.97.25.0)로 가는 경로가 없습니다. KinD 노드의 IP 주소를 게이트웨이로 사용하여 정적 경로를 추가할 수 있습니다. 아래와 같이 Dockerps를 실행하기만 하면 KinD 노드 IP 주소를 얻을 수 있습니다.

% docker ps
────                 ─────                                                                                  ───────                   ──               ─────            ──────    ─────────────
NAME                 IMAGE                                                                                  COMMAND                   IP               PORTS            STATUS    CREATION TIME
────                 ─────                                                                                  ───────                   ──               ─────            ──────    ─────────────
kind-control-plane   kindest/node@sha256:98cf5288864662e37115e362b23e4369c8c4a408f99cbc06e58ac30ddc721600   /usr/local/bin/entry...   172.16.255.128   54785:6443/tcp   running   2021-02-10T12:43:03Z

이제 KinD 노드의 IP 주소가 확인되었으므로 Pod 네트워크와 Service 네트워크에 경로를 추가할 때 게이트웨이로 사용할 수 있습니다. 그런 다음 다음과 같이 curl을 사용하여 index.html 랜딩 페이지를 검색하여 웹 서버가 실행 중인지 테스트할 수 있습니다.

% sudo route add -net 10.244.0.0 -gateway 172.16.255.128
Password: *****
add net 10.244.0.0


% curl 10.244.0.13:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>


% curl 10.244.0.14:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>

보기 좋습니다. 두 개의 Pods에서 Nginx 웹 서버 랜딩 페이지를 가져올 수 있습니다. 이제 서비스를 통해 접근성을 확인해 보겠습니다. 먼저 Pods로 가는 경로를 제거한 다음 서비스에 경로를 추가하겠습니다.

% sudo route delete -net 10.244.0.0
delete net 10.244.0.0


% sudo route add -net 10.97.25.0 -gateway 172.16.255.128
add net 10.97.25.0


% curl 10.97.25.54:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>

잘됐네요, 모든 게 예상대로 되고 있는 것 같아요. 그러나 일반적으로 외부 클라이언트의 ClusterIP 액세스를 허용하지 않습니다. 일반적으로 EXTERNAL-IP를 생성하는 로드 밸런서 서비스를 설정합니다. 앞에서 살펴본 서비스 출력에 따라 이 값은 현재 없음으로 설정됩니다. 우리는 MetalLB를 사용하여 LoadBalancer를 구성할 것입니다. 필요한 몇가지 단계입니다. (1) MetalLB 네임스페이스 매니페스트 배포, (2) MetalLB 개체 매니페스트 배포, (3) 로드 밸런서 / 외부 IP 주소 범위로 ConfigMap 생성 및 배포. 1단계와 2단계는 MetalLB 설치 페이지에서 다룹니다. 항목 3은 MetalLB Configuration 페이지에서 다룹니다. 다음은 내 KinD 설정에서 취한 단계입니다. 선택한 로드 밸런서 IP 주소의 범위는 구성 맵에 따라 192.168.1.1에서 192.168.1.250까지입니다.

% kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/namespace.yaml
namespace/metallb-system created


% kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/metallb.yaml
podsecuritypolicy.policy/controller created
podsecuritypolicy.policy/speaker created
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister created
daemonset.apps/speaker created
deployment.apps/controller created


% cat config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.1.1-192.168.1.250


% kubectl apply -f config.yaml
configmap/config created
%

이제 Nginx 매니페스트를 하나만 변경하면 됩니다. 즉, spec.type: LoadBalancer를 Service에 추가하기 위해 다음과 같이 파란색으로 강조 표시됩니다.

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: my-ngin
  replicas: 2 
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    app: my-nginx
spec:
  type: LoadBalancer
  ports:
    - port: 80
      protocol: TCP
  selector:
    app: my-nginx

이 매니페스트에서 생성된 개체를 다시 쿼리합니다. 이제 서비스에 ClusterIP와 External-IP가 둘 다 채워져 있는지 확인해야 합니다. MetalLB의 ConfigMap에서 제공하는 범위의 첫 번째 IP 주소(192.168.1.1)와 일치해야 합니다.

% kubectl apply -f nginx.yaml
deployment.apps/my-nginx created
service/my-nginx created


% kubectl get deploy my-nginx
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
my-nginx   2/2     2            2           4s


% kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
my-nginx-74b6849986-z77ph   1/1     Running   0          10s
my-nginx-74b6849986-zlwdh   1/1     Running   0          10s


% kubectl get endpoints
NAME         ENDPOINTS                       AGE
kubernetes   172.16.255.128:6443             98m
my-nginx     10.244.0.18:80,10.244.0.19:80   16s


% kubectl get svc my-nginx
NAME       TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
my-nginx   LoadBalancer   10.96.90.176   192.168.1.1   80:31374/TCP   27s

이 주소는 이제 외부 클라이언트가 웹 서비스에 액세스하는 데 사용해야 하는 IP 주소입니다. 그러나 이전과 마찬가지로 데스크톱에서 이 네트워크로 연결되는 경로가 없으므로 KinD 노드를 게이트웨이로 사용하여 정적 경로를 다시 추가해야 합니다.

% sudo route add -net 192.168.1.0 -gateway 172.16.255.128
add net 192.168.1.0

% curl 192.168.1.1:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>

모든 것이 예상대로 되고 있다. 이를 통해 VMware Fusion(및 VMware Workstation)에서 KinD를 사용하여 Kubernetes에 익숙해질 수 있는 방법을 잘 알 수 있기를 바랍니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

You May Also Like