Post-Bicep workflow: Maven build → local run → Docker build/run → ACR tag/login/push → AKS deploy → Ingress controller install via YAML (no Helm) → Ingress deploy → Ops commands → Chrome test.
target/app.jar (<finalName>app</finalName> in the POM).deployment.yml (Deployment + Service) and ingress.yml (Ingress) files.export AZ_SUBSCRIPTION_ID="<your-subscription-id>"
export AZ_RESOURCE_GROUP="rg-aks-spring-demo"
export AZ_LOCATION="eastus"
export AKS_NAME="aks-spring-demo"
export ACR_NAME="<your-acr-name>" # no .azurecr.io
export ACR_LOGIN_SERVER="${ACR_NAME}.azurecr.io"
export APP_IMAGE_NAME="spring-ui-api"
export APP_IMAGE_VERSION="1.0"
export APP_PORT="9087"
export INGRESS_HOSTNAME="spring-ui-api.dev.yourcompany.com"
az login
az account set --subscription "$AZ_SUBSCRIPTION_ID"
az account show --output table
az command operates against the correct subscription.
mvn -U -DskipTests clean package
ls -lh target/app.jar
java -jar target/app.jar
http://localhost:9087/http://localhost:9087/actuator/healthdocker build -t ${APP_IMAGE_NAME}:${APP_IMAGE_VERSION} .
docker images | grep "${APP_IMAGE_NAME}" | head
docker run --rm \
-p 9087:9087 \
--name ${APP_IMAGE_NAME} \
${APP_IMAGE_NAME}:${APP_IMAGE_VERSION}
http://localhost:9087/http://localhost:9087/actuator/healthdocker tag ${APP_IMAGE_NAME}:${APP_IMAGE_VERSION} \
${ACR_LOGIN_SERVER}/${APP_IMAGE_NAME}:${APP_IMAGE_VERSION}
az acr login --name "$ACR_NAME"
docker push ${ACR_LOGIN_SERVER}/${APP_IMAGE_NAME}:${APP_IMAGE_VERSION}
az acr repository list --name "$ACR_NAME" --output table
az acr repository show-tags --name "$ACR_NAME" --repository "$APP_IMAGE_NAME" --output table
adminUserEnabled: false), so prefer az acr login.
Username/password based docker login is generally not desired unless you explicitly enabled admin.
az aks get-credentials \
--resource-group "$AZ_RESOURCE_GROUP" \
--name "$AKS_NAME" \
--overwrite-existing
kubectl get nodes
deployment.yml contains this placeholder:
image: REPLACEME_ACR_LOGIN/spring-ui-api:1.0
sed -i.bak "s|REPLACEME_ACR_LOGIN|${ACR_LOGIN_SERVER}|g" deployment.yml
kubectl apply -f deployment.yml
kubectl get deploy
kubectl get pods -l app=spring-ui-api -o wide
kubectl get svc spring-ui-api-svc -o wide
Ingress object is only a rule definition. You need an Ingress Controller
(NGINX here) running in the cluster to implement those rules and expose an external endpoint.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/cloud/deploy.yaml
kubectl get pods -n ingress-nginx -w
kubectl get svc -n ingress-nginx ingress-nginx-controller -o wide
<pending>, wait and retry.
ingress.yml has:
host: REPLACEME_HOSTNAME
sed -i.bak "s|REPLACEME_HOSTNAME|${INGRESS_HOSTNAME}|g" ingress.yml
kubectl apply -f ingress.yml
kubectl get ingress
kubectl describe ingress spring-ui-api-ingress
/etc/hosts:
sudo sh -c 'echo "<EXTERNAL-IP> spring-ui-api.dev.yourcompany.com" >> /etc/hosts'
kubectl get all
kubectl get deploy,rs,pods,svc,ingress -o wide
kubectl get pods -l app=spring-ui-api -o wide
kubectl get endpoints spring-ui-api-svc -o wide
kubectl describe deploy spring-ui-api
kubectl describe pod -l app=spring-ui-api
kubectl describe svc spring-ui-api-svc
kubectl describe ingress spring-ui-api-ingress
describe when you see image pull failures, probe failures, 502/503, or unexpected restarts.
kubectl logs -l app=spring-ui-api --tail=200
kubectl logs -l app=spring-ui-api -f
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller --tail=200
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller -f
kubectl get events --sort-by=.metadata.creationTimestamp | tail -n 80
kubectl rollout status deployment/spring-ui-api
kubectl rollout history deployment/spring-ui-api
http://INGRESS_HOSTNAME/http://<hostname>/actuator/healthhttps://.
curl -i http://${INGRESS_HOSTNAME}/
curl -i http://${INGRESS_HOSTNAME}/actuator/health
# Build JAR
mvn -U -DskipTests clean package
# Build Docker image locally
docker build -t ${APP_IMAGE_NAME}:${APP_IMAGE_VERSION} .
# Azure login & subscription
az login
az account set --subscription "$AZ_SUBSCRIPTION_ID"
# Login to ACR and push
az acr login --name "$ACR_NAME"
docker tag ${APP_IMAGE_NAME}:${APP_IMAGE_VERSION} ${ACR_LOGIN_SERVER}/${APP_IMAGE_NAME}:${APP_IMAGE_VERSION}
docker push ${ACR_LOGIN_SERVER}/${APP_IMAGE_NAME}:${APP_IMAGE_VERSION}
# Connect kubectl to AKS
az aks get-credentials -g "$AZ_RESOURCE_GROUP" -n "$AKS_NAME" --overwrite-existing
# Deploy app (Deployment + Service)
sed -i.bak "s|REPLACEME_ACR_LOGIN|${ACR_LOGIN_SERVER}|g" deployment.yml
kubectl apply -f deployment.yml
# Install NGINX ingress controller (NO HELM)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/cloud/deploy.yaml
kubectl get svc -n ingress-nginx ingress-nginx-controller -w
# Deploy ingress rules
sed -i.bak "s|REPLACEME_HOSTNAME|${INGRESS_HOSTNAME}|g" ingress.yml
kubectl apply -f ingress.yml
# Verify
kubectl get pods,svc,ingress -o wide
kubectl logs -l app=spring-ui-api --tail=200