Triển khai ứng dụng ASP.NET Core cho Google Kubernetes Engine bằng Istio (Phần 1)

1. Tổng quan

ASP.NET Core là một khung nguồn mở và đa nền tảng để xây dựng các ứng dụng hiện đại dựa trên đám mây và có kết nối Internet bằng ngôn ngữ lập trình C#.

Kubernetes là một hệ thống nguồn mở để tự động hoá việc triển khai, mở rộng quy mô và quản lý các ứng dụng được đóng gói trong vùng chứa. Istio là một khung mở để kết nối, bảo mật, quản lý và giám sát các dịch vụ.

Trong phần đầu tiên của phòng thí nghiệm này, bạn sẽ triển khai một ứng dụng ASP.NET Core đơn giản vào Kubernetes đang chạy trên Google Kubernetes Engine (GKE) và định cấu hình ứng dụng đó để được Istio quản lý.

Trong phần thứ hai của phòng thí nghiệm, bạn sẽ khám phá thêm các tính năng của Istio, chẳng hạn như chỉ số, theo dõi, quản lý lưu lượng truy cập động, chèn lỗi, v.v.

Kiến thức bạn sẽ học được

  • Cách tạo và đóng gói một ứng dụng ASP.NET Core đơn giản trong vùng chứa Docker.
  • Cách tạo một cụm Kubernetes bằng Google Kubernetes Engine (GKE).
  • Cách cài đặt Istio trên một cụm Kubernetes trên GKE.
  • Cách triển khai ứng dụng ASP.NET Core và định cấu hình lưu lượng truy cập của ứng dụng để Istio quản lý.

Bạn cần có

Bạn sẽ sử dụng hướng dẫn này như thế nào?

Chỉ đọc Đọc và hoàn thành bài tập

Bạn đánh giá thế nào về trải nghiệm của mình với Google Cloud Platform?

Người mới bắt đầu Trung cấp Thành thạo

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tốc độ của riêng bạn

  1. Đăng nhập vào Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Hãy nhớ mã dự án, một tên duy nhất trên tất cả các dự án trên Google Cloud (tên ở trên đã được sử dụng và sẽ không hoạt động đối với bạn, xin lỗi!). Sau này trong lớp học lập trình này, chúng ta sẽ gọi nó là PROJECT_ID.

  1. Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên của Google Cloud.

Việc thực hiện lớp học lập trình này sẽ không tốn nhiều chi phí, nếu có. Hãy nhớ làm theo mọi hướng dẫn trong phần "Dọn dẹp" để biết cách tắt các tài nguyên nhằm tránh bị tính phí ngoài phạm vi hướng dẫn này. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí trị giá 300 USD.

Khởi động Cloud Shell

Mặc dù có thể vận hành Google Cloud từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, bạn sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trong Google Cloud.

Kích hoạt Cloud Shell

  1. Trong Cloud Console, hãy nhấp vào Kích hoạt Cloud Shell 4292cbf4971c9786.png.

bce75f34b2c53987.png

Nếu chưa từng khởi động Cloud Shell, bạn sẽ thấy một màn hình trung gian (bên dưới phần hiển thị đầu tiên) mô tả về Cloud Shell. Nếu vậy, hãy nhấp vào Tiếp tục (và bạn sẽ không bao giờ thấy màn hình này nữa). Sau đây là giao diện của màn hình xuất hiện một lần:

70f315d7b402b476.png

Quá trình cung cấp và kết nối với Cloud Shell chỉ mất vài giây.

fbe3a0674c982259.png

Máy ảo này được trang bị tất cả các công cụ phát triển mà bạn cần. Nền tảng này cung cấp một thư mục chính có dung lượng 5 GB và chạy trong Google Cloud, giúp tăng cường đáng kể hiệu suất mạng và hoạt động xác thực. Bạn có thể thực hiện hầu hết, nếu không muốn nói là tất cả, công việc trong lớp học lập trình này chỉ bằng một trình duyệt hoặc Chromebook.

