Published on

Microsoft Hyper-V Server - Thiết lập Kubernetes NGINX Ingress và MetalLB

Sau khi cài đặt xong công cụ để quản lý Kubernetes cluster, tiếp theo mình sẽ thực hiện tiếp các bước để deploy một demo trên Kubernetes. Trong bài viết này:

  • Cài đặt NGINX trên Hyper-V server nó đóng vài trò là Reverse Proxy quản lý traffic đến server
  • Deploy Nginx Ingress Controller và MetalLB load balancer trên cluster
  • Deploy một ví dụ trên Kuberentes cluster

Như sơ đồ hệ thống ở trên thì mình cần 1 Reverse Proxy ở phía trước K8s Cluster để điều hướng request đến các service.

NGINX Reverse Proxy trên Microsoft Hyper-V server

Cài đặt Nginx

Bạn có thể dùng bản nginx/Window mặc định, tuy nhiên bản này không có module --with-stream_ssl_module--with-stream_ssl_preread_module. Trong bài viết này mình sử dụng bản tự build của mình có thêm 2 module ở trên.

Như thường lệ, mở Window Admin Center > PowerShell và thực thi lệnh trên server:

Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/nvtienanh/hyperv-k8s/main/nginx/nginx.zip' -OutFile 'C:\nginx.zip'
Expand-Archive -LiteralPath 'C:\nginx.zip' -DestinationPath C:\
Remove-Item 'C:\nginx.zip'

Cài đặt winSW

Nginx windows không hỗ trợ chạy dưới dạng 1 service vì vậy mà mình cài Windows Service Wrapper để cho phép nginx chạy dưới dạng là 1 service

Invoke-WebRequest -Uri https://github.com/winsw/winsw/releases/download/v2.11.0/WinSW-x64.exe -OutFile 'C:\nginx\nginx-service.exe'

Tạo file nginx-service.xml trong thư mục C:\nginx với nội dung:

<configuration>
  <id>nginx</id>
  <name>nginx</name>
  <description>nginx</description>
  <executable>%BASE%/nginx.exe</executable>
  <stopexecutable>%BASE%/nginx.exe -s stop</stopexecutable>
  <logpath>%BASE%/logs/</logpath>
  <logmode>roll</logmode>
  <depend></depend>
</configuration>

Cài đặt nginx service:

cd C:\nginx
.\nginx-service.exe install
net start nginx 2>&1 | % { $_.ToString() }

Cấu hình để nginx tự chạy khi sau khi server chạy bằng cách tạo file C:\nginx\startup.ps1 với nội dung

net start nginx 2>&1 | % { $_.ToString() }

Rồi chạy lệnh tạo scheduled job, mỗi khi Server khởi động thì sẽ tự chạy Nginx cùng windows.

$trigger = New-JobTrigger -AtStartup -RandomDelay 00:00:30
Register-ScheduledJob -Trigger $trigger -FilePath C:\nginx\startup.ps1 -Name StartNginx

Enable Firewall

Thiết lập cho phép nginx sử dụng cổng 80 và 443

New-NetFirewallRule -DisplayName "Allow HTTP and HTTPs over Nginx" -Group "NGINX Reverse Proxy" -Direction Inbound -Action Allow -EdgeTraversalPolicy Allow -Protocol TCP -LocalPort 80,443 -Program "C:\nginx\nginx.exe"

Kubernetes cluster

Cài đặt NGINX Ingress controller

Mình sử dụng Ingress nginx (provider cloud), sau khi cài đặt xong phải thiết lập Bare-metal hoặc Cloud Load balancer.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/cloud/deploy.yaml

Cert manager để quản lý SSL sau này

kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml

MetalLB

MetalLB cung cấp triển khai cân bằng tải mạng cho các cụm Kubernetes không chạy trên nền tảng nhà cung dịch vụ cloud, cho phép sử dụng hiệu quả Dịch vụ LoadBalancer trong bất kỳ cụm nào.

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml

Sau khi deploy xong, cần phải cấu hình dải IP mà MetalLB có thể sử dụng, dải IP này nằm trong subnet 10.10.0.0/24 của KubeNatNet và không trùng với IP của các K8s node. Dưới đây là file metallb-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 10.10.0.200-10.10.0.250

Sau đó apply file yaml vừa tạo

kubectl apply -f metallb-config.yaml

Thử deploy app đơn giản

Trong ví dụ này mình sẽ demo triển khi 1 dứng dụng lên kubernetes như thế nào. Tóm tắt lại trong ví dụ này sẽ deploy 2 app trên 2 đường dẫn:

  • apple.adtsolutions.com.vn: truy cập vào sẽ trả về chữ apple
  • banana.adtsolutions.com.vn: truy cập sẽ trả về chữ banana

apple.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: apple-app
  labels:
    app: apple
spec:
  selector:
    matchLabels:
      app: apple
  template:
    metadata:
      labels:
        app: apple
    spec:
      containers:
        - name: apple-app
          image: hashicorp/http-echo
          args:
            - '-text=apple'
          imagePullPolicy: Always
          ports:
            - containerPort: 5678
---
kind: Service
apiVersion: v1
metadata:
  name: apple-service
spec:
  selector:
    app: apple
  ports:
    - port: 5678 # Default port for image
  type: LoadBalancer

banana.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: banana-app
  labels:
    app: banana
spec:
  selector:
    matchLabels:
      app: banana
  template:
    metadata:
      labels:
        app: banana
    spec:
      containers:
        - name: banana-app
          image: hashicorp/http-echo
          args:
            - '-text=banana'
          imagePullPolicy: Always
          ports:
            - containerPort: 5678
---
kind: Service
apiVersion: v1
metadata:
  name: banana-service
spec:
  selector:
    app: banana
  ports:
    - port: 5678
  type: LoadBalancer
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: banana-ingress
  labels:
    app: banana-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: banana.adtsolutions.com.vn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: banana-service
                port:
                  number: 5678
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: apple-ingress
  labels:
    app: apple-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: apple.adtsolutions.com.vn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: apple-service
                port:
                  number: 5678
kubectl create namespace example
kubectl -n example apply -f apple.yaml
kubectl -n example apply -f banana.yaml
kubectl -n example apply -f ingress.yaml

Các file yaml có thể download trên GitHub của mình

Chi tiết hơn nữa các bạn có thể theo dõi video