argocd & traefik: argocd unreachable - traefik

I'm struggling with exposing argocd using traefik.
Argocd is well deployed on my kubernetes. I'm able to reach it using port forwarding:
curl -I -k https://localhost:36651
HTTP/1.1 200 OK
I've deployed this ingressroute:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: argocd-server
namespace: argocd
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`argocd.localhost`)
priority: 10
services:
- name: argocd-server
port: 80
- kind: Rule
match: Host(`argocd.localhost`) && Headers(`Content-Type`, `application/grpc`)
priority: 11
services:
- name: argocd-server
port: 80
scheme: h2c
tls:
certResolver: default
options: {}
When I'm trying to reach it, I'm getting an 404.
curl argocd.localhost
404 page not found
I've also tried to reach https directly:
curl -I -k https://argocd.localhost:8443/
HTTP/2 307
location: https://argocd.localhost:8443/
It's getting me a redirection to https://argocd.localhost:8443/, which is the same that requested on curl command...
Any ideas?

Related

AKS Istio Ingress gateway Certificate is not valid

I have an AKS cluster with Istio install and I'm trying to deploy a containerised web api with TLS.
The api runs and is accessible but is showing as Not secure.
I have followed the directions on istios website to set this so not sure what I've missed.
I have created the secret with the command
kubectl create secret tls mycredential -n istio-system --key mycert.key --cert mycert.crt
and setup a gateway as follows
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: my-gateway
namespace: mynamespace
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: mycredential # must be the same as secret
hosts:
- 'dev.api2.mydomain.com'
The following virtual service
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapi
namespace: mynamespace
spec:
hosts:
- "dev.api2.mydomain.com"
gateways:
- my-gateway
http:
- match:
- uri:
prefix: "/myendpoint"
rewrite:
uri: " "
route:
- destination:
port:
number: 8080
host: myapi
and service
apiVersion: v1
kind: Service
metadata:
name: myapi
namespace: mynamespace
labels:
app: myapi
service: myapi
spec:
ports:
- name: http
port: 8080
targetPort: 80
selector:
app: myapi
The container exposes port 80
Can someone please point me in the right direction because I'm not sure what I've done wrong
I managed to resolve the issue by setting up cert manager and pointing it at letsencrypt to generate the certificate, rather than using the pre-purchased one I was trying to add manually.
Although it took some searching to find how to correctly configure this, it is now working and actually saves having to purchase certificates, so win win :)

400 Bad Request You're speaking plain HTTP to an SSL-enabled server port kubernetes pod

