thoth
thoth

Reputation: 1248

Forward to ExternalName with traefik in kubernetes as the documenation suggests

Following the Official Guide I got to the section onForwarding to ExtternalNames. Where it says:

When specifying an ExternalName, Træfik will forward requests to the given host accordingly

which points to the docs from kubernetes services without selectors

Which led me to create a service

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

Of which Traefik happily ignores when I point to it:

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-service
  namespace: kube-system
spec:
  rules:
  - host: my-service.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 4080

I have also tried as an endpoint.

---                                                                                                                                                                                           
kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: kube-system
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 4080
---
kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 10.0.0.3
    ports:
      - port: 4080

Does anyone know how to get traefik to point to an externalname as the documentation suggests?

Upvotes: 2

Views: 4215

Answers (2)

berto
berto

Reputation: 8503

I'm running k3s with the built-in traefik and ran into not being able to point to an external service. In the logs I saw this error related to externally named services:

$ kubectl logs traefik-7d5f6474df-j2bh7 | grep pihole
[...]
time="2024-11-01T12:35:21Z" level=error msg="Cannot create service: externalName services not allowed: pihole/pihole-forwarder-service" ingress=pihole-ingress namespace=pihole servicePort="&ServiceBackendPort
{Name:,Number:80,}" serviceName=pihole-forwarder-service providerName=kubernetes                        

I finally stumbled upon this forum post describing that traefik v2 does not enable external name services by default and to add some options to the manifest; here's my diff:

root@ubuntu:/var/lib/rancher/k3s/server# diff -u manifests.bak/traefik.yaml manifests/traefik.yaml 
--- manifests.bak/traefik.yaml 2024-10-23 22:10:23.609778411 +0000
+++ manifests/traefik.yaml 2024-11-01 13:01:34.597876597 +0000
@@ -40,3 +40,13 @@
       effect: "NoSchedule"
     service:
       ipFamilyPolicy: "PreferDualStack"
+    additionalArguments:
+    - "--providers.kubernetesingress.allowemptyservices=true"
+    - "--providers.kubernetesingress.allowexternalnameservices=true"
+    - "--providers.kubernetescrd.allowemptyservices=true"
+    - "--providers.kubernetescrd.allowexternalnameservices=true"

Once the .yaml file is saved Traefik automatically restarts and the external service worked.

HTH.

Upvotes: 1

Anton Kostenko
Anton Kostenko

Reputation: 9033

As I see, you missed at least one line in your Ingress object - traefik.frontend.passHostHeader: "false".

Also, you need to create an Ingress object in a same Namespace with your Service.

So, your Ingress should be like:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-service
  namespace: prod
  annotations:
    traefik.frontend.passHostHeader: "false"
spec:
  rules:
  - host: my-service.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 4080

And service:

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  ports:
  - name: app-port
    port: 4080
  externalName: my.database.example.com

Upvotes: 1

Related Questions