Развертывание приложения ASP.NET Core в Google Kubernetes Engine с помощью Istio (часть 1)

1. Обзор

ASP.NET Core — это кроссплатформенный фреймворк с открытым исходным кодом для создания современных облачных и подключенных к интернету приложений с использованием языка программирования C#.

Kubernetes — это система с открытым исходным кодом для автоматизации развертывания, масштабирования и управления контейнеризированными приложениями. Istio — это открытая платформа для подключения, обеспечения безопасности, управления и мониторинга сервисов.

В первой части лабораторной работы вы развернете простое приложение ASP.NET Core в Kubernetes, работающем на Google Kubernetes Engine (GKE), и настроите его для управления с помощью Istio.

Во второй части лабораторной работы вы более подробно изучите возможности Istio, такие как метрики, трассировка, динамическое управление трафиком, внедрение ошибок и многое другое.

Что вы узнаете

  • Как создать и упаковать простое приложение ASP.NET Core в контейнер Docker.
  • Как создать кластер Kubernetes с помощью Google Kubernetes Engine (GKE).
  • Как установить Istio в кластере Kubernetes на GKE.
  • Как развернуть приложение ASP.NET Core и настроить управление трафиком с помощью Istio.

Что вам понадобится

Как вы будете использовать этот учебный материал?

Прочитайте только от начала до конца. Прочитайте текст и выполните упражнения.

Как бы вы оценили свой опыт работы с Google Cloud Platform?

Новичок Средний Профессионал

2. Настройка и требования

Настройка среды для самостоятельного обучения

  1. Войдите в Cloud Console и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Запомните идентификатор проекта (Project ID) — уникальное имя для всех проектов Google Cloud (указанное выше имя уже занято и вам не подойдёт, извините!). В дальнейшем в этом практическом занятии оно будет обозначаться как PROJECT_ID .

  1. Далее вам потребуется включить оплату в Cloud Console, чтобы использовать ресурсы Google Cloud.

Выполнение этого практического задания не должно стоить дорого, если вообще что-либо. Обязательно следуйте инструкциям в разделе «Очистка», где указано, как отключить ресурсы, чтобы избежать дополнительных расходов после завершения этого урока. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с ноутбука, в этом практическом занятии вы будете использовать Google Cloud Shell — среду командной строки, работающую в Google Cloud.

Активировать Cloud Shell

  1. В консоли Cloud нажмите «Активировать Cloud Shell» . 4292cbf4971c9786.png .

bce75f34b2c53987.png

Если вы никогда раньше не запускали Cloud Shell, вам будет показан промежуточный экран (внизу), описывающий его назначение. В этом случае нажмите «Продолжить» (и вы больше никогда его не увидите). Вот как выглядит этот одноразовый экран:

70f315d7b402b476.png

Подготовка и подключение к Cloud Shell займут всего несколько минут.

fbe3a0674c982259.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предоставляет постоянный домашний каталог размером 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Большая часть, если не вся, работа в этом практическом задании может быть выполнена с помощью обычного браузера или вашего Chromebook.

После подключения к Cloud Shell вы увидите, что ваша аутентификация пройдена и что проект уже настроен на ваш идентификатор проекта.

  1. Выполните следующую команду в Cloud Shell, чтобы подтвердить свою аутентификацию:
gcloud auth list

вывод команды

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project

вывод команды

[core]
project = <PROJECT_ID>

Если это не так, вы можете установить это с помощью следующей команды:

gcloud config set project <PROJECT_ID>

вывод команды

Updated property [core/project].

3. Создайте приложение ASP.NET Core в Cloud Shell.

В командной строке Cloud Shell вы можете проверить, установлен ли инструмент командной строки dotnet, проверив его версию. В результате должна отобразиться версия установленного инструмента командной строки dotnet:

dotnet --version

Далее создайте новый шаблон веб-приложения ASP.NET Core.

dotnet new mvc -o HelloWorldAspNetCore

Это должно создать проект и восстановить его зависимости. Вы должны увидеть сообщение, похожее на приведенное ниже.

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. Запустите приложение ASP.NET Core.

Мы почти готовы запустить наше приложение. Перейдите в папку приложения.

cd HelloWorldAspNetCore

Наконец, запустите приложение.

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

Приложение начинает прослушивать порт 8080.

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

Чтобы убедиться, что приложение запущено, нажмите кнопку предварительного просмотра в веб-версии в правом верхнем углу и выберите «Предварительный просмотр на порту 8080».

Capture.PNG

Вы увидите стандартную веб-страницу ASP.NET Core:

f579a9baedc108a9.png

