feat: add private nodes support via networkConfig#149
Closed
pedro-tamandua wants to merge 1 commit intocloudpilot-ai:mainfrom
Closed
feat: add private nodes support via networkConfig#149pedro-tamandua wants to merge 1 commit intocloudpilot-ai:mainfrom
pedro-tamandua wants to merge 1 commit intocloudpilot-ai:mainfrom
Conversation
Contributor
|
Thanks to your contribution, the maintainers will review it as soon as they can! |
Contributor
|
The release note is either empty or incomplete, please consider: |
09d35f2 to
015529a
Compare
Contributor
|
Hi, @pedro-tamandua thanks for your contribution, can you help fix the DCO workflow? |
Add NetworkConfig to GCENodeClass spec to control external IP allocation and subnet selection for provisioned nodes. Features: - Add NetworkConfig struct with enableExternalIPAccess and subnetwork fields - Implement resolveAccessConfigs() to conditionally disable external IPs - Implement resolveSubnetwork() to allow custom subnet configuration - Update CRD with new networkConfig fields - Simplify CRD validation rules to meet Kubernetes cost limits - Add unit tests for network configuration resolution - Add example manifests for private nodes and custom subnets When enableExternalIPAccess is false, nodes are provisioned without external IP addresses (private nodes), improving security posture. Backward compatible: defaults to existing behavior when networkConfig is not specified. RELEASE NOTE: Add support for private nodes via networkConfig in GCENodeClass to improve security by allowing nodes to be provisioned without external IP addresses. Users can now configure enableExternalIPAccess and subnetwork fields to control network settings. Signed-off-by: pedro-tamandua <[email protected]>
015529a to
170b1ad
Compare
Contributor
Author
|
DCO workflow fixed. |
jwcesign
reviewed
Nov 13, 2025
Contributor
jwcesign
left a comment
There was a problem hiding this comment.
Thanks @pedro-tamandua
Other lgtm
| NetworkTags []string `json:"networkTags,omitempty"` | ||
| // NetworkConfig specifies network configuration for instances | ||
| // +optional | ||
| NetworkConfig *NetworkConfig `json:"networkConfig,omitempty"` |
Contributor
There was a problem hiding this comment.
- Put NetworkTags into NetworkConfig field
- It could have multiple network interface, so,
EnableExternalIPAccessandSubnetworkshould be array list. Something like:
type xxx struct {
..
NetworkConfig NetworkConfig
}
type NetworkConfig {
Tags []string
NetworkInterfaces []NetworkInterface
}
type NetworkInterface {
EnableExternalIPAccess bool
Subnetwork string
}
dm3ch
added a commit
to dm3ch/karpenter-provider-gcp
that referenced
this pull request
Mar 28, 2026
…odes) Add NetworkConfig to GCENodeClassSpec to allow overriding per-network-interface settings on provisioned nodes. The primary use case is private nodes: setting enableExternalIPAccess: false on the primary interface removes the AccessConfig entry, resulting in a node with no external (public) IP address. - New NetworkConfig struct with NetworkInterfaces []NetworkInterface field - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces are matched to node pool template by position (index) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes cloudpilot-ai#149 Co-Authored-By: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]>
dm3ch
added a commit
to dm3ch/karpenter-provider-gcp
that referenced
this pull request
Mar 28, 2026
…odes) Redesign and complete the initial approach from pedro-tamandua (cloudpilot-ai#149): the original concept had a flat NetworkConfig (single enableExternalIPAccess + subnetwork), this rework promotes it to a per-interface list so multiple NICs on multi-homed nodes can each be controlled independently. Changes: - New NetworkConfig struct with NetworkInterfaces []NetworkInterface - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces matched to node pool template by position (index) - Deep-copy AccessConfigs on each interface to prevent template mutation - Force-send empty AccessConfigs slice when disabling external IP so the GCP API does not default-insert ONE_TO_ONE_NAT (was silent security gap) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes cloudpilot-ai#182 Based on initial work by @pedro-tamandua: cloudpilot-ai#149 Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]>
dm3ch
added a commit
to dm3ch/karpenter-provider-gcp
that referenced
this pull request
Apr 1, 2026
…odes) Redesign and complete the initial approach from pedro-tamandua (cloudpilot-ai#149): the original concept had a flat NetworkConfig (single enableExternalIPAccess + subnetwork), this rework promotes it to a per-interface list so multiple NICs on multi-homed nodes can each be controlled independently. Changes: - New NetworkConfig struct with NetworkInterfaces []NetworkInterface - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces matched to node pool template by position (index) - Deep-copy AccessConfigs on each interface to prevent template mutation - Force-send empty AccessConfigs slice when disabling external IP so the GCP API does not default-insert ONE_TO_ONE_NAT (was silent security gap) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes cloudpilot-ai#182 Based on initial work by @pedro-tamandua: cloudpilot-ai#149 Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]>
dm3ch
added a commit
to dm3ch/karpenter-provider-gcp
that referenced
this pull request
Apr 2, 2026
…odes) Redesign and complete the initial approach from pedro-tamandua (cloudpilot-ai#149): the original concept had a flat NetworkConfig (single enableExternalIPAccess + subnetwork), this rework promotes it to a per-interface list so multiple NICs on multi-homed nodes can each be controlled independently. Changes: - New NetworkConfig struct with NetworkInterfaces []NetworkInterface - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces matched to node pool template by position (index) - Deep-copy AccessConfigs on each interface to prevent template mutation - Force-send empty AccessConfigs slice when disabling external IP so the GCP API does not default-insert ONE_TO_ONE_NAT (was silent security gap) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes cloudpilot-ai#182 Based on initial work by @pedro-tamandua: cloudpilot-ai#149 Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]>
dm3ch
added a commit
to dm3ch/karpenter-provider-gcp
that referenced
this pull request
Apr 9, 2026
…odes) Redesign and complete the initial approach from pedro-tamandua (cloudpilot-ai#149): the original concept had a flat NetworkConfig (single enableExternalIPAccess + subnetwork), this rework promotes it to a per-interface list so multiple NICs on multi-homed nodes can each be controlled independently. Changes: - New NetworkConfig struct with NetworkInterfaces []NetworkInterface - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces matched to node pool template by position (index) - Deep-copy AccessConfigs on each interface to prevent template mutation - Force-send empty AccessConfigs slice when disabling external IP so the GCP API does not default-insert ONE_TO_ONE_NAT (was silent security gap) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes cloudpilot-ai#182 Based on initial work by @pedro-tamandua: cloudpilot-ai#149 Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]>
dm3ch
added a commit
to dm3ch/karpenter-provider-gcp
that referenced
this pull request
Apr 9, 2026
…odes) Redesign and complete the initial approach from pedro-tamandua (cloudpilot-ai#149): the original concept had a flat NetworkConfig (single enableExternalIPAccess + subnetwork), this rework promotes it to a per-interface list so multiple NICs on multi-homed nodes can each be controlled independently. Changes: - New NetworkConfig struct with NetworkInterfaces []NetworkInterface - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces matched to node pool template by position (index) - Deep-copy AccessConfigs on each interface to prevent template mutation - Force-send empty AccessConfigs slice when disabling external IP so the GCP API does not default-insert ONE_TO_ONE_NAT (was silent security gap) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes cloudpilot-ai#182 Based on initial work by @pedro-tamandua: cloudpilot-ai#149 Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]>
thameezb
pushed a commit
to dm3ch/karpenter-provider-gcp
that referenced
this pull request
Apr 11, 2026
…odes) Redesign and complete the initial approach from pedro-tamandua (cloudpilot-ai#149): the original concept had a flat NetworkConfig (single enableExternalIPAccess + subnetwork), this rework promotes it to a per-interface list so multiple NICs on multi-homed nodes can each be controlled independently. Changes: - New NetworkConfig struct with NetworkInterfaces []NetworkInterface - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces matched to node pool template by position (index) - Deep-copy AccessConfigs on each interface to prevent template mutation - Force-send empty AccessConfigs slice when disabling external IP so the GCP API does not default-insert ONE_TO_ONE_NAT (was silent security gap) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes cloudpilot-ai#182 Based on initial work by @pedro-tamandua: cloudpilot-ai#149 Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]>
thameezb
pushed a commit
that referenced
this pull request
Apr 12, 2026
…odes) (#229) * feat: add NetworkConfig for per-interface network settings (private nodes) Redesign and complete the initial approach from pedro-tamandua (#149): the original concept had a flat NetworkConfig (single enableExternalIPAccess + subnetwork), this rework promotes it to a per-interface list so multiple NICs on multi-homed nodes can each be controlled independently. Changes: - New NetworkConfig struct with NetworkInterfaces []NetworkInterface - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces matched to node pool template by position (index) - Deep-copy AccessConfigs on each interface to prevent template mutation - Force-send empty AccessConfigs slice when disabling external IP so the GCP API does not default-insert ONE_TO_ONE_NAT (was silent security gap) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes #182 Based on initial work by @pedro-tamandua: #149 Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]> * review: fix ForceSendFields/NullFields slice aliasing and test gaps Address findings from code review of the NetworkConfig PR: - Remove no-op []*compute.AccessConfig(...) type conversion - Always copy ForceSendFields and NullFields from the template interface rather than aliasing the backing array; prevents latent mutation if a template cache is ever introduced - Rename shadowed `t` variable in makeTemplateWithAccessConfig closure - Add ForceSendFields mutation-safety assertion to the private-node test - Add missing test for the lo.Contains deduplication branch (template already carries "AccessConfigs" in ForceSendFields) - Tighten NetworkInterface doc comments: consolidate repeated index- matching prose and rewrite EnableExternalIPAccess to lead with its asymmetric semantics (only false acts; true/nil both inherit) Co-Authored-By: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]> * review: de-AI pass and regenerate CRDs - Remove duplicate "matched by index" sentence from GCENodeClassSpec.NetworkConfig field comment (already stated on NetworkInterfaces); trim to single purpose line - Rename accessConfigsCount → count in deduplication test (trivially-scoped counter) - Regenerate CRD yaml and deepcopy with updated comments (make update) Co-Authored-By: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]> * docs: expand NetworkConfig examples with prerequisites and subnetwork override - private-nodes-gcenodeclass.yaml: add background section explaining that Karpenter manages the karpenter-default/ubuntu node pool templates and inherits the cluster's default network config; add Cloud NAT, VPC-native cluster, and firewall prerequisites; note behaviour on fully-private clusters - subnetwork-override-gcenodeclass.yaml: new example showing how to place Karpenter nodes in a specific subnetwork via networkConfig.networkInterfaces Co-Authored-By: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]> * docs: add private-nodes.md covering cluster modes, prerequisites, and NetworkConfig Explains the full picture that was previously only in YAML comments: - How Karpenter creates and uses karpenter-default/ubuntu node pool templates - Fully-private clusters work transparently (GKE handles enablePrivateNodes) - When to use enableExternalIPAccess: false (standard cluster, selective privacy) - Cloud NAT, VPC-native, and IAP prerequisites - Subnetwork override usage and URL format - Multi-interface configuration - Why networkTags is top-level (GCP Instance vs NetworkInterface API design) Co-Authored-By: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]> * docs: retract unverified claim about fully-private cluster support The karpenter-default node pool template is created without setting NodePool.NetworkConfig.EnablePrivateNodes. Behaviour on clusters with enablePrivateNodes at the cluster level is untested — replace the confident "works transparently" claim with an honest note and a recommendation to set enableExternalIPAccess: false explicitly regardless. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]> * docs: update private-nodes issue link from #TODO to #230 Co-Authored-By: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]> --------- Signed-off-by: Dmitry Chepurovskiy <[email protected]> Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]>
Collaborator
|
Closing this as it was done in #229 . |
dm3ch
added a commit
to dm3ch/karpenter-provider-gcp
that referenced
this pull request
Apr 12, 2026
…odes) Redesign and complete the initial approach from pedro-tamandua (cloudpilot-ai#149): the original concept had a flat NetworkConfig (single enableExternalIPAccess + subnetwork), this rework promotes it to a per-interface list so multiple NICs on multi-homed nodes can each be controlled independently. Changes: - New NetworkConfig struct with NetworkInterfaces []NetworkInterface - NetworkInterface supports enableExternalIPAccess (*bool) and subnetwork (string) - Interfaces matched to node pool template by position (index) - Deep-copy AccessConfigs on each interface to prevent template mutation - Force-send empty AccessConfigs slice when disabling external IP so the GCP API does not default-insert ONE_TO_ONE_NAT (was silent security gap) - Unset fields inherit from the node pool template (backward compatible) - Updated CRD and deepcopy; added tests and example YAML Closes cloudpilot-ai#182 Based on initial work by @pedro-tamandua: cloudpilot-ai#149 Co-authored-by: pedro-tamandua <[email protected]> Co-authored-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Dmitry Chepurovskiy <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Add NetworkConfig to GCENodeClass spec to control external IP allocation and subnet selection for provisioned nodes.
Features:
When enableExternalIPAccess is false, nodes are provisioned without external IP addresses (private nodes), improving security posture.
Usage Example
apiVersion: karpenter.k8s.gcp/v1alpha1
kind: GCENodeClass
metadata:
name: private-nodes
spec:
networkConfig:
enableExternalIPAccess: false
imageSelectorTerms:
- alias: ContainerOptimizedOS@latest## Testing
resolveAccessConfigsandresolveSubnetworkBackward Compatibility
Fully backward compatible. When
networkConfigis not specified, behavior remains unchanged (nodes get external IPs by default).