Configure Ingress Gateways for Consul on Kubernetes
Note
Ingress gateway is deprecated and will not be enhanced beyond its current capabilities. Ingress gateway is fully supported in this version but will be removed in a future release of Consul.
Consul's API gateway is the recommended alternative to ingress gateway.
This topic requires familiarity with Ingress Gateways.
This page describes how to enable external access through Consul ingress gateways to mesh services running inside Kubernetes. See Ingress Gateways for more information on use-cases and how it works.
Adding an ingress gateway is a multi-step process that consists of the following steps:
- Setting the Helm chart configuration
- Deploying the Helm chart
- Configuring the gateway
- Defining an Intention (if ACLs are enabled)
- Deploying your application to Kubernetes
- Connecting to your application
Setting the helm chart configuration
When deploying the Helm chart you must provide Helm with a custom YAML file that contains your environment configuration.
values.yaml
global: name: consulconnectInject: enabled: trueingressGateways: enabled: true gateways: - name: ingress-gateway service: type: LoadBalancer
Note: this will create a public unauthenticated LoadBalancer in your cluster, please take appropriate security considerations.
The YAML snippet is the launching point for a valid configuration that must be supplied when installing using the official consul-helm chart. Information on additional options can be found in the Helm reference. Configuration options for ingress gateways reside under the ingressGateways entry.
The gateways stanza is where you will define and configure the set of ingress gateways you want deployed to your environment.
The only required field for each entry is name
, though entries may contain any of the fields found in the defaults
stanza.
Values in this section override the values from the defaults stanza for the given ingress gateway with one exception:
the annotations from the defaults stanza will be appended to any user-defined annotations defined in the gateways stanza rather than being overridden.
Please refer to the ingress gateway configuration documentation for a detailed explanation of each option.
Deploying the Helm chart
Ensure you have the latest consul-helm chart and install Consul via helm using the following guide while being sure to provide the yaml configuration as previously discussed.
The following example installs Consul 1.0.4 using the values.yaml
configuration:
$ helm install consul -f values.yaml hashicorp/consul --version 1.0.4 --wait --debug
Configuring the gateway
Now that Consul has been installed with ingress gateways enabled,
you can configure the gateways via the IngressGateway
custom resource.
Here is an example IngressGateway
resource:
ingress-gateway.yaml
apiVersion: consul.hashicorp.com/v1alpha1kind: IngressGatewaymetadata: name: ingress-gatewayspec: listeners: - port: 8080 protocol: http services: - name: static-server
Note: The 'name' field for the IngressGateway resource must match the name specified when creating the gateway in the Helm chart. In the above example, the name "ingress-gateway" is the default name used by the Helm chart when enabling ingress gateways.
Apply the IngressGateway
resource with kubectl apply
:
$ kubectl apply --filename ingress-gateway.yamlingressgateway.consul.hashicorp.com/ingress-gateway created
Since we're using protocol: http
, we also need to set the protocol of our service
static-server
to http. To do that, we create a ServiceDefaults
custom resource:
service-defaults.yaml
apiVersion: consul.hashicorp.com/v1alpha1kind: ServiceDefaultsmetadata: name: static-serverspec: protocol: http
Apply the ServiceDefaults
resource with kubectl apply
:
$ kubectl apply --filename service-defaults.yamlservicedefaults.consul.hashicorp.com/static-server created
Ensure both resources have synced to Consul successfully:
$ kubectl get servicedefaultsNAME SYNCED AGEstatic-server True 45s $ kubectl get ingressgatewayNAME SYNCED AGEingress-gateway True 13m
Viewing the UI
You can confirm the ingress gateways have been configured as expected by viewing the ingress-gateway service instances in the Consul UI.
To view the UI, use the kubectl port-forward
command. See Viewing The Consul UI
for full instructions.
Once you've port-forwarded to the UI, navigate to the Ingress Gateway instances: http://localhost:8500/ui/dc1/services/ingress-gateway/instances
If TLS is enabled, use https://localhost:8501/ui/dc1/services/ingress-gateway/instances.
Defining an Intention
If ACLs are enabled (via the global.acls.manageSystemACLs
setting), you must define an intention
to allow the ingress gateway to route to the upstream services defined in the IngressGateway
resource (in the example above the upstream service is static-server
).
To create an intention that allows the ingress gateway to route to the service static-server
, create a ServiceIntentions
resource:
service-intentions.yaml
apiVersion: consul.hashicorp.com/v1alpha1kind: ServiceIntentionsmetadata: name: static-serverspec: destination: name: static-server sources: - name: ingress-gateway action: allow
Apply the ServiceIntentions
resource with kubectl apply
:
$ kubectl apply --filename service-intentions.yamlserviceintentions.consul.hashicorp.com/ingress-gateway created
For detailed instructions on how to configure zero-trust networking with intentions please refer to this guide.
Deploying your application to Kubernetes
Now you will deploy a sample application which echoes "hello world"
static-server.yaml
apiVersion: v1kind: Servicemetadata: name: static-serverspec: selector: app: static-server ports: - protocol: TCP port: 80 targetPort: 8080---apiVersion: v1kind: ServiceAccountmetadata: name: static-server---apiVersion: apps/v1kind: Deploymentmetadata: name: static-serverspec: replicas: 1 selector: matchLabels: app: static-server template: metadata: name: static-server labels: app: static-server annotations: 'consul.hashicorp.com/connect-inject': 'true' spec: containers: - name: static-server image: hashicorp/http-echo:latest args: - -text="hello world" - -listen=:8080 ports: - containerPort: 8080 name: http serviceAccountName: static-server
$ kubectl apply --filename static-server.yaml
Connecting to your application
You can validate the service is running and registered in the Consul UI by navigating to http://localhost:8500/ui/dc1/services/static-server/instances
If TLS is enabled, use: https://localhost:8501/ui/dc1/services/static-server/instances
You can also validate the connectivity of the application from the ingress gateway using curl
:
$ EXTERNAL_IP=$(kubectl get services --selector component=ingress-gateway --output jsonpath="{range .items[*]}{@.status.loadBalancer.ingress[*].ip}{end}")$ echo "Connecting to \"$EXTERNAL_IP\""$ curl --header "Host: static-server.ingress.consul" "http://$EXTERNAL_IP:8080""hello world"
Security Warning: Please be sure to delete the application and services created here as they represent a security risk through leaving an open and unauthenticated load balancer alive in your cluster.
To delete the ingress gateway, set enabled to false
in your Helm configuration:
values.yaml
global: name: consulconnectInject: enabled: trueingressGateways: enabled: false # Set to false gateways: - name: ingress-gateway service: type: LoadBalancer
And run Helm upgrade:
$ helm upgrade consul hashicorp/consul --values values.yaml