Search code examples
kubernetestraefik

How to create a HTTPS route to a Service that is listening on Https with Traefik, and Kubernetes


I'm a newbie in kubernetes and Traefik.

I follow up that tutorial: https://docs.traefik.io/user-guides/crd-acme/

And I changed it to use my Service in Scala, that it is under https and 9463 port. I'm trying to deploy my Scala service with kubernetes and traefik.

When I forward directly to the service :

kubectl port-forward service/core-service 8001:9463

And I perform a curl -k 'https://localhost:8001/health' :

I get the "{Message:Ok}"

But when I perform a port forward to traefik

kubectl port-forward service/traefik 9463:9463 -n default

And perform a curl -k 'https://ejemplo.com:9463/tls/health' I get an "Internal server error"

I guess the problem is that my "core-service" is listening over HTTPS protocol, that's what I add scheme:https. I tried to find the solution over the documentation but it is confusing.

Those are my yml files:

Services.yaml

apiVersion: v1  
kind: Service  
metadata:  
  name: traefik

spec:  
  ports:
    - protocol: TCP
      name: admin
      port: 8080
    - protocol: TCP
      name: websecure
      port: 9463
  selector:
    app: traefik

---
apiVersion: v1  
kind: Service  
metadata:  
  name: core-service

spec:  
  ports:
    - protocol: TCP
      name: websecure
      port: 9463
  selector:
    app: core-service

Deployment.yaml

apiVersion: v1  
kind: ServiceAccount  
metadata:  
  namespace: default
  name: traefik-ingress-controller

---
kind: Deployment  
apiVersion: apps/v1  
metadata:  
  namespace: default
  name: traefik
  labels:
    app: traefik

spec:  
  replicas: 1
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      containers:
        - name: traefik
          image: traefik:v2.0
          args:
            - --api.insecure
            - --accesslog
            - --entrypoints.websecure.Address=:9463
            - --providers.kubernetescrd
            - --certificatesresolvers.default.acme.tlschallenge
            - --certificatesresolvers.default.acme.email=foo@you.com
            - --certificatesresolvers.default.acme.storage=acme.json
            # Please note that this is the staging Let's Encrypt server.
            # Once you get things working, you should remove that whole line altogether.
            - --certificatesresolvers.default.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
          ports:
            - name: websecure
              containerPort: 9463
            - name: admin
              containerPort: 8080

---
kind: Deployment  
apiVersion: apps/v1  
metadata:  
  namespace: default
  name: core-service
  labels:
    app: core-service

spec:  
  replicas: 1
  selector:
    matchLabels:
      app: core-service
  template:
    metadata:
      labels:
        app: core-service
    spec:
      containers:
        - name: core-service
          image: core-service:0.1.4-SNAPSHOT
          ports:
            - name: websecure
              containerPort: 9463
          livenessProbe:
            httpGet:
              port: 9463
              scheme: HTTPS
              path: /health
            initialDelaySeconds: 10

IngressRoute2.yaml

apiVersion: traefik.containo.us/v1alpha1  
kind: IngressRoute  
metadata:  
  name: ingressroutetls
  namespace: default
spec:  
  entryPoints:
    - websecure
  routes:
  - match: Host(`ejemplo.com`) && PathPrefix(`/tls`)
    kind: Rule
    services:
    - name: core-service
      port: 9463
      scheme: https
  tls:
    certResolver: default

Solution

  • From the docs

    A TLS router will terminate the TLS connection by default. However, the passthrough option can be specified to set whether the requests should be forwarded "as is", keeping all data encrypted.

    In your case SSL Passthrough need to be enabled because the pod is expecting HTTPS traffic.

    apiVersion: traefik.containo.us/v1alpha1  
    kind: IngressRoute  
    metadata:  
      name: ingressroutetls
      namespace: default
    spec:  
      entryPoints:
        - websecure
      routes:
      - match: Host(`ejemplo.com`) && PathPrefix(`/tls`)
        kind: Rule
        services:
        - name: core-service
          port: 9463
          scheme: https
      tls:
        certResolver: default
        passthrough: true