Tối ưu hóa quản lý Microservices trên Kubernetes với Istio Service Mesh: Đánh giá 6 tháng triển khai thực tế

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

Bối cảnh & Lý do: Áp dụng Service Mesh trong hệ sinh thái Kubernetes

Kiến trúc microservices của chúng tôi trên Kubernetes đang phát triển nhanh chóng. Cùng với sự phát triển đó là những thách thức quen thuộc về khả năng mở rộng.

Việc quản lý lưu lượng truy cập, đảm bảo an ninh vững chắc và đạt được khả năng quan sát toàn diện trên hàng chục dịch vụ phụ thuộc lẫn nhau nhanh chóng trở thành một gánh nặng vận hành đáng kể. Việc triển khai các tính năng như logic thử lại (retry logic), cơ chế ngắt mạch (circuit breakers), TLS lẫn nhau (mTLS) để giao tiếp an toàn và theo dõi yêu cầu từ đầu đến cuối (end-to-end request tracing) tỏ ra phức tạp. Những điều này thường đòi hỏi các thay đổi mã cấp ứng dụng hoặc cơ sở hạ tầng tùy chỉnh rộng rãi, tiêu tốn thời gian của nhà phát triển.

Đây chính là nơi mà Service Mesh phát huy tác dụng. Nó cung cấp một lớp hạ tầng chuyên dụng để quản lý giao tiếp giữa các dịch vụ với nhau. Lớp này trừu tượng hóa phần lớn sự phức tạp cơ bản, giúp nhà phát triển tập trung vào logic nghiệp vụ thay vì đau đầu về mạng. Hơn nữa, nó cung cấp các khả năng mạnh mẽ để quản lý lưu lượng, thực thi chính sách và thu thập dữ liệu đo từ xa (telemetry data).

Trong số nhiều tùy chọn service mesh, Istio nhanh chóng trở thành ứng cử viên hàng đầu của chúng tôi. Tại sao? Bộ tính năng toàn diện, khả năng mở rộng và sự hỗ trợ mạnh mẽ từ cộng đồng đã khiến nó trở thành một lựa chọn dễ dàng. Istio hoạt động bằng cách chèn các sidecar proxy Envoy trực tiếp bên cạnh các vùng chứa ứng dụng của bạn. Các proxy này sau đó chặn tất cả giao tiếp mạng, áp dụng các chính sách được xác định bởi mặt phẳng điều khiển của Istio.

Sau khi vật lộn với những phức tạp này trong một khoảng thời gian dài, tôi nhận ra một sự thật quan trọng: nắm vững các khả năng của service mesh không phải là điều “phải có”, mà là điều “thiết yếu”. Từ kinh nghiệm thực tế của tôi, đây là một kỹ năng cốt lõi cho bất kỳ chuyên gia DevOps hoặc kỹ sư đám mây nào nghiêm túc ngày nay.

Đối với chúng tôi, Istio đã hoàn toàn thay đổi cách chúng tôi quản lý và mở rộng các microservices trên Kubernetes trong sáu tháng qua. Chúng tôi đã chuyển từ việc liên tục khắc phục sự cố sang chủ động kiểm soát môi trường của mình bằng các chính sách rõ ràng.

Cài đặt: Triển khai Istio trên Cluster của bạn

Việc triển khai Istio vào một cụm Kubernetes hiện có nhìn chung khá đơn giản, nhưng đòi hỏi phải cân nhắc kỹ lưỡng về hồ sơ cài đặt bạn chọn. Trước khi bắt đầu, hãy đảm bảo kubectl được cấu hình để truy cập cụm của bạn. Bạn cũng có thể muốn sử dụng helm nếu bạn thích nó hơn istioctl để quản lý các cài đặt.

Bước 1: Tải xuống Istio

Đầu tiên, tải xuống bản phát hành Istio. Luôn kiểm tra tài liệu chính thức của Istio để biết phiên bản ổn định nhất hiện có.

