Skip to content

Commit e8a49ae

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

File tree

4 files changed

+197
-0
lines changed

4 files changed

+197
-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: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,112 @@ 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+
default:
200+
- userToken
201+
description: |-
202+
Authentications defines how the agent authenticates with the cluster.
203+
If not specified, defaults to ["userToken"].
204+
items:
205+
enum:
206+
- userToken
207+
- impersonation
208+
type: string
209+
type: array
210+
grpcEndpoint:
211+
description: GRPCEndpoint represents the gRPC endpoint configuration
212+
for the proxy connection.
213+
properties:
214+
grpc:
215+
description: grpc represents the configuration for grpc endpoint.
216+
properties:
217+
hostname:
218+
description: hostname points to a fixed hostname for serving
219+
agents' handshakes.
220+
properties:
221+
caBundle:
222+
description: caBundle of the endpoint.
223+
format: byte
224+
type: string
225+
host:
226+
description: host is the host name of the endpoint.
227+
type: string
228+
required:
229+
- host
230+
type: object
231+
type:
232+
default: hostname
233+
description: |-
234+
type specifies how the endpoint is exposed.
235+
You may need to apply an object to expose the endpoint, for example: a route.
236+
enum:
237+
- hostname
238+
type: string
239+
required:
240+
- type
241+
type: object
242+
https:
243+
description: https represents the configuration for https
244+
endpoint.
245+
properties:
246+
hostname:
247+
description: hostname points to a fixed hostname for serving
248+
agents' handshakes.
249+
properties:
250+
caBundle:
251+
description: caBundle of the endpoint.
252+
format: byte
253+
type: string
254+
host:
255+
description: host is the host name of the endpoint.
256+
type: string
257+
required:
258+
- host
259+
type: object
260+
type:
261+
default: hostname
262+
description: |-
263+
type specifies how the endpoint is exposed.
264+
You may need to apply an object to expose the endpoint, for example: a route.
265+
enum:
266+
- hostname
267+
type: string
268+
required:
269+
- type
270+
type: object
271+
protocol:
272+
default: grpc
273+
description: protocol is the protocol used for the endpoint,
274+
could be https or grpc.
275+
enum:
276+
- grpc
277+
- https
278+
type: string
279+
usage:
280+
description: |-
281+
usage defines the usage of the endpoint. It could be "agentToHub" indicating the endpoint is used
282+
for communication between agent and hub, or "consumer" indicating the endpoint is used for external consumer.
283+
type: string
284+
required:
285+
- protocol
286+
type: object
287+
required:
288+
- grpcEndpoint
289+
type: object
184290
registrationConfiguration:
185291
description: RegistrationConfiguration contains the configuration
186292
of registration

operator/v1/types_klusterlet.go

Lines changed: 36 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,28 @@ const (
331345
ClusterAnnotationsKeyPrefix = "agent.open-cluster-management.io"
332346
)
333347

348+
// ProxyConfig holds the configuration of klusterlet-proxy.
349+
type ProxyConfig struct {
350+
// GRPCEndpoint represents the gRPC endpoint configuration for the proxy connection.
351+
// +required
352+
// +kubebuilder:validation:Required
353+
GRPCEndpoint *EndpointExposure `json:"grpcEndpoint"`
354+
355+
// Authentications defines how the agent authenticates with the cluster.
356+
// If not specified, defaults to ["userToken"].
357+
// +optional
358+
// +kubebuilder:default={userToken}
359+
Authentications []ProxyAuthenticationType `json:"authentications,omitempty"`
360+
}
361+
362+
// +kubebuilder:validation:Enum=userToken;impersonation
363+
type ProxyAuthenticationType string
364+
365+
const (
366+
ProxyAuthenticationUserToken ProxyAuthenticationType = "userToken"
367+
ProxyAuthenticationImpersonation ProxyAuthenticationType = "impersonation"
368+
)
369+
334370
// KlusterletDeployOption describes the deployment options for klusterlet
335371
type KlusterletDeployOption struct {
336372
// 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)