Развертывание приложения 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

Запомните идентификатор проекта — уникальное имя для всех проектов 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 Console нажмите «Активировать Cloud Shell». 4292cbf4971c9786.png .

bce75f34b2c53987.png

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

70f315d7b402b476.png

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

fbe3a0674c982259.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Большую часть, если не всю, работу в этой лаборатории кода можно выполнить с помощью просто браузера или 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».

Захват.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 , частный репозиторий для ваших образов 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.

Сначала убедитесь, что у вас включен Kubernetes Engine API:

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 автоматически внедряются в каждый модуль сервиса.

Чтобы это работало, вам необходимо включить внедрение сайдкара для пространства имен («по умолчанию»), которое вы используете для своих микросервисов. Вы делаете это, применяя метку:

kubectl label namespace default istio-injection=enabled

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

kubectl get namespace -L istio-injection

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

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>

Входной шлюз имеет тип 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

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

Чтобы разрешить входящему трафику достигать сетки, вам необходимо создать шлюз и VirtualService .

Шлюз настраивает балансировщик нагрузки для трафика 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 License.

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:

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

Чтобы подтвердить, что Istio больше нет:

kubectl get pods -n istio-system

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

gcloud container clusters delete hello-istio