Hace unas semanas te compartí como desplegar Azure App Services, Functions y Logic Apps donde quisieras usando Azure Arc y Kubernetes. En aquel artículo lo monté sobre un AKS, que era lo fácil 😜 Hoy quiero compartir contigo el mismo ejemplo con un clúster en EKS, el servicio de Kubernetes de AWS.
Nota: Esta funcionalidad está en preview y no está recomendado su uso en un entorno productivo por ahora.
Creación del clúster en EKS
Para este ejemplo he creado un clúster en EKS con el menor número de parámetros posible para mantener el ejemplo sencillo:
# Install aws cli
pip3 install awscli --upgrade --user
# Init session in your AWS account
aws configure
# Install eksctl
brew tap weaveworks/tap
brew install weaveworks/tap/eksctl
eksctl version
EKS_NAME="eks-cluster"
# Create a Kubernetes cluster in EKS
eksctl create cluster \
--name $EKS_NAME \
--region eu-west-3 # Paris
# Check that the cluster is running
kubectl get nodes
Este proceso tardará unos minutos. Una vez que finalice podrás ver los nodos de tu clúster en AWS listo para empezar con la configuración.
Conectar el clúster con Azure Arc e instalar la extensión de App Service
Al igual que hice en el primer artículo, necesitamos conectar el clúster con Azure Arc y configurar la extensión, para poder desplegar servicios basados en App Service:
RESOURCE_GROUP="eks-azure-arc"
LOCATION="westeurope"
# Create a resource group
az group create --name $RESOURCE_GROUP --location $LOCATION
# Connect the EKS cluster to Azure Arc
az connectedk8s connect \
--resource-group $RESOURCE_GROUP \
--name $EKS_NAME \
--location $LOCATION
# Validate connection
az connectedk8s show --resource-group $RESOURCE_GROUP --name $EKS_NAME --query "provisioningState"
# Install App Service extension
EXTENSION_NAME="appservice-ext"
NAMESPACE="app-service-resources"
# Check storage classes
kubectl get sc
az k8s-extension create \
--resource-group $RESOURCE_GROUP \
--name $EXTENSION_NAME \
--cluster-type connectedClusters \
--cluster-name $EKS_NAME \
--extension-type 'Microsoft.Web.Appservice' \
--release-train stable \
--auto-upgrade-minor-version true \
--scope cluster \
--release-namespace $NAMESPACE \
--configuration-settings "Microsoft.CustomLocation.ServiceAccount=default" \
--configuration-settings "appsNamespace=${NAMESPACE}" \
--configuration-settings "clusterName=${EKS_NAME}" \
--configuration-settings "keda.enabled=true" \
--configuration-settings "buildService.storageClassName=gp2" \
--configuration-settings "buildService.storageAccessMode=ReadWriteOnce" \
--configuration-settings "customConfigMap=${NAMESPACE}/kube-environment-config" \
--configuration-settings "envoy.annotations.service.beta.kubernetes.io/azure-load-balancer-resource-group=${RESOURCE_GROUP}"
# Store the extension Id
EXTENSION_ID=$(az k8s-extension show \
--cluster-type connectedClusters \
--cluster-name $EKS_NAME \
--resource-group $RESOURCE_GROUP \
--name $EXTENSION_NAME \
--query id \
--output tsv)
az resource wait --ids $EXTENSION_ID --custom "properties.installState!='Pending'" --api-version "2020-07-01-preview"
# Check pods created
kubectl get pods -n $NAMESPACE
En este ejemplo, respecto del anterior, he tenido que modificar el nombre de la Storage Class ya que en el caso de EKS la por defecto se llama gp2.
Crear una custom location y un App Service Kubernetes Environment
Para poder crear cualquiera de los servicios necesitas crear lo que se conoce como una ubicación personalizada y, asociada a esta, un App Service Kubernetes Environment, el cual genera una configuración común de las aplicaciones de la ubicación personalizada, como el sufijo DNS predeterminado. En este caso he llamado a esa ubicación aws:
# Create a custom location
CUSTOM_LOCATION_NAME="aws"
CONNECTED_CLUSTER_ID=$(az connectedk8s show --resource-group $RESOURCE_GROUP --name $EKS_NAME --query id -o tsv)
az customlocation create \
--resource-group $RESOURCE_GROUP \
--name $CUSTOM_LOCATION_NAME \
--host-resource-id $CONNECTED_CLUSTER_ID \
--namespace $NAMESPACE \
--cluster-extension-id $EXTENSION_ID \
--location $LOCATION
# Validate the custom location
az customlocation show --resource-group $RESOURCE_GROUP --name $CUSTOM_LOCATION_NAME
CUSTOM_LOCATION_ID=$(az customlocation show \
--resource-group $RESOURCE_GROUP \
--name $CUSTOM_LOCATION_NAME \
--query id \
--output tsv)
# Create a Kube Environment for this location
KUBE_ENV="kube-env"
az appservice kube create \
--resource-group $RESOURCE_GROUP \
--name $KUBE_ENV \
--custom-location $CUSTOM_LOCATION_ID \
--location $LOCATION
# Wait for the Kube Environment to be ready
az appservice kube show --resource-group $RESOURCE_GROUP --name $KUBE_ENV --query "provisioningState"
Desplegar una aplicación de prueba
Por último, para comprobar que todo sigue funcionando igual de bien que en AKS, puedes desplegar este ejemplo:
# Create a web app
WEB_APP_NAME="aws-webapp"
az webapp create \
--resource-group $RESOURCE_GROUP \
--name $WEB_APP_NAME \
--custom-location $CUSTOM_LOCATION_ID \
--runtime "NODE|14-lts"
# Check status web app
az webapp show --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME --query "state"
# Get URL
az webapp show --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME --query "defaultHostName"
# Deploy an app
git clone https://github.com/Azure-Samples/nodejs-docs-hello-world
cd nodejs-docs-hello-world
zip -r package.zip .
az webapp deployment source config-zip --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME --src package.zip
¡Saludos!