Sau khi kết nối với Cloud Shell, bạn sẽ thấy rằng mình đã được xác thực và dự án đã được đặt thành mã dự án của bạn.

  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng bạn đã được xác thực:
gcloud auth list

Đầu ra của lệnh

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng lệnh gcloud biết về dự án của bạn:
gcloud config list project

Đầu ra của lệnh

[core]
project = <PROJECT_ID>

Nếu không, bạn có thể đặt nó bằng lệnh sau:

gcloud config set project <PROJECT_ID>

Đầu ra của lệnh

Updated property [core/project].

3. Tạo một ứng dụng ASP.NET Core trong Cloud Shell

Trong dấu nhắc Cloud Shell, bạn có thể xác minh rằng công cụ dòng lệnh dotnet đã được cài đặt bằng cách kiểm tra phiên bản của công cụ này. Lệnh này sẽ in phiên bản của công cụ dòng lệnh dotnet đã cài đặt:

dotnet --version

Tiếp theo, hãy tạo một ứng dụng web ASP.NET Core cơ bản.

dotnet new mvc -o HelloWorldAspNetCore

Thao tác này sẽ tạo một dự án và khôi phục các phần phụ thuộc của dự án. Bạn sẽ thấy một thông báo tương tự như bên dưới.

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. Chạy ứng dụng ASP.NET Core

Chúng ta sắp chạy xong ứng dụng. Chuyển đến thư mục ứng dụng.

cd HelloWorldAspNetCore

Cuối cùng, hãy chạy ứng dụng.

dotnet run --urls=http://localhost:8080

Ứng dụng bắt đầu nghe trên cổng 8080.

Hosting environment: Production
Content root path: /home/atameldev/HelloWorldAspNetCore
Now listening on: http://[::]:8080
Application started. Press Ctrl+C to shut down.

Để xác minh rằng ứng dụng đang chạy, hãy nhấp vào nút xem trước trên web ở trên cùng bên phải rồi chọn "Xem trước trên cổng 8080".

Capture.PNG

Bạn sẽ thấy trang web ASP.NET Core mặc định:

f579a9baedc108a9.png

Sau khi bạn xác minh rằng ứng dụng đang chạy, hãy nhấn Ctrl+C để tắt ứng dụng.

5. Đóng gói ứng dụng ASP.NET Core trong một vùng chứa Docker

Tiếp theo, hãy chuẩn bị ứng dụng để chạy dưới dạng một vùng chứa. Bước đầu tiên là xác định vùng chứa và nội dung của vùng chứa đó.

Trong thư mục cơ sở của ứng dụng, hãy tạo một Dockerfile để xác định hình ảnh Docker.

touch Dockerfile

Thêm nội dung sau vào Dockerfile bằng trình chỉnh sửa mà bạn yêu thích (vim, nano,emacs hoặc trình soạn thảo mã của Cloud Shell).

# Use Microsoft's official build .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-sdk/
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /app

# Install production dependencies.
# Copy csproj and restore as distinct layers.
COPY *.csproj ./
RUN dotnet restore

# Copy local code to the container image.
COPY . ./
WORKDIR /app

# Build a release artifact.
RUN dotnet publish -c Release -o out

# Use Microsoft's official runtime .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-aspnet/
FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS runtime
WORKDIR /app
COPY --from=build /app/out ./

# Make sure the app binds to port 8080
ENV ASPNETCORE_URLS http://*:8080

# Run the web service on container startup.
ENTRYPOINT ["dotnet", "HelloWorldAspNetCore.dll"]

Một cấu hình quan trọng có trong Dockerfile là cổng mà ứng dụng lắng nghe lưu lượng truy cập đến (8080). Bạn có thể thực hiện việc này bằng cách thiết lập biến môi trường ASPNETCORE_URLS. Các ứng dụng ASP.NET Core sẽ dùng biến này để xác định cổng cần theo dõi.

Lưu Dockerfile này. Bây giờ, hãy tạo hình ảnh:

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1 .

Sau khi quá trình này hoàn tất (sẽ mất một chút thời gian để tải xuống và trích xuất mọi thứ), bạn có thể thấy hình ảnh được tạo và lưu cục bộ:

