Разработка приложения Kubernetes для База данных SQL Azure

Применимо к:База данных SQL Azure

В этом руководстве описано, как разработать современное приложение с помощью Python, Контейнеров Docker, Kubernetes и База данных SQL Azure.

Разработка современных приложений имеет несколько проблем. От выбора "стека" интерфейсного интерфейса через хранилище данных и обработку из нескольких конкурирующих стандартов, обеспечивая высокий уровень безопасности и производительности, разработчики должны обеспечить масштабирование приложений и хорошо работать и поддерживать их на нескольких платформах. Для этого последнего требования объединение приложения в технологии контейнеров, такие как Docker и развертывание нескольких контейнеров на платформе Kubernetes, теперь является де rigueur в разработке приложений.

В этом примере мы рассмотрим использование Python, Контейнеров Docker и Kubernetes — все работает на платформе Microsoft Azure. Использование Kubernetes означает, что у вас также есть гибкость использования локальных сред или даже других облаков для простого и согласованного развертывания приложения и позволяет развертывать многооблачные развертывания для обеспечения еще более высокой устойчивости. Мы также будем использовать База данных SQL Microsoft Azure для службы, масштабируемой, высоконадежной и безопасной среды для хранения и обработки данных. В большинстве случаев другие приложения часто используют База данных SQL Microsoft Azure уже, и этот пример приложения можно использовать для дальнейшего использования и обогащения этих данных.

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

Использование Python, контейнеров Docker, Kubernetes и пример базы данных AdventureWorksLT в практическом примере

Компания AdventureWorks (вымышленная) использует базу данных, которая хранит данные о продажах и маркетинге, продуктах, клиентах и производстве. Он также содержит представления и хранимые процедуры, которые объединяют сведения о продуктах, таких как название продукта, категория, цена и краткое описание.

Команда разработчиков AdventureWorks хочет создать проверку концепции (PoC), которая возвращает данные из представления в AdventureWorksLT базе данных и сделать их доступными в качестве REST API. С помощью этого PoC команда разработчиков создаст более масштабируемое и многооблачное готовое приложение для команды продаж. Они выбрали платформу Microsoft Azure для всех аспектов развертывания. PoC использует следующие элементы:

  • Приложение Python с помощью пакета Flask для головного веб-развертывания.
  • Контейнеры Docker для изоляции кода и среды, хранящиеся в частном реестре, чтобы вся компания могли повторно использовать контейнеры приложений в будущих проектах, экономя время и деньги.
  • Kubernetes для упрощения развертывания и масштабирования и предотвращения блокировки платформы.
  • База данных SQL Microsoft Azure для выбора размера, производительности, масштабирования, автоматического управления и резервного копирования в дополнение к хранилищу реляционных данных и обработке на самом высоком уровне безопасности.

В этой статье мы объясним процесс создания всего проекта проверки концепции. Ниже приведены общие действия по созданию приложения.

  1. Настройка предварительных требований
  2. Создание приложения
  3. Создание контейнера Docker для развертывания приложения и тестирования
  4. Создание реестра службы контейнеров Azure (ACS) и загрузка контейнера в реестр ACS
  5. Создание среды Служба Azure Kubernetes (AKS)
  6. Развертывание контейнера приложения из реестра ACS в AKS
  7. Тестирование приложения
  8. Очистка

Необходимые компоненты

В этой статье существует несколько значений, которые следует заменить. Убедитесь, что эти значения последовательно заменяются на каждом шаге. Вы можете открыть текстовый редактор и удалить эти значения, чтобы задать правильные значения при работе с проектом проверки концепции:

  • ReplaceWith_AzureSubscriptionName: замените это значение именем подписки Azure, которое у вас есть.
  • ReplaceWith_PoCResourceGroupName: замените это значение именем группы ресурсов, которое вы хотите создать.
  • ReplaceWith_AzureSQLDBServerName: замените это значение именем создаваемого База данных SQL Azure логического сервера с помощью портал Azure.
  • ReplaceWith_AzureSQLDBSQLServerLoginName: замените это значение значением имени пользователя SQL Server, создаваемого в портал Azure.
  • ReplaceWith_AzureSQLDBSQLServerLoginPassword: замените это значение значением пароля пользователя SQL Server, создаваемого в портал Azure.
  • ReplaceWith_AzureSQLDBDatabaseName: замените это значение именем создаваемого База данных SQL Azure с помощью портал Azure.
  • ReplaceWith_AzureContainerRegistryName: замените это значение именем Реестр контейнеров Azure, который вы хотите создать.
  • ReplaceWith_AzureKubernetesServiceName: замените это значение именем Служба Azure Kubernetes, которое вы хотите создать.

