-
Notifications
You must be signed in to change notification settings - Fork 4.6k
docs: Multi-port and catalog changes #19050
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 9 commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
d6ea0cb
Page creation + nav listing
boruszak 84d1107
Overview page
boruszak 319e24b
Updated end-to-end configuration
boruszak 9f0dc4e
Nav error fix
boruszak b0364cb
Edits
boruszak 8f9f7ad
Fixes
boruszak 8aa4d1d
Background/catalog explanation updates
boruszak e5551a3
updates
boruszak 46644f3
Updates
boruszak e1262ff
Typo fix
boruszak cb267a3
Merge branch 'main' into docs/multiport-rc
boruszak 3ee9a0b
Additional method
boruszak 1e01d98
additional fixes
boruszak 627c166
Apply suggestions from code review
boruszak 70d06de
Code review and other fixes
boruszak be31c08
"similar to" fix
boruszak fb0e5af
Apply suggestions from code review
boruszak f65a8e3
Merge branch 'main' into docs/multiport-rc
boruszak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,332 @@ | ||
| --- | ||
| layout: docs | ||
| page_title: Configure multi-port services | ||
| description: Learn how to enable the v2 catalog and configure services to support multiple ports in Consul on Kubernetes. You can configure multiple ports on a single service or multiple services and ports in a single container. | ||
| --- | ||
|
|
||
| # Configure multi-port services | ||
|
|
||
| <Warning> | ||
|
|
||
| Multi-port services are part of a beta release. This documentation supports testing and development scenarios. Do not use multi-port services or the v2 catalog API in secure production environments. | ||
|
|
||
| </Warning> | ||
|
|
||
| This page describes the process for integrating a service that uses multiple ports in a single container when running Consul on Kubernetes deployments. It includes example configurations to demonstrate an end-to-end deployment test of Consul's multi-port features. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| Registering multi-port services with Consul requires Kubernetes. Multi-port services are not supported on VM deployments. | ||
|
|
||
| There are also software version prerequisites: | ||
|
|
||
| - `consul` v1.17.0 | ||
| - `consul-k8s` v1.1.0+ or Consul Helm chart release v1.1.0+ | ||
|
|
||
| Configuring multi-port services for service discovery does not have additional prerequisites. | ||
|
|
||
| Consul’s transparent proxy for service mesh, which enables Kube DNS instead of Consul DNS through permissive mTLS settings, has additional prerequisites. For more information about the steps to configure global settings and enable permissive mTLS mode before registering a service, refer to the [onboard services in transparent mode workflow](/consul/docs/k8s/connect/onboarding-tproxy-mode#workflow). | ||
|
boruszak marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Enable the v2 catalog | ||
|
|
||
| To enable the v2 catalog and its support for multi-port services, set `global.experiments: ["resource-apis"]`. The following example includes this parameter in a Helm chart with minimal required configurations for the Consul installation: | ||
|
boruszak marked this conversation as resolved.
Outdated
|
||
|
|
||
| <CodeBlockConfig name="values.yaml"> | ||
|
|
||
| ```yaml | ||
| global: | ||
| enabled: true | ||
| name: consul | ||
| image: hashicorp/consul:1.17.0-rc1 | ||
|
boruszak marked this conversation as resolved.
|
||
| datacenter: dc1 | ||
| tls: | ||
| enabled: true | ||
| experiments: ["resource-apis"] | ||
| server: | ||
| enabled: true | ||
| replicas: 1 | ||
| connectInject: | ||
| enabled: true | ||
|
boruszak marked this conversation as resolved.
|
||
| ``` | ||
|
|
||
| </CodeBlockConfig> | ||
|
|
||
| Then install Consul to your Kubernetes cluster using either the `consul-k8s` CLI or Helm. | ||
|
|
||
| <Tabs> | ||
|
|
||
| <Tab heading="consul-k8s CLI" group="consul-k8s"> | ||
|
|
||
| ```shell-session | ||
| $ consul-k8s install -config-file=values.yaml | ||
| ``` | ||
|
|
||
| </Tab> | ||
|
|
||
| <Tab heading="Helm" group="helm"> | ||
|
|
||
| ```shell-session | ||
| $ helm install consul hashicorp/consul --create-namespace --namespace consul --values values.yaml | ||
| ``` | ||
|
|
||
| </Tab> | ||
| </Tabs> | ||
|
|
||
| ## Define the multi-port service | ||
|
|
||
| To deploy a multi-port service that uses a single Envoy proxy in a single pod, you must define a Kubernetes ServiceAccount, two Kubernetes Services that expose their target ports, and schedule a single Kubernetes Workload that configures two service containers and the ports they listen on. | ||
|
|
||
| The following example contains two tabs with configurations for two Kubernetes Pods. The first Pod schedules two services, `api` and `api-admin`, deployed in separate containers. This pod has a single Envoy proxy that listens on ports 80 and 90 and then forwards traffic to the appropriate container and port. The second pod schedules a `web` service that functions as a static client you can use to verify that the multi-port service functions correctly. | ||
|
|
||
| <CodeTabs tabs={[ "API services", "Web services" ]}> | ||
|
|
||
| <CodeBlockConfig filename="api.yaml"> | ||
|
|
||
| ```yaml | ||
| apiVersion: v1 | ||
| kind: ServiceAccount | ||
| metadata: | ||
| name: api | ||
|
|
||
| --- | ||
| apiVersion: v1 | ||
| kind: Service | ||
| metadata: | ||
| name: api | ||
| spec: | ||
| selector: | ||
| app: api | ||
| ports: | ||
| - name: api | ||
| port: 80 | ||
| targetPort: api | ||
| --- | ||
| apiVersion: v1 | ||
| kind: Service | ||
| metadata: | ||
| name: api-admin | ||
| spec: | ||
| selector: | ||
| app: api | ||
| ports: | ||
| - name: admin | ||
| port: 90 | ||
| targetPort: admin | ||
| --- | ||
| apiVersion: apps/v1 | ||
| kind: Deployment | ||
| metadata: | ||
| name: api | ||
| spec: | ||
| replicas: 1 | ||
| selector: | ||
| matchLabels: | ||
| app: api | ||
| template: | ||
| metadata: | ||
| name: api | ||
| labels: | ||
| app: api | ||
| annotations: | ||
| "consul.hashicorp.com/mesh-inject": "true" | ||
| 'consul.hashicorp.com/transparent-proxy': 'true' | ||
| spec: | ||
| containers: | ||
| - name: api | ||
| image: docker.mirror.hashicorp.services/hashicorp/http-echo:alpine | ||
| args: | ||
| - -text="hello world" | ||
| - -listen=:8080 | ||
| ports: | ||
| - containerPort: 8080 | ||
| name: api | ||
| - name: api-admin | ||
| image: docker.mirror.hashicorp.services/hashicorp/http-echo:alpine | ||
|
boruszak marked this conversation as resolved.
Outdated
|
||
| args: | ||
| - -text="hello world from 9090 admin" | ||
| - -listen=:9090 | ||
| ports: | ||
| - containerPort: 9090 | ||
| name: admin | ||
| serviceAccountName: api | ||
| ``` | ||
|
|
||
| </CodeBlockConfig> | ||
|
|
||
| <CodeBlockConfig filename="web.yaml"> | ||
|
|
||
| ```yaml | ||
| apiVersion: v1 | ||
| kind: ServiceAccount | ||
| metadata: | ||
| name: web | ||
| --- | ||
| apiVersion: v1 | ||
| kind: Service | ||
| metadata: | ||
| name: web | ||
| spec: | ||
| selector: | ||
| app: web | ||
| ports: | ||
| - port: 80 | ||
| --- | ||
| 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/mesh-inject": "true" | ||
| 'consul.hashicorp.com/transparent-proxy': 'true' | ||
| spec: | ||
| containers: | ||
| - name: static-client | ||
| image: curlimages/curl:latest | ||
| # Just spin & wait forever, we'll use `kubectl exec` to demo | ||
| command: ['/bin/sh', '-c', '--'] | ||
| args: ['while true; do sleep 30; done;'] | ||
| serviceAccountName: web | ||
| ``` | ||
|
|
||
| </CodeBlockConfig> | ||
| </CodeTabs> | ||
|
|
||
| To apply these services to your Kubernetes deployment and register them with Consul, run the following command: | ||
|
|
||
| ```shell-session | ||
| $ kubectl apply -f api.yaml -f web.yaml | ||
| ``` | ||
|
|
||
| ## Configure traffic permissions | ||
|
|
||
| Consul uses traffic permissions to validate communication between services based on L4 identity. In the beta release of the v2 catalog API, traffic permissions allow all services by default. In order to verify that services function correctly on each port, create CRDs that deny traffic to each port. | ||
|
|
||
| The following examples create Consul CRDs that allow traffic to only one port of the multi-port service. Each resource separately denies `web` permission when it is a source of traffic to one of the services. | ||
|
|
||
| <CodeTabs tabs={[ "Deny port 80", "Deny port 90" ]}> | ||
|
|
||
| <CodeBlockConfig filename="deny-80.yaml"> | ||
|
|
||
| ```yaml | ||
| apiVersion: auth.consul.hashicorp.com/v2beta1 | ||
| kind: TrafficPermissions | ||
| metadata: | ||
| name: web-to-api-admin-port-allow | ||
| spec: | ||
| destination: | ||
| identityName: api | ||
| action: deny | ||
| permissions: | ||
| - sources: | ||
| - identityName: web | ||
| destinationRules: | ||
| - portNames: ["api"] | ||
| ``` | ||
|
|
||
| </CodeBlockConfig> | ||
|
|
||
| <CodeBlockConfig filename="deny-90.yaml"> | ||
|
|
||
| ```yaml | ||
| apiVersion: auth.consul.hashicorp.com/v2beta1 | ||
| kind: TrafficPermissions | ||
| metadata: | ||
| name: web-to-api-api-port-allow | ||
| spec: | ||
| destination: | ||
| identityName: api | ||
| action: deny | ||
| permissions: | ||
| - sources: | ||
| - identityName: web | ||
| destinationRules: | ||
| - portNames: ["admin"] | ||
| ``` | ||
|
|
||
| </CodeBlockConfig> | ||
| </CodeTabs> | ||
|
|
||
| ## Validate multi-port connection | ||
|
|
||
| To open a shell to the `web` container, you need the name of the pod it currently runs on. Run the following command to return a list of pods: | ||
|
boruszak marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```shell-session | ||
| $ kubectl get pods | ||
| NAME READY STATUS RESTARTS AGE | ||
| api-7dc9d84f-kfnwz 2/2 Running 0 23s | ||
| web-7bc5786747-b5pzl 1/1 Running 0 23s | ||
| ``` | ||
|
|
||
| ### Validate both ports | ||
|
boruszak marked this conversation as resolved.
|
||
|
|
||
| Use the `web` Pod's name to open a shell session and test the `api` service. | ||
|
|
||
| ```shell-session | ||
| $ kubectl exec -it web-7bc5786747-b5pzl -- curl api:80 | ||
| hello world | ||
| ``` | ||
|
|
||
| Then test the `api-admin` service. | ||
|
|
||
| ```shell-session | ||
| $ kubectl exec -it web-7bc5786747-b5pzl -- curl api-admin:90 | ||
| hello world from 9090 admin | ||
| ``` | ||
|
|
||
| ### Validate port 80 | ||
|
|
||
| Apply the CRD to allow traffic to port 80 only: | ||
|
|
||
| ```shell-session | ||
| $ kubectl apply -f deny-90.yaml | ||
| ``` | ||
|
|
||
| Then, open a shell session in the `web` container and test the `api` service on port 80. | ||
|
boruszak marked this conversation as resolved.
|
||
|
|
||
| ```shell-session | ||
| $ kubectl exec -it web-7bc5786747-b5pzl -- curl api:80 | ||
| hello world | ||
| ``` | ||
|
|
||
| Test the `admin` service on port 90. This command should fail, indicating that the traffic permission is in effect. | ||
|
|
||
| ```shell-session | ||
| $ kubectl exec -it web-7bc5786747-b5pzl -- curl api-admin:90 | ||
| ``` | ||
|
|
||
| Before testing the other port, remove the TrafficPermissions CRD. | ||
|
|
||
| ```shell-session | ||
| $ kubectl delete -f deny-90.yaml | ||
| ``` | ||
|
|
||
| ### Validate port 90 | ||
|
|
||
| Apply the CRD to allow traffic to port 90 only: | ||
|
|
||
| ```shell-session | ||
| $ kubectl apply -f deny-80.yaml | ||
| ``` | ||
|
|
||
| Then, open a shell session in the `web` container and test the `admin` service on port 90. | ||
|
|
||
| ```shell-session | ||
| $ kubectl exec -it web-7bc5786747-b5pzl -- curl api-admin:90 | ||
| hello world | ||
| ``` | ||
|
|
||
| Test the `api` service on port 80. This command should fail, indicating that the traffic permission is in effect. | ||
|
|
||
| ```shell-session | ||
| $ kubectl exec -it web-7bc5786747-b5pzl -- curl api:80 | ||
| ``` | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.