Skip to content

Commit 8f341fb

Browse files
committed
Gateway Settings Enhancement Proposal
Problem: We want a design for GatewayClass level settings that applies to all Gateways, such as `otel_exporter`. Solution: Add enhancement proposal introducing `GatewaySettings`. Enhancement Proposal: #1775
1 parent 03e24fe commit 8f341fb

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

docs/proposals/gateway-settings.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# Enhancement Proposal-1630: Gateway Settings
2+
3+
- Issue: https://github.com/nginxinc/nginx-gateway-fabric/issues/1775
4+
- Status: Implementable
5+
6+
## Summary
7+
8+
This Enhancement Proposal introduces the `GatewaySettings` API, which allows Cluster Operators to define configuration at the GatewayClass level for all Gateways under that Class. This configuration is attached via the GatewayClass `parametersRef` field.
9+
10+
## Goals
11+
12+
- Define the Gateway settings.
13+
- Define an API for the Gateway settings.
14+
15+
## Non-Goals
16+
17+
- Provide implementation details for implementing the Gateway settings.
18+
19+
## Introduction
20+
21+
### Gateway Settings
22+
23+
Gateway Settings are NGINX directives or configuration attached at the GatewayClass level that should be solely controlled by the Cluster Operator and should not be changed by the Application Developers. All Gateways attached to this GatewayClass will inherit these settings.
24+
25+
These settings apply to the `main`, `http`, and/or `stream` contexts of the NGINX config.
26+
27+
To begin, the Gateway Settings config will include the following NGINX directives (focusing on OpenTelemetry tracing):
28+
29+
- [`otel_exporter`](https://nginx.org/en/docs/ngx_otel_module.html#otel_exporter)
30+
- [`otel_service_name`](https://nginx.org/en/docs/ngx_otel_module.html#otel_service_name)
31+
- [`otel_span_attr`](https://nginx.org/en/docs/ngx_otel_module.html#otel_span_attr): set global span attributes that will be merged with the span attributes set in the [Observability extension](nginx-extensions.md#gateway-settings).
32+
33+
In the future, this config will be extended to support other directives, such as those defined in the [NGINX Extensions Proposal](nginx-extensions.md#gateway-settings).
34+
35+
## API, Customer Driven Interfaces, and User Experience
36+
37+
The `GatewaySettings` API is a CRD that is a part of the `gateway.nginx.org` Group. It will be referenced in the `parametersRef` field of a GatewayClass. It will live at the cluster scope.
38+
39+
For example, a `GatewaySettings` named `gw-settings` would be referenced as follows:
40+
41+
```yaml
42+
kind: GatewayClass
43+
metadata:
44+
name: nginx
45+
spec:
46+
controllerName: gateway.nginx.org/nginx-gateway-controller
47+
parametersRef:
48+
group: gateway.nginx.org/v1alpha1
49+
kind: GatewaySettings
50+
name: gw-settings
51+
```
52+
53+
Below is the Golang API for the `GatewaySettings` API:
54+
55+
### Go
56+
57+
```go
58+
package v1alpha1
59+
60+
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
61+
62+
type GatewaySettings struct {
63+
metav1.TypeMeta `json:",inline"`
64+
metav1.ObjectMeta `json:"metadata,omitempty"`
65+
66+
// Spec defines the desired state of the GatewaySettings.
67+
Spec GatewaySettingsSpec `json:"spec"`
68+
69+
// Status defines the state of the GatewaySettings.
70+
Status GatewaySettingsStatus `json:"status,omitempty"`
71+
}
72+
73+
type GatewaySettingsSpec struct {
74+
// OtelExporter specifies OpenTelemetry export parameters.
75+
// +optional
76+
OtelExporter *OtelExporter `json:"otelExporter,omitempty"`
77+
78+
// OtelServiceName is the "service.name" attribute of the Otel resource.
79+
// +optional
80+
OtelServiceName *string `json:"otelServiceName,omitempty"`
81+
82+
// OtelSpanAttributes are custom key/value attributes that are added to each span.
83+
// Variables can be included in the values.
84+
// +optional
85+
OtelSpanAttributes map[string]string `json:"otelSpanAttributes,omitempty"`
86+
}
87+
88+
type GatewaySettingsStatus struct {
89+
// Conditions describe the current conditions of the GatewaySettings.
90+
// +optional
91+
Conditions []metav1.Condition `json:"conditions,omitempty"`
92+
}
93+
94+
// OtelExporter specifies OpenTelemetry export parameters.
95+
type OtelExporter struct {
96+
// Interval is the maximum interval between two exports, by default is 5 seconds.
97+
// +optional
98+
Interval *Duration `json:"interval,omitempty"`
99+
100+
// BatchSize is the maximum number of spans to be sent in one batch per worker, by default is 512.
101+
// +optional
102+
BatchSize *int32 `json:"batchSize,omitempty"`
103+
104+
// BatchCount is the number of pending batches per worker, spans exceeding the limit are dropped,
105+
// by default is 4.
106+
// +optional
107+
BatchCount *int32 `json:"batchCount,omitempty"`
108+
109+
// Endpoint is the address of OTLP/gRPC endpoint that will accept telemetry data.
110+
Endpoint string `json:"endpoint"`
111+
}
112+
113+
// Duration is a string value representing a duration in time.
114+
// The format is a subset of the syntax parsed by Golang time.ParseDuration.
115+
// Examples: 1h, 12m, 30s, 150ms.
116+
type Duration string
117+
```
118+
119+
### Status
120+
121+
#### Conditions
122+
123+
According to the [Policy and Metaresources GEP](https://gateway-api.sigs.k8s.io/geps/gep-713/), the `GatewaySettings` CRD must include a `status` stanza with a slice of Conditions.
124+
125+
The `Accepted` Condition must be populated on the `GatewaySettings` CRD using the reasons defined in the [PolicyCondition API](https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/policy_types.go). If these reasons are not sufficient, we can add implementation-specific reasons.
126+
127+
#### GatewayClass Status
128+
129+
While this status does not officially exist, in order to be consistent with other resources with object refs we should add a custom `ResolvedRefs` Condition to the `GatewayClass` when the `parametersRef` is in use.
130+
131+
NGINX Gateway Fabric must set this Condition on the GatewayClass affected by a `GatewaySettings`.
132+
Below is an example of what this Condition may look like:
133+
134+
```yaml
135+
Conditions:
136+
Type: gateway.nginx.org/ResolvedRefs
137+
Message: All references are resolved
138+
Observed Generation: 1
139+
Reason: ResolvedRefs
140+
Status: True
141+
```
142+
143+
Some additional rules:
144+
145+
- This Condition should be added when the affected object starts being affected by a `GatewaySettings`.
146+
- When the `GatewaySettings` affecting that object is removed, the Condition should be removed.
147+
- The Observed Generation is the generation of the GatewayClass, not the generation of the `GatewaySettings`.
148+
149+
## Use Cases
150+
151+
- As a Cluster Operator, I want to set global settings that will apply to all Gateways that are a part of a GatewayClass. These settings should not be overriden at a lower level.
152+
153+
## Testing
154+
155+
- Unit tests
156+
- Functional tests that verify the attachment of the CRD to the GatewayClass, and that NGINX behaves properly based on the configuration.
157+
158+
## Security Considerations
159+
160+
Validating all fields in the `GatewaySettings` is critical to ensuring that the NGINX config generated by NGINX Gateway Fabric is correct and secure.
161+
162+
All fields in the `GatewaySettings` will be validated with Open API Schema. If the Open API Schema validation rules are not sufficient, we will use [CEL](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules).
163+
164+
RBAC via the Kubernetes API server will ensure that only authorized users can update the CRD containing Gateway Settings.
165+
166+
## Alternatives
167+
168+
- ParametersRef with ConfigMap: A ConfigMap is another resource type where a user can provide configuration options. However, unlike CRDs, ConfigMaps do not have built-in schema validation, versioning, or conversion webhooks.
169+
- Direct Policy: A Direct Policy may also work for Gateway Settings. It can be attached to a Gateway and scoped to Cluster Operators through RBAC. It would allow Cluster Operators to apply settings for specific Gateways, instead of all Gateways.
170+
171+
## References
172+
173+
- [NGINX Extensions Enhancement Proposal](nginx-extensions.md)
174+
- [Attaching Policy to GatewayClass](https://gateway-api.sigs.k8s.io/geps/gep-713/#attaching-policy-to-gatewayclass)
175+
- [Kubernetes API Conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md)

0 commit comments

Comments
 (0)