docker images

REPOSITORY                             TAG   
gcr.io/yourproject-XXXX/hello-dotnet   v1            

Kiểm thử hình ảnh cục bộ bằng lệnh sau. Lệnh này sẽ chạy một vùng chứa Docker cục bộ trên cổng 8080 từ hình ảnh vùng chứa bạn vừa tạo:

docker run -p 8080:8080 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

Và một lần nữa, hãy tận dụng tính năng Xem trước trên web của Cloud Shell :

Ảnh chụp màn hình từ 2015-11-03 17:20:22.png

Bạn sẽ thấy trang web ASP.NET Core mặc định trong một thẻ mới.

f579a9baedc108a9.png

Sau khi xác minh rằng ứng dụng đang chạy bình thường trên một vùng chứa Docker cục bộ, bạn có thể dừng vùng chứa đang chạy bằng cách nhấn Ctrl-> C.

Giờ đây, khi hình ảnh hoạt động như mong đợi, bạn có thể đẩy hình ảnh đó vào Google Container Registry, một kho lưu trữ riêng cho các hình ảnh Docker của bạn mà mọi dự án trên đám mây của Google đều có thể truy cập (nhưng cũng có thể truy cập từ bên ngoài Google Cloud Platform) :

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

Nếu không có vấn đề gì xảy ra và sau một thời gian ngắn, bạn sẽ thấy hình ảnh vùng chứa xuất hiện trong phần Container Registry (Sổ đăng ký vùng chứa). Lúc này, bạn đã có một hình ảnh Docker trên toàn dự án mà Kubernetes có thể truy cập và điều phối như bạn sẽ thấy trong vài phút nữa.

73558f3a54ce1c0c.png

Nếu muốn tìm hiểu, bạn có thể di chuyển qua các hình ảnh vùng chứa khi chúng được lưu trữ trong Google Cloud Storage bằng cách truy cập vào đường liên kết này: https://console.cloud.google.com/storage/browser/ (đường liên kết đầy đủ thu được sẽ có dạng như sau: https://console.cloud.google.com/project/PROJECT_ID/storage/browser/).

6. Tạo một cụm Kubernetes/GKE bằng Istio

Trước tiên, hãy đảm bảo rằng bạn đã bật Kubernetes Engine API:

gcloud services enable container.googleapis.com

Tạo một cụm Kubernetes. Bạn có thể thay đổi khu vực thành một nơi gần bạn nếu muốn:

gcloud container clusters create hello-istio \
  --cluster-version=latest \
  --machine-type=n1-standard-2 \
  --num-nodes=4 \
  --region europe-west1

Đợi một chút trong khi hệ thống thiết lập cụm cho bạn. Thông tin này sẽ xuất hiện trong phần Kubernetes Engine của bảng điều khiển Google Cloud Platform.

e46fd9c6ee82bcc4.png

Trong lớp học lập trình này, chúng ta sẽ tải và cài đặt Istio từ istio.io. Có các lựa chọn cài đặt khác, bao gồm cả tiện ích bổ sung Istio cho GKEAnthos Service Mesh. Các bước ứng dụng sau bước này sẽ hoạt động trên mọi bản cài đặt Istio.

Trước tiên, hãy tải ứng dụng Istio và các mẫu xuống. Trang phát hành Istio cung cấp các cấu phần phần mềm có thể tải xuống cho một số hệ điều hành. Trong trường hợp này, chúng ta có thể dùng một lệnh thuận tiện để tải xuống và trích xuất bản phát hành mới nhất cho nền tảng hiện tại:

curl -L https://istio.io/downloadIstio | sh -

Tập lệnh sẽ cho bạn biết phiên bản Istio đã được tải xuống:

Istio has been successfully downloaded into the istio-1.8.1 folder on your system.

Thư mục cài đặt chứa các ứng dụng mẫu và tệp nhị phân ứng dụng istioctl. Thay đổi thành thư mục đó:

cd istio-1.8.1

