I am using the Azure Application Gateway Ingress Controller for Kubernetes. I was able to successfully configure the controller to expose my Kubernetes Services over http. However, I would like the Application Gateway to do SSL offload. So that the Application Gateway will handle https requests, and then forward a plain http request to my Kubernetes service. Currently the Ingress Controller documentation for https requires you to specify the certificate for your Kubernetes Service.
Is it possible to configure the Ingress Controller to do SSL offload so that I don't have to configure https on my Kubernetes Services?
I would assume this is the document you are looking for.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: guestbook
annotations:
kubernetes.io/ingress.class: azure/application-gateway
spec:
tls:
- secretName: <guestbook-secret-name>
rules:
- http:
paths:
- backend:
serviceName: frontend
servicePort: 80
ps. no idea why you would use application gateway with k8s. its garbage.
Adding appgw.ingress.kubernetes.io/ssl-redirect: "true" annotation with properly configured TLS certificate on ingress enables us to configure Application Gateway to automatically redirect HTTP URLs to their HTTPS counterparts. i.e. it creates https & http listener on Application Gateway
Related
I am trying to integrate AGIC with AKS in the following method, but using Terraform: https://learn.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-existing
I have Terraform scripts to create Azure Application Gateway (AGW) with a basic configuration, then create AKS with the AGIC addon. After that the AGW should configure the corresponding backends, listeners and rules automatically when we create the Ingress resource with correct annotation.
In order to configure SSL, there are 2 approaches it seems:
Method 1:
Add SSL certs as secret in kubernetes cluster, then configure 'tls' section and proper annotatons (to pint to AGIC) in the ingress resource. That will automatically add the certificate in the listener of AGW.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-app-ingress-tls
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- secretName: test-tls-secret
hosts:
- test.mydomain.com
rules:
- host: test.mydomain.com
http:
paths:
- path: /
backend:
service:
name: hello-app-service-tls
port:
number: 80
pathType: Exact
Method 2:
Convert SSL certs into pfx format, add it to the AGW directly ( with name test-ssl-certs ). Then mention 2 annotations in the ingress resource:
one - tell to use agic as ingress controller,
two - another annotation mentioning the certificate name that we manually added in AGW.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-world
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/appgw-ssl-certificate: "test-ssl-certs"
spec:
rules:
- host: "test.mydomain.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-world
port:
number: 80
What is the difference between these 2 methods?
In both the cases, where is the SSL termination happens -inside k8s cluster, or in azure application gateway??
Which one is the better method?
What is the difference between these 2 methods?
This force-ssl-redirect method will route to Ingress-nginx to convert all incoming HTTP request to Https
`ingress.kubernetes.io/force-ssl-redirect: "true"`
This appgw-ssl-certificate Initiate an interaction between Ingress and Applicaiton Gateway with certificate named "test-ssl-certs", which we manually added in Applicaiton Gateway listener.
appgw.ingress.kubernetes.io/appgw-ssl-certificate: "test-ssl-certs"
Details:
SSL certificate reference at Applicaiton gateway
Reference of the same from ingress file
NOTE: If any Certificate name mismatch it will turn to 504 error on Applicaiton Gateway.
In both the cases, where is the SSL termination happens -inside k8s cluster, or in azure application gateway?? Which one is the better method?
In My view appending certificate at ingress level is a best approach, SSL termination happens at load balancer [Application Gateway] level not at K8s. Gateway acts as a reverse proxy, means just routing requests from clients to services
what is the best way to access a web app running in aks container from outside the cluster with a name, which is already defined in Azure DNS zone? and an external DNS server can be helpful for this?
I would setup an ingress that would point to your service which exposes the web app.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: your.web.app.address
http:
paths:
- path: /
backend:
serviceName: service
servicePort: 8080
Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.
internet
|
[ Ingress ]
--|-----|--
[ Services ]
An Ingress may be configured to give Services externally-reachable URLs, load balance traffic, terminate SSL / TLS, and offer name based virtual hosting. An Ingress controller is responsible for fulfilling the Ingress, usually with a load balancer, though it may also configure your edge router or additional frontends to help handle the traffic.
An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type Service.Type=NodePort or Service.Type=LoadBalancer.
I would recommend reading Create an ingress controller in Azure Kubernetes Service (AKS), or use Azure Application Gateway as an ingress this is explained here and you can find tutorials on GitHub
I'm trying to redirect an ingress for the service deployed in Azure Kubernetes to https. Whatever I try doesn't work. I tried configuring Ingress and Traefik itself (via ConfigMap) with no effect.
The config for Traefik looks as the following:
---
# Traefik_config.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: traefik-conf
namespace: kube-system
# traefik.toml
data:
traefik.toml: |
defaultEntryPoints = ["http","https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[frontends]
[frontends.frontend2]
backend = "backend1"
passHostHeader = true
# overrides default entry points
entrypoints = ["http", "https"]
[backends]
[backends.backend1]
[backends.backend1.servers.server1]
url = "http://auth.mywebsite.com"
The subject for redirection is containerized IdentityServer API website with no TLS encryption. There are a couple of questions on the matter:
What's the best way to redirect the frontend app in Azure Kubernetes with Traefik
In the config the frontend is numbered, i.e. "frontend2". I assume this a sequential number of the app on the Traefik's dashboard. The problem is, the dashboard only shows the total sum of apps. If there are many of them, how to figure what the number is?
When I apply annotations to the Ingress, like "traefik.ingress.kubernetes.io/redirect-permanent: true" the respective labels are not showing up in the Traefik's dashboard for the respective app. Is there any reason for that?
Your configuration for redirecting http to https looks good. If you have followed the official Doc of Traefik to deploy on kubernetes, The Traefik ingress controller service will not have 443. Make sure you have port 443 opened on the Service with service type as LoadBalancer. Once we open a port in service, Then Azure opens the same port in the Azure load balancer. Service yaml is here.
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
type: LoadBalancer
If you want to redirect all the http to https in your cluster, You can go for the redirection in the configuration file.
If you want to redirect only some of the services, then add annotations in the Ingress to achieve redirection for specific services.
traefik.ingress.kubernetes.io/frontend-entry-points: http,https
traefik.ingress.kubernetes.io/redirect-entry-point: https
After setting up the redirection, Traffic Dashboard reflects that here.
You can also set up a permanent rediection using traefik.ingress.kubernetes.io/redirect-permanent: "true
Iv'e stumbled on this question while looking for a solution myself.
We are using traefik as a load balancer and i wanted to add https redirect to an ingress route. To do that I added a https-redirect middleware :
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: https-redirect
namespace: <your-namespace>
spec:
redirectScheme:
scheme: https
permanent: true
The namespace here is important as you need it for the annotation.
You then need to add an annotation to your ingress :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
traefik.ingress.kubernetes.io/router.middlewares: <your-namespace>-https-redirect#kubernetescrd
traefik.ingress.kubernetes.io/router.tls: "true"
...
I found the explanation here :
https://community.traefik.io/t/how-to-configure-middleware-with-kubernetes-ingress-middleware-xyz-does-not-exist/5016
I've followed this doc from microsoft Deploy an HTTPS ingress controller on Azure Kubernetes Service (AKS) and have successfully deployed a managed Kubernetes cluster (AKS) with nginx ingress controller. it works with https as expected.
However, the domain that responds of the format subdomain.eastus2.cloudapp.azure.com. However I would like to use my own custom domain www.somedomain.com. I then add a CNAME entry to my custom domain, pointing to the public ip address configured by the kubernetes cluster.
However, when I do this, I get a response on the browser of
default backend - 404
It looks like I need to change the public ip address in Azure (or somewhere) so that it understands that it will be used by a custom domain as well as by an azure subdomain.
I've had a look at the command:
az network
command. However, it's not very clear is this is the right command to use or not. Does anyone know how I can make the changes required so that my custom FQDN can be routed properly to my kubernetes cluster?
thanks
Here's the yaml that worked for me.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: webapp-ingress
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-staging
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- subdomain.eastus2.cloudapp.azure.com
- subdomain.domain.com
secretName: tls-secret
rules:
- host: subdomain.eastus2.cloudapp.azure.com
http:
paths:
- path: /
backend:
serviceName: aks-helloworld
servicePort: 80
- host: subdomain.domain.com
http:
paths:
- path: /
backend:
serviceName: aks-helloworld
servicePort: 80
See here for worked through example: Deploy an HTTPS ingress controller on Azure Kubernetes Service (AKS)
The 'default backend 404' indicates that it is hitting the ingress controller. If it were being rejected or not reaching I'd expect a generic 404 without the 'default backend' bit. This response means it is hitting the ingress contoller but the inress controller doesn't know where to send it on to. This is because there's no ingress route/resource matching the host of that request. The steps to create that route/resource are specific to the domain so the ingress rules only match for the azure domain and not the custom one. I think you'll need to go back and repeat the ingress resource and certificate steps for your custom domain as those steps are domain-specific.
I've been facing the same problem the last couple of days and came across an awesome step-by-step guide which allowed me to use custom domains and provisioning certs with Letsencrypt.
If you want to use your own custom certificates you may want to follow this article instead
I have deployed a Kubernetes cluster to a custom virtual network on Azure using acs-engine. There is an ASP.NET Core 2.0 Kestrel app running on the agent VMs and the app is accessed over VPN through a Service of the Azure internal load balancer type. Now I would like to enable HTTPS on the service. I have already obtained a domain name and a certificate but have no idea how to proceed. Apparently configuring Kestrel to use HTTPS and copying the certificate to each container is not the way to go.
I have checked out tutorials such as ingress on k8s using acs and configure Nginx Ingress Controller for TLS termination on k8s on Azure but both of them end up exposing a public external IP and I want to keep the IP internal and not accessible from the internet. Is this possible? Can it be done without ingresses and their controllers?
While for some reason I still can't access the app through the ingress I was able to create an internal ingress service with the IP I want with the following configuration:
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
name: nginx-ingress-svc
spec:
type: LoadBalancer
ports:
- port: 443
targetPort: 443
loadBalancerIP: 130.10.1.9
selector:
k8s-app: nginx-ingress-controller
The tutorial you linked is a bit outdated, at least the instructions have you go to a 'examples' folder in the GitHub repo they link but that doesn't exist. Anyhow, a normal nginx ingress controller consists of several parts: the nginx deployment, the service that exposes it and the default backed parts. You need to look at the yamls they ask you to deploy, look for the second part of what I listed - the ingress service - and change type from LoadBalancer to ClusterIP (or delete type altogether since ClusterIP is the default)