Skip to content

Commit 80653e5

Browse files
committed
Add xDS docs
1 parent 5afa110 commit 80653e5

7 files changed

Lines changed: 274 additions & 3 deletions

File tree

site/src/sphinx/_images/xds_1.png

111 KB
Loading

site/src/sphinx/_images/xds_2.png

132 KB
Loading

site/src/sphinx/_images/xds_3.png

298 KB
Loading

site/src/sphinx/_images/xds_4.png

374 KB
Loading

site/src/sphinx/index.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ Dynamic configuration with templates and variables
101101
- Manage environment-specific configurations with variable files (``/vars/dev.json``, ``/vars/prod.json``)
102102
- Preview rendered templates in real-time through the Web UI
103103

104+
Envoy xDS v3 control plane
105+
--------------------------
106+
- Manage Envoy Listeners, Routes, Clusters and Endpoints as version-controlled YAML.
107+
- Edit resources through the Web UI or a YAML-over-HTTP REST API.
108+
- Serve them to Envoy and Armeria clients over the gRPC xDS discovery services from the same server port.
109+
- See :ref:`xds` for more information.
110+
104111
Read more
105112
---------
106113
.. toctree::
@@ -112,6 +119,7 @@ Read more
112119
client-java
113120
templates-variables
114121
mirroring
122+
xds
115123
auth
116124
known-issues
117125

site/src/sphinx/mirroring.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,13 @@ Here is the properties of the mirroring task:
114114
- whether the mirroring task is enabled.
115115

116116
Central Dogma to Central Dogma mirroring
117-
=========================================
117+
----------------------------------------
118118
In addition to Git-to-CD mirroring, Central Dogma supports mirroring between two Central Dogma servers.
119119
This is useful when you want to replicate configuration across multiple Central Dogma clusters, such as
120120
syncing configurations between different environments or regions.
121121

122122
Setting up a CD-to-CD mirror
123-
-----------------------------
123+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
124124
The setup is similar to Git mirroring, with a few differences:
125125

