몇 달 전에 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에 익숙해질 수 있는 방법을 잘 알 수 있기를 바랍니다.