curl -L https://istio.io/downloadIstio | sh -
cd istio-1.x.x # Thay thế bằng phiên bản đã tải xuống của bạn, ví dụ: istio-1.20.0
export PATH=$PWD/bin:$PATH

Lệnh này thuận tiện tải xuống và giải nén gói Istio, sau đó thêm client istioctl vào PATH của bạn. Về cơ bản, istioctl trở thành công cụ dòng lệnh chính của bạn cho mọi thứ liên quan đến Istio.

Bước 2: Cài đặt Istio với một Profile

Istio cung cấp một số hồ sơ cấu hình, mỗi hồ sơ được điều chỉnh cho các môi trường và trường hợp sử dụng khác nhau. Đối với môi trường production, hồ sơ default thường cung cấp sự cân bằng tốt giữa các tính năng và việc sử dụng tài nguyên hiệu quả. Nếu bạn chỉ đang khám phá hoặc phát triển, hồ sơ demo thường là đủ. Đối với triển khai production của chúng tôi, chúng tôi đã chọn default.

istioctl install --set profile=default --verify

Chạy lệnh này sẽ bắt đầu quá trình cài đặt. Nó thiết lập tất cả các Định nghĩa tài nguyên tùy chỉnh (CRD) thiết yếu, triển khai các thành phần mặt phẳng điều khiển của Istio—như Istiod—và cấu hình cổng ingress. Quan trọng là, cờ --verify xác nhận cài đặt thành công, đảm bảo tất cả các thành phần cốt lõi đang hoạt động.

Bước 3: Xác minh cài đặt

Sau khi lệnh cài đặt hoàn tất, điều quan trọng là phải xác nhận rằng tất cả các thành phần mặt phẳng điều khiển của Istio đang hoạt động trong namespace istio-system.

kubectl get ns istio-system
kubectl get pods -n istio-system

Bạn sẽ thấy istio-system được liệt kê dưới dạng một namespace. Quan trọng là, tất cả các pod trong đó—như istiodistio-ingressgateway—phải hiển thị trạng thái Running.

Cấu hình: Tích hợp các dịch vụ của bạn vào Mesh

Giờ đây, khi Istio đã được cài đặt, đã đến lúc tích hợp các dịch vụ hiện có của bạn. Mục tiêu chính ở đây là chèn sidecar proxy Envoy vào các pod ứng dụng của bạn. May mắn thay, Istio có thể tự động chèn các sidecar này vào bất kỳ pod nào được triển khai trong các namespace mà bạn đã gắn nhãn để inject.

Bước 1: Gắn nhãn Namespace của bạn để Istio Inject

Để kích hoạt tính năng tự động chèn sidecar cho tất cả các pod *mới* trong một namespace nhất định, bạn chỉ cần gắn nhãn cho nó. Ví dụ, nếu các ứng dụng của bạn nằm trong namespace default, bạn sẽ sử dụng:

kubectl label namespace default istio-injection=enabled --overwrite

Cờ --overwrite rất quan trọng nếu namespace đã có nhãn istio-injection. Hãy nhớ rằng, điều này chỉ áp dụng cho các pod *mới*. Nếu bạn có các triển khai hiện có, bạn sẽ cần khởi động lại chúng để đảm bảo các sidecar được chèn chính xác:

kubectl rollout restart deployment -n default # Hoặc tên triển khai cụ thể

Bước 2: Triển khai ứng dụng mẫu (ví dụ: Bookinfo)

Để thực sự thấy Istio hoạt động, chúng tôi sẽ triển khai ứng dụng Bookinfo nổi tiếng của nó. Ứng dụng mẫu này có nhiều microservices, minh họa đẹp mắt các mẫu giao tiếp đa dạng. Bắt đầu bằng cách triển khai các dịch vụ này:

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n default

