- Đăng vào
Microsoft Hyper-V Server - Cài đặt Istio service mesh trên K8s cluster
Ở 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.
HMicrosoft 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
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
Chi tiết có thể theo dõi trong video này