Разработчики в AdventureWorks используют сочетание систем Windows, Linux и Apple для разработки, поэтому они используют Visual Studio Code в качестве своей среды и git для управления версиями, оба из которых выполняют кроссплатформенную платформу.

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

  1. Python, pip и пакеты . Команда разработчиков выбирает язык программирования Python в качестве стандарта для этого веб-приложения. В настоящее время они используют версию 3.9, но любая версия, поддерживающая необходимые пакеты PoC, является приемлемой.

  2. Команда использует pyodbc пакет для доступа к базе данных.

  3. Команда использует ConfigParser пакет для управления переменными конфигурации и настройки.

  4. Команда использует пакет Flask для веб-интерфейса для приложения.

  5. Затем команда установила средство Azure CLI, легко идентифицируемо с az помощью синтаксиса. Это кроссплатформенное средство позволяет использовать командную строку и сценарий для PoC, чтобы они могли повторять шаги по мере внесения изменений и улучшений.

  6. При настройке Azure CLI команда входит в свою подписку Azure и задает имя подписки, которую они использовали для PoC. Затем они убедились, что сервер База данных SQL Azure и база данных доступны для подписки:

    az login
    az account set --name "ReplaceWith_AzureSubscriptionName"
    az sql server list
    az sql db list ReplaceWith_AzureSQLDBDatabaseName 
    
  7. Группа ресурсов Microsoft Azure — это логический контейнер, содержащий связанные ресурсы для решения Azure. Как правило, ресурсы, использующие тот же жизненный цикл, добавляются в ту же группу ресурсов, чтобы можно было легко развертывать, обновлять и удалять их как группу. Группа ресурсов хранит метаданные о ресурсах и может указать расположение для группы ресурсов.

    Группы ресурсов можно создавать и управлять с помощью портал Azure или Azure CLI. Они также можно использовать для группировки связанных ресурсов для приложения и разделения их на группы для рабочей и непроизводства или любой другой организационной структуры, которую вы предпочитаете.

    Screenshot from the Azure portal showing how to search for and filter for Azure Resource groups.

    В следующем фрагменте кода вы увидите az команду, используемую для создания группы ресурсов. В нашем примере мы используем регион eastusв Azure.

    az group create --name ReplaceWith_PoCResourceGroupName --location eastus
    
  8. Команда разработчиков создает База данных SQL Azure с AdventureWorksLT установленной примером базы данных с помощью имени входа, прошедшего проверку подлинности SQL.

    AdventureWorks стандартизировалась на платформе системы управления реляционными базами данных Microsoft SQL Server, и команда разработчиков хочет использовать управляемую службу для базы данных, а не устанавливать локально. Использование База данных SQL Azure позволяет этой управляемой службе быть полностью совместимой с кодом, где бы они ни выполняли подсистему SQL Server: локальную, в контейнере, в Linux или Windows или даже в среде Интернета вещей (IoT).

    1. Во время создания они использовали портал управления Azure для установки брандмауэра для приложения на локальный компьютер разработки и изменили значение по умолчанию, которое вы видите здесь, чтобы разрешить все службы Azure, а также получить учетные данные подключения.

      Screenshot from the Azure portal showing the Create SQL Database page. On the Networking tab, for Connectivity method, the Public endpoint option is selected. The Add current client IP Address option is Yes.

      С помощью этого подхода база данных может быть доступна в другом регионе или даже другой подписке.

    2. Команда настроит имя входа, прошедшее проверку подлинности SQL для тестирования, но вернется к этому решению в проверке безопасности.

    3. Команда использовала образец AdventureWorksLT базы данных для PoC, используя ту же группу ресурсов PoC. Не беспокойтесь, в конце этого руководства мы очистим все ресурсы в этой новой группе ресурсов PoC.

    4. Для развертывания База данных SQL Azure можно использовать портал Azure. При создании База данных SQL Azure на вкладке "Дополнительные параметры" для параметра "Использовать существующие данные" выберите "Пример".

      Screenshot from the Azure portal showing the Create SQL Database page. In the Additional settings tab, for the Use existing data option, select Sample.

    5. Наконец, на вкладке "Теги" новой База данных SQL Azure команда разработчиков предоставила метаданные тегов для этого ресурса Azure, например owner или ServiceClass или WorkloadName.