Bây giờ hãy xem các pod của bạn. Đối với mỗi dịch vụ Bookinfo, bạn sẽ thấy hai vùng chứa trên mỗi pod: vùng chứa ứng dụng của bạn *và* sidecar Envoy mới được chèn.

kubectl get pods -n default

Bước 3: Phơi bày ứng dụng với Gateway

Để truy cập ứng dụng Bookinfo từ bên ngoài cụm của bạn, bạn sẽ cần hai thành phần Istio quan trọng: một Gateway và một Virtual Service. Gateway xử lý tất cả lưu lượng truy cập vào và ra cho mesh. Trong khi đó, Virtual Service quy định cách lưu lượng truy cập định tuyến đến các dịch vụ của bạn.

# samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # sử dụng cổng ingress mặc định của Istio
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080
            
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n default

Tiếp theo, bạn cần tìm IP và cổng ingress để truy cập ứng dụng của mình. Hãy nhớ rằng, các chi tiết này sẽ khác nhau tùy thuộc vào môi trường Kubernetes cụ thể của bạn.

export INGRESS_HOST=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

echo "Bạn có thể truy cập ứng dụng Bookinfo tại: http://$GATEWAY_URL/productpage"

Bước 4: Quản lý lưu lượng – Thử nghiệm A/B hoặc Triển khai Canary

Istio thực sự nổi bật với khả năng quản lý lưu lượng tiên tiến. Sau nhiều tháng điều chỉnh định tuyến thủ công, việc áp dụng VirtualServices và DestinationRules của Istio để thử nghiệm A/B và triển khai canary thực sự là một bước đột phá. Hãy thiết lập lưu lượng truy cập ngay bây giờ: chúng tôi sẽ định tuyến 50% đến reviews:v1 và 50% còn lại đến reviews:v3 (phiên bản bao gồm xếp hạng sao).

# reviews-v1-v3-route.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 50
    - destination:
        host: reviews
        subset: v3
      weight: 50
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
            
kubectl apply -f reviews-v1-v3-route.yaml -n default

Thiết lập này đầu tiên định nghĩa các đối tượng DestinationRule. Chúng tạo ra các tập con được đặt tên (như v1, v2v3) có nguồn gốc từ nhãn version của dịch vụ reviews. Sau đó, VirtualService tiếp quản, định tuyến lưu lượng truy cập giữa các tập con này theo trọng số bạn chỉ định.

Bước 5: Kích hoạt Mutual TLS (mTLS) để tăng cường bảo mật

Trong mọi môi trường, bảo mật là tối quan trọng. Istio giúp việc triển khai mTLS trên các dịch vụ của bạn cực kỳ đơn giản. Nó tự động mã hóa và xác thực tất cả giao tiếp giữa các dịch vụ. Đối với nhóm của chúng tôi, đây đã trở thành một tính năng quan trọng để củng cố tư thế bảo mật tổng thể của chúng tôi.

# default-mtls.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
            
kubectl apply -f default-mtls.yaml

Chính sách PeerAuthentication này, khi được áp dụng cho namespace istio-system, buộc tất cả các dịch vụ trong mesh phải sử dụng STRICT mutual TLS. Istio chủ động xử lý việc cấp và xoay vòng chứng chỉ, giảm đáng kể gánh nặng vận hành trong việc bảo mật giao tiếp nội bộ.

Xác minh & Giám sát: Thu thập thông tin chi tiết về Mesh của bạn

Một trong những lợi ích tức thì nhất mà chúng tôi nhận được từ Istio là sự cải thiện đáng kể về khả năng quan sát. Khả năng giám sát lưu lượng truy cập, theo dõi dấu vết và trực quan hóa các phụ thuộc của dịch vụ một cách tự nhiên đã thực sự thay đổi cách chúng tôi gỡ lỗi và hiểu môi trường microservices phức tạp của mình.

Bước 1: Truy cập Bảng điều khiển Istio

