Closed andormarkus closed 3 years ago
I believe all the deployments in K8S should be done using http (or if istio is enabled they can be additionally protected via mTLS).
I think the usual pattern of providing SSL deployment is via external proxy/gateways, especially that they can then provide additional authentication mechanism (Oauth/client certificates etc.) which can be configured outside of Airflow and even provide single authentication/SSL endpoints for multiple services.
I think this is common best practice to decouple SSL termination and the service itself.
Here is a example of simple nginx-based SSL proxy that you can follow: https://kubernetes.io/blog/2015/07/strong-simple-ssl-for-kubernetes/
You just don't need to configure Nginx, but you can configure SSL in Ingress. This will also allow certmanager to automatically manage the certificates.
Example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# add an annotation indicating the issuer to use.
cert-manager.io/cluster-issuer: nameOfClusterIssuer
name: myIngress
namespace: myIngress
spec:
rules:
- host: example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: myservice
port:
number: 80
tls: # < placing a host in the TLS config will indicate a certificate should be created
- hosts:
- example.com
secretName: myingress-cert # < cert-manager will store the created certificate in this secret.
Hi @potiuk and @mik-laj
Thank you for the idea to shifting the SSL into the Ingress. We are using AWS Load Balancer Controller which supports ingress side certificates. I think more people might have the same issue who are new into Kubernetes and Airflow. Can we extended Helm chart documentation with mik-laj's recommendation?
I have followed Marc Lamberti's 'Apache Airflow on AWS EKS: The Hands-On Guide' which clearly won't work with the newly released official chart.
Helm chart myconf.yaml looks like this
ingress:
enabled: true
web:
precedingPaths:
- path: "/*"
serviceName: "ssl-redirect"
servicePort: "use-annotation"
path: "/airflow/*"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=3600
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-central-1:XXXXXXXXXX:certificate/XXXXXXXXXXX
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
Can we extended Helm chart documentation with mik-laj's recommendation?
Good idea. Are you willing to submit a PR? I'm happy to help. with review.
I have followed Marc Lamberti's 'Apache Airflow on AWS EKS: The Hands-On Guide' which clearly won't work with the newly released official chart.
CC: @marclamberti
Thanks for noticing me :) I will update the course
Yep. It would be great to submit a pr @andormarkus . And yeah. Ingress is even better than having your own proxy.
I'm more than happy to submit a pr, however I'm busy with migration to the official helm chart. Airflow version 2.0.2+
are causing so much headache. See #16013 #16020
I'm more than happy to submit a pr, however I'm busy with migration to the official helm chart. Airflow version
2.0.2+
are causing so much headache. See #16013 #16020
I see. Did you (by any chance) try 2.1.0 or manually upgrading cncf-kubernetes
provider to 1.2.0?
I think there are couple of issues fixed in cncf.kubernetes
1.2.0 version of the provider and at least one looks like might be fixing the labelling problem you explained (https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/stable/index.html#id1) - you can see detailed list of commits for 1.2.0 cncf.kubernetes
provider here: https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/stable/commits.html#id1 and the one I am thinking about is https://github.com/apache/airflow/commit/be421a6b07c2ae9167150b77dc1185a94812b358
The easiest (if you want to try 1.0.2 with new provider) is to build your own image and extend it by installing the new provider with something like:
FROM apache/airflow:2.0.2-pythonX.Y
RUN pip install --upgrade apache-airflow-providers-cncf-kubernetes
Hi @potiuk, I have tried the official helm chart 1.0.0 with Airflow 2.0.1, 2.0.2, 2.1.0 as well. Only 2.0.1 is working, 2.0.2 and 2.1.0 does not work mentioned in the related issues. As I checked Airflow 2.1.0 comes with apache-airflow-providers-cncf-kubernetes==1.2.0
So we need to take a closer look then! Thanks for verifying.
Thanks @andormarkus We will take a look at those issues you have created
My issue is somewhat related. Airflow UI keeps redirecting me to HTTP instead of https.
I was following this. https://airflow.apache.org/docs/apache-airflow/stable/howto/run-behind-proxy.html
I tried adding something like this
webserver:
base_url: "https://k8s.foobaa.com/airflow"
But it gave me
airflow:
- webserver: Additional property base_url is not allowed
I am using aws elb with Kong for proxy.
@Anirudhaagrawal During my initial comment I was'n fully familiar with the helm chart values file. potiuk and mik-laj recommended: we should not use HTTPS inside kubernetes, it will fail on the liveness and readiness probes.
Recommended traffic flow looks like this: internet --> HTTPS --> K8s ingress controller --> HTTP --> Airflow webserver
my configuration looks like this (AWS EKS with aws-load-balancer-controller
):
config:
webserver:
base_url: https://k8s.foobaa.com/airflow
ingress:
enabled: true
web:
precedingPaths:
- path: "/*"
serviceName: "ssl-redirect"
servicePort: "use-annotation"
path: "/airflow/*"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=3600
alb.ingress.kubernetes.io/certificate-arn: ${aws_acm_certificate_arn}
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
I am going to close this ticket for now with https://github.com/apache/airflow/issues/16010#issuecomment-847929472 as the correct solution. For other issues #16013 #16020 -- We will take a look and comment on those specific tickets
Hello
Is it still working ?
I'am on k8s v1.21, helm 1.3.0, airflow 2.2.3. After getting an error about a missing pathType I tried :
values:
config:
webserver:
base_url: "http://localhost:8080/dev"
ingress:
enabled: true
web:
precedingPaths:
- path: "/*"
pathType: "ImplementationSpecific"
serviceName: "ssl-redirect"
servicePort: "use-annotation"
path: /dev/*
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=3600
alb.ingress.kubernetes.io/certificate-arn: mycertificate
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
I let the service to be a cluster ip. My ingress gives me:
Name: airflow-dev-airflow-ingress
Namespace: dev
Address: my-adress
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
*
/* ssl-redirect:use-annotation (<error: endpoints "ssl-redirect" not found>)
/dev/* airflow-dev-webserver:airflow-ui ()
Annotations: alb.ingress.kubernetes.io/actions.ssl-redirect:
{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}
alb.ingress.kubernetes.io/certificate-arn: mycertificate
alb.ingress.kubernetes.io/listen-ports: [{"HTTP": 80}, {"HTTPS":443}]
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=3600
alb.ingress.kubernetes.io/target-type: ip
kubernetes.io/ingress.class: alb
meta.helm.sh/release-name: airflow-dev
meta.helm.sh/release-namespace: dev
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfullyReconciled 112s ingress Successfully reconciled
The ingress manifest that it created is:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig":
{ "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
alb.ingress.kubernetes.io/certificate-arn: *****
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=3600
alb.ingress.kubernetes.io/target-type: ip
kubernetes.io/ingress.class: alb
meta.helm.sh/release-name: airflow-dev
meta.helm.sh/release-namespace: dev
spec:
rules:
- http:
paths:
- backend:
service:
name: ssl-redirect
port:
name: use-annotation
path: /*
pathType: ImplementationSpecific
- backend:
service:
name: airflow-dev-webserver
port:
name: airflow-ui
path: /dev/*
pathType: ImplementationSpecific
status:
loadBalancer:
ingress:
- hostname: *****
Hi
We are using this config with helm 1.3.0
config:
webserver:
base_url: "http://dataengineering.acme.com/airflow"
ingress:
enabled: true
web:
precedingPaths:
- path: "/*"
pathType: "ImplementationSpecific"
serviceName: "ssl-redirect"
servicePort: "use-annotation"
path: "/airflow/*"
annotations:
external-dns.alpha.kubernetes.io/hostname: ${web_url}
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/group.name: dataengineering
alb.ingress.kubernetes.io/group.order: '10'
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=3600
alb.ingress.kubernetes.io/certificate-arn: ${aws_acm_certificate_arn}
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
I think your config.webserver.base_url
is incorrect, it needs to be a valid private/public URL
Thx for the response. I've already tried it. Which k8s version are you working with ?
I also tried it without the reverse proxy :
ingress:
enabled: true
web:
precedingPaths:
- path: "/*"
pathType: "ImplementationSpecific"
serviceName: "ssl-redirect"
servicePort: "use-annotation"
path: "/*"
annotations:
external-dns.alpha.kubernetes.io/hostname: ****
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/group.name: airflow
alb.ingress.kubernetes.io/group.order: '10'
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=3600
alb.ingress.kubernetes.io/certificate-arn: ****
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
I have:
ts=2022-01-04T18:52:13.592931819Z caller=release.go:397 component=release release=airflow-dev targetNamespace=dev resource=dev:helmrelease/airflow helmVersion=v3 warning="failed to annotate release resources: error: arguments in resource/name form must have a single resource and name\n" phase=annotate
The alb controller has changed since v2.3 : https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/guide/tasks/ssl_redirect/ I'll try to make it work/
@andormarkus is the most recent chart you provided still working? I've tried a few versions of it, also updating the ssl-redirect
but no luck. Is localhost not acceptable in the base_url
? Should it match my external-dns annotation?
At this point I feel I've tried just about every combination of NLB/ALB annotations, enabling the proxy fix vars for gunicorn, and am still struggling with getting Airflow SSL to work on EKS. It's just completely stuck in "redirect hell". Is there no config variation that will simply not perform redirects?
Hi @dylac
Do you have running AWS Load Balancer Controller or NGINX Ingress Controller on you EKS cluster?
Your base_url
should be the same as your Route53 entry plus path. I have followed Marc Lamberti's course for the initial setup of Airflow. Sorry I got no access to my Airflow configuration anymore because I switched job.
Thanks, Andor
Hi @andormarkus , i am using NGINX ingress controller on my eks cluster. Do i need to change anything in your provided solution?
Apache Airflow version: 2.0.2 Helm chart version: 1.0.0 Kubernetes version: 1.20
What happened: I have tried to enable HTTPS connection, however when I enable it liveness and readiness probes are failing
How to reproduce it: Helm chart myconf.yaml looks like this