Zum Inhalt

Lab 07: Übung: Node.js-Anwendung über ACR in AKS deployen


Teil 1: Azure Container Registry erstellen

Erstelle eine ACR-Instanz und verbinde sie diese mit deinemAKS-Cluster.

# Variablen setzen
RESOURCE_GROUP="<Deine-Resource-Group>"
CLUSTER_NAME="<Dein-AKS-Cluster>"
ACR_NAME="acr$(openssl rand -hex 4)"  # Muss global eindeutig sein

# ACR erstellen
az acr create \
  --resource-group $RESOURCE_GROUP \
  --name $ACR_NAME \
  --sku Basic

# ACR mit AKS verbinden (AcrPull-Berechtigung)
az aks update \
  --resource-group $RESOURCE_GROUP \
  --name $CLUSTER_NAME \
  --attach-acr $ACR_NAME

# Login-Server ermitteln
ACR_LOGIN_SERVER=$(az acr show --name $ACR_NAME --query loginServer -o tsv)
echo "ACR Login Server: $ACR_LOGIN_SERVER"

Teil 2: Node.js-Anwendung erstellen

Erstelle folgende Dateien in einem neuen Verzeichnis hello-aks/:

package.json

{
  "name": "hello-aks",
  "version": "1.0.0",
  "description": "Demo-App für AKS-Deployment",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}

server.js

const express = require('express');
const os = require('os');

const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
    res.json({
        message: 'Hallo aus AKS!',
        hostname: os.hostname(),
        timestamp: new Date().toISOString(),
        version: '1.0.0'
    });
});

app.get('/health', (req, res) => {
    res.status(200).send('OK');
});

app.listen(PORT, () => {
    console.log(`Server läuft auf Port ${PORT}`);
});

Dockerfile

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

# Anwendungscode
COPY server.js ./

# Nicht als root ausführen
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
USER nodejs

EXPOSE 3000

CMD ["node", "server.js"]

Teil 3: Image bauen und in ACR pushen

Führe folgende Befehle aus:

cd hello-aks/

# Bei ACR anmelden
az acr login --name $ACR_NAME

# Image bauen und taggen
docker build -t ${ACR_LOGIN_SERVER}/hello-aks:v1 .

# Image pushen
docker push ${ACR_LOGIN_SERVER}/hello-aks:v1

# Überprüfen
az acr repository list --name $ACR_NAME -o table
az acr repository show-tags --name $ACR_NAME --repository hello-aks -o table

Teil 4: Kubernetes-Manifeste erstellen

Erzeuge folgende Manifeste. Denke bitte daran, den Platzhalter <ACR_LOGIN_SERVER> zu ersetzen:

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-aks
  labels:
    app: hello-aks
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-aks
  template:
    metadata:
      labels:
        app: hello-aks
    spec:
      containers:
        - name: hello-aks
          image: "<ACR_LOGIN_SERVER>/hello-aks:v1"  # Ersetzen!
          ports:
            - containerPort: 3000
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 3
            periodSeconds: 5

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-aks
spec:
  type: LoadBalancer
  selector:
    app: hello-aks
  ports:
    - port: 80
      targetPort: 3000

Teil 5: Deployment durchführen

Führe das Deployment aus.

# Deployen
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

# Status prüfen
kubectl get deployments
kubectl get pods -l app=hello-aks
kubectl get service hello-aks

# Auf externe IP warten
kubectl get service hello-aks -w

Teil 6: Testen und Verifizieren

Nun testen wir die Anwendung.

# Externe IP abrufen
EXTERNAL_IP=$(kubectl get service hello-aks -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

# Anwendung testen
curl http://${EXTERNAL_IP}/

# Mehrfach aufrufen (verschiedene Hostnamen durch Load-Balancing)
for i in {1..5}; do
  curl -s http://${EXTERNAL_IP}/ | jq .hostname
done

# Health-Endpoint testen
curl http://${EXTERNAL_IP}/health