Sao chép và dán lệnh được cung cấp để thêm thư mục bin vào PATH, nhờ đó bạn có thể sử dụng istioctl:

export PATH="$PATH:/home/<YOURHOMEID>/istio-1.8.1/bin"

Xác minh rằng istioctl có sẵn bằng cách kiểm tra xem cụm của bạn đã sẵn sàng cho Istio hay chưa:

istioctl x precheck

Bạn sẽ thấy thông báo Install Pre-Check passed! The cluster is ready for Istio installation.

Cài đặt Istio bằng hồ sơ minh hoạ:

istioctl install --set profile=demo

Istio hiện đã được cài đặt trong cụm của bạn.

Tự động chèn sidecar

Để bắt đầu sử dụng Istio, bạn không cần thay đổi gì cho ứng dụng. Khi bạn định cấu hình và chạy các dịch vụ, các Envoy sidecar sẽ tự động được chèn vào mỗi nhóm cho dịch vụ.

Để làm được việc đó, bạn cần bật tính năng chèn sidecar cho không gian tên ("mặc định") mà bạn dùng cho các vi dịch vụ. Bạn có thể thực hiện việc đó bằng cách áp dụng một nhãn:

kubectl label namespace default istio-injection=enabled

Để xác minh rằng bạn đã áp dụng nhãn thành công, hãy chạy lệnh sau:

kubectl get namespace -L istio-injection

Đầu ra xác nhận rằng tính năng chèn vùng phụ được bật cho không gian tên mặc định:

NAME              STATUS   AGE    ISTIO-INJECTION
default           Active   3m     enabled
istio-system      Active   63s    disabled
...

7. Xác minh quá trình cài đặt

Istio đi kèm với 3 dịch vụ: mặt phẳng điều khiển istiod, cổng vào và cổng ra (bạn có thể coi đây là "các proxy phụ cho phần còn lại của Internet") , lần lượt có tên là istio-ingressgatewayistio-egressgateway.

kubectl get svc -n istio-system

Đầu ra của bạn sẽ có dạng như sau:

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                                                     AGE
istio-egressgateway    ClusterIP      10.55.252.182   <none>
istio-ingressgateway   LoadBalancer   10.55.250.185   35.233.118.42
istiod                 ClusterIP      10.55.253.217   <none>

Cổng Ingress có loại LoadBalancer nên có thể truy cập từ Internet; các cổng khác chỉ cần có thể truy cập từ bên trong cụm.

Tiếp theo, hãy đảm bảo rằng các pod Kubernetes tương ứng đã được triển khai và tất cả các vùng chứa đều đang hoạt động:

kubectl get pods -n istio-system

Khi tất cả các pod đang chạy, bạn có thể tiếp tục.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod: mặt phẳng điều khiển Istio. Xử lý việc định cấu hình và lập trình các sidecar proxy, khám phá dịch vụ, phân phối chứng chỉ và chèn sidecar
  • ingress gateway: Xử lý các yêu cầu đến từ bên ngoài cụm của bạn.
  • egress gateway: Xử lý các yêu cầu gửi đi đến các điểm cuối bên ngoài cụm của bạn.

8. Triển khai ứng dụng

Giờ đây, bạn đã xác minh rằng Istio đã được cài đặt và đang chạy, bạn có thể triển khai ứng dụng ASP.NET Core.

Triển khai và dịch vụ

Trước tiên, hãy tạo một tệp aspnetcore.yaml bằng trình soạn thảo mà bạn yêu thích (vim, nano,emacs hoặc trình soạn thảo mã của Cloud Shell) rồi xác định Kubernetes Deployment và Service cho ứng dụng:

apiVersion: v1
kind: Service
metadata:
  name: aspnetcore-service
  labels:
    app: aspnetcore
spec:
  ports:
  - port: 8080
    name: http
  selector:
    app: aspnetcore
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v1
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v1
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

Nội dung của tệp là các Triển khai và Dịch vụ tiêu chuẩn để triển khai ứng dụng và không chứa bất kỳ nội dung nào dành riêng cho Istio.

