Skip to content

Commit

Permalink
Merge pull request #14347 from hashicorp/update-terminating-gateway-docs
Browse files Browse the repository at this point in the history
Update Kubernetes Terminating Gateway Docs
  • Loading branch information
Thomas Eckert committed Aug 26, 2022
2 parents eb0c5bb + 70a1cbd commit e64a285
Showing 1 changed file with 66 additions and 57 deletions.
123 changes: 66 additions & 57 deletions website/content/docs/k8s/connect/terminating-gateways.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ description: Configuring Terminating Gateways on Kubernetes

# Terminating Gateways on Kubernetes

-> 1.9.0+: This feature is available in Consul versions 1.9.0 and higher

~> This topic requires familiarity with [Terminating Gateways](/docs/connect/gateways/terminating-gateway).

Adding a terminating gateway is a multi-step process:

- Update the Helm chart with terminating gateway config options
- Deploy the Helm chart
- Access the Consul agent
- Register external services with Consul

## Update the helm chart with terminating gateway config options
## Requirements

- [Consul](https://www.consul.io/docs/install#install-consul)
- [Consul on Kubernetes CLI](/docs/k8s/k8s-cli)
- Familiarity with [Terminating Gateways](/docs/connect/gateways/terminating-gateway)

## Update the Helm chart with terminating gateway config options

Minimum required Helm options:

Expand All @@ -38,37 +40,41 @@ terminatingGateways:

## Deploying the Helm chart

Ensure you have the latest consul-helm chart and install Consul via helm using the following
[guide](/docs/k8s/installation/install#installing-consul) while being sure to provide the yaml configuration
as previously discussed.
The Helm chart may be deployed using the [Consul on Kubernetes CLI](/docs/k8s/k8s-cli).

```shell-session
$ consul-k8s install -f config.yaml
```

## Accessing the Consul agent

You can access the Consul server directly from your host via `kubectl port-forward`. This is helpful for interacting with your Consul UI locally as well as to validate connectivity of the application.
You can access the Consul server directly from your host via `kubectl port-forward`. This is helpful for interacting with your Consul UI locally as well as for validating the connectivity of the application.

<Tabs>
<Tab heading="Without TLS">

```shell-session
$ kubectl port-forward consul-server-0 8500 &
```

If TLS is enabled use port 8501:

```shell-session
$ kubectl port-forward consul-server-0 8501 &
$ export CONSUL_HTTP_ADDR=http://localhost:8500
```
</Tab>
<Tab heading="With TLS">

-> Be sure the latest consul binary is installed locally on your host.
[https://releases.hashicorp.com/consul/](https://releases.hashicorp.com/consul/)
If TLS is enabled use port 8501:

```shell-session
$ export CONSUL_HTTP_ADDR=http://localhost:8500
$ kubectl port-forward consul-server-0 8501 &
```

If TLS is enabled set:

```shell-session
$ export CONSUL_HTTP_ADDR=https://localhost:8501
$ export CONSUL_HTTP_SSL_VERIFY=false
```
</Tab>
</Tabs>

If ACLs are enabled also set:

Expand All @@ -88,34 +94,35 @@ Registering the external services with Consul is a multi-step process:

### Register external services with Consul

There are two ways to register an external service with Consul:
1. If [`TransparentProxy`](/docs/connect/transparent-proxy) is enabled, the preferred method is to declare external endpoints in the [`destination`](/docs/connect/config-entries/service-defaults#terminating-gateway-destination) field of `ServiceDefaults`.
1. You can add the service as a node in the Consul catalog.
You may register an external service with Consul using `ServiceDefaults` if
[`TransparentProxy`](/docs/connect/transparent-proxy) is enabled. Otherwise,
you may register the service as a node in the Consul catalog.

#### Register an external service as a destination
<Tabs>
<Tab heading="Using ServiceDefaults and TransparentProxy">

The [`destination`](/docs/connect/config-entries/service-defaults#terminating-gateway-destination) field of the `ServiceDefaults` Custom Resource Definition (CRD) allows clients to dial the external service directly. It is valid only in [`TransparentProxy`](/docs/connect/transparent-proxy)) mode.
The following table describes traffic behaviors when using `destination`s to route traffic through a terminating gateway:
The [`destination`](/docs/connect/config-entries/service-defaults#terminating-gateway-destination) field of the `ServiceDefaults` Custom Resource Definition (CRD) allows clients to dial an external service directly. For this method to work, [`TransparentProxy`](/docs/connect/transparent-proxy) must be enabled.
The following table describes traffic behaviors when using the `destination` field to route traffic through a terminating gateway:

| External Services Layer | Client dials | Client uses TLS | Allowed | Notes |
|---|---|---|---|---|
| L4 | Hostname | Yes | Allowed | `CAFiles` are not allowed because traffic is already end-to-end encrypted by the client. |
| L4 | IP | Yes | Allowed | `CAFiles` are not allowed because traffic is already end-to-end encrypted by the client. |
| L4 | Hostname | No | Not allowed | The sidecar is not protocol aware and can not identify traffic going to the external service. |
| L4 | IP | No | Allowed | There are no limitations on dialing IPs without TLS. |
| L7 | Hostname | Yes | Not allowed | Because traffic is already encrypted before the sidecar, it cannot route as L7 traffic. |
| L7 | IP | Yes | Not allowed | Because traffic is already encrypted before the sidecar, it cannot route as L7 traffic. |
| L7 | Hostname | No | Allowed | A `Host` or `:authority` header is required. |
| L7 | IP | No | Allowed | There are no limitations on dialing IPs without TLS. |
| <nobr>External Services Layer</nobr> | <nobr>Client dials</nobr> | <nobr>Client uses TLS</nobr> | Allowed | Notes |
|--------------------------------------|---------------------------|------------------------------|--------------------------|-----------------------------------------------------------------------------------------------|
| L4 | Hostname | Yes | <nobr>Allowed</nobr> | `CAFiles` are not allowed because traffic is already end-to-end encrypted by the client. |
| L4 | IP | Yes | <nobr>Allowed</nobr> | `CAFiles` are not allowed because traffic is already end-to-end encrypted by the client. |
| L4 | Hostname | No | <nobr>Not allowed</nobr> | The sidecar is not protocol aware and can not identify traffic going to the external service. |
| L4 | IP | No | <nobr>Allowed</nobr> | There are no limitations on dialing IPs without TLS. |
| L7 | Hostname | Yes | <nobr>Not allowed</nobr> | Because traffic is already encrypted before the sidecar, it cannot route as L7 traffic. |
| L7 | IP | Yes | <nobr>Not allowed</nobr> | Because traffic is already encrypted before the sidecar, it cannot route as L7 traffic. |
| L7 | Hostname | No | <nobr>Allowed</nobr> | A `Host` or `:authority` header is required. |
| L7 | IP | No | <nobr>Allowed</nobr> | There are no limitations on dialing IPs without TLS. |

You can provide a `caFile` to secure traffic between unencrypted clients that connect to external services through the terminating gateway.
Refer to [Create the configuration entry for the terminating gateway](#create-the-configuration-entry-for-the-terminating-gateway) for details.

Also note that regardless of the `protocol` specified in the `ServiceDefaults`, [L7 intentions](/docs/connect/config-entries/service-intentions#permissions) are not currently supported with `ServiceDefaults` destinations.
-> **Note:** Regardless of the `protocol` specified in the `ServiceDefaults`, [L7 intentions](/docs/connect/config-entries/service-intentions#permissions) are not currently supported with `ServiceDefaults` destinations.

Create a `ServiceDefaults` custom resource for the external service:

<CodeBlockConfig filename="serviceDefaults.yaml">
<CodeBlockConfig filename="service-defaults.yaml">

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
Expand All @@ -135,14 +142,15 @@ Create a `ServiceDefaults` custom resource for the external service:
Apply the `ServiceDefaults` resource with `kubectl apply`:

```shell-session
$ kubectl apply --filename serviceDefaults.yaml
$ kubectl apply --filename service-defaults.yaml
```

All other terminating gateway operations can use the name of the `ServiceDefaults` in place of a typical Consul service name.
All other terminating gateway operations can use the name of the `ServiceDefaults` component, in this case "example-https", as a Consul service name.

#### Register an external service as a Catalog Node
</Tab>
<Tab heading="Using Consul catalog">

-> **Note:** Normal Consul services are registered with the Consul client on the node that
Normally, Consul services are registered with the Consul client on the node that
they're running on. Since this is an external service, there is no Consul node
to register it onto. Instead, we will make up a node name and register the
service to that node.
Expand Down Expand Up @@ -191,14 +199,15 @@ If ACLs and TLS are enabled :
$ curl --request PUT --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" --data @external.json --insecure $CONSUL_HTTP_ADDR/v1/catalog/register
true
```
</Tab>
</Tabs>

### Update terminating gateway ACL role if ACLs are enabled

If ACLs are enabled, update the terminating gateway acl role to have `service: write` permissions on all of the services
being represented by the gateway:
being represented by the gateway.

- Create a new policy that includes these permissions
- Update the existing role to include the new policy
Create a new policy that includes the write permission for the service you created.

<CodeBlockConfig filename="write-policy.hcl">

Expand All @@ -222,15 +231,15 @@ service "example-https" {
}
```

Now fetch the ID of the terminating gateway token
Fetch the ID of the terminating gateway token.

```shell-session
consul acl role list | grep -B 6 -- "- RELEASE_NAME-terminating-gateway-policy" | grep ID
ID: <role id>
```

Update the terminating gateway acl token with the new policy
Update the terminating gateway ACL token with the new policy.

```shell-session
$ consul acl role update -id <role id> -policy-name example-https-write-policy
Expand Down Expand Up @@ -269,8 +278,6 @@ Configure the [`caFile`](https://www.consul.io/docs/connect/config-entries/termi
- Consul Helm chart 0.43 or older
- An Envoy image with an alpine base image

For `ServiceDefaults` destinations, refer to [Register an external service as a destination](#register-an-external-service-as-a-destination).

Apply the `TerminatingGateway` resource with `kubectl apply`:

```shell-session
Expand Down Expand Up @@ -306,7 +313,7 @@ $ kubectl apply --filename service-intentions.yaml

### Define the external services as upstreams for services in the mesh

Finally define and deploy the external services as upstreams for the internal mesh services that wish to talk to them.
As a final step, you may define and deploy the external services as upstreams for the internal mesh services that wish to talk to them.
An example deployment is provided which will serve as a static client for the terminating gateway service.

<CodeBlockConfig filename="static-client.yaml">
Expand Down Expand Up @@ -355,33 +362,35 @@ spec:

</CodeBlockConfig>

Run the service via `kubectl apply`:
Deploy the service with `kubectl apply`.

```shell-session
$ kubectl apply --filename static-client.yaml
```

Wait for the service to be ready:
Wait for the service to be ready.

```shell-session
$ kubectl rollout status deploy static-client --watch
deployment "static-client" successfully rolled out
```

You can verify connectivity of the static-client and terminating gateway via a curl command:
You can verify connectivity of the static-client and terminating gateway via a curl command.

<CodeBlockConfig heading="External services registered with the Consul catalog">
<Tabs>
<Tab heading="Registered with `ServiceDefaults` destinations">

```shell-session
$ kubectl exec deploy/static-client -- curl -vvvs --header "Host: example-https.com" http://localhost:1234/
$ kubectl exec deploy/static-client -- curl -vvvs https://example.com/
```

</CodeBlockConfig>

<CodeBlockConfig heading="External services registered with `ServiceDefaults` destinations">
</Tab>
<Tab heading="Registered with the Consul catalog">

```shell-session
$ kubectl exec deploy/static-client -- curl -vvvs https://example.com/
$ kubectl exec deploy/static-client -- curl -vvvs --header "Host: example-https.com" http://localhost:1234/
```

</CodeBlockConfig>
</Tab>
</Tabs>

0 comments on commit e64a285

Please sign in to comment.