После того, как вы убедитесь, что приложение запущено, нажмите Ctrl+C, чтобы закрыть его.

5. Упакуйте приложение ASP.NET Core в контейнер Docker.

Далее подготовьте ваше приложение к работе в контейнере. Первым шагом является определение контейнера и его содержимого.

В корневом каталоге приложения создайте Dockerfile , определяющий образ Docker.

touch Dockerfile

Добавьте следующее в Dockerfile , используя ваш любимый редактор ( vim, nano,emacs или редактор кода 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"]

Важным параметром в вашем Dockerfile является порт, на котором приложение принимает входящий трафик (8080). Это достигается путем установки переменной среды ASPNETCORE_URLS , которую приложения ASP.NET Core используют для определения порта, на котором следует принимать трафик.

Сохраните этот Dockerfile . Теперь давайте соберем образ:

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

После завершения этого процесса (потребуется некоторое время для загрузки и распаковки всего содержимого) вы увидите, что образ создан и сохранен локально:

docker images

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

Проверьте образ локально с помощью следующей команды, которая запустит контейнер Docker локально на порту 8080 из созданного вами образа контейнера:

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

И снова воспользуйтесь функцией предварительного просмотра веб-страниц в CloudShell:

Скриншот от 03.11.2015 17:20:22.png

В новой вкладке должна открыться стандартная веб-страница ASP.NET Core.

f579a9baedc108a9.png

После того, как вы убедитесь, что приложение корректно работает локально в контейнере Docker, вы можете остановить запущенный контейнер, нажав Ctrl-> C .

Теперь, когда образ работает как положено, вы можете загрузить его в Google Container Registry — частный репозиторий для ваших образов Docker, доступный из любого проекта Google Cloud (а также извне Google Cloud Platform):

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

Если все пройдет успешно, через некоторое время вы сможете увидеть образ контейнера в разделе « Реестр контейнеров» . На этом этапе у вас будет доступен образ Docker для всего проекта, к которому Kubernetes сможет получить доступ и управлять им, как вы увидите через несколько минут.

73558f3a54ce1c0c.png

Если вам интересно, вы можете просмотреть образы контейнеров, хранящиеся в Google Cloud Storage, перейдя по этой ссылке: https://console.cloud.google.com/storage/browser/ (полная ссылка должна выглядеть примерно так: https://console.cloud.google.com/project/ PROJECT_ID /storage/browser/).

6. Создайте кластер Kubernetes/GKE с помощью Istio.

Во-первых, убедитесь, что у вас включен API Kubernetes Engine:

gcloud services enable container.googleapis.com

Создайте кластер Kubernetes. При желании вы можете изменить регион на более близкий к вашему:

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

Подождите несколько минут, пока ваш кластер будет настроен. Он отобразится в разделе Kubernetes Engine в консоли Google Cloud Platform.

e46fd9c6ee82bcc4.png

Для этой практической работы мы скачаем и установим Istio с сайта istio.io. Существуют и другие варианты установки, включая дополнение Istio для GKE и Anthos Service Mesh . Следующие шаги по применению будут работать на любой установленной версии Istio.

Для начала давайте загрузим клиент Istio и примеры. На странице релизов Istio доступны файлы для загрузки для нескольких операционных систем. В нашем случае мы можем использовать удобную команду для загрузки и распаковки последней версии для нашей текущей платформы:

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

Скрипт покажет вам версию Istio, которая была загружена:

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

В установочном каталоге находятся примеры приложений и исполняемый файл клиента istioctl . Перейдите в этот каталог:

cd istio-1.8.1

Скопируйте и вставьте предоставленную команду, чтобы добавить каталог bin в переменную PATH , и вы сможете использовать istioctl :

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

Убедитесь в доступности istioctl , проверив готовность вашего кластера к работе с Istio:

istioctl x precheck

Вы должны увидеть сообщение: « Install Pre-Check passed! The cluster is ready for Istio installation.

Установите Istio с демонстрационным профилем:

istioctl install --set profile=demo

Istio теперь установлен в вашем кластере.

Автоматический впрыск топлива в коляску

Для начала использования Istio вам не нужно вносить никаких изменений в приложение. При настройке и запуске сервисов в каждый под для сервиса автоматически внедряются сайдкары Envoy.

Для этого необходимо включить внедрение сайдкаров для пространства имен ('default'), которое вы используете для своих микросервисов. Это делается путем применения метки:

kubectl label namespace default istio-injection=enabled

Чтобы убедиться в успешном применении метки, выполните следующую команду:

kubectl get namespace -L istio-injection

Полученные данные подтверждают, что внедрение сайдкаров включено для пространства имен по умолчанию:

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

7. Проверьте установку.

Istio включает в себя три сервиса: плоскость управления istiod и входящие и исходящие шлюзы (которые можно рассматривать как «дополнительные прокси для остальной части Интернета»), названные соответственно istio-ingressgateway и istio-egressgateway .

kubectl get svc -n istio-system

Результат должен выглядеть примерно так:

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>

Шлюз Ingress Gateway имеет тип LoadBalancer , поэтому он доступен из Интернета; остальные шлюзы должны быть доступны только внутри кластера.

Далее убедитесь, что соответствующие поды Kubernetes развернуты и все контейнеры запущены и работают:

kubectl get pods -n istio-system

Когда все модули будут запущены, вы можете продолжить.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod : плоскость управления Istio. Отвечает за настройку и программирование прокси-сайдкаров, обнаружение сервисов, распространение сертификатов и внедрение сайдкаров.
  • ingress gateway : обрабатывает входящие запросы извне вашего кластера.
  • egress gateway : обрабатывает исходящие запросы к конечным точкам за пределами вашего кластера.

8. Разверните приложение.

Теперь, когда вы убедились, что Istio установлен и запущен, вы можете развернуть приложение ASP.NET Core.

Развертывание и обслуживание

Сначала создайте файл aspnetcore.yaml с помощью вашего любимого редактора ( vim, nano,emacs или редактора кода Cloud Shell) и определите развертывание и службу Kubernetes для приложения:

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

Содержимое файла представляет собой стандартные развертывания и службы для развертывания приложения и не содержит ничего специфичного для Istio.

Разверните сервисы в пространстве имен по умолчанию с помощью kubectl :

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

Убедитесь, что поды запущены:

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

Шлюз и виртуальный сервис

Для обеспечения доступа входящего трафика к сети необходимо создать шлюз (Gateway) и виртуальный сервис (VirtualService) .

Шлюз (Gateway) настраивает балансировщик нагрузки для HTTP/TCP-трафика, чаще всего работающий на границе сети для обеспечения входящего трафика для приложения. Виртуальный сервис (VirtualService) определяет правила, управляющие маршрутизацией запросов к сервису внутри сервисной сети Istio.

Создайте файл aspnetcore-gateway.yaml для определения шлюза:

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:
    - "*"

Создайте файл aspnetcore-virtualservice.yaml для определения виртуальной службы (VirtualService):

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

Для развертывания шлюза выполните команду kubectl:

kubectl apply -f aspnetcore-gateway.yaml

В результате выполнения команды будет получен следующий вывод:

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

Далее выполните следующую команду для развертывания VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

В результате выполнения команды будет получен следующий вывод:

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

Убедитесь, что всё работает:

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

Поздравляем! Вы только что развернули приложение, поддерживающее Istio. Далее вы увидите, как приложение используется.

9. Протестируйте приложение.

Наконец-то вы можете увидеть приложение в действии. Вам нужно получить внешний IP-адрес и порт шлюза. Они указаны в разделе EXTERNAL-IP :

kubectl get svc istio-ingressgateway -n istio-system

Сохраните внешний IP-адрес и порт в переменную 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

Используйте curl для тестирования приложения. Сервис должен ответить кодом 200 :

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

В качестве альтернативы вы можете открыть браузер и перейти по адресу http://<gatewayurl> чтобы просмотреть приложение:

f579a9baedc108a9.png

10. Поздравляем!

Вы только что развернули простое приложение ASP.NET Core в Kubernetes, работающем на Google Kubernetes Engine (GKE), и настроили его для управления с помощью Istio.

Возможно, вы задаетесь вопросом: «В чем преимущество Istio?». Это отличный вопрос. Пока что нет никаких преимуществ в использовании Istio для управления этим приложением. Во второй части лабораторной работы мы подробнее рассмотрим возможности Istio, такие как метрики, трассировка, динамическое управление трафиком, визуализация сервисов и внедрение ошибок.

Следующие шаги

Лицензия

Данная работа распространяется под лицензией Creative Commons Attribution 2.0 Generic.

11. Уборка

Если вы не собираетесь переходить ко второй части лабораторной работы, вы можете удалить приложение и деинсталлировать Istio, или же просто удалить кластер Kubernetes.

Удалите приложение

Чтобы удалить приложение:

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

Чтобы убедиться, что приложение удалено:

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

Удалите Istio

Чтобы удалить Istio:

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

Чтобы убедиться, что Истио исчез:

kubectl get pods -n istio-system

Удалить кластер Kubernetes

gcloud container clusters delete hello-istio