I am getting the error "400 Bad Request Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please."
What I am trying to achieve is :
1.Docker Run
Docker Image which is using apache2 and Shibboleth both are running on port http(8090) & https(8443) respectively with self signed certificate. Running the image locally using the docker run it is working fine.
http://localhost:8090/ ----> working fine
https://localhost:8443/Shibboleth.sso/Status ----> giving cert error but after accept and ignore working fine.
(Shibboleth service which is being accessed via apache2 000-default.conf ProxyPass /Shibboleth.sso/ https://localhost:8443/Shibboleth.sso/Status)
Kubernetes Platform
Below are the deployment,Service and Ingress created to access the same image.
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: demo
labels:
app: demo
spec:
#replicas: 1
selector:
matchLabels:
app: demo-pod
template:
metadata:
labels:
app: demo-pod
spec:
containers:
- image: <repository>public/demo-v1
name: demo
ports:
- containerPort: 8154
name: demo-ui
- containerPort: 8090
name: http
- containerPort: 8443
name: https
securityContext:
runAsNonRoot: true
runAsUser: 1000
resources:
limits:
cpu: 1000m
memory: 8024Mi
requests:
cpu: 500m
memory: 4096Mi
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: regcred
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
namespace: test
name: demo-svc
labels:
app: demo
spec:
selector:
app: demo-pod
ports:
- port: 8154
name: demo-ui
targetPort: 8154
protocol: TCP
- port: 8090
name: http
targetPort: 8090
protocol: TCP
- port: 8443
name: https
targetPort: 8443
protocol: TCP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: demo-ing
labels:
app: demo
spec:
ingressClassName: internal
tls:
- hosts:
- demo.example.com
rules:
- host: demo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 8090
- path: /demo-ui
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 8090
- path: /Shibboleth.sso
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 8443
the default domain is using the https for *.example.com
when hitting **https://demo.example.com/ --> http://<pod-IP>:8090** and working fine
but when accessing the **https://demo.example.com/Shibboleth.sso/Status --- > http://<pod-IP>:8443**
And returning "400 Bad Request Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please"
I have tried multiple solutions via ingress annotations and apache2 redirect as well but nothing seems to help.
when doing redirect on apache2 it is not taking the localhost as variable.
RewriteEngine on
ReWriteCond %{SERVER_PORT} !^8443$
RewriteRule ^/Shibboleth.sso(.*) https://localhost:8443/Shibboleth.sso/$1 [NC,R,L]
not considering localhost and taking as dns.
Also tried to redirect at ingress level also which is giving 404 not found error.
Please help here !!!
Can you please try adding this annotation to your ingress file?
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/secure-backends: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

Istio Egress Gateways with TLS Origination CERTIFICATE_VERIFY_FAILED

I'm trying to setup istio (v1.7.3) on AKS (v1.16.13) in a way that for some of the HTTP destinations a TLS Origination will be performed. So when one of my pods is invoking abc.mydomain.com with HTTP, the Egress request will be upgraded to HTTPS and the TLS verification done through the Egress gateway.
I have followed these 2 tutorials to achieve that:
https://istio.io/latest/docs/tasks/traffic-management/egress/egress-gateway-tls-origination-sds/
https://istio.io/latest/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/
I ended up with something like this (abc.mydomain.com is an external URL so that why I created a ServiceEntry for it):
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: abc.mydomain.com
spec:
hosts:
- abc.mydomain.com
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway
namespace: istio-system
spec:
selector:
istio: egressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- abc.mydomain.com
tls:
mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-abc
namespace: istio-system
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: abc
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: ISTIO_MUTUAL
sni: abc.mydomain.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-abc-through-egress-gateway
namespace: istio-system
spec:
hosts:
- abc.mydomain.com
gateways:
- istio-egressgateway
- mesh
http:
- match:
- gateways:
- mesh
port: 80
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
subset: abc
port:
number: 443
weight: 100
- match:
- gateways:
- istio-egressgateway
port: 443
route:
- destination:
host: abc.mydomain.com
port:
number: 443
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: originate-tls-for-abc
namespace: istio-system
spec:
host: abc.mydomain.com
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE
credentialName: abc # this must match the secret created earlier without the "-cacert" suffix
sni: abc.mydomain.com
I'm creating a secret for my CA root with: kubectl create secret generic abc-cacert --from-file=ca.crt=mydomainrootca.crt -n istio-system
I've used the same certificate for my java applications and I can successfully invoke HTTPS for the same url using JKS. It seems the certificate is loaded properly into egress (kubectl logs -f -l istio=egressgateway -n istio-system):
2020-10-06T20:00:36.611607Z info sds resource:abc-cacert new connection
2020-10-06T20:00:36.612907Z info sds Skipping waiting for gateway secret
2020-10-06T20:00:36.612994Z info cache GenerateSecret abc-cacert
2020-10-06T20:00:36.613063Z info sds resource:abc-cacert pushed root cert to proxy
When I invoke curl abc.mydomain.com from a pod running on my cluster I'm getting this error from egress gateway:
[2020-10-06T19:33:40.902Z] "GET / HTTP/1.1" 503 UF,URX "-" "TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED" 0 91 172 - "192.244.0.191" "curl/7.64.0" "b618b1e6-e543-4053-bf2f-8ae56664545f" "abc.mydomain.com" "192.223.24.254:443" outbound|443||abc.mydomain.com - 192.244.0.188:8443 192.244.0.191:41306 abc.mydomain.com -
Any idea what I might be doing wrong? I'm quite new to istio and I don't understand all of the need of DestinationRule/VirtualService so please bare with me.
UPDATE1
After putting the DestinationRules in the namespace where my pod is running, I'm getting the following:
curl abc.mydomain.com
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.17.10</center>
</body>
</html>
Here is the output of istioctl proxy-status:
NAME CDS LDS EDS RDS ISTIOD VERSION
istio-egressgateway-695dc4fc7c-p5p42.istio-system SYNCED SYNCED SYNCED SYNCED istiod-5c6b7b5b8f-csggg 1.7.3
istio-ingressgateway-5689f7c67-j54m7.istio-system SYNCED SYNCED SYNCED SYNCED istiod-5c6b7b5b8f-csggg 1.7.3
test-5bbfdb8f4b-hg7vf.test SYNCED SYNCED SYNCED SYNCED istiod-5c6b7b5b8f-csggg 1.7.3

Why Traefik 2.2 & Let's Encrypt does not support new annotations?

I have setup traefik 2.2 in my self managed kubernetes cluster with Let's Encrypt support.
So far everything works. But the ingress Route configuration in my eyes is still clumsy. It only works if I define two IntgresRoutes - one for HTTP with a redirect middleware to https and one for the https. So my objects look like this:
# Middleware for Redirect http -> https
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: https-redirect
spec:
redirectScheme:
scheme: https
# IngressRoute http for a simple whoami service
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
name: whoami-notls
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`mydomain.foo.com`)
kind: Rule
services:
- name: whoami
port: 8080
# redirect http to https
middlewares:
- name: https-redirect
# IngresRoute https
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
name: whoami-tls
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`mydomain.foo.com`)
kind: Rule
services:
- name: whoami
port: 8080
tls:
certResolver: default
Is there not a more easy way to simply tell traefik that my service - which is listening on port 8080 - should be redirected to HTTPS in any case. Why do I need two separate ingresRoutes in my setup?
In the announcements for traefik 2.2. there was something like this:
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: foo
namespace: bar
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web, websecure
traefik.ingress.kubernetes.io/router.middlewares: redirect-http#kuberntes-crd
spec:
rules:
- host: foo.com
http:
paths:
- path: ""
backend:
serviceName: service1
servicePort: 80
It looks very simple. But this did not work for me - traefik is not recognizing this Ingress configuration.
With the help of the Traefik.io team in this discussion, I now solved the problem:
To use traefik annotations in Ingress make sure that in your deployment object you have added the ‘kubernetesingress’ provider:
...
spec:
containers:
- args:
- --api
....
- --providers.kubernetescrd=true
- --providers.kubernetesingress=true
....
For a global redirect form HTTP to HTTPS you can also configure this in your traefik deplyoment object:
# permanent redirecting of all requests on http (80) to https (443)
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.websecure.http.tls.certResolver=default
Now you can configure your ingress in an easy way:
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: myingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web, websecure
spec:
rules:
- host: example.foo.com
http:
paths:
- path: /
backend:
serviceName: whoami
servicePort: 80
See also my latest Blog post.

TLS setup on K8S Ingress with Traefik

I have a setup that is not too much different than the user guide for use with k8s. For some reason I can only access http://app.minikube and not https://app.minikube.
Can someone look at my setup and see what I am obviously missing?
apiVersion: v1
kind: Service
metadata:
name: myapp
labels:
app: myapp
spec:
ports:
- name: http
port: 80
targetPort: 7777
selector:
app: myapp
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myingress
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: app.minikube
http:
paths:
- path: /
backend:
serviceName: myapp
servicePort: http
tls:
- secretName: mytls
FYI, according to the Traefik user guide, the hosts definition in tls is unneeded, which is why I left it out.
The field hosts in the TLS configuration is ignored. Instead, the domains provided by the certificate are used for this purpose. It is recommended to not use wildcard certificates as they will match globally)
You're missing the hosts section:
tls:
- hosts:
- my-host.example.com
secretName: my-secret