Consul-ui through consul api gateway

Hi All,

Here is what I am trying to do and what I have done -

I have installed and configured consul on AKS with API gateway.

Now I want to access consul UI using my host like https://abcd.xyz.com/consul

For this I created gateway as well as http route as shown below -

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
  name: consul-gateway
spec:
  gatewayClassName: consul-api-gateway
  listeners:
  - protocol: HTTPS
    port: 443
    name: https
    hostname: abcd.xyz.com
    tls:
      certificateRefs:
      - kind: Secret
        group: ""
        name: abcd.xyz.com-ingress-secret
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
  name: example-route-1
spec:
  parentRefs:
  - name: consul-gateway
  hostnames:
  - abcd.xyz.com
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /consul
    backendRefs:
    - name: consul-ui
      namespace: consul
      port: 443

It is not working. I am new to consul and so may be missing something. Any help will be highly appreciated…

Hi @mdaslamansari,

It probably isn’t working because the hostname is set in both the Listener and the HTTPRoute. You only need to specify the hostname FQDN once.

When hostname is configured in both the Listener and the HTTPRoute, the Kubernetes Gateway API specification treats the two hostnames as parts of the FQDN and combines the two into a single FQDN.

Based on the config you posted, the Gateway is trying to match the hostname to:

abcd.xyz.com.abcd.xyz.com

Try deleting the hostname from the HTTPRoute and see if that works for you.

Done but still same issue…

Getting below status on editing httproute - Not sure why it is not able to find consul-ui service…

status:
parents:

  • conditions:
    • lastTransitionTime: “2022-03-11T16:48:02Z”
      message: “1 error occurred:\n\t* route is in an invalid state and cannot bind\n\n”
      observedGeneration: 2
      reason: BindError
      status: “False”
      type: Accepted
    • lastTransitionTime: “2022-03-11T16:48:02Z”
      message: ‘consul: consul service consul/consul-ui not found’
      observedGeneration: 2
      reason: ConsulServiceNotFound
      status: “False”
      type: ResolvedRefs
      controllerName: hashicorp.com/consul-api-gateway-controller
      parentRef:
      group: gateway.networking.k8s.io
      kind: Gateway
      name: consul-gateway

Hi @mdaslamansari

The issue is actually with the fact that at this time the API Gateway only supports services that are registered inside of the Consul Service Mesh.

Due to the fact that the controllers that handle transparent service mesh proxying and registration require a Consul server to be running at the time that the mesh proxies are launched, there is no simple way of serving up the Consul UI itself through the service mesh with our current Kubernetes infrastructure.

One workaround is to register a lightweight reverse proxy on the mesh and use that to front the UI by leveraging the consul-ui service registered in kubedns. For example, this sets up a Caddy-based reverse proxy to consul-ui that is accessible on the service mesh (though your namespaces and kubedns addresses might need to change):

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: caddy
automountServiceAccountToken: true
---
apiVersion: v1
kind: Service
metadata:
  name: caddy
spec:
  selector:
    app: caddy
  ports:
    - name: http
      protocol: TCP
      port: 8080
      targetPort: 8080
---
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: caddy
spec:
  protocol: "http"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: caddy
data:
  caddyfile: |
    {
      auto_https off
    }
    :8080 {
      reverse_proxy consul-ui.default.svc.cluster.local
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: caddy
  labels:
    app: caddy
spec:
  selector:
    matchLabels:
      app: caddy
  template:
    metadata:
      labels:
        app: caddy
      annotations:
        consul.hashicorp.com/connect-inject: "true"
    spec:
      serviceAccountName: caddy
      containers:
        - name: caddy
          image: caddy
          ports:
            - containerPort: 8080
          volumeMounts:
          - name: config
            mountPath: "/etc/caddy"
            readOnly: true
      volumes:
        - name: config
          configMap:
            name: caddy
            items:
            - key: "caddyfile"
              path: "Caddyfile"

Rather than trying to hit the consul-ui service directly, you’d reference this reverse proxy in your route configuration. That said, as a rich front-end application, I don’t believe that the Consul UI supports being run with a path prefix, so you’ll likely break things if you add the prefix matching rule:

    - path:
        type: PathPrefix
        value: /consul

to your route.