Ở bài viết trước mình đã triển trình bày cách mà mình thiết lập NGINX Ingress và MetalLB trên cluster. Bên cạnh đó, mình cũng đã cài đặt 1 Reverse Proxy trên host computer (Hyper-V Server) làm nhiệm vụ điều hướng request đến các dịch vụ khác nằm ngoài K8s cluster.
Trong viết này mình sẽ giới thiệu cách cài đặt Istio mesh server trên Kubernetes cluster.

Microsoft Hyper-V server
Cài đặt Istio service mesh
Invoke-WebRequest -Uri 'https://github.com/istio/istio/releases/download/1.11.1/istio-1.11.1-win.zip' -OutFile 'C:\istio.zip' Expand-Archive -LiteralPath 'C:\istio.zip' -DestinationPath C:\ Remove-Item 'C:\istio.zip'
Thêm thư mục C:\istio-1.11.1\bin vào PATH environment để powershell có thể sử dụng command istioctl
$oldPath = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path $newPath = "$oldPath;C:\istio-1.11.1\bin" Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
Cài đặt Istio với profile demo
istioctl install --set profile=demo -y kubectl label namespace default istio-injection=enabled
Cài đặt một số Dashboard dùng để quản lý Istio:
cd C:\istio-1.11.1 kubectl apply -f samples/addons
Thiết lập Nodeport services
Deploy NodePort service cho phép truy xuất vào các ứng dụng trong cluster. Dưới đây là nội dung file istio-services-node-port.yaml
#Grafana apiVersion: v1 kind: Service metadata: labels: app: grafana release: istio name: grafana-np namespace: istio-system spec: ports: - name: http nodePort: 32493 port: 3000 protocol: TCP targetPort: 3000 selector: app: grafana sessionAffinity: None type: NodePort --- #prometheus apiVersion: v1 kind: Service metadata: labels: app: prometheus release: istio name: prometheus-np namespace: istio-system spec: ports: - name: http nodePort: 32494 port: 9090 protocol: TCP targetPort: 9090 selector: app: prometheus sessionAffinity: None type: NodePort --- #jaeger apiVersion: v1 kind: Service metadata: labels: app: jaeger release: istio name: tracing-np namespace: istio-system spec: ports: - name: http-tracing nodePort: 32495 port: 80 protocol: TCP targetPort: 16686 selector: app: jaeger sessionAffinity: None type: NodePort --- #kiali apiVersion: v1 kind: Service metadata: labels: app: kiali release: istio name: kiali-np namespace: istio-system spec: ports: - name: http-kiali nodePort: 32496 port: 20001 protocol: TCP targetPort: 20001 selector: app: kiali sessionAffinity: None type: NodePort
Sau đó chúng ta chạy lệnh để deploy
kubectl apply -f istio-services-node-port.yaml
Add NetNatStaticMapping, điều này cho phép truy cập đến NodePort server từ máy tính khác
Add-NetNatStaticMapping -ExternalIPAddress "0.0.0.0/24" -ExternalPort 32493 -Protocol TCP -InternalIPAddress "10.10.0.10" -InternalPort 32493 -NatName KubeNatNet Add-NetNatStaticMapping -ExternalIPAddress "0.0.0.0/24" -ExternalPort 32494 -Protocol TCP -InternalIPAddress "10.10.0.10" -InternalPort 32494 -NatName KubeNatNet Add-NetNatStaticMapping -ExternalIPAddress "0.0.0.0/24" -ExternalPort 32495 -Protocol TCP -InternalIPAddress "10.10.0.10" -InternalPort 32495 -NatName KubeNatNet Add-NetNatStaticMapping -ExternalIPAddress "0.0.0.0/24" -ExternalPort 32496 -Protocol TCP -InternalIPAddress "10.10.0.10" -InternalPort 32496 -NatName KubeNatNet
Đến đây có thể truy cập các dashboar lần lượt các địa chỉ: http://Hyper-V-local-ip:32493, http://Hyper-V-local-ip:32494, http://Hyper-V-local-ip:32495, http://Hyper-V-local-ip:32496
Hiện tại thì NGINX của host đang quản lý các request HTTP(s) đến cluster cũng như các service khác, điều này mình đã thực hiện ở các bài viết trước. Bây giờ mình sử dụng Istio để quản lý các request đến cluster, nên NGINX cần bàn giao lại cho Istio bằng cách dừng service đang chạy và xóa Firewall rule dành cho nó.
net stop nginx 2>&1 | % { $_.ToString() } Remove-NetFirewallRule -DisplayName "Allow HTTP and HTTPs over Nginx"
Sau đó thêm Firewall rule để Istio quản lý các HTTP(s) request đến cluster
$INGRESS_HOST = (kubectl -n istio-system get service istio-ingressgateway -o json | ConvertFrom-Json).status.loadBalancer.ingress[0].ip $INGRESS_PORT = ((kubectl -n istio-system get service istio-ingressgateway -o json | ConvertFrom-Json).spec.ports | where { $_.name -eq "http2" }).port $SECURE_INGRESS_PORT = ((kubectl -n istio-system get service istio-ingressgateway -o json | ConvertFrom-Json).spec.ports | where { $_.name -eq "https" }).port Add-NetNatStaticMapping -ExternalIPAddress "0.0.0.0/24" -ExternalPort 80 -Protocol TCP -InternalIPAddress "$INGRESS_HOST" -InternalPort $INGRESS_PORT -NatName KubeNatNet Add-NetNatStaticMapping -ExternalIPAddress "0.0.0.0/24" -ExternalPort 443 -Protocol TCP -InternalIPAddress "$INGRESS_HOST" -InternalPort $SECURE_INGRESS_PORT -NatName KubeNatNet
Istio traffic split sample
Trong ví dụ này Istio sẽ điều phối các request tới 1 endpoint, 50% request sẽ điều hướng tới app apple, 50% request còn lại sẽ điều hướng tới app banana. Tỷ lệ này mình có thể cài đặt tùy ý.
apple.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: apple-app labels: app: fruit name: apple spec: selector: matchLabels: app: fruit name: apple template: metadata: labels: app: fruit name: apple spec: containers: - name: apple-app image: hashicorp/http-echo args: - "-text=apple" imagePullPolicy: Always ports: - containerPort: 5678
banana.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: banana-app labels: app: fruit name: banana spec: selector: matchLabels: app: fruit name: banana template: metadata: labels: app: fruit name: banana spec: containers: - name: banana-app image: hashicorp/http-echo args: - "-text=banana" imagePullPolicy: Always ports: - containerPort: 5678
istio.yaml
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: fruit-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "fruits.adtsolutions.com.vn" --- apiVersion: v1 kind: Service metadata: name: fruit-service labels: app: fruit spec: ports: - port: 5678 selector: app: fruit --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: fruit-rule spec: host: fruit-service subsets: - name: fruit-apple labels: name: apple - name: fruit-banana labels: name: banana --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: fruit-virtualservice spec: hosts: - "fruits.adtsolutions.com.vn" gateways: - fruit-gateway http: - match: - uri: prefix: / route: - destination: host: fruit-service #Name of the service subset: fruit-apple weight: 50 - destination: host: fruit-service #Name of the service subset: fruit-banana weight: 50
Chạy các lệnh sau để deploy các resources:
kubectl create namespace example kubectl label namespace example istio-injection=enabled kubectl -n example apply -f apple.yaml kubectl -n example apply -f banana.yaml kubectl -n example apply -f istio.yaml