Skip to content

Commit 8649ff4

Browse files
authored
chore(docs): simplifying readme (#49)
* chore: simplifying readme Signed-off-by: Aron Kerekes <arkereke@cisco.com> * chore: updating gitignore Signed-off-by: Aron Kerekes <arkereke@cisco.com> --------- Signed-off-by: Aron Kerekes <arkereke@cisco.com>
1 parent 52d4600 commit 8649ff4

3 files changed

Lines changed: 23 additions & 318 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
.idea/
44
.continue/
55

6+
# macOS
7+
.DS_Store
8+
69
# Builds
710
.bin/

README.md

Lines changed: 8 additions & 306 deletions
Original file line numberDiff line numberDiff line change
@@ -5,324 +5,26 @@
55
[![License](https://img.shields.io/github/license/agntcy/dir-runtime)](./LICENSE.md)
66
[![Contributor-Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-fbab2c.svg)](CODE_OF_CONDUCT.md)
77

8-
The Directory Runtime is a discovery service that watches runtimes (Docker, Kubernetes) for workloads and provides a gRPC API for querying them. It resolves workloads using various resolvers (A2A, OASF) to extract and provide details about the workload's capabilities, integrating with the [Directory](https://github.com/agntcy/dir) for capability-based discovery.
8+
The Directory Runtime watches container runtimes (Docker, Kubernetes) for labeled workloads and exposes them through a gRPC API. Resolvers enrich workloads with capability metadata (A2A agent cards, OASF records from the [Directory](https://github.com/agntcy/dir)) for discovery-based routing.
99

10-
## Architecture
11-
12-
The system is split into two independent components:
13-
14-
```
15-
┌──────────────────────────────────────────────────────────────────────────────┐
16-
│ Runtime Discovery System │
17-
└──────────────────────────────────────────────────────────────────────────────┘
18-
19-
┌─────────────────────────────┐ ┌──────────────────────────────────────┐
20-
│ Discovery │ │ Server │
21-
│ (runtime/discovery) │ │ (runtime/server) │
22-
│ │ │ │
23-
│ ┌─────────────────────┐ │ │ ┌─────────────────────────┐ │
24-
│ │ Runtime Adapters │ │ │ │ gRPC API │ │
25-
│ │ - Docker │ │ │ │ /ListWorkloads │ │
26-
│ │ - Kubernetes │ │ │ └─────────────────────────┘ │
27-
│ └─────────────────────┘ │ │ ▲ │
28-
│ │ │ │ │ │
29-
│ ▼ │ └──────────────────────────────────────┘
30-
│ ┌─────────────────────┐ │ │
31-
│ │ Resolvers │ │ │
32-
│ │ - A2A │ │ │
33-
│ │ - OASF │ │ │
34-
│ └─────────────────────┘ │ │
35-
│ │ │ │
36-
│ ▼ │ │
37-
│ ┌─────────────────────┐ │ │
38-
│ │ Store Writer │ │ │
39-
│ └─────────────────────┘ │ │
40-
└────────────│────────────────┘ │
41-
│ write/manage │
42-
▼ │
43-
┌──────────────────────────────┐ │
44-
│ Storage Backend │ read/watch │
45-
│ - etcd (distributed) │──────────────────────┘
46-
│ - Kubernetes CRDs (native) │
47-
└──────────────────────────────┘
48-
```
49-
50-
## Components
51-
52-
### Discovery (`discovery/`)
53-
54-
The discovery component is responsible for:
55-
- **Watching runtimes** for workloads with the `org.agntcy/discover=true` label. Supported runtimes:
56-
- **Docker**: Watches Docker daemon for labeled containers
57-
- **Kubernetes**: Watches Kubernetes API for labeled pods/services
58-
- Extensible architecture allows adding more runtimes in the future
59-
- **Resolving workload metadata** using configurable resolvers:
60-
- **A2A resolver**: Extracts A2A agent card from workloads with `org.agntcy/agent-type=a2a` label
61-
- **OASF resolver**: Resolves OASF records from Directory for workloads with `org.agntcy/agent-record=<fqdn>` label
62-
- Extensible architecture allows adding more resolvers in the future
63-
- **Writing workloads** to the storage backend (etcd or CRDs)
64-
65-
The storage backend can be used to expose discovered workloads to other components (e.g., clients/servers) without coupling them directly and to reduce attack surface.
66-
67-
In non-Kubernetes environments, etcd is recommended as the storage backend for better portability.
68-
In Kubernetes environments, CRDs can be used for a more native experience to ensure clients can access workloads via the Kubernetes API.
69-
70-
```
71-
Runtime Discovery --------> Runtime Server (for querying workloads via gRPC)
72-
73-
└-------------------> CRD (for querying workloads via Kubernetes API)
74-
```
75-
76-
### Server (`server/`)
77-
78-
The server component provides a **gRPC API** for querying discovered workloads
79-
80-
## Example Setup
81-
82-
### Build Container Images
10+
## Quick Start
8311

8412
```bash
13+
# Build images
8514
IMAGE_TAG=latest task build
86-
```
87-
88-
### Docker Compose
8915

90-
```bash
91-
# Deploy the stack
16+
# Deploy discovery + server
9217
docker compose -f install/docker/docker-compose.yml up -d
9318

94-
# Deploy example workloads
95-
docker compose -f install/examples/docker-compose.yml up -d
96-
97-
# Add discovery to all networks (required for resolvers to work)
98-
docker network connect examples_team-a runtime-discovery
99-
docker network connect examples_team-b runtime-discovery
100-
docker restart runtime-discovery
101-
102-
# Query the API
103-
grpcurl -plaintext localhost:8080 agntcy.dir.runtime.v1.DiscoveryService/ListWorkloads
104-
105-
# Cleanup
106-
docker compose -f install/docker/docker-compose.yml down
107-
docker compose -f install/examples/docker-compose.yml down
108-
```
109-
110-
### Kubernetes
111-
112-
The Helm chart supports both CRD and etcd storage backends.
113-
114-
#### Setup KIND Cluster
115-
116-
```bash
117-
# Create cluster
118-
kind create cluster --name runtime
119-
120-
# Load images into KIND
121-
kind load docker-image ghcr.io/agntcy/dir-runtime-discovery:latest --name runtime
122-
kind load docker-image ghcr.io/agntcy/dir-runtime-server:latest --name runtime
123-
```
124-
125-
#### Deploy Example Workloads
126-
127-
```bash
128-
kubectl apply -f install/examples/k8s.workloads.yaml
129-
```
130-
131-
#### Deploy with CRD Storage
132-
133-
```bash
134-
# Install the chart with CRD storage (default)
135-
helm install runtime install/chart/
136-
137-
# Wait for pods
138-
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=discovery --timeout=60s
139-
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=server --timeout=60s
140-
141-
# Query the gRPC API
142-
kubectl port-forward svc/runtime-server 8080:8080 &
19+
# Query discovered workloads
14320
grpcurl -plaintext localhost:8080 agntcy.dir.runtime.v1.DiscoveryService/ListWorkloads
144-
145-
# Query the Kubernetes API to see discovered workloads
146-
kubectl get dw
14721
```
14822

149-
#### Deploy with etcd Storage
150-
151-
```bash
152-
# Install the chart with etcd storage
153-
helm install runtime install/chart/ \
154-
--set etcd.enabled=true \
155-
--set discovery.config.store.type=etcd \
156-
--set server.config.store.type=etcd
157-
158-
# Wait for pods
159-
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=etcd --timeout=60s
160-
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=discovery --timeout=60s
161-
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=server --timeout=60s
162-
163-
# Query the gRPC API
164-
kubectl port-forward svc/runtime-server 8080:8080 &
165-
grpcurl -plaintext localhost:8080 agntcy.dir.runtime.v1.DiscoveryService/ListWorkloads
166-
```
167-
168-
#### Cleanup
169-
170-
```bash
171-
kind delete cluster --name runtime
172-
```
23+
See the [documentation](docs/dir-component-runtime-discovery.md) for example workloads, Kubernetes deployment, workload labels, configuration, and the full gRPC API reference.
17324

174-
## Workload Labels
25+
## Documentation
17526

176-
Workloads are discovered based on labels. The discovery component watches for workloads with specific labels and processes their metadata.
177-
178-
### Discovery Labels
179-
180-
| Label | Runtime | Description |
181-
|-------|---------|-------------|
182-
| `org.agntcy/discover=true` | Kubernetes | Marks a pod/service for discovery |
183-
| `org.agntcy/discover=true` | Docker | Marks a container for discovery |
184-
185-
### Resolver Labels
186-
187-
Resolvers extract metadata from discovered workloads based on their labels.
188-
They provide additional information about the workload's capabilities.
189-
190-
| Label/Annotation | Description |
191-
|------------------|-------------|
192-
| `org.agntcy/agent-type=a2a` | Enables A2A resolver - fetches A2A agent card from workload |
193-
| `org.agntcy/agent-record=<fqdn>` | Enables OASF resolver - resolves record from Directory (e.g., `my-agent:v1.0.0`) |
194-
195-
To configure OASF resolver, the Directory client must be set up using environment variables (e.g., `DIRECTORY_CLIENT_SERVER_ADDRESS`, `DIRECTORY_CLIENT_AUTH_MODE`).
196-
197-
### Workload Services
198-
199-
Discovered workloads have a `services` field that holds metadata extracted by resolvers:
200-
201-
```json
202-
{
203-
"id": "4467371c-84fd-4683-ab30-93895d78bab7",
204-
"name": "service-a2a",
205-
"hostname": "service-a2a",
206-
"runtime": "kubernetes",
207-
"type": "pod",
208-
"labels": {
209-
"app": "service-a2a",
210-
"org.agntcy/discover": "true",
211-
"org.agntcy/agent-type": "a2a",
212-
"org.agntcy/agent-record": "my-agent:1.0.0"
213-
},
214-
"addresses": [
215-
"10-244-0-9.team-a.pod"
216-
],
217-
"ports": [
218-
"8080",
219-
"9999"
220-
],
221-
"isolationGroups": [
222-
"team-a"
223-
],
224-
"services": {
225-
"a2a": {
226-
"name": "My Agent",
227-
"description": "...",
228-
"capabilities": [...]
229-
},
230-
"oasf": {
231-
"cid": "baf123",
232-
"name": "my-agent:1.0.0",
233-
"record": {
234-
"name": "my-agent",
235-
"version": "1.0.0",
236-
"skills": [...]
237-
}
238-
}
239-
}
240-
}
241-
```
242-
243-
## Configuration
244-
245-
### Discovery Component
246-
247-
| Environment Variable | Description | Default |
248-
|---------------------|-------------|---------|
249-
| `DISCOVERY_WORKERS` | Number of resolver workers | `16` |
250-
| `DISCOVERY_STORE_TYPE` | Storage type (`etcd`, `crd`) | `etcd` |
251-
| `DISCOVERY_STORE_ETCD_HOST` | etcd server hostname | `localhost` |
252-
| `DISCOVERY_STORE_ETCD_PORT` | etcd server port | `2379` |
253-
| `DISCOVERY_STORE_ETCD_USERNAME` | etcd username for authentication | `` |
254-
| `DISCOVERY_STORE_ETCD_PASSWORD` | etcd password for authentication | `` |
255-
| `DISCOVERY_STORE_ETCD_DIAL_TIMEOUT` | Timeout for connecting to etcd | `5s` |
256-
| `DISCOVERY_STORE_ETCD_WORKLOADS_PREFIX` | etcd key prefix for workloads | `/discovery/workloads/` |
257-
| `DISCOVERY_STORE_CRD_NAMESPACE` | Namespace to store workloads in | `default` |
258-
| `DISCOVERY_STORE_CRD_KUBECONFIG` | Path to kubeconfig file (empty for in-cluster) | `` |
259-
| `DISCOVERY_STORE_CRD_RESYNC_PERIOD` | How often to resync the cache from the API server | `30s` |
260-
| `DISCOVERY_RUNTIME_TYPE` | Runtime type (`docker`, `kubernetes`) | `docker` |
261-
| `DISCOVERY_RUNTIME_DOCKER_HOST` | Docker daemon socket path | `unix:///var/run/docker.sock` |
262-
| `DISCOVERY_RUNTIME_DOCKER_LABEL_KEY` | Label key to filter containers | `org.agntcy/discover` |
263-
| `DISCOVERY_RUNTIME_DOCKER_LABEL_VALUE` | Label value to filter containers | `true` |
264-
| `DISCOVERY_RUNTIME_KUBERNETES_KUBECONFIG` | Path to kubeconfig file (empty for in-cluster) | `` |
265-
| `DISCOVERY_RUNTIME_KUBERNETES_NAMESPACE` | Namespace to watch (empty for all namespaces) | `` |
266-
| `DISCOVERY_RUNTIME_KUBERNETES_LABEL_KEY` | Label key to filter pods | `org.agntcy/discover` |
267-
| `DISCOVERY_RUNTIME_KUBERNETES_LABEL_VALUE` | Label value to filter pods | `true` |
268-
| `DISCOVERY_RESOLVER_A2A_ENABLED` | Enable A2A resolver | `true` |
269-
| `DISCOVERY_RESOLVER_A2A_TIMEOUT` | Timeout for A2A discovery | `5s` |
270-
| `DISCOVERY_RESOLVER_A2A_PATHS` | Comma-separated list of paths to probe for A2A discovery | `/.well-known/agent-card.json,/.well-known/card.json` |
271-
| `DISCOVERY_RESOLVER_A2A_LABEL_KEY` | Label key to identify A2A workloads | `org.agntcy/agent-type` |
272-
| `DISCOVERY_RESOLVER_A2A_LABEL_VALUE` | Label value to identify A2A workloads | `a2a` |
273-
| `DISCOVERY_RESOLVER_OASF_ENABLED` | Enable OASF resolver | `true` |
274-
| `DISCOVERY_RESOLVER_OASF_TIMEOUT` | Timeout for OASF resolution | `5s` |
275-
| `DISCOVERY_RESOLVER_OASF_LABEL_KEY` | Label key to identify OASF workloads | `org.agntcy/agent-record` |
276-
277-
The OASF resolver requires Directory client configuration via environment variables.
278-
These are the same as those used by the Directory client library, e.g. `DIRECTORY_CLIENT_SERVER_ADDRESS`.
279-
Refer to the [Directory Client documentation](https://github.com/agntcy/dir/tree/main/client) for all available options.
280-
281-
When a workload has the configured OASF resolver label, the resolver will attempt to fetch the corresponding record from Directory and validate its signature before attaching it to the workload.
282-
283-
### Server Component
284-
285-
| Environment Variable | Description | Default |
286-
|---------------------|-------------|---------|
287-
| `SERVER_HOST` | Server bind address | `0.0.0.0` |
288-
| `SERVER_PORT` | Server listen port | `8080` |
289-
| `SERVER_STORE_TYPE` | Storage type (`etcd`, `crd`) | `etcd` |
290-
| `SERVER_STORE_ETCD_HOST` | etcd server hostname | `localhost` |
291-
| `SERVER_STORE_ETCD_PORT` | etcd server port | `2379` |
292-
| `SERVER_STORE_ETCD_USERNAME` | etcd username for authentication | `` |
293-
| `SERVER_STORE_ETCD_PASSWORD` | etcd password for authentication | `` |
294-
| `SERVER_STORE_ETCD_DIAL_TIMEOUT` | Timeout for connecting to etcd | `5s` |
295-
| `SERVER_STORE_ETCD_WORKLOADS_PREFIX` | etcd key prefix for workloads | `/discovery/workloads/` |
296-
| `SERVER_STORE_CRD_NAMESPACE` | Namespace to read workloads from | `default` |
297-
| `SERVER_STORE_CRD_KUBECONFIG` | Path to kubeconfig file (empty for in-cluster) | `` |
298-
| `SERVER_STORE_CRD_RESYNC_PERIOD` | How often to resync the cache from the API server | `30s` |
299-
300-
## gRPC API
301-
302-
The server exposes a gRPC API defined in `proto/agntcy/dir/runtime/v1/discovery_service.proto`.
303-
304-
### GetWorkload
305-
306-
Get a specific workload by ID, name, or hostname.
307-
308-
```bash
309-
grpcurl -plaintext -d '{"id": "my-service"}' \
310-
localhost:8080 agntcy.dir.runtime.v1.DiscoveryService/GetWorkload
311-
```
312-
313-
### ListWorkloads
314-
315-
Stream all workloads with optional label filters. Labels support regex patterns.
316-
317-
```bash
318-
# List all workloads
319-
grpcurl -plaintext -d '{}' \
320-
localhost:8080 agntcy.dir.runtime.v1.DiscoveryService/ListWorkloads
321-
322-
# Filter by labels (supports regex)
323-
grpcurl -plaintext -d '{"labels": {"org.agntcy/agent-type": "a2a"}}' \
324-
localhost:8080 agntcy.dir.runtime.v1.DiscoveryService/ListWorkloads
325-
```
27+
- [Runtime Discovery](docs/dir-component-runtime-discovery.md) — architecture, setup, labels, configuration, and API
32628

32729
## Contributing
32830

0 commit comments

Comments
 (0)