Skip to content

Commit 37e9d57

Browse files
committed
Enhance ClusterProxy API.
Signed-off-by: xuezhaojun <[email protected]>
1 parent a8652dd commit 37e9d57

File tree

4 files changed

+182
-0
lines changed

4 files changed

+182
-0
lines changed

feature/feature.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,26 @@ const (
9393
// When enabled, the work controller will automatically clean up completed manifest works based on the configured
9494
// time-to-live duration to prevent accumulation of old completed resources.
9595
CleanUpCompletedManifestWork featuregate.Feature = "CleanUpCompletedManifestWork"
96+
97+
// ClusterProxy integrates cluster-proxy functionality directly into the klusterlet-agent, enabling
98+
// HTTP-based proxying to managed cluster API servers through gRPC tunnels.
99+
//
100+
// When enabled on the hub (via ClusterManager), it starts a gRPC server that provides an externally accessible
101+
// HTTP endpoint to proxy requests to managed cluster API servers. The API path format is:
102+
// https://<server-address>:<port>/<cluster-name>
103+
//
104+
// When enabled on the spoke (via Klusterlet), the agent establishes a gRPC connection to the hub and proxies
105+
// requests to its local API server. The agent sends a CSR with signer name "open-cluster-management.io/klusterlet-proxy"
106+
// to obtain the gRPC configuration, which is stored in the hub-kubeconfig-secret as "proxy-grpc.yaml".
107+
//
108+
// This feature requires gRPC configuration in ClusterManager.spec.grpcConfiguration with the ClusterProxy
109+
// feature gate enabled. Users can authenticate using either userToken or impersonation methods.
110+
//
111+
// Use cases include: fetching pod logs, accessing VM consoles (kubevirt), multicluster job submission (MultiKueue),
112+
// and multicluster apiserver access (Kubernetes MCP).
113+
//
114+
// When disabled, the legacy cluster-proxy addon should be used instead for proxy functionality.
115+
ClusterProxy featuregate.Feature = "ClusterProxy"
96116
)
97117

98118
// DefaultSpokeRegistrationFeatureGates consists of all known ocm-registration
@@ -137,3 +157,7 @@ var DefaultSpokeWorkFeatureGates = map[featuregate.Feature]featuregate.FeatureSp
137157
ExecutorValidatingCaches: {Default: false, PreRelease: featuregate.Alpha},
138158
RawFeedbackJsonString: {Default: false, PreRelease: featuregate.Alpha},
139159
}
160+
161+
var DefaultServerConfigFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
162+
ClusterProxy: {Default: false, PreRelease: featuregate.Alpha},
163+
}

operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,103 @@ spec:
181181
deployed klusterlet agent. It will be ignored when the PriorityClass/v1 API
182182
is not available on the managed cluster.
183183
type: string
184+
proxyConfig:
185+
description: |-
186+
ProxyConfig holds the configuration for enabling klusterlet-proxy functionality,
187+
which allows the hub cluster to access the managed cluster's API server through
188+
a gRPC-based proxy tunnel established by the klusterlet agent.
189+
190+
When configured, the klusterlet agent establishes a gRPC connection to the hub's
191+
proxy server and proxies incoming HTTP requests to the local managed cluster API server.
192+
This enables hub-to-spoke API access even when the managed cluster is not directly
193+
accessible from the hub (e.g., behind a firewall or NAT).
194+
195+
This feature requires the ClusterProxy feature gate to be enabled and corresponding
196+
GRPCConfiguration to be set in the ClusterManager on the hub side.
197+
properties:
198+
authentications:
199+
description: |-
200+
Authentications defines how the agent authenticates with the cluster.
201+
By default it is `userToken`, but it could also be `impersonation` or both.
202+
items:
203+
type: string
204+
type: array
205+
grpcEndpoint:
206+
properties:
207+
grpc:
208+
description: grpc represents the configuration for grpc endpoint.
209+
properties:
210+
hostname:
211+
description: hostname points to a fixed hostname for serving
212+
agents' handshakes.
213+
properties:
214+
caBundle:
215+
description: caBundle of the endpoint.
216+
format: byte
217+
type: string
218+
host:
219+
description: host is the host name of the endpoint.
220+
type: string
221+
required:
222+
- host
223+
type: object
224+
type:
225+
default: hostname
226+
description: |-
227+
type specifies how the endpoint is exposed.
228+
You may need to apply an object to expose the endpoint, for example: a route.
229+
enum:
230+
- hostname
231+
type: string
232+
required:
233+
- type
234+
type: object
235+
https:
236+
description: https represents the configuration for https
237+
endpoint.
238+
properties:
239+
hostname:
240+
description: hostname points to a fixed hostname for serving
241+
agents' handshakes.
242+
properties:
243+
caBundle:
244+
description: caBundle of the endpoint.
245+
format: byte
246+
type: string
247+
host:
248+
description: host is the host name of the endpoint.
249+
type: string
250+
required:
251+
- host
252+
type: object
253+
type:
254+
default: hostname
255+
description: |-
256+
type specifies how the endpoint is exposed.
257+
You may need to apply an object to expose the endpoint, for example: a route.
258+
enum:
259+
- hostname
260+
type: string
261+
required:
262+
- type
263+
type: object
264+
protocol:
265+
default: grpc
266+
description: protocol is the protocol used for the endpoint,
267+
could be https or grpc.
268+
enum:
269+
- grpc
270+
- https
271+
type: string
272+
usage:
273+
description: |-
274+
usage defines the usage of the endpoint. It could be "agentToHub" indicating the endpoint is used
275+
for communication between agent and hub, or "consumer" indicating the endpoint is used for external consumer.
276+
type: string
277+
required:
278+
- protocol
279+
type: object
280+
type: object
184281
registrationConfiguration:
185282
description: RegistrationConfiguration contains the configuration
186283
of registration

operator/v1/types_klusterlet.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,20 @@ type KlusterletSpec struct {
100100
// is not available on the managed cluster.
101101
// +optional
102102
PriorityClassName string `json:"priorityClassName,omitempty"`
103+
104+
// ProxyConfig holds the configuration for enabling klusterlet-proxy functionality,
105+
// which allows the hub cluster to access the managed cluster's API server through
106+
// a gRPC-based proxy tunnel established by the klusterlet agent.
107+
//
108+
// When configured, the klusterlet agent establishes a gRPC connection to the hub's
109+
// proxy server and proxies incoming HTTP requests to the local managed cluster API server.
110+
// This enables hub-to-spoke API access even when the managed cluster is not directly
111+
// accessible from the hub (e.g., behind a firewall or NAT).
112+
//
113+
// This feature requires the ClusterProxy feature gate to be enabled and corresponding
114+
// GRPCConfiguration to be set in the ClusterManager on the hub side.
115+
// +optional
116+
ProxyConfig *ProxyConfig `json:"proxyConfig,omitempty"`
103117
}
104118

105119
// ServerURL represents the apiserver url and ca bundle that is accessible externally
@@ -331,6 +345,22 @@ const (
331345
ClusterAnnotationsKeyPrefix = "agent.open-cluster-management.io"
332346
)
333347

348+
// ProxyConfig holds the configuration of klusterlet-proxy.
349+
type ProxyConfig struct {
350+
GRPC *EndpointExposure `json:"grpcEndpoint"`
351+
352+
// Authentications defines how the agent authenticates with the cluster.
353+
// By default it is `userToken`, but it could also be `impersonation` or both.
354+
Authentications []ProxyAuthenticationType `json:"authentications,omitempty"`
355+
}
356+
357+
type ProxyAuthenticationType string
358+
359+
const (
360+
ProxyAuthenticationUserToken ProxyAuthenticationType = "userToken"
361+
ProxyAuthenticationImpersonation ProxyAuthenticationType = "impersonation"
362+
)
363+
334364
// KlusterletDeployOption describes the deployment options for klusterlet
335365
type KlusterletDeployOption struct {
336366
// Mode can be Default, Hosted, Singleton or SingletonHosted. It is Default mode if not specified

operator/v1/zz_generated.deepcopy.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)