diff --git a/website/data/docs-navigation.js b/website/data/docs-navigation.js index 954af09cbd..19411b28fa 100644 --- a/website/data/docs-navigation.js +++ b/website/data/docs-navigation.js @@ -234,10 +234,7 @@ export default [ { category: 'connect', name: 'Connect Service Mesh', - content: [ - 'overview', - 'ingress-gateways', - ], + content: ['overview', 'ingress-gateways', 'terminating-gateways'], }, 'service-sync', 'dns', diff --git a/website/pages/docs/k8s/connect/terminating-gateways.mdx b/website/pages/docs/k8s/connect/terminating-gateways.mdx new file mode 100644 index 0000000000..07d2902069 --- /dev/null +++ b/website/pages/docs/k8s/connect/terminating-gateways.mdx @@ -0,0 +1,211 @@ +--- +layout: docs +page_title: Terminating Gateways - Kubernetes +sidebar_title: Terminating Gateways +description: Configuring Terminating Gateways on Kubernetes +--- + +# Terminating Gateways on Kubernetes + +-> 1.8.0+: This feature is available in Consul versions 1.8.0 and higher + +-> 0.16.0+: This feature is available in consul-k8s versions 0.16.0 and higher + +~> This topic requires familiarity with [Terminating Gateways](/docs/connect/terminating-gateway). + +Terminating gateways are a new feature included in Consul 1.8. The correlating consul-k8s binary version is +[0.16.0](https://github.com/hashicorp/consul-k8s/blob/master/CHANGELOG.md#0160-june-17-2020), and is required to enable +terminating gateways. If you are using the latest official [consul-helm chart](https://github.com/hashicorp/consul-helm), +and have not customized the [imageK8S](/docs/k8s/helm#v-global-imagek8s) configuration for any of +your components, you should be running a compatible version by default. + +Adding a terminating gateway is a multi-step process: + +* Update the helm chart with terminating gateway config options +* Deploying the helm chart +* Accessing 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 +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/overview#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-foward consul-server-0 8500 & +``` +If TLS is enabled use port 8501: +```shell-session +$ kubectl port-foward 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 the configuration entry for the terminating gateway +* Create intentions 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 + +Create a sample external service and register it with Consul. +```json +{ + "Node": "legacy_node", + "Address": "example.com", + "NodeMeta": { + "external-node": "true", + "external-probe": "true" + }, + "Service": { + "ID": "example-https", + "Service": "example-https", + "Port": 443 + } +} +``` + +Register the external service with Consul: +```shell-session +$ curl --request PUT --data @external.json -k $CONSUL_HTTP_ADDR/v1/catalog/register +``` +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 +``` + +### 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 +``` +Now fetch the id of the terminating gateway token +```shell-session +$ consul acl token list | grep terminating-gateway-terminating-gateway-token +``` +Update the terminating gateway acl token with the new policy +```shell-session +$ consul acl token update -id -policy-name example-https-write-policy -merge-policies -merge-roles -merge-service-identities +``` + +### Create the configuration entry for the terminating gateway +Once the tokens have been updated, next write the Consul [config](/docs/agent/config-entries/terminating-gateway) +entry for the terminating gateway: +```hcl +Kind = "terminating-gateway" +Name = "terminating-gateway" +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. + +Submit the terminating gateway entry with the Consul CLI using this command. +```shell-session +$ consul config write terminating-gateway.hcl +``` + +If using ACLs and TLS, create intentions to allow access from services in the mesh to the external service +```shell-session +$ consul intention create -allow static-client example-https +``` + +### 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: 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 +``` + +You can verify connectivity of the static-client and terminating gateway via a curl command: +```shell-session +$ kubectl exec static-client-7cc6df495-qdtkp -- curl -vvvs -H "Host: example-https.com" http://localhost:1234/ +```