2018-10-08 06:30:07 +00:00
|
|
|
|
---
|
2020-04-07 18:55:19 +00:00
|
|
|
|
layout: docs
|
2022-04-05 14:46:14 +00:00
|
|
|
|
page_title: Consul Service Mesh on Kubernetes
|
2020-04-07 18:55:19 +00:00
|
|
|
|
description: >-
|
2022-04-05 14:46:14 +00:00
|
|
|
|
Consul Service Mesh is a feature built into to Consul that enables automatic
|
2020-04-07 18:55:19 +00:00
|
|
|
|
service-to-service authorization and connection encryption across your Consul
|
2022-04-05 14:46:14 +00:00
|
|
|
|
services. Consul Service Mesh can be used with Kubernetes to secure pod communication with
|
2020-04-07 18:55:19 +00:00
|
|
|
|
other services.
|
2018-10-08 06:30:07 +00:00
|
|
|
|
---
|
|
|
|
|
|
2022-04-05 14:46:14 +00:00
|
|
|
|
# Consul Service Mesh on Kubernetes
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
2022-04-05 14:46:14 +00:00
|
|
|
|
[Consul Service Mesh](/docs/connect) is a feature built into to Consul that enables
|
2018-10-08 06:30:07 +00:00
|
|
|
|
automatic service-to-service authorization and connection encryption across
|
2022-04-05 14:46:14 +00:00
|
|
|
|
your Consul services. Consul Service Mesh can be used with Kubernetes to secure pod
|
|
|
|
|
communication with other pods and external Kubernetes services. Consul Connect is used interchangeably with the name
|
|
|
|
|
Consul Service Mesh and is what will be used to refer to for Service Mesh functionality within Consul.
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
2018-10-09 16:30:37 +00:00
|
|
|
|
The Connect sidecar running Envoy can be automatically injected into pods in
|
|
|
|
|
your cluster, making configuration for Kubernetes automatic.
|
2018-10-08 06:30:07 +00:00
|
|
|
|
This functionality is provided by the
|
|
|
|
|
[consul-k8s project](https://github.com/hashicorp/consul-k8s) and can be
|
|
|
|
|
automatically installed and configured using the
|
2022-04-05 14:46:14 +00:00
|
|
|
|
[Consul Helm chart](/docs/k8s/installation/install#helm-chart-installation).
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
|
|
When the
|
2020-08-18 22:22:29 +00:00
|
|
|
|
[Connect injector is installed](/docs/k8s/connect#installation-and-configuration),
|
2020-05-20 10:40:24 +00:00
|
|
|
|
the Connect sidecar can be automatically added to all pods. This sidecar can both
|
2018-10-08 06:30:07 +00:00
|
|
|
|
accept and establish connections using Connect, enabling the pod to communicate
|
|
|
|
|
to clients and dependencies exclusively over authorized and encrypted
|
|
|
|
|
connections.
|
|
|
|
|
|
2021-04-16 19:49:02 +00:00
|
|
|
|
-> **Note:** The examples in this section are valid and use
|
2018-10-08 06:30:07 +00:00
|
|
|
|
publicly available images. If you've installed the Connect injector, feel free
|
2021-04-16 19:49:02 +00:00
|
|
|
|
to run the examples in this section to try Connect with Kubernetes.
|
2019-01-16 22:03:40 +00:00
|
|
|
|
Please note the documentation below this section on how to properly install
|
2018-10-09 16:30:37 +00:00
|
|
|
|
and configure the Connect injector.
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
|
|
|
|
### Accepting Inbound Connections
|
|
|
|
|
|
2021-04-16 19:49:02 +00:00
|
|
|
|
An example Deployment is shown below with Connect enabled to accept inbound
|
|
|
|
|
connections. Notice that the Deployment would still be fully functional without
|
|
|
|
|
Connect. Minimal to zero modifications are required to enable Connect in Kubernetes.
|
|
|
|
|
Notice also that even though we're using a Deployment here, the same configuration
|
|
|
|
|
would work on a Pod, a StatefulSet, or a DaemonSet.
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
2021-04-16 19:49:02 +00:00
|
|
|
|
This Deployment specification starts a server that responds to any
|
2018-10-08 06:30:07 +00:00
|
|
|
|
HTTP request with the static text "hello world".
|
|
|
|
|
|
2021-06-22 22:04:50 +00:00
|
|
|
|
-> **Note:** As of consul-k8s `v0.26.0` and Consul Helm `v0.32.0`, having a Kubernetes
|
2021-04-16 19:49:02 +00:00
|
|
|
|
service is **required** to run services on the Consul Service Mesh.
|
|
|
|
|
|
2018-10-08 06:30:07 +00:00
|
|
|
|
```yaml
|
|
|
|
|
apiVersion: v1
|
2021-04-16 19:49:02 +00:00
|
|
|
|
kind: Service
|
2019-11-29 17:17:56 +00:00
|
|
|
|
metadata:
|
2021-06-22 23:34:20 +00:00
|
|
|
|
# This name will be the service name in Consul.
|
2019-11-29 17:17:56 +00:00
|
|
|
|
name: static-server
|
2021-04-16 19:49:02 +00:00
|
|
|
|
spec:
|
|
|
|
|
selector:
|
|
|
|
|
app: static-server
|
|
|
|
|
ports:
|
|
|
|
|
- protocol: TCP
|
|
|
|
|
port: 80
|
|
|
|
|
targetPort: 8080
|
2019-11-29 17:17:56 +00:00
|
|
|
|
---
|
|
|
|
|
apiVersion: v1
|
2021-04-16 19:49:02 +00:00
|
|
|
|
kind: ServiceAccount
|
|
|
|
|
metadata:
|
|
|
|
|
name: static-server
|
|
|
|
|
---
|
|
|
|
|
apiVersion: apps/v1
|
|
|
|
|
kind: Deployment
|
2018-10-08 06:30:07 +00:00
|
|
|
|
metadata:
|
2018-10-08 15:24:25 +00:00
|
|
|
|
name: static-server
|
2018-10-08 06:30:07 +00:00
|
|
|
|
spec:
|
2021-04-16 19:49:02 +00:00
|
|
|
|
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
|
2021-06-22 23:34:20 +00:00
|
|
|
|
# If ACLs are enabled, the serviceAccountName must match the Consul service name.
|
2021-04-16 19:49:02 +00:00
|
|
|
|
serviceAccountName: static-server
|
2018-10-08 06:30:07 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The only change for Connect is the addition of the
|
|
|
|
|
`consul.hashicorp.com/connect-inject` annotation. This enables injection
|
2021-04-16 19:49:02 +00:00
|
|
|
|
for the Pod in this Deployment. The injector can also be
|
2020-08-18 22:22:29 +00:00
|
|
|
|
[configured](/docs/k8s/connect#installation-and-configuration)
|
2018-10-08 06:30:07 +00:00
|
|
|
|
to automatically inject unless explicitly disabled, but the default
|
|
|
|
|
installation requires opt-in using the annotation shown above.
|
|
|
|
|
|
2021-04-16 19:49:02 +00:00
|
|
|
|
~> **A common mistake** is to set the annotation on the Deployment or
|
|
|
|
|
other resource. Ensure that the injector annotations are specified on
|
|
|
|
|
the _pod specification template_ as shown above.
|
|
|
|
|
|
|
|
|
|
This will start a sidecar proxy that listens on port `20000` registered
|
2018-10-08 06:30:07 +00:00
|
|
|
|
with Consul and proxies valid inbound connections to port 8080 in the pod.
|
2018-10-09 16:30:37 +00:00
|
|
|
|
To establish a connection to the pod using Connect, a client must use another Connect
|
2018-10-08 06:30:07 +00:00
|
|
|
|
proxy. The client Connect proxy will use Consul service discovery to find
|
|
|
|
|
all available upstream proxies and their public ports.
|
|
|
|
|
|
2021-06-22 23:34:20 +00:00
|
|
|
|
In the example above, the server is listening on `:8080`.
|
|
|
|
|
By default, the Consul Service Mesh runs in [transparent proxy](/docs/connect/transparent-proxy) mode.
|
|
|
|
|
This means that even though the server binds to all interfaces,
|
|
|
|
|
the inbound and outbound connections will automatically go through to the sidecar proxy.
|
|
|
|
|
It also allows you to use Kubernetes DNS like you normally would without the
|
|
|
|
|
Consul Service Mesh.
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
2021-06-22 22:25:58 +00:00
|
|
|
|
-> **Note:** As of consul `v1.10.0`, consul-k8s `v0.26.0` and Consul Helm `v0.32.0`,
|
2021-04-16 19:49:02 +00:00
|
|
|
|
all Consul Service Mesh services will run with transparent proxy enabled by default. Running with transparent
|
|
|
|
|
proxy will enforce all inbound and outbound traffic to go through the Envoy proxy.
|
|
|
|
|
|
|
|
|
|
The service name registered in Consul will be set to the name of the Kubernetes service
|
|
|
|
|
associated with the Pod. This can be customized with the `consul.hashicorp.com/connect-service`
|
2019-10-24 23:51:51 +00:00
|
|
|
|
annotation. If using ACLs, this name must be the same as the Pod's `ServiceAccount` name.
|
|
|
|
|
|
2018-10-08 06:30:07 +00:00
|
|
|
|
### Connecting to Connect-Enabled Services
|
|
|
|
|
|
2021-04-16 19:49:02 +00:00
|
|
|
|
The example Deployment specification below configures a Deployment that is capable
|
2018-10-08 15:24:25 +00:00
|
|
|
|
of establishing connections to our previous example "static-server" service. The
|
|
|
|
|
connection to this static text service happens over an authorized and encrypted
|
2018-10-08 06:30:07 +00:00
|
|
|
|
connection via Connect.
|
|
|
|
|
|
2021-06-22 23:34:20 +00:00
|
|
|
|
-> **Note:** As of consul-k8s `v0.26.0` and Consul Helm `v0.32.0`, having a Kubernetes
|
2021-04-16 19:49:02 +00:00
|
|
|
|
Service is **required** to run services on the Consul Service Mesh.
|
|
|
|
|
|
2018-10-08 06:30:07 +00:00
|
|
|
|
```yaml
|
|
|
|
|
apiVersion: v1
|
2021-04-16 19:49:02 +00:00
|
|
|
|
kind: Service
|
2019-11-29 17:17:56 +00:00
|
|
|
|
metadata:
|
2021-06-22 23:34:20 +00:00
|
|
|
|
# This name will be the service name in Consul.
|
2019-11-29 17:17:56 +00:00
|
|
|
|
name: static-client
|
2021-04-16 19:49:02 +00:00
|
|
|
|
spec:
|
|
|
|
|
selector:
|
|
|
|
|
app: static-client
|
|
|
|
|
ports:
|
|
|
|
|
- port: 80
|
2019-11-29 17:17:56 +00:00
|
|
|
|
---
|
|
|
|
|
apiVersion: v1
|
2021-04-16 19:49:02 +00:00
|
|
|
|
kind: ServiceAccount
|
|
|
|
|
metadata:
|
|
|
|
|
name: static-client
|
|
|
|
|
---
|
|
|
|
|
apiVersion: apps/v1
|
|
|
|
|
kind: Deployment
|
2018-10-08 06:30:07 +00:00
|
|
|
|
metadata:
|
2018-10-08 15:24:25 +00:00
|
|
|
|
name: static-client
|
2018-10-08 06:30:07 +00:00
|
|
|
|
spec:
|
2021-04-16 19:49:02 +00:00
|
|
|
|
replicas: 1
|
|
|
|
|
selector:
|
|
|
|
|
matchLabels:
|
|
|
|
|
app: static-client
|
|
|
|
|
template:
|
|
|
|
|
metadata:
|
|
|
|
|
name: static-client
|
|
|
|
|
labels:
|
|
|
|
|
app: static-client
|
|
|
|
|
annotations:
|
|
|
|
|
'consul.hashicorp.com/connect-inject': 'true'
|
|
|
|
|
spec:
|
|
|
|
|
containers:
|
|
|
|
|
- name: static-client
|
2021-06-29 20:23:36 +00:00
|
|
|
|
image: curlimages/curl:latest
|
2021-04-16 19:49:02 +00:00
|
|
|
|
# Just spin & wait forever, we'll use `kubectl exec` to demo
|
|
|
|
|
command: ['/bin/sh', '-c', '--']
|
|
|
|
|
args: ['while true; do sleep 30; done;']
|
2021-06-22 23:34:20 +00:00
|
|
|
|
# If ACLs are enabled, the serviceAccountName must match the Consul service name.
|
2021-04-16 19:49:02 +00:00
|
|
|
|
serviceAccountName: static-client
|
2018-10-08 06:30:07 +00:00
|
|
|
|
```
|
|
|
|
|
|
2021-06-22 23:34:20 +00:00
|
|
|
|
By default when ACLs are enabled or when ACLs default policy is `allow`,
|
|
|
|
|
Consul will automatically configure proxies with all upstreams from the same datacenter.
|
|
|
|
|
When ACLs are enabled with default `deny` policy,
|
|
|
|
|
you must supply an [intention](/docs/connect/intentions) to tell Consul which upstream you need to talk to.
|
2018-10-08 16:55:55 +00:00
|
|
|
|
|
2021-06-22 23:34:20 +00:00
|
|
|
|
When upstreams are specified explicitly with the
|
2022-04-04 21:35:07 +00:00
|
|
|
|
[`consul.hashicorp.com/connect-service-upstreams` annotation](/docs/k8s/annotations-and-labels#consul-hashicorp-com-connect-service-upstreams),
|
2021-06-22 23:34:20 +00:00
|
|
|
|
the injector will also set environment variables `<NAME>_CONNECT_SERVICE_HOST`
|
2021-04-16 19:49:02 +00:00
|
|
|
|
and `<NAME>_CONNECT_SERVICE_PORT` in every container in the Pod for every defined
|
2018-10-09 16:30:37 +00:00
|
|
|
|
upstream. This is analogous to the standard Kubernetes service environment variables, but
|
2018-10-08 16:55:55 +00:00
|
|
|
|
point instead to the correct local proxy port to establish connections via
|
|
|
|
|
Connect.
|
|
|
|
|
|
2021-06-22 23:34:20 +00:00
|
|
|
|
We can verify access to the static text server using `kubectl exec`.
|
|
|
|
|
Because transparent proxy is enabled by default,
|
|
|
|
|
we use Kubernetes DNS to connect to our desired upstream.
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
2020-05-19 18:32:38 +00:00
|
|
|
|
```shell-session
|
2022-01-12 23:05:01 +00:00
|
|
|
|
$ kubectl exec deploy/static-client -- curl --silent http://static-server/
|
2018-10-08 06:30:07 +00:00
|
|
|
|
"hello world"
|
|
|
|
|
```
|
|
|
|
|
|
2020-04-09 23:46:54 +00:00
|
|
|
|
We can control access to the server using [intentions](/docs/connect/intentions).
|
2020-10-14 15:23:05 +00:00
|
|
|
|
If you use the Consul UI or [CLI](/commands/intention/create) to
|
2020-04-09 23:46:54 +00:00
|
|
|
|
create a deny [intention](/docs/connect/intentions) between
|
2018-10-08 15:24:25 +00:00
|
|
|
|
"static-client" and "static-server", connections are immediately rejected
|
2018-10-08 06:30:07 +00:00
|
|
|
|
without updating either of the running pods. You can then remove this
|
|
|
|
|
intention to allow connections again.
|
|
|
|
|
|
2020-05-19 18:32:38 +00:00
|
|
|
|
```shell-session
|
2022-01-12 23:05:01 +00:00
|
|
|
|
$ kubectl exec deploy/static-client -- curl --silent http://static-server/
|
2018-10-08 06:30:07 +00:00
|
|
|
|
command terminated with exit code 52
|
|
|
|
|
```
|
|
|
|
|
|
2022-02-24 00:11:52 +00:00
|
|
|
|
### Kubernetes Pods with Multiple ports
|
|
|
|
|
To configure a pod with multiple ports to be a part of the service mesh and receive and send service mesh traffic, you
|
|
|
|
|
will need to add configuration so that a Consul service can be registered per port. This is because services in Consul
|
|
|
|
|
currently support a single port per service instance.
|
|
|
|
|
|
|
|
|
|
In the following example, suppose we have a pod which exposes 2 ports, `8080` and `9090`, both of which will need to
|
|
|
|
|
receive service mesh traffic.
|
|
|
|
|
|
|
|
|
|
First, decide on the names for the two Consul services that will correspond to those ports. In this example, the user
|
|
|
|
|
chooses the names `web` for `8080` and `web-admin` for `9090`.
|
|
|
|
|
|
|
|
|
|
Create two service accounts for `web` and `web-admin`:
|
|
|
|
|
```yaml
|
|
|
|
|
apiVersion: v1
|
|
|
|
|
kind: ServiceAccount
|
|
|
|
|
metadata:
|
|
|
|
|
name: web
|
|
|
|
|
---
|
|
|
|
|
apiVersion: v1
|
|
|
|
|
kind: ServiceAccount
|
|
|
|
|
metadata:
|
|
|
|
|
name: web-admin
|
|
|
|
|
```
|
|
|
|
|
Create two Service objects for `web` and `web-admin`:
|
|
|
|
|
```yaml
|
|
|
|
|
apiVersion: v1
|
|
|
|
|
kind: Service
|
|
|
|
|
metadata:
|
|
|
|
|
name: web
|
|
|
|
|
spec:
|
|
|
|
|
selector:
|
|
|
|
|
app: web
|
|
|
|
|
ports:
|
|
|
|
|
- protocol: TCP
|
|
|
|
|
port: 80
|
|
|
|
|
targetPort: 8080
|
|
|
|
|
---
|
|
|
|
|
apiVersion: v1
|
|
|
|
|
kind: Service
|
|
|
|
|
metadata:
|
|
|
|
|
name: web-admin
|
|
|
|
|
spec:
|
|
|
|
|
selector:
|
|
|
|
|
app: web
|
|
|
|
|
ports:
|
|
|
|
|
- protocol: TCP
|
|
|
|
|
port: 80
|
|
|
|
|
targetPort: 9090
|
|
|
|
|
```
|
|
|
|
|
`web` will target `containerPort` `8080` and select pods labeled `app: web`. `web-admin` will target `containerPort`
|
|
|
|
|
`9090` and will also select the same pods.
|
|
|
|
|
|
|
|
|
|
Create a Deployment with any chosen name, and use the following annotations:
|
|
|
|
|
```yaml
|
|
|
|
|
consul.hashicorp.com/connect-inject: true
|
2022-02-24 02:24:15 +00:00
|
|
|
|
consul.hashicorp.com/transparent-proxy: false
|
2022-02-24 00:11:52 +00:00
|
|
|
|
consul.hashicorp.com/connect-service: web,web-admin
|
|
|
|
|
consul.hashicorp.com/connect-service-port: 8080,9090
|
|
|
|
|
```
|
|
|
|
|
Note that the order the ports are listed in the same order as the service names, i.e. the first service name `web`
|
|
|
|
|
corresponds to the first port, `8080`, and the second service name `web-admin` corresponds to the second port, `9090`.
|
|
|
|
|
|
|
|
|
|
The service account on the pod spec for the deployment should be set to the first service name `web`:
|
|
|
|
|
```yaml
|
|
|
|
|
serviceAccountName: web
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
For reference, the full deployment example could look something like the following:
|
|
|
|
|
```yaml
|
|
|
|
|
apiVersion: apps/v1
|
|
|
|
|
kind: Deployment
|
|
|
|
|
metadata:
|
|
|
|
|
name: web
|
|
|
|
|
spec:
|
|
|
|
|
replicas: 1
|
|
|
|
|
selector:
|
|
|
|
|
matchLabels:
|
|
|
|
|
app: web
|
|
|
|
|
template:
|
|
|
|
|
metadata:
|
|
|
|
|
name: web
|
|
|
|
|
labels:
|
|
|
|
|
app: web
|
|
|
|
|
annotations:
|
|
|
|
|
'consul.hashicorp.com/connect-inject': 'true'
|
2022-02-24 02:24:15 +00:00
|
|
|
|
'consul.hashicorp.com/transparent-proxy': 'false'
|
2022-02-24 00:11:52 +00:00
|
|
|
|
'consul.hashicorp.com/connect-service': 'web,web-admin'
|
|
|
|
|
'consul.hashicorp.com/connect-service-port': '8080,9090'
|
|
|
|
|
spec:
|
|
|
|
|
containers:
|
|
|
|
|
- name: web
|
|
|
|
|
image: hashicorp/http-echo:latest
|
|
|
|
|
args:
|
|
|
|
|
- -text="hello world"
|
|
|
|
|
- -listen=:8080
|
|
|
|
|
ports:
|
|
|
|
|
- containerPort: 8080
|
|
|
|
|
name: http
|
|
|
|
|
- name: web-admin
|
|
|
|
|
image: hashicorp/http-echo:latest
|
|
|
|
|
args:
|
|
|
|
|
- -text="hello world from 9090"
|
|
|
|
|
- -listen=:9090
|
|
|
|
|
ports:
|
|
|
|
|
- containerPort: 9090
|
|
|
|
|
name: http
|
|
|
|
|
serviceAccountName: web
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
After deploying the `web` application, you can test service mesh connections by deploying the `static-client`
|
|
|
|
|
application with the configuration in the [previous section](#connecting-to-connect-enabled-services) and add the
|
|
|
|
|
following annotation to the pod template on `static-client`:
|
|
|
|
|
```yaml
|
|
|
|
|
consul.hashicorp.com/connect-service-upstreams: "web:1234,web-admin:2234"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
If you exec on to a static-client pod, using a command like:
|
|
|
|
|
```shell-session
|
|
|
|
|
$ kubectl exec -it static-client-5bd667fbd6-kk6xs -- /bin/sh
|
|
|
|
|
```
|
|
|
|
|
you can then run:
|
|
|
|
|
```shell-session
|
|
|
|
|
$ curl localhost:1234
|
|
|
|
|
```
|
|
|
|
|
to see the output `hello world` and run:
|
|
|
|
|
```shell-session
|
|
|
|
|
$ curl localhost:2234
|
|
|
|
|
```
|
|
|
|
|
to see the output `hello world from 9090`.
|
|
|
|
|
|
|
|
|
|
The way this works is that a Consul service instance is being registered per port on the Pod, so there are 2 Consul
|
|
|
|
|
services in this case. An additional Envoy sidecar proxy and `connect-init` init container are also deployed per port in
|
|
|
|
|
the Pod. So the upstream configuration can use the individual service names to reach each port as seen in the example.
|
|
|
|
|
|
|
|
|
|
#### Caveats for Multi-port Pods
|
|
|
|
|
* Transparent proxy is not supported for multi-port Pods.
|
|
|
|
|
* Metrics and metrics merging is not supported for multi-port Pods.
|
|
|
|
|
* Upstreams will only be set on the first service's Envoy sidecar proxy for the pod.
|
|
|
|
|
* This means that ServiceIntentions from a multi-port pod to elsewhere, will need to use the first service's name,
|
|
|
|
|
`web` in the example above to accept connections from either `web` or `web-admin`. ServiceIntentions from elsewhere
|
|
|
|
|
to a multi-port pod can use the individual service names within the multi-port Pod.
|
|
|
|
|
* Health checking is done on a per-Pod basis, so if any Kubernetes health checks (like readiness, liveness, etc) are
|
|
|
|
|
failing for any container on the Pod, the entire Pod is marked unhealthy, and any Consul service referencing that Pod
|
|
|
|
|
will also be marked as unhealthy. So, if `web` has a failing health check, `web-admin` would also be marked as
|
|
|
|
|
unhealthy for service mesh traffic.
|
|
|
|
|
|
2018-10-08 06:30:07 +00:00
|
|
|
|
## Installation and Configuration
|
|
|
|
|
|
|
|
|
|
The Connect sidecar proxy is injected via a
|
|
|
|
|
[mutating admission webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
|
|
|
|
provided by the
|
|
|
|
|
[consul-k8s project](https://github.com/hashicorp/consul-k8s).
|
|
|
|
|
This enables the automatic pod mutation shown in the usage section above.
|
|
|
|
|
Installation of the mutating admission webhook is automated using the
|
2020-09-14 17:37:35 +00:00
|
|
|
|
[Helm chart](/docs/k8s/installation/install).
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
|
|
|
|
To install the Connect injector, enable the Connect injection feature using
|
2020-05-11 21:15:59 +00:00
|
|
|
|
[Helm values](/docs/k8s/helm#configuration-values) and
|
2018-10-08 06:30:07 +00:00
|
|
|
|
upgrade the installation using `helm upgrade` for existing installs or
|
2021-02-17 19:01:52 +00:00
|
|
|
|
`helm install` for a fresh install.
|
2018-10-08 06:30:07 +00:00
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
connectInject:
|
|
|
|
|
enabled: true
|
|
|
|
|
|
2021-02-17 19:01:52 +00:00
|
|
|
|
controller:
|
2018-10-08 06:30:07 +00:00
|
|
|
|
enabled: true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This will configure the injector to inject when the
|
2020-02-04 19:05:25 +00:00
|
|
|
|
[injection annotation](#consul-hashicorp-com-connect-inject)
|
|
|
|
|
is set to `true`. Other values in the Helm chart can be used to limit the namespaces
|
2018-10-08 06:30:07 +00:00
|
|
|
|
the injector runs in, enable injection by default, and more.
|
|
|
|
|
|
2022-03-03 16:11:28 +00:00
|
|
|
|
### Verifying the Installation
|
|
|
|
|
|
|
|
|
|
To verify the installation, run the
|
|
|
|
|
["Accepting Inbound Connections"](/docs/k8s/connect#accepting-inbound-connections)
|
|
|
|
|
example from the "Usage" section above. After running this example, run
|
|
|
|
|
`kubectl get pod static-server --output yaml`. In the raw YAML output, you should
|
|
|
|
|
see injected Connect containers and an annotation
|
|
|
|
|
`consul.hashicorp.com/connect-inject-status` set to `injected`. This
|
|
|
|
|
confirms that injection is working properly.
|
|
|
|
|
|
|
|
|
|
If you do not see this, then use `kubectl logs` against the injector pod
|
|
|
|
|
and note any errors.
|
|
|
|
|
|
2020-02-04 19:05:25 +00:00
|
|
|
|
### Controlling Injection Via Annotation
|
|
|
|
|
|
|
|
|
|
By default, the injector will inject only when the
|
|
|
|
|
[injection annotation](#consul-hashicorp-com-connect-inject)
|
|
|
|
|
on the pod (not the deployment) is set to `true`:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
annotations:
|
2020-04-06 20:27:35 +00:00
|
|
|
|
'consul.hashicorp.com/connect-inject': 'true'
|
2020-02-04 19:05:25 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Injection Defaults
|
|
|
|
|
|
|
|
|
|
If you wish for the injector to always inject, you can set the default to `true`
|
|
|
|
|
in the Helm chart:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
connectInject:
|
|
|
|
|
enabled: true
|
|
|
|
|
default: true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
You can then exclude specific pods via annotation:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
annotations:
|
2020-04-06 20:27:35 +00:00
|
|
|
|
'consul.hashicorp.com/connect-inject': 'false'
|
2020-02-04 19:05:25 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Controlling Injection Via Namespace
|
|
|
|
|
|
|
|
|
|
You can control which Kubernetes namespaces are allowed to be injected via
|
|
|
|
|
the `k8sAllowNamespaces` and `k8sDenyNamespaces` keys:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
connectInject:
|
|
|
|
|
enabled: true
|
2020-04-06 20:27:35 +00:00
|
|
|
|
k8sAllowNamespaces: ['*']
|
2020-02-04 19:05:25 +00:00
|
|
|
|
k8sDenyNamespaces: []
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
In the default configuration (shown above), services from all namespaces are allowed
|
|
|
|
|
to be injected. Whether or not they're injected depends on the value of `connectInject.default`
|
|
|
|
|
and the `consul.hashicorp.com/connect-inject` annotation.
|
|
|
|
|
|
|
|
|
|
If you wish to only enable injection in specific namespaces, you can list only those
|
|
|
|
|
namespaces in the `k8sAllowNamespaces` key. In the configuration below
|
|
|
|
|
only the `my-ns-1` and `my-ns-2` namespaces will be enabled for injection.
|
|
|
|
|
All other namespaces will be ignored, even if the connect inject [annotation](#consul-hashicorp-com-connect-inject)
|
|
|
|
|
is set.
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
connectInject:
|
|
|
|
|
enabled: true
|
2020-04-06 20:27:35 +00:00
|
|
|
|
k8sAllowNamespaces: ['my-ns-1', 'my-ns-2']
|
2020-02-04 19:05:25 +00:00
|
|
|
|
k8sDenyNamespaces: []
|
|
|
|
|
```
|
|
|
|
|
|
2020-04-06 20:27:35 +00:00
|
|
|
|
If you wish to enable injection in every namespace _except_ specific namespaces, you can
|
2020-02-04 19:05:25 +00:00
|
|
|
|
use `*` in the allow list to allow all namespaces and then specify the namespaces to exclude in the deny list:
|
|
|
|
|
|
|
|
|
|
```yaml
|
2020-08-13 21:29:59 +00:00
|
|
|
|
connectInject:
|
2020-02-04 19:05:25 +00:00
|
|
|
|
enabled: true
|
2020-04-06 20:27:35 +00:00
|
|
|
|
k8sAllowNamespaces: ['*']
|
2020-08-13 21:29:59 +00:00
|
|
|
|
k8sDenyNamespaces: ['no-inject-ns-1', 'no-inject-ns-2']
|
2020-02-04 19:05:25 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
-> **NOTE:** The deny list takes precedence over the allow list. If a namespace
|
2020-04-06 20:27:35 +00:00
|
|
|
|
is listed in both lists, it will **not** be synced.
|
2020-02-04 19:05:25 +00:00
|
|
|
|
|
|
|
|
|
~> **NOTE:** The `kube-system` and `kube-public` namespaces will never be injected.
|
|
|
|
|
|
|
|
|
|
### Consul Enterprise Namespaces
|
|
|
|
|
|
|
|
|
|
Consul Enterprise 1.7+ supports Consul namespaces. When Kubernetes pods are registered
|
|
|
|
|
into Consul, you can control which Consul namespace they are registered into.
|
|
|
|
|
|
|
|
|
|
There are three options available:
|
|
|
|
|
|
2020-04-06 20:27:35 +00:00
|
|
|
|
1. **Single Destination Namespace** – Register all Kubernetes pods, regardless of namespace,
|
|
|
|
|
into the same Consul namespace.
|
2020-02-04 19:05:25 +00:00
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
This can be configured with:
|
2020-02-04 19:05:25 +00:00
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
```yaml
|
|
|
|
|
global:
|
|
|
|
|
enableConsulNamespaces: true
|
2020-04-06 20:27:35 +00:00
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
connectInject:
|
|
|
|
|
enabled: true
|
|
|
|
|
consulNamespaces:
|
|
|
|
|
consulDestinationNamespace: 'my-consul-ns'
|
|
|
|
|
```
|
2020-02-04 19:05:25 +00:00
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
-> **NOTE:** If the destination namespace does not exist we will create it.
|
2020-02-04 19:05:25 +00:00
|
|
|
|
|
2020-04-06 20:27:35 +00:00
|
|
|
|
1. **Mirror Namespaces** - Register each Kubernetes pod into a Consul namespace with the same name as its Kubernetes namespace.
|
|
|
|
|
For example, pod `foo` in Kubernetes namespace `ns-1` will be synced to the Consul namespace `ns-1`.
|
|
|
|
|
If a mirrored namespace does not exist in Consul, it will be created.
|
2020-04-07 18:55:19 +00:00
|
|
|
|
|
|
|
|
|
This can be configured with:
|
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
```yaml
|
2020-02-04 19:05:25 +00:00
|
|
|
|
global:
|
2020-04-09 00:09:01 +00:00
|
|
|
|
enableConsulNamespaces: true
|
2020-04-07 18:55:19 +00:00
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
connectInject:
|
|
|
|
|
enabled: true
|
|
|
|
|
consulNamespaces:
|
|
|
|
|
mirroringK8S: true
|
|
|
|
|
```
|
2020-02-04 19:05:25 +00:00
|
|
|
|
|
2020-04-06 20:27:35 +00:00
|
|
|
|
1. **Mirror Namespaces With Prefix** - Register each Kubernetes pod into a Consul namespace with the same name as its Kubernetes
|
|
|
|
|
namespace **with a prefix**.
|
|
|
|
|
For example, given a prefix `k8s-`, pod `foo` in Kubernetes namespace `ns-1` will be synced to the Consul namespace `k8s-ns-1`.
|
2020-02-04 19:05:25 +00:00
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
This can be configured with:
|
2020-04-06 20:27:35 +00:00
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
```yaml
|
|
|
|
|
global:
|
|
|
|
|
enableConsulNamespaces: true
|
2020-04-06 20:27:35 +00:00
|
|
|
|
|
2020-04-09 00:09:01 +00:00
|
|
|
|
connectInject:
|
|
|
|
|
enabled: true
|
|
|
|
|
consulNamespaces:
|
|
|
|
|
mirroringK8S: true
|
|
|
|
|
mirroringK8SPrefix: 'k8s-'
|
|
|
|
|
```
|
2020-02-04 19:05:25 +00:00
|
|
|
|
|
|
|
|
|
### Consul Enterprise Namespace Upstreams
|
2020-04-06 20:27:35 +00:00
|
|
|
|
|
2021-06-22 23:34:20 +00:00
|
|
|
|
When [transparent proxy](/docs/connect/transparent-proxy) is enabled and ACLs are disabled,
|
|
|
|
|
the upstreams will be configured automatically across Consul namespaces.
|
|
|
|
|
When ACLs are enabled, you must configure it by specifying an [intention](/docs/connect/intentions),
|
|
|
|
|
allowing services across Consul namespaces to talk to each other.
|
|
|
|
|
|
|
|
|
|
If you wish to specify an upstream explicitly via the `consul.hashicorp.com/connect-service-upstreams` annotation,
|
2020-02-04 19:05:25 +00:00
|
|
|
|
use the format `[service-name].[namespace]:[port]:[optional datacenter]`:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
annotations:
|
2020-04-06 20:27:35 +00:00
|
|
|
|
'consul.hashicorp.com/connect-inject': 'true'
|
|
|
|
|
'consul.hashicorp.com/connect-service-upstreams': '[service-name].[namespace]:[port]:[optional datacenter]'
|
2020-02-04 19:05:25 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
See [consul.hashicorp.com/connect-service-upstreams](#consul-hashicorp-com-connect-service-upstreams) for more details.
|
|
|
|
|
|
2021-06-22 23:34:20 +00:00
|
|
|
|
-> **Note:** When you specify upstreams via an upstreams annotation, you will need to use
|
|
|
|
|
`localhost:<port>` with the port from the upstreams annotation instead of KubeDNS to connect to your upstream
|
|
|
|
|
application.
|