mirror of
https://github.com/status-im/consul.git
synced 2025-01-09 13:26:07 +00:00
ac384e2a1f
Previously if you were to follow these docs and register two external services, you would set the Address field on the node. The second registered service would change the address of the node for the first service. Now the docs explain the address key and how to register more than one external service.
297 lines
8.5 KiB
Plaintext
297 lines
8.5 KiB
Plaintext
---
|
|
layout: docs
|
|
page_title: Terminating Gateways - Kubernetes
|
|
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/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
|
|
|
|
Minimum required Helm options:
|
|
|
|
```yaml
|
|
global:
|
|
name: consul
|
|
connectInject:
|
|
enabled: true
|
|
controller:
|
|
enabled: true
|
|
terminatingGateways:
|
|
enabled: true
|
|
```
|
|
|
|
## 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.
|
|
|
|
## 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.
|
|
|
|
```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 &
|
|
```
|
|
|
|
-> Be sure the latest consul binary is installed locally on your host.
|
|
[https://releases.hashicorp.com/consul/](https://releases.hashicorp.com/consul/)
|
|
|
|
```shell-session
|
|
$ export CONSUL_HTTP_ADDR=http://localhost:8500
|
|
```
|
|
|
|
If TLS is enabled set:
|
|
|
|
```shell-session
|
|
$ export CONSUL_HTTP_ADDR=https://localhost:8501
|
|
$ export CONSUL_HTTP_SSL_VERIFY=false
|
|
```
|
|
|
|
If ACLs are enabled also set:
|
|
|
|
```shell-session
|
|
$ export CONSUL_HTTP_TOKEN=$(kubectl get secret consul-bootstrap-acl-token -o jsonpath={.data.token} | base64 -D)
|
|
```
|
|
|
|
## Register external services with Consul
|
|
|
|
Registering the external services with Consul is a multi-step process:
|
|
|
|
- Register external services with Consul
|
|
- Update the terminating gateway ACL token if ACLs are enabled
|
|
- Create a [`TerminatingGateway`](/docs/connect/config-entries/terminating-gateway) resource to configure the terminating gateway
|
|
- Create a [`ServiceIntentions`](/docs/connect/config-entries/service-intentions) resource to allow access from services in the mesh to external service
|
|
- Define upstream annotations for any services that need to talk to the external services
|
|
|
|
### Register external services with Consul
|
|
|
|
-> **Note:** Normal 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.
|
|
|
|
Create a sample external service and register it with Consul.
|
|
|
|
```json
|
|
{
|
|
"Node": "example_com",
|
|
"Address": "example.com",
|
|
"NodeMeta": {
|
|
"external-node": "true",
|
|
"external-probe": "true"
|
|
},
|
|
"Service": {
|
|
"Address": "example.com",
|
|
"ID": "example-https",
|
|
"Service": "example-https",
|
|
"Port": 443
|
|
}
|
|
}
|
|
```
|
|
|
|
- `"Node": "example_com"` is our made up node name.
|
|
- `"Address": "example.com"` is the address of our node. Services registered to that node will use this address if
|
|
their own address isn't specified. If you're registering multiple external services, ensure you
|
|
use different node names with different addresses or set the `Service.Address` key.
|
|
- `"Service": { "Address": "example.com" ... }` is the address of our service. In this example this doesn't need to be set
|
|
since the address of the node is the same, but if there were two services registered to that same node
|
|
then this should be set.
|
|
|
|
Register the external service with Consul:
|
|
|
|
```shell-session
|
|
$ curl --request PUT --data @external.json -k $CONSUL_HTTP_ADDR/v1/catalog/register
|
|
true
|
|
```
|
|
|
|
If ACLs and TLS are enabled :
|
|
|
|
```shell-session
|
|
$ curl --request PUT --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" --data @external.json -k $CONSUL_HTTP_ADDR/v1/catalog/register
|
|
true
|
|
```
|
|
|
|
### Update terminating gateway ACL token if ACLs are enabled
|
|
|
|
If ACLs are enabled, update the terminating gateway acl token to have `service: write` permissions on all of the services
|
|
being represented by the gateway:
|
|
|
|
- Create a new policy that includes these permissions
|
|
- Update the existing token to include the new policy
|
|
|
|
~> The CLI command should be run with the `-merge-policies`, `-merge-roles` and `-merge-service-identities` so
|
|
nothing is removed from the terminating gateway token
|
|
|
|
```hcl
|
|
service "example-https" {
|
|
policy = "write"
|
|
}
|
|
```
|
|
|
|
```shell-session
|
|
$ consul acl policy create -name "example-https-write-policy" -rules @write-policy.hcl
|
|
ID: xxxxxxxxxxxxxxx
|
|
Name: example-https-write-policy
|
|
Description:
|
|
Datacenters:
|
|
Rules:
|
|
service "example-https" {
|
|
policy = "write"
|
|
}
|
|
```
|
|
|
|
Now fetch the ID of the terminating gateway token
|
|
|
|
```shell-session
|
|
consul acl token list | grep -B 6 -- "- terminating-gateway-terminating-gateway-token" | grep AccessorID
|
|
|
|
AccessorID: <token id>
|
|
```
|
|
|
|
Update the terminating gateway acl token with the new policy
|
|
|
|
```shell-session
|
|
$ consul acl token update -id <token-id> -policy-name example-https-write-policy -merge-policies -merge-roles -merge-service-identities
|
|
AccessorID: <token id>
|
|
SecretID: <secret id>
|
|
Description: terminating-gateway-terminating-gateway-token Token
|
|
Local: true
|
|
Create Time: 2021-01-08 21:18:47.957450486 +0000 UTC
|
|
Policies:
|
|
63bf1d9b-a87d-8672-ddcb-d25e2d88adb8 - terminating-gateway-terminating-gateway-token
|
|
f63d1ae6-ffe7-44bd-bf7a-704a86939a63 - example-https-write-policy
|
|
```
|
|
|
|
### Create the configuration entry for the terminating gateway
|
|
|
|
Once the tokens have been updated, create the [TerminatingGateway](/docs/connect/config-entries/terminating-gateway)
|
|
resource to configure the terminating gateway:
|
|
|
|
```hcl
|
|
apiVersion: consul.hashicorp.com/v1alpha1
|
|
kind: TerminatingGateway
|
|
metadata:
|
|
name: terminating-gateway
|
|
spec:
|
|
services:
|
|
- name: example-https
|
|
caFile: /etc/ssl/cert.pem
|
|
```
|
|
|
|
~> If TLS is enabled a `caFile` must be provided, it must point to the system trust store of the terminating gateway
|
|
container (`/etc/ssl/cert.pem`).
|
|
|
|
Apply the `TerminatingGateway` resource with `kubectl apply`:
|
|
|
|
```shell-session
|
|
$ kubectl apply -f terminating-gateway.yaml
|
|
```
|
|
|
|
If using ACLs and TLS, create a [`ServiceIntentions`](/docs/connect/config-entries/service-intentions) resource to allow access from services in the mesh to the external service
|
|
|
|
```yaml
|
|
apiVersion: consul.hashicorp.com/v1alpha1
|
|
kind: ServiceIntentions
|
|
metadata:
|
|
name: example-https
|
|
spec:
|
|
destination:
|
|
name: example-https
|
|
sources:
|
|
- name: static-client
|
|
action: allow
|
|
```
|
|
|
|
Apply the `ServiceIntentions` resource with `kubectl apply`:
|
|
|
|
```shell-session
|
|
$ kubectl apply -f 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.
|
|
An example deployment is provided which will serve as a static client for the terminating gateway service.
|
|
|
|
```yaml
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: static-client
|
|
spec:
|
|
selector:
|
|
app: static-client
|
|
ports:
|
|
- port: 80
|
|
---
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: static-client
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: static-client
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: static-client
|
|
template:
|
|
metadata:
|
|
name: static-client
|
|
labels:
|
|
app: static-client
|
|
annotations:
|
|
'consul.hashicorp.com/connect-inject': 'true'
|
|
'consul.hashicorp.com/connect-service-upstreams': 'example-https:1234'
|
|
spec:
|
|
containers:
|
|
# This name will be the service name in Consul.
|
|
- name: static-client
|
|
image: tutum/curl:latest
|
|
command: ['/bin/sh', '-c', '--']
|
|
args: ['while true; do sleep 30; done;']
|
|
# If ACLs are enabled, the serviceAccountName must match the Consul service name.
|
|
serviceAccountName: static-client
|
|
```
|
|
|
|
Run the service via `kubectl apply`:
|
|
|
|
```shell-session
|
|
$ kubectl apply -f static-client.yaml
|
|
```
|
|
|
|
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:
|
|
|
|
```shell-session
|
|
$ kubectl exec deploy/static-client -- curl -vvvs -H "Host: example-https.com" http://localhost:1234/
|
|
```
|