Развертывание образа контейнера в службе Azure Kubernetes
В этом модуле вы развернете контейнерный образ в сервисе Azure Kubernetes (AKS). С помощью AKS вы настраиваете кластер Kubernetes для работы в требуемом состоянии посредством развертывания, что представляет собой процесс предоставления декларативных обновлений для pod и ReplicaSets. Эта декларация состояния управляется в YAML файле манифеста, и контроллер Kubernetes изменяет текущее состояние на объявленное состояние при получении соответствующих инструкций. Вы создаете этот файл манифеста deployment.yml и указываете экземпляру AKS работать в требуемом состоянии с подами, настроенными для извлечения и запуска flightbookingsystemsample образа контейнера, содержащегося в реестре контейнеров Azure, который вы загрузили в предыдущем модуле. Этот манифест декларативно определяет Deployment и Service. Kubernetes использует контроллер развертывания для управления подами приложения; вы также можете создать развертывание императивно с помощью kubectl create deployment.
Заметка
Если сеанс неактивен или вы выполняете этот шаг в другой момент времени или из другого интерфейса командной строки, может потребоваться повторно инициализировать переменные среды и повторно выполнить проверку подлинности с помощью следующих команд:
Восстановите значения переменных ресурсов, используемые при установке. Замените приведенное ниже на идентификатор подписки, использованной для этого модуля. Если при входе отображается средство выбора подписки, выберите ту же подписку. Выполните команды аутентификации по одной за раз. После az account showэтого убедитесь, что активная подписка соответствует настройке, прежде чем продолжить. Если команда завершается ошибкой, остановите и устраните ошибку.
export AZ_RESOURCE_GROUP=java-containerization-demo-rg
export AZ_CONTAINER_REGISTRY=<your-container-registry>
export AZ_KUBERNETES_CLUSTER=java-containerization-demo-aks
export AZ_LOCATION=<your-Azure-region>
export AZ_KUBERNETES_CLUSTER_DNS_PREFIX=<your-unique-DNS-prefix-to-access-your-AKS-cluster>
az login
az account set --subscription "<your-subscription-ID>"
az account show --output table
az acr login --name "$AZ_CONTAINER_REGISTRY"
Разверните образ контейнера
Теперь вы развернете образ контейнера в flightbookingsystemsample кластере AKS. В containerize-and-deploy-Java-app-to-Azure/Project/Airlines используйте установленный текстовый редактор для создания файла с именем deployment.yml. Этот путь задается относительно родительского каталога, в котором вы клонировали репозиторий. Если вы уже находитесь в Project/Airlines, оставайтесь там, а не снова переходите на полный относительный путь. Создайте файл и выполните следующую kubectl apply -f deployment.yml команду из этого каталога.
Добавьте следующее содержимое в deployment.yml, а затем сохраните файл. Замените заполнитель <AZ_CONTAINER_REGISTRY> значением переменной среды AZ_CONTAINER_REGISTRY, заданной ранее.
apiVersion: apps/v1
kind: Deployment
metadata:
name: flightbookingsystemsample
spec:
replicas: 1
selector:
matchLabels:
app: flightbookingsystemsample
template:
metadata:
labels:
app: flightbookingsystemsample
spec:
nodeSelector:
kubernetes.io/os: linux
kubernetes.io/arch: amd64
containers:
- name: flightbookingsystemsample
image: <AZ_CONTAINER_REGISTRY>.azurecr.io/flightbookingsystemsample:latest
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: flightbookingsystemsample
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 8080
selector:
app: flightbookingsystemsample
Заметка
Если вы используете файл deployment_solution.yml в корневой папке проекта в качестве отправной точки, обновите образ и тег до тех же значений образа реестра и тега, которые показаны здесь. Кроме того, добавьте тот же Linux AMD64 nodeSelector в разделе развертывания containers, наряду с spec.template.spec. Не оставляйте альтернативный вариант без изменений: его образ и селектор узлов должны соответствовать платформе сборки этого модуля.
В предыдущем deployment.yml файл содержит развертывание и службу. Развертывание используется для администрирования набора pod'ов, а служба используется для предоставления сетевого доступа к pod'ам. Контейнеры pod настроены для загрузки одного образа из <AZ_CONTAINER_REGISTRY>.azurecr.io/flightbookingsystemsample:latest реестра контейнеров Azure. Служба настроена для разрешения входящего трафика pod HTTP через порт 8080, аналогично тому, как вы запустили образ контейнера локально с аргументом -p порта.
Селектор узлов ограничивает размещение подов узлами Linux AMD64, соответствующими образу linux/amd64, созданному ранее. Он принадлежит Deployment, а не Service. Селектор ограничивает планирование; он не позволяет несовместимому образу запускаться на другой архитектуре.
Перед настройкой доступа к кластеру убедитесь, что создание кластера AKS в модуле установки завершено успешно. Проверьте состояние подготовки ресурсов и текущую версию Kubernetes:
az aks show \
--resource-group "$AZ_RESOURCE_GROUP" \
--name "$AZ_KUBERNETES_CLUSTER" \
--query '{provisioningState:provisioningState,currentKubernetesVersion:currentKubernetesVersion}' \
--output table
Не продолжайте работу, если команда завершается ошибкой, provisioningState не является Succeeded или currentKubernetesVersion не является непустой версией в формате major.minor.patch.
Следующие инструкции по инструменту применяются к локальному сеансу Linux, macOS или WSL Bash, созданному на этапе настройки, а не к собственному PowerShell или командной строке. Если у вас уже есть работающие установки kubectl и kubelogin в этом сеансе, сохраните их вместо переустановки. Проверьте их с помощью kubectl version --client и kubelogin --version и убедитесь, что kubectl соответствует поддерживаемой политике распределения версий для кластера.
В противном случае замените <control-plane-version> возвращенным currentKubernetesVersion. Установите соответствующую kubectl версию и kubelogin в расположения, доступные для записи пользователем:
KUBECTL_VERSION="<control-plane-version>"
if [[ "$KUBECTL_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
mkdir -p "$HOME/.local/bin" &&
az aks install-cli \
--client-version "$KUBECTL_VERSION" \
--install-location "$HOME/.local/bin/kubectl" \
--kubelogin-install-location "$HOME/.local/bin/kubelogin" &&
export PATH="$HOME/.local/bin:$PATH" &&
kubectl version --client &&
kubelogin --version
else
printf 'Stop: set KUBECTL_VERSION to the returned major.minor.patch version.\n' >&2
false
fi
Оба пути установки включают имя исполняемого файла. Команда PATH export применяется только к текущей оболочке; повторите её в новом сеансе или добавьте её в соответствующую конфигурацию запуска Bash. Прежде чем продолжить, устраните все ошибки установки или проверки версий.
После того как оба средства доступны и проверены, настройте kubectl, чтобы подключиться к вашему кластеру AKS:
az aks get-credentials \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_KUBERNETES_CLUSTER
Ниже приведены типичные выходные данные:
Merged AZ_KUBERNETES_CLUSTER as current context in ~/.kube/config
Перед применением манифеста проверьте фактические операционные системы и архитектуры узлов:
kubectl get nodes \
-o custom-columns='NAME:.metadata.name,OS:.status.nodeInfo.operatingSystem,ARCH:.status.nodeInfo.architecture'
Для пути сборки linux/amd64 этого модуля требуются узлы Linux AMD64. Если соответствующих узлов нет, остановите и устраните несоответствие перед продолжением. Используйте поддерживаемый пул узлов AMD64 или перестройте, запустите и опубликуйте образ для другой поддерживаемой архитектуры узла Linux и обновите селектор архитектуры Deployment, чтобы он соответствовал. Параметр Docker --platform не создает или не изменяет пул узлов AKS.
Из containerize-and-deploy-Java-app-to-Azure/Project/Airlines примените deployment.yml к своему кластеру:
kubectl apply -f deployment.yml
Ниже приведены типичные выходные данные:
deployment.apps/flightbookingsystemsample created
service/flightbookingsystemsample created
Отслеживайте состояние развертывания с помощью следующей команды:
kubectl get all
Ниже приведены типичные выходные данные:
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/flightbookingsystemsample-b7fd6684f-4j8vf 1/1 Running 0 37s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/flightbookingsystemsample LoadBalancer 10.0.62.153 <external-IP> 8080:30534/TCP 37s
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 11h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/flightbookingsystemsample 1/1 1 1 37s
NAME DESIRED CURRENT READY AGE
replicaset.apps/flightbookingsystemsample-b7fd6684f 1 1 1 37s
Состояние pod Running не подтверждает, что Tomcat завершил развертывание приложения или что HTTP-запросы выполняются успешно. Дождитесь развертывания, а затем отслеживайте журналы запуска приложения:
kubectl rollout status deployment/flightbookingsystemsample --timeout=300s &&
kubectl logs deployment/flightbookingsystemsample --tail=100 --follow
Успешное развертывание возможно при доступности Kubernetes. Так как в этом манифесте нет проверки готовности приложения, развертывание не является HTTP-проверкой состояния. Следите за журналами до тех пор, пока Tomcat не сообщит о завершении запуска сервера и развертывание AirlinesReservationSample.war не завершится без ошибок. Затем нажмите клавиши CTRL+C, чтобы прекратить отслеживание журналов. Это останавливает только поток журнала, а не контейнер. Если развертывание или запуск приложения завершается сбоем или не завершается, проверьте журналы и события pod вместо продолжения проверки браузера.
В следующем историческом выводе показаны сообщения о запуске из более раннего образа Tomcat 10.1.33. Это не вывод из обновленного образа в этом модуле; используйте собственные журналы, чтобы проверить запуск, а не ожидать одинаковых версий, меток времени или сведений о среде:
kubectl logs pod/flightbookingsystemsample-b7fd6684f-4j8vf
15-Nov-2024 12:31:51.208 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/10.1.33
15-Nov-2024 12:31:51.211 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Nov 7 2024 22:28:55 UTC
15-Nov-2024 12:31:51.212 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 10.1.33.0
15-Nov-2024 12:31:51.212 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
15-Nov-2024 12:31:51.212 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 5.15.0-1074-azure
15-Nov-2024 12:31:51.212 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/lib/jvm/msopenjdk-17
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 17.0.13+11-LTS
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Microsoft
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/tomcat
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/tomcat
15-Nov-2024 12:31:51.226 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
15-Nov-2024 12:31:51.226 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
15-Nov-2024 12:31:51.227 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
15-Nov-2024 12:31:51.227 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
15-Nov-2024 12:31:51.227 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
15-Nov-2024 12:31:51.227 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
15-Nov-2024 12:31:51.228 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
15-Nov-2024 12:31:51.228 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
15-Nov-2024 12:31:51.228 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
15-Nov-2024 12:31:51.229 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
15-Nov-2024 12:31:51.229 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
15-Nov-2024 12:31:51.229 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
15-Nov-2024 12:31:51.229 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
15-Nov-2024 12:31:51.231 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The Apache Tomcat Native library which allows using OpenSSL was not found on the java.library.path: [/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib]
15-Nov-2024 12:31:51.565 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
15-Nov-2024 12:31:51.602 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [616] milliseconds
15-Nov-2024 12:31:51.658 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
15-Nov-2024 12:31:51.659 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/10.1.33]
15-Nov-2024 12:31:51.689 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat/webapps/AirlinesReservationSample.war]
15-Nov-2024 12:31:53.264 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
15-Nov-2024 12:31:55.155 INFO [main] com.sun.xml.ws.server.MonitorBase.createRoot Metro monitoring rootname successfully set to: com.sun.metro:pp=/,type=WSEndpoint,name=/AirlinesReservationSample-PriceAndSeats-PriceAndSeatsPort
15-Nov-2024 12:31:55.347 INFO [main] com.sun.xml.ws.transport.http.servlet.WSServletDelegate.<init> WSSERVLET14: XML-WS servlet initializing
WARNING:Error in the metadata of the table SEATS: table's row count in the metadata is 5 but 6 records have been found and loaded by UCanAccess. All will work fine, but it's better to repair your database.
15-Nov-2024 12:31:56.248 INFO [main] com.sun.xml.ws.transport.http.servlet.WSServletContextListener.contextInitialized WSSERVLET12: XML-WS context listener initializing
15-Nov-2024 12:31:56.249 INFO [main] com.sun.xml.ws.transport.http.servlet.WSServletContextListener.contextInitialized WSSERVLET12: XML-WS context listener initializing
15-Nov-2024 12:31:56.284 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat/webapps/AirlinesReservationSample.war] has finished in [4,595] ms
15-Nov-2024 12:31:56.285 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/docs]
15-Nov-2024 12:31:56.315 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/docs] has finished in [30] ms
15-Nov-2024 12:31:56.316 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/examples]
15-Nov-2024 12:31:56.439 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/examples] has finished in [123] ms
15-Nov-2024 12:31:56.440 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/manager]
15-Nov-2024 12:31:56.456 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/manager] has finished in [16] ms
15-Nov-2024 12:31:56.457 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/ROOT]
15-Nov-2024 12:31:56.468 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/ROOT] has finished in [11] ms
15-Nov-2024 12:31:56.468 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/host-manager]
15-Nov-2024 12:31:56.481 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/host-manager] has finished in [13] ms
15-Nov-2024 12:31:56.484 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
15-Nov-2024 12:31:56.501 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [4897] milliseconds
Отслеживайте службу по её внешнему адресу:
kubectl get service flightbookingsystemsample --watch
Изначально значение EXTERNAL-IP может быть <pending>, в то время как Azure подготавливает балансировщик нагрузки. Это может занять несколько минут и само по себе не является свидетельством сбоя развертывания. Когда появится адрес, нажмите сочетание клавиш Ctrl+C, чтобы остановить просмотр. Если подготовка не завершена, остановите watch и проверьте события службы с kubectl describe service flightbookingsystemsample.
В следующем примере вывода показано, где отображается назначенный адрес:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
flightbookingsystemsample LoadBalancer 10.0.62.153 <external-IP> 8080:30534/TCP 3m28s
Заметка
Замените IP-адрес <external-IP> в следующем URL-адресе значением EXTERNAL-IP из ранее выполненной команды.
Откройте браузер и перейдите на целевую страницу http://<external-IP>:8080/AirlinesReservationSample/системы резервирования полетов. Убедитесь, что страница приложения отвечает; pod Running или назначенный IP-адрес сами по себе не подтверждают готовность приложения. Браузер должен выглядеть следующим образом:
Вы можете при необходимости войти с любым пользователем из tomcat-users.xml , например someuser@azure.com: password.
Устранение неполадок несовместимости образа и платформы
Для сбоев запуска pod, проверьте kubectl describe pods -l app=flightbookingsystemsample, kubectl logs deployment/flightbookingsystemsample --tail=100 и kubectl get events --sort-by=.metadata.creationTimestamp. Состояние CrashLoopBackOff может иметь несколько причин, включая ошибки приложения; не предполагайте, что каждый сбой является несоответствием архитектуры.
Если вы убедитесь, что уже развернутый образ имеет неправильную платформу, сначала повторите сборку, локальный запуск, проверку образа, присвоение тега образу в реестре и отправку образа с соответствующими параметрами платформы. После успешного перестроения исправленного образа, повторной маркировки и отправки под тем же тегом :latest явно замените запущенные поды:
kubectl rollout restart deployment/flightbookingsystemsample &&
kubectl rollout status deployment/flightbookingsystemsample --timeout=300s
Для этого манифеста imagePullPolicy: Always используется по умолчанию, поэтому поды замены разрешают текущий тег реестра. Повторное применение без изменений манифеста не запускает развертывание. Если вы настроили политику извлечения, используйте обновленный тег образа или дайджест и обновите развертывание. Повторите проверку журнала запуска и URL-адреса приложения после развертывания.
Очистите ресурсы
Ресурсы, созданные в этом модуле, могут нести текущие затраты. Чтобы очистить ресурсы, удалите группу ресурсов, содержащую их, с помощью следующей команды:
az group delete --name $AZ_RESOURCE_GROUP