Создание приложения

Затем команда разработчиков создала простое приложение Python, которое открывает подключение к База данных SQL Azure и возвращает список продуктов. Этот код будет заменен более сложными функциями, а также может включать несколько приложений, развернутых в pod Kubernetes в рабочей среде для надежного, управляемого манифестом подхода к решениям приложений.

  1. Команда создала простой текстовый файл, который вызывается .env для хранения переменных для подключений сервера и других сведений. С помощью библиотеки python-dotenv они могут отделять переменные от кода Python. Это распространенный подход к поддержанию секретов и других сведений из самого кода.

    SQL_SERVER_ENDPOINT = ReplaceWith_AzureSQLDBServerName
    SQL_SERVER_USERNAME = ReplaceWith_AzureSQLDBSQLServerLoginName
    SQL_SERVER_PASSWORD = ReplaceWith_AzureSQLDBSQLServerLoginPassword
    SQL_SERVER_DATABASE = ReplaceWith_AzureSQLDBDatabaseName
    

    Внимание

    Для ясности и простоты это приложение использует файл конфигурации, считывающийся из Python. Так как код будет развернут с контейнером, сведения о подключении могут быть производными от содержимого. Следует тщательно рассмотреть различные методы работы с безопасностью, подключениями и секретами, а также определить лучший уровень и механизм, который следует использовать для нашего приложения. Всегда выбирайте самый высокий уровень безопасности и даже несколько уровней, чтобы обеспечить безопасность приложения. У вас есть несколько вариантов работы с секретными сведениями, такими как строка подключения и подобные, и в следующем списке показаны некоторые из этих параметров.

    Дополнительные сведения см. в разделе База данных SQL Azure безопасности.

  2. Следующая команда написала приложение PoC и назвала его app.py.

    Следующий скрипт выполняет следующие действия:

    1. Настройте библиотеки для конфигурации и базовых веб-интерфейсов.
    2. Загрузите переменные из .env файла.
    3. Создайте приложение Flask-RESTful.
    4. Получите База данных SQL Azure сведения о подключении с помощью значений config.ini файлов.
    5. Создайте подключение к База данных SQL Azure с помощью значений config.ini файлов.
    6. Подключение База данных SQL Azure с помощью pyodbc пакета.
    7. Создайте SQL-запрос для выполнения в базе данных.
    8. Создайте класс, который будет использоваться для возврата данных из API.
    9. Задайте конечную точку API классу Products .
    10. Наконец, запустите приложение на порте Flask по умолчанию 5000.
    # Set up the libraries for the configuration and base web interfaces
    from dotenv import load_dotenv
    from flask import Flask
    from flask_restful import Resource, Api
    import pyodbc
    
    # Load the variables from the .env file
    load_dotenv()
    
    # Create the Flask-RESTful Application
    app = Flask(__name__)
    api = Api(app)
    
    # Get to Azure SQL Database connection information using the config.ini file values
    server_name = os.getenv('SQL_SERVER_ENDPOINT')
    database_name = os.getenv('SQL_SERVER_DATABASE')
    user_name = os.getenv('SQL_SERVER_USERNAME')
    password = os.getenv('SQL_SERVER_PASSWORD')
    
    # Create connection to Azure SQL Database using the config.ini file values
    ServerName = config.get('Connection', 'SQL_SERVER_ENDPOINT')
    DatabaseName = config.get('Connection', 'SQL_SERVER_DATABASE')
    UserName = config.get('Connection', 'SQL_SERVER_USERNAME')
    PasswordValue = config.get('Connection', 'SQL_SERVER_PASSWORD')
    
    # Connect to Azure SQL Database using the pyodbc package
    # Note: You may need to install the ODBC driver if it is not already there. You can find that at:
    # https://learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server
    connection = pyodbc.connect(f'Driver=ODBC Driver 17 for SQL Server;Server={ServerName};Database={DatabaseName};uid={UserName};pwd={PasswordValue}')
    
    # Create the SQL query to run against the database
    def query_db():
        cursor = connection.cursor()
        cursor.execute("SELECT TOP (10) [ProductID], [Name], [Description] FROM [SalesLT].[vProductAndDescription] WHERE Culture = 'EN' FOR JSON AUTO;")
        result = cursor.fetchone()
        cursor.close()
        return result
    
    # Create the class that will be used to return the data from the API
    class Products(Resource):
        def get(self):
            result = query_db()
            json_result = {} if (result == None) else json.loads(result[0])     
            return json_result, 200
    
    # Set the API endpoint to the Products class
    api.add_resource(Products, '/products')
    
    # Start App on default Flask port 5000
    if __name__ == "__main__":
        app.run(debug=True)
    
  3. Они проверка, что это приложение выполняется локально, и возвращает страницу http://localhost:5000/productsв .

    Screenshot from a web browser of the Flask return page.

    Важно!

    При создании рабочих приложений не используйте учетную запись администратора для доступа к базе данных. Дополнительные сведения см. в статье о настройке учетной записи для приложения. Код в этой статье упрощен, чтобы быстро приступить к работе с приложениями с помощью Python и Kubernetes в Azure.

    Более реалистично можно использовать пользователя автономной базы данных с разрешениями только для чтения, а также имя входа или пользователя автономной базы данных , подключенного к управляемому удостоверению , назначаемого пользователем, с разрешениями только для чтения.

    Дополнительные сведения см. в полном примере по созданию API с помощью Python и База данных SQL Azure.

Развертывание приложения в контейнере Docker

Контейнер — это зарезервированное, защищенное пространство в вычислительной системе, которая обеспечивает изоляцию и инкапсуляцию. Чтобы создать контейнер, используйте файл манифеста, который является просто текстовым файлом, описывающим двоичные файлы и код, который требуется содержать. С помощью среды выполнения контейнера (например, Docker) можно создать двоичный образ со всеми файлами, которые требуется запустить и ссылаться. Оттуда можно "запустить" двоичный образ, который называется контейнером, который можно ссылаться, как если бы это была полная вычислительная система. Это меньший, простой способ абстрагировать среды выполнения и среды приложения, чем использовать полную виртуальную машину. Дополнительные сведения см. в разделе "Контейнеры" и "Docker".

Команда начала работу с DockerFile (манифест), которая слои элементов того, что команда хочет использовать. Они начинаются с базового образа Python, который уже имеет pyodbc установленные библиотеки, а затем выполняют все команды, необходимые для хранения файла программы и конфигурации на предыдущем шаге.

Следующий Файл Dockerfile имеет следующие действия:

  1. Начните с двоичного файла контейнера, который уже имеет Python и pyodbc установлен.
  2. Создайте рабочий каталог для приложения.
  3. Скопируйте весь код из текущего каталога в каталог WORKDIR.
  4. Установите необходимые библиотеки.
  5. После запуска контейнера запустите приложение и откройте все порты TCP/IP.
# syntax=docker/dockerfile:1

# Start with a Container binary that already has Python and pyodbc installed
FROM laudio/pyodbc

# Create a Working directory for the application
WORKDIR /flask2sql

# Copy all of the code from the current directory into the WORKDIR
COPY . .

# Install the libraries that are required
RUN pip install -r ./requirements.txt

# Once the container starts, run the application, and open all TCP/IP ports 
CMD ["python3", "-m" , "flask", "run", "--host=0.0.0.0"]

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

docker build -t flask2sql .
docker run -d -p 5000:5000 -t flask2sql

Еще раз команда проверяет ссылку http://localhost:5000/products , чтобы убедиться, что контейнер может получить доступ к базе данных, и они видят следующее возвращение:

Screenshot from a web browser of the Flask return page from the Container.

Развертывание образа в реестре Docker

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

Область хранения для образов контейнеров называется репозиторием, и могут быть как общедоступные, так и частные репозитории для образов контейнеров. На самом деле AdvenureWorks использовал общедоступный образ для среды Python в dockerfile.

Команда хотела бы контролировать доступ к изображению, а не помещать его в Интернет, они решили, что они хотели бы разместить его самостоятельно, но в Microsoft Azure, где они имеют полный контроль над безопасностью и доступом. Дополнительные сведения о microsoft Реестр контейнеров Azure см. здесь.

Возвращаясь к командной строке, команда разработчиков использует az CLI для добавления службы реестра контейнеров, включения учетной записи администрирования, задания анонимного "вытягивания" на этапе тестирования и задания контекста входа в реестр:

az acr create --resource-group ReplaceWith_PoCResourceGroupName --name ReplaceWith_AzureContainerRegistryName --sku Standard
az acr update -n ReplaceWith_AzureContainerRegistryName --admin-enabled true
az acr update --name ReplaceWith_AzureContainerRegistryName --anonymous-pull-enabled
az acr login --name ReplaceWith_AzureContainerRegistryName

Этот контекст будет использоваться в последующих шагах.

Пометьте локальный образ Docker, чтобы подготовить его к отправке

Следующим шагом является отправка образа контейнера локального приложения в службу Реестр контейнеров Azure (ACR), чтобы она была доступна в облаке.

  1. В следующем примере скрипта команда использует команды Docker для перечисления изображений на компьютере.
  2. Они используют служебную az CLI программу для перечисления изображений в службе ACR.
  3. Они используют команду Docker для тега изображения с именем назначения ACR, созданного на предыдущем шаге, и для задания номера версии для правильного DevOps.
  4. Наконец, они снова перечисляют сведения о локальном изображении, чтобы убедиться, что тег применен правильно.
docker images
az acr list --resource-group ReplaceWith_PoCResourceGroupName --query "[].{acrLoginServer:loginServer}" --output table
docker tag flask2sql ReplaceWith_AzureContainerRegistryName.azurecr.io/azure-flask2sql:v1
docker images

При написании и тестировании кода Dockerfile, образа и контейнера выполняется и тестируется, служба ACR настроена и все примененные теги, команда может отправить образ в службу ACR.

Они используют команду Docker push для отправки файла, а затем служебную az CLI программу, чтобы убедиться, что образ загружен:

docker push ReplaceWith_AzureContainerRegistryName.azurecr.io/azure-flask2sql:v1
az acr repository list --name ReplaceWith_AzureContainerRegistryName --output table

Развертывание в Kubernetes

Команда может просто запустить контейнеры и развернуть приложение в локальных и облачных средах. Однако они хотели бы добавить несколько копий приложения для масштабирования и доступности, добавить другие контейнеры, выполняющие различные задачи, и добавить мониторинг и инструментирование во все решение.

Чтобы объединить контейнеры в полное решение, команда решила использовать Kubernetes. Kubernetes работает локально и во всех основных облачных платформах. Microsoft Azure имеет полную управляемую среду для Kubernetes, называемую Служба Azure Kubernetes (AKS). Дополнительные сведения об AKS см. в статье "Введение в Kubernetes" в схеме обучения Azure.

az CLI С помощью служебной программы команда добавляет AKS в ту же группу ресурсов, которую они создали ранее. С помощью одной az команды команда разработчика выполняет следующие действия:

  • Добавление двух узлов или вычислительных сред для обеспечения устойчивости на этапе тестирования
  • Автоматическое создание ключей SSH для доступа к среде
  • Подключите службу ACR, созданную на предыдущих шагах, чтобы кластер AKS смог найти образы, которые они хотят использовать для развертывания.
az aks create --resource-group ReplaceWith_PoCResourceGroupName --name ReplaceWith_AzureKubernetesServiceName --node-count 2 --generate-ssh-keys --attach-acr ReplaceWith_AzureContainerRegistryName

Kubernetes использует средство командной строки для доступа к кластеру и управления ими.kubectl Команда использует служебную az CLI программу для скачивания kubectl средства и его установки:

az aks install-cli

Так как у них есть подключение к AKS в данный момент, он может попросить его отправить ключи SSH для использования при выполнении служебной kubectl программы:

az aks get-credentials --resource-group ReplaceWith_PoCResourceGroupName --name ReplaceWith_AzureKubernetesServiceName

Эти ключи хранятся в файле с именем config в каталоге пользователя. С помощью этого набора контекста безопасности команда использует kubectl get nodes для отображения узлов в кластере:

kubectl get nodes

Теперь команда использует az CLI средство для перечисления изображений в службе ACR:

az acr list --resource-group ReplaceWith_PoCResourceGroupName --query "[].{acrLoginServer:loginServer}" --output table

Теперь они могут создать манифест, который Kubernetes использует для управления развертыванием. Это текстовый файл, хранящийся в формате yaml . Ниже приведен аннотированный текст в flask2sql.yaml файле:

apiVersion: apps/v1
# The type of commands that will be sent, along with the name of the deployment
kind: Deployment
metadata:
  name: flask2sql
# This section sets the general specifications for the application
spec:
  replicas: 1
  selector:
    matchLabels:
      app: flask2sql
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  minReadySeconds: 5 
  template:
    metadata:
      labels:
        app: flask2sql
    spec:
      nodeSelector:
        "kubernetes.io/os": linux
# This section sets the location of the Image(s) in the deployment, and where to find them 
      containers:
      - name: flask2sql
        image:  bwoodyflask2sqlacr.azurecr.io/azure-flask2sql:v1
# Recall that the Flask application uses (by default) TCIP/IP port 5000 for access. This line tells Kubernetes that this "pod" uses that address.
        ports:
        - containerPort: 5000
---
apiVersion: v1
# This is the front-end of the application access, called a "Load Balancer"
kind: Service
metadata:
  name: flask2sql
spec:
  type: LoadBalancer
# this final step then sets the outside exposed port of the service to TCP/IP port 80, but maps it internally to the app's port of 5000
  ports:
  - protocol: TCP
    port: 80
    targetPort: 5000
  selector:
    app: flask2sql

flask2sql.yaml Определив файл, команда может развернуть приложение в работающем кластере AKS. Это сделано с kubectl apply помощью команды, которая, как вы помните, по-прежнему имеет контекст безопасности в кластере. kubectl get service Затем команда отправляется для просмотра кластера по мере его создания.

kubectl apply -f flask2sql.yaml
kubectl get service flask2sql --watch

Через несколько минут команда watch вернет внешний IP-адрес. На этом этапе команда нажимает клавиши CTRL-C, чтобы прервать команду наблюдения, и записывает внешний IP-адрес подсистемы балансировки нагрузки.

Тестирование приложения

Используя IP-адрес (конечную точку), полученные на последнем шаге, команда проверка, чтобы обеспечить те же выходные данные, что и локальное приложение и контейнер Docker:

Screenshot from a web browser of the Flask return page when finally testing the container. The output is the same as before.

Очистка

После создания, редактирования и тестирования приложения команда теперь может "сломить" приложение. Сохраняя все в одной группе ресурсов в Microsoft Azure, это простой вопрос удаления группы ресурсов PoC с помощью служебной az CLI программы:

az group delete -n ReplaceWith_PoCResourceGroupName -y

Примечание.

Если вы создали База данных SQL Azure в другой группе ресурсов и больше не нуждаетесь в ней, вы можете использовать портал Azure для удаления.

Участник группы, ведущий проект PoC, использует Microsoft Windows в качестве рабочей станции и хочет сохранить файл секретов из Kubernetes, но удалить его из системы в качестве активного расположения. Они могут просто скопировать файл в текстовый config.old файл, а затем удалить его:

copy c:\users\ReplaceWith_YourUserName\.kube\config c:\users\ReplaceWith_YourUserName\.kube\config.old
del c:\users\ReplaceWith_YourUserName\.kube\config