126126
- ``Remote``
@@ -161,7 +161,7 @@ All other properties (``Mirror ID``, ``Schedule``, ``Local path``, ``Zone``, ``E
161161
same way as in Git mirroring.
162162

163163
Mirror limit settings
164-
---------------------
164+
^^^^^^^^^^^^^^^^^^^^^^
165165
Central Dogma limits the number of files and the total size of the files in a mirror for its reliability.
166166
As your configuration grows, you may want to bump the limit. See :ref:`setup-configuration` to learn about
167167
the options related with mirroring: ``numMirroringThreads``, ``maxNumFilesPerMirror`` and

site/src/sphinx/xds.rst

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
.. _xds:
2+
3+
Serving Envoy configuration with the xDS control plane
4+
=======================================================
5+
Central Dogma can act as an `Envoy <https://www.envoyproxy.io/>`__
6+
`xDS <https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol>`__ v3 control plane. It stores Envoy
7+
resources — Listeners, Routes, Clusters and Endpoints — as version-controlled YAML files, lets you edit them
8+
through the Web UI, and serves them to Envoy and Armeria clients over the gRPC xDS discovery services — LDS,
9+
RDS, CDS, EDS and the aggregated ADS.
10+
11+
Because the resources live in ordinary Central Dogma repositories, every change is reviewable, auditable and
12+
revertible, and you can watch or mirror them just like any other configuration file. This brings the
13+
:ref:`configuration change workflow <mirroring>` and :ref:`access control <auth>` you already use for your
14+
YAML settings to your Envoy service mesh.
15+
16+
.. note::
17+
18+
The xDS control plane runs only when the xDS plugin is enabled on the server. When it is enabled, the Web
19+
UI exposes the xDS console at ``/app/xds``.
20+
21+
Concepts
22+
--------
23+
- **Group** — the unit of organization and access control. A group is a repository under the internal
24+
``@xds`` project, and it holds all the xDS resources for one logical set of services.
25+
- **Resource types** — each group contains a directory per resource type: ``listeners`` (LDS), ``routes``
26+
(RDS), ``clusters`` (CDS) and ``endpoints`` (EDS). Each resource is a single YAML file,
27+
e.g. ``/clusters/foo.yaml``.
28+
- **Resource name** — the server assigns each resource a name derived from its group and ID, so you never
29+
write it yourself:
30+
31+
- Listeners, Routes and Clusters get a ``name`` of ``groups/{group}/{type}/{id}`` — for example, a cluster
32+
``foo`` in group ``my-group`` becomes ``groups/my-group/clusters/foo``.
33+
- Endpoints get a ``clusterName`` of ``groups/{group}/clusters/{id}``, binding the load assignment to the
34+
cluster of the same ID (an endpoint ``foo`` supplies the endpoints for cluster
35+
``groups/my-group/clusters/foo``).
36+
37+
A group repository is laid out like this:
38+
39+
.. code-block:: none
40+
41+
@xds (project)
42+
└── my-group (repository = xDS group)
43+
├── listeners/<id>.yaml (LDS)
44+
├── routes/<id>.yaml (RDS)
45+
├── clusters/<id>.yaml (CDS)
46+
└── endpoints/<id>.yaml (EDS)
47+
48+
Managing xDS resources with the Web UI
49+
--------------------------------------
50+
The xDS console lives at ``/app/xds``. It opens on the list of groups you can access, with a button to create
51+
a new one.
52+
53+
.. image:: _images/xds_1.png
54+
:alt: xDS group list
55+
56+
Creating a group
57+
^^^^^^^^^^^^^^^^
58+
Click "New Group" and enter a group ID. The ID must start with a lowercase letter and may contain
59+
lowercase letters, digits, ``_``, ``.`` and ``-``.
60+
61+
.. image:: _images/xds_2.png
62+
:alt: Creating a new xDS group
63+
64+
Editing resources
65+
^^^^^^^^^^^^^^^^^
66+
Selecting a group reveals a sidebar that navigates everything in it:
67+
68+
- *Overview* — a summary of the group.
69+
- *Listeners*, *Routes*, *Clusters*, *Endpoints* — the four core resource types.
70+
- *K8s Aggregators* — generate Endpoints from Kubernetes services (see
71+
`Aggregating Kubernetes service endpoints`_).
72+
- *References* — a dependency graph of the group's resources, with reverse-reference lookup and
73+
dangling-reference detection.
74+
- *History* — the commit log of every resource change.
75+
- *Mirroring*, *Credentials*, *Permissions*, *Danger Zone* — administrative sections, visible to group
76+
administrators only.
77+
78+
To add a resource, open its type and click "New". The editor is pre-filled with a starter YAML template for
79+
that type; edit it, optionally add a commit summary, and save. Each resource follows its Envoy v3 API schema —
80+
see the Envoy reference for the
81+
`Listener <https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto>`__,
82+
`RouteConfiguration <https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route.proto>`__,
83+
`Cluster <https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto>`__ and
84+
`ClusterLoadAssignment <https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/endpoint/v3/endpoint.proto>`__
85+
messages.
86+
87+
.. image:: _images/xds_3.png
88+
:alt: Editing an xDS resource
89+
90+
The *Mirroring* section configures :ref:`mirroring <mirroring>` for the group's backing repository, the
91+
*Permissions* section manages :ref:`access control <auth>`, and the *Credentials* section holds the credentials
92+
the group uses for mirroring and for reaching a Kubernetes control plane.
93+
94+
Aggregating Kubernetes service endpoints
95+
----------------------------------------
96+
A **Kubernetes endpoint aggregator** watches one or more Kubernetes services and continuously generates an EDS
97+
``ClusterLoadAssignment`` from their ready endpoints, served to xDS clients under the name
98+
``groups/{group}/k8s/clusters/{id}``. Unlike a hand-written Endpoint resource, it stays in sync with the
99+
cluster automatically as Pods come and go.
100+
101+
.. tip::
102+
103+
Aggregators are created and edited through the Web UI form, so you never write the resource YAML by hand.
104+
105+
.. note::
106+
107+
When you create or update an aggregator, the server connects to each watcher's Kubernetes API and requires
108+
the endpoints to resolve within a few seconds, otherwise the request is rejected. A saved aggregator is
109+
therefore always known to be resolvable.
110+
111+
Creating and editing in the Web UI
112+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
113+
Open a group's *K8s Aggregators* section and click "New". The editor is a form: enter an *Aggregator ID*, then
114+
add one or more *Watchers* — each watcher maps to a single Kubernetes service. Click "Preview endpoints" to
115+
resolve the watchers against Kubernetes and see the ``ClusterLoadAssignment`` that would be generated, without
116+
saving; then click "Create". An existing aggregator opens read-only; click "Edit" to modify it or "Delete" to
117+
remove it. Both require the ``WRITE`` role on the group. The endpoints an aggregator generates appear,
118+
read-only, in the group's *Endpoints* section.
119+
120+
.. image:: _images/xds_4.png
121+
:alt: Creating a Kubernetes endpoint aggregator
122+
123+
Watcher fields
124+
^^^^^^^^^^^^^^
125+
Each watcher exposes the following fields (the underlying YAML key is shown in parentheses):
126+
127+
- ``Service name`` (required, ``watcher.serviceName``)
128+
129+
- the Kubernetes service whose endpoints are resolved.
130+
131+
- ``Port name`` (``watcher.portName``)
132+
133+
- the named port to select when the service exposes more than one port.
134+
135+
- ``Control plane URL`` (required, ``kubeconfig.controlPlaneUrl``)
136+
137+
- the Kubernetes API server URL, e.g. ``https://kubernetes.default.svc``.
138+
139+
- ``Namespace`` (``kubeconfig.namespace``)
140+
141+
- the namespace to watch.
142+
143+
- ``Credential ID`` (``kubeconfig.credentialId``)
144+
145+
- the ID of an access-token credential in the group's *Credentials* section, used as the OAuth token to
146+
authenticate to the Kubernetes API server. See :ref:`auth` for credential management.
147+
148+
- ``Trust certificates`` (``kubeconfig.trustCerts``)
149+
150+
- trust the Kubernetes API server's certificate (skip TLS verification).
151+
152+
- ``Priority`` (``priority``) and ``Load balancing weight`` (``loadBalancingWeight``)
153+
154+
- the Envoy locality priority and load balancing weight applied to the endpoints this watcher resolves.
155+
156+
- ``Region`` / ``Zone`` / ``Sub zone`` (``locality.region`` / ``locality.zone`` / ``locality.subZone``)
157+
158+
- the optional locality assigned to every endpoint this watcher resolves.
159+
160+
- ``Distinct endpoint`` (``watcher.distinctEndpoint``)
161+
162+
- when enabled, endpoints that share the same host and port are collapsed into a single endpoint. This is
163+
useful in NodePort mode, where multiple Pods on the same node resolve to the same ``nodeIP:nodePort``.
164+
165+
- ``Metadata mapping`` (``watcher.metadataMapping``)
166+
167+
- copies a Kubernetes Pod or Node label/annotation into the metadata of the generated endpoint. Each mapping
168+
has a ``resourceType`` (``POD`` or ``NODE``), an ``entryType`` (``LABEL`` or ``ANNOTATION``), exactly one
169+
of ``sourceKey`` (a single key, e.g. ``topology.kubernetes.io/zone``) or ``sourceKeyPrefix`` (every key
170+
with the given prefix), an optional ``metadataNamespace`` (the Envoy ``filter_metadata`` namespace,
171+
``envoy.lb`` by default) and an optional ``metadataKey`` (the destination key, defaulting to
172+
``sourceKey``).
173+
174+
- ``Additional properties`` (``watcher.additionalProperties``)
175+
176+
- free-form key/value pairs passed to a custom node-IP extractor plugin, if one is installed on the server.
177+
They are ignored otherwise.
178+
179+
Beyond its watchers, the aggregator itself has an optional ``policy`` — an Envoy
180+
``ClusterLoadAssignment.Policy`` applied to the whole generated assignment.
181+
182+
Access control
183+
--------------
184+
Access to a group is governed by the ``ADMIN``, ``WRITE`` and ``READ`` repository roles of its backing
185+
repository. Mutations require ``WRITE``; reads require ``READ``, except Endpoints, which are readable without
186+
it.
187+
188+
An application identity — together with its access token or mTLS client certificate — is created in the
189+
Application identities menu. To give it access to a group, register it under that group's *Permissions*
190+
section, in *Application IDs*, with the desired role; *Permissions* grants roles to individual users the same
191+
way. See :ref:`auth` for the underlying authentication and access-control model.
192+
193+
The *Credentials* section is unrelated to granting clients access. It holds the credentials the group uses
194+
itself: to :ref:`mirror <mirroring>` its backing repository — with an SSH key, a password or an access token —
195+
and to authenticate to a Kubernetes control plane, which requires an access token (the *Credential ID* a
196+
watcher references).
197+
198+
Serving resources to clients
199+
----------------------------
200+
The gRPC discovery services (LDS, RDS, CDS, EDS and ADS) are served on the same server port as the REST API
201+
and follow the server's TLS configuration. An authenticated application identity is
202+
served the union of every group it has ``READ`` access to, and resources are addressed as
203+
``groups/{group}/{type}/{id}``.
204+
205+
.. tip::
206+
207+
Run the xDS control plane with :ref:`authentication <auth>` enabled and authenticate every xDS client, so
208+
that each client is served only the groups it is authorized for. Prefer an mTLS client certificate; an
209+
application access token (as an HTTP ``Authorization: Bearer`` header) is also supported.
210+
211+
Connecting Envoy
212+
^^^^^^^^^^^^^^^^
213+
Point Envoy's dynamic resources at Central Dogma's ADS endpoint with a bootstrap configuration like the
214+
following. It defines a cluster for the Central Dogma server (speaking HTTP/2) and configures LDS, CDS and ADS
215+
to use it:
216+
217+
.. code-block:: yaml
218+
219+
node:
220+
id: my-envoy
221+
cluster: my-service
222+
223+
dynamic_resources:
224+
ads_config:
225+
api_type: GRPC
226+
transport_api_version: V3
227+
grpc_services:
228+
- envoy_grpc:
229+
cluster_name: centraldogma
230+
# For token-based auth, attach the access token as gRPC metadata:
231+
# initial_metadata:
232+
# - key: authorization
233+
# value: "Bearer <token>"
234+
lds_config:
235+
ads: {}
236+
resource_api_version: V3
237+
cds_config:
238+
ads: {}
239+
resource_api_version: V3
240+
241+
static_resources:
242+
clusters:
243+
- name: centraldogma
244+
type: STRICT_DNS
245+
typed_extension_protocol_options:
246+
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
247+
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
248+
explicit_http_config:
249+
http2_protocol_options: {}
250+
load_assignment:
251+
cluster_name: centraldogma
252+
endpoints:
253+
- lb_endpoints:
254+
- endpoint:
255+
address:
256+
socket_address:
257+
address: 127.0.0.1
258+
port_value: 36462
259+
260+
.. note::
261+
262+
Add a TLS ``transport_socket`` to the ``centraldogma`` cluster when the server uses TLS. This is also where
263+
the client certificate is configured for the recommended mTLS authentication.

0 commit comments

Comments
 (0)