Istio tích hợp mượt mà với các công cụ quan sát phổ biến như Kiali, Prometheus và Grafana. Tùy thuộc vào hồ sơ cài đặt của bạn, những công cụ này có thể đã được triển khai hoặc bạn có thể cần cài đặt chúng riêng biệt. Với hồ sơ default, bạn thường có thể truy cập chúng thông qua istioctl:

istioctl dashboard kiali
istioctl dashboard grafana
istioctl dashboard prometheus
  • Kiali: Cung cấp bảng điều khiển toàn diện để quan sát service mesh. Bạn có thể trực quan hóa cấu trúc liên kết mesh, hiểu luồng lưu lượng và phân tích tình trạng dịch vụ.
  • Grafana: Lý tưởng để tạo các bảng điều khiển phong phú, có thể tùy chỉnh bằng cách sử dụng các chỉ số được thu thập bởi Prometheus.
  • Prometheus: Đây là xương sống thiết yếu để thu thập các chỉ số từ cả proxy Envoy và mặt phẳng điều khiển Istio.

Bước 2: Theo dõi yêu cầu với Jaeger

Theo dõi phân tán (Distributed tracing) là hoàn toàn cần thiết để gỡ lỗi microservices. Istio tự động tích hợp với Jaeger (hoặc Zipkin), cung cấp các dấu vết từ đầu đến cuối của các yêu cầu khi chúng di chuyển qua các dịch vụ của bạn. Bạn có thể dễ dàng khởi chạy bảng điều khiển Jaeger:

istioctl dashboard jaeger

Bằng cách gửi yêu cầu đến ứng dụng của bạn—ví dụ, bằng cách làm mới trang sản phẩm Bookinfo—bạn sẽ thấy các dấu vết xuất hiện ngay lập tức trong Jaeger. Những dấu vết này tiết lộ độ trễ và đường dẫn của mỗi yêu cầu qua các dịch vụ khác nhau, giúp bạn dễ dàng xác định các nút thắt cổ chai về hiệu suất.

Bước 3: Quan sát các tuyến lưu lượng và việc thực thi chính sách

Bây giờ, hãy truy cập lại bảng điều khiển Kiali và điều hướng đến chế độ xem Đồ thị. Khi bạn làm mới ứng dụng Bookinfo, bạn sẽ thấy luồng lưu lượng truy cập được biểu diễn trực quan. Vì chúng tôi đã cấu hình VirtualService của reviews để chia lưu lượng 50/50 giữa v1v3, Kiali cung cấp xác nhận trực quan rõ ràng về sự phân phối này. Bạn có thể nhấp vào từng dịch vụ và kết nối để xem các chỉ số chi tiết, dấu vết và các chính sách được áp dụng.

export INGRESS_HOST=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

for i in $(seq 1 100); do curl -s -o /dev/null -w "%{http_code}" http://$GATEWAY_URL/productpage; done

Quan sát biểu đồ Kiali cho dịch vụ reviews khi lệnh này chạy. Bạn sẽ thấy một sự phân chia yêu cầu gần như đồng đều chảy đến các phiên bản v1v3 của dịch vụ. Điều này xác nhận cấu hình quản lý lưu lượng của chúng tôi hoàn toàn hoạt động và hoạt động chính xác như mong đợi.

Sau sáu tháng triển khai thực tế, Istio đã chứng tỏ mình là một lớp không thể thiếu trong ngăn xếp Kubernetes của chúng tôi. Nó cung cấp các khả năng quan trọng để kiểm soát lưu lượng, bảo mật và khả năng quan sát mà nếu không sẽ cực kỳ khó khăn—và tốn nhiều tài nguyên—để triển khai thủ công. Mặc dù chắc chắn có một đường cong học tập, nhưng những lợi ích vận hành mà nó mang lại cho việc quản lý các microservices phức tạp là rất lớn và thực sự mang tính chuyển đổi cho bất kỳ nhóm nào.

Share: