We have discussed getting Application Gateway Ingress Controller (AGIC) deployed using AGIC addon method in the post "Enable Application Gateway Ingress Controller (AGIC) for AKS - SImplest Way with a New App Gatway in Same vNet of AKS Cluster". We have tried a sample app deployment and added a routing ingress rule, to route to root, and reach the sample application toverify the working state of the AGIC in AKS cluster. However, generally in the APIs we deploy to AKS cluster, would require path based routing to reach, diffrent APIs. Let's discuss how to create ingress path based routing to AKS deployed APIs using AGIC.
Firts lets undersdtand how APIs are implemneted with path based routing. As described in the post "Enable Swagger UI with an .NET 6 API having Custom Routing" even the swagger UI can be set to use custom routing with APIs. Now lets take four APIs customer, order, invoice and payment. Each API route is supposed to have a prefix as below.
- /customer/api/
- /order/api/
- /invoice/api/
- /payment/api/
To implement in each API for swagger the changes should be done in program.cs (.NET 6) as described in post "Enable Swagger UI with an .NET 6 API having Custom Routing". Routing of each API is done as shown in below sample. Note that we are using weatherforecast controller created by defualt with dotnet new webapi command to create the project using template.
To create such routing with AGIC the Kubernetes ingress can be defined as shown below. Note that for health probe path we are using swagger UI path as it would return healthy to APP gateway health probe.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: customerapi namespace: demo annotations: # -------------- # AGIC kubernetes.io/ingress.class: azure/application-gateway appgw.ingress.kubernetes.io/health-probe-path: /customer/api/swagger # -------------- spec: rules: - http: paths: - path: /customer/api/* pathType: Prefix backend: service: name: customer-clusterip # Name of the cluster IP service of API port: number: 8091 # cluster ip port
apiVersion: apps/v1 kind: Deployment metadata: name: ${aks.appName}$ namespace: demo labels: app: ${aks.appName}$ spec: # replicas: 1 selector: matchLabels: service: ${aks.appName}$ template: metadata: labels: app: ${aks.appName}$ service: ${aks.appName}$ spec: nodeSelector: "kubernetes.io/os": ${aks.nodeSelector}$ volumes: # `name` here must match the name # specified in the volume mount - name: demo-configmap-${aks.appName}$-volume # configMap: # `name` here must match the name # specified in the ConfigMap's YAML name: demo-configmap containers: - name: ${aks.appName}$ # when aks image: ${aks.containerRegistry}$.azurecr.io/demo/${aks.appName}$:${Build.BuildId}$ # when k3d # image: demo-k3d-registry:44263/${aks.appName}$:dev imagePullPolicy: Always volumeMounts: - mountPath: /etc/config name: demo-configmap-${aks.appName}$-volume ports: - containerPort: 80 protocol: TCP env: - name: ASPNETCORE_URLS value: http://+:80 - name: ASPNETCORE_ENVIRONMENT value: ${aks.aspNetCoreEnv}$ - name: DEMO_CONFIG_PATH value: /etc/config/config_${envname}$.json resources: limits: memory: ${aks.container.limits.memory}$ cpu: "${aks.container.limits.cpu}$" requests: memory: ${aks.container.requests.memory}$ cpu: "${aks.container.requests.cpu}$" --- apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: ${aks.appName}$-hpa namespace: demo spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: ${aks.appName}$ maxReplicas: ${aks.hpa.maxReplicas}$ minReplicas: ${aks.hpa.minReplicas}$ behavior: scaleDown: stabilizationWindowSeconds: ${aks.hpa.scaleDown.stabilizationWindowSecs}$ policies: - type: Percent value: ${aks.hpa.scaleDown.percentage}$ periodSeconds: ${aks.hpa.scaleDown.periodSecs}$ scaleUp: stabilizationWindowSeconds: ${aks.hpa.scaleUp.stabilizationWindowSecs}$ policies: - type: Percent value: ${aks.hpa.scaleUp.percentage}$ periodSeconds: ${aks.hpa.scaleUp.periodSecs}$ metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: ${aks.hpa.metrics.cpu.averageUtilization}$ - type: Resource resource: name: memory target: type: Utilization averageUtilization: ${aks.hpa.metrics.memory.averageUtilization}$ --- apiVersion: v1 kind: Service metadata: name: ${aks.appName}$-clusterip namespace: demo labels: app: ${aks.appName}$ service: ${aks.appName}$ spec: type: ClusterIP ports: - port: ${aks.clusterIp.port}$ targetPort: 80 protocol: TCP selector: service: ${aks.appName}$ --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ${aks.appName}$ namespace: demo annotations: # kubernetes.io/ingress.class: nginx # for nginx # -------------- # when AGIC is ready kubernetes.io/ingress.class: azure/application-gateway appgw.ingress.kubernetes.io/health-probe-path: ${aks.appHeathProbePath}$ # -------------- spec: rules: - http: paths: - path: ${aks.appRoutePrefix}$ pathType: Prefix backend: service: name: ${aks.appName}$-clusterip port: number: ${aks.clusterIp.port}$
Custom probe will have the Swagger UI path of the Customer API set to it as we have defined in the Ingress. However, proper liveness, readiness and startup health probes should be defined for an API and Liveness and readiness probes should be ideally validated to check the pod health via app gateway. We can dicuss such topics in later posts.
Once all 4 APIs mentioned above deployed with ingress in AKS the rule will be updated by AGIC as shown below, and the required probes and backend settings will be added to app gateway automatically.
No comments:
Post a Comment