Traefik IngressRoute. How to proxy a request to an external IP-address

kubernetestraefik

I use Traefik IngressRoute in Kubernetes.

My goal is to proxy a request when accessing https://kubernetes_host.com/my_api/… to http://10.139.158.30:5000/api/v1/

I would do this in Nginx:

location /my_api {
    proxy_pass http://10.139.158.30:5000/api/v1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme http;
    proxy_set_header X-Forwarded-Proto http;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
    }

But I can’t figure out how to do this in Traefik IngressRoute.
In the documentation, proxying requests only for internal Kubernetes services.
Example:

---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: route-proxy
  namespace: xxx
spec:
  entryPoints:
  - xxx
  routes:
  - kind: Rule
    match: PathPrefix(`/my_api`)
    services:
    - kind: Service
      name: some-service
      port: 80

Best Answer

You can try creating an Endpoint-Service pair to point to your IP:

apiVersion: v1
kind: Endpoints
metadata:
  name: api
subsets:
  - addresses:
      - ip: 10.139.158.30
    ports:
      - port: 5000
---
kind: Service
apiVersion: v1
metadata:
  # Service name has to match Endpoints so k8s can route traffic
  name: api
spec:
  ports:
    - port: 80
      # targetPort has to match the Endpoints ports above
      targetPort: 5000

Or using the newer EndpointSlice API (from k8s v1.21):

kind: Service
apiVersion: v1
metadata:
  name: api
spec:
  ports:
    - port: 80
      # targetPort has to match the EndpointSlice port
      targetPort: 5000
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: api-endpoint # by convention, use the name of the Service
                     # as a prefix for the name of the EndpointSlice
  labels:
    # You should set the "kubernetes.io/service-name" label.
    # Set its value to match the name of the Service
    kubernetes.io/service-name: api
addressType: IPv4
ports:
  - appProtocol: http
    protocol: TCP
    port: 5000
endpoints:
  - addresses:
      - "10.139.158.30"

Then, reference the Service in your IngressRoute definition:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: route-proxy
  namespace: xxx
spec:
  entryPoints:
  - xxx
  routes:
  - kind: Rule
    match: PathPrefix(`/my_api`)
    services:
    - kind: Service
      name: api
      port: 80

More information: https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors.

Related Topic