Triển khai các dịch vụ vào không gian tên mặc định bằng kubectl:

kubectl apply -f aspnetcore.yaml
service "aspnetcore-service" created
deployment.extensions "aspnetcore-v1" created

Xác minh rằng các pod đang chạy:

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s

Gateway và VirtualService

Để cho phép lưu lượng truy cập đến tiếp cận lưới, bạn cần tạo một Cổng và một VirtualService.

Cổng định cấu hình một trình cân bằng tải cho lưu lượng truy cập HTTP/TCP, thường hoạt động ở rìa của lưới để cho phép lưu lượng truy cập đến cho một ứng dụng. VirtualService xác định các quy tắc kiểm soát cách yêu cầu đối với một dịch vụ được định tuyến trong lưới dịch vụ Istio.

Tạo tệp aspnetcore-gateway.yaml để xác định Cổng:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: aspnetcore-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

Tạo tệp aspnetcore-virtualservice.yaml để xác định VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service

Chạy lệnh kubectl để triển khai Cổng bằng:

kubectl apply -f aspnetcore-gateway.yaml

Lệnh này tạo ra kết quả sau:

gateway.networking.istio.io "aspnetcore-gateway" created

Tiếp theo, hãy chạy lệnh sau để triển khai VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

Lệnh này tạo ra kết quả sau:

virtualservice.networking.istio.io "aspnetcore-virtualservice" created

Xác minh rằng mọi thứ đang chạy:

kubectl get gateway
NAME                      AGE
aspnetcore-gateway   28s
kubectl get virtualservice
NAME                             AGE
aspnetcore-virtualservice   33s

Xin chúc mừng! Bạn vừa triển khai một ứng dụng có hỗ trợ Istio. Tiếp theo, bạn sẽ thấy ứng dụng đang được sử dụng.

9. Kiểm thử ứng dụng

Cuối cùng, bạn có thể thấy ứng dụng đang hoạt động. Bạn cần lấy IP ngoài và cổng của cổng. Bạn có thể xem thông tin này trong phần EXTERNAL-IP:

kubectl get svc istio-ingressgateway -n istio-system

Xuất IP ngoài và cổng sang biến GATEWAY_URL:

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')

export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

Sử dụng curl để kiểm thử ứng dụng. Dịch vụ này sẽ phản hồi bằng mã phản hồi 200:

curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/

Ngoài ra, bạn có thể mở trình duyệt, chuyển đến http://<gatewayurl> để xem ứng dụng:

f579a9baedc108a9.png

10. Xin chúc mừng!

Bạn vừa triển khai một ứng dụng ASP.NET Core đơn giản vào Kubernetes chạy trên Google Kubernetes Engine (GKE) và định cấu hình ứng dụng đó để được Istio quản lý.

Bạn có thể thắc mắc "Istio có lợi ích gì?". Đó là một câu hỏi hay. Cho đến nay, việc Istio quản lý ứng dụng này không mang lại lợi ích gì. Trong phần thứ hai của phòng thí nghiệm, chúng ta sẽ khám phá thêm các tính năng của Istio, chẳng hạn như chỉ số, tính năng theo dõi, quản lý lưu lượng truy cập động, trực quan hoá dịch vụ và chèn lỗi.

Các bước tiếp theo

Giấy phép

Tác phẩm này được cấp phép theo giấy phép Ghi công theo Creative Commons 2.0 Chung.

11. Dọn dẹp

Nếu không tiếp tục phần thứ hai của phòng thí nghiệm, bạn có thể xoá ứng dụng và gỡ cài đặt Istio hoặc chỉ cần xoá cụm Kubernetes.

Xoá ứng dụng

Cách xóa ứng dụng:

kubectl delete -f aspnetcore-gateway.yaml
Kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore.yaml

Cách xác nhận rằng ứng dụng đã bị xoá:

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

Gỡ cài đặt Istio

Cách xoá Istio:

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

Cách xác nhận rằng Istio đã bị xoá:

kubectl get pods -n istio-system

Xoá cụm Kubernetes

gcloud container clusters delete hello-istio