mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-13 11:25:19 +00:00
Merge pull request #58052 from m1093782566/nodeip-config
Automatic merge from submit-queue (batch tested with PRs 60430, 60115, 58052, 60355, 60116). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Make nodeport ip configurable **What this PR does / why we need it**: By default, kube-proxy accepts everything from NodePort without any filter. It can be a problem for nodes which has both public and private NICs, and people only want to provide a service in private network and avoid exposing any internal service on the public IPs. This PR makes nodeport ip configurable. **Which issue(s) this PR fixes**: Closes: #21070 **Special notes for your reviewer**: Design proposal see: https://github.com/kubernetes/community/pull/1547 Issue in feature repo: https://github.com/kubernetes/features/issues/539 **Release note**: ```release-note Make NodePort IP addresses configurable ```
This commit is contained in:
@@ -44,7 +44,9 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
obj.IPTables.MasqueradeBit = utilpointer.Int32Ptr(c.Int31())
|
||||
obj.MetricsBindAddress = fmt.Sprintf("%d.%d.%d.%d:%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(65536))
|
||||
obj.OOMScoreAdj = utilpointer.Int32Ptr(c.Int31())
|
||||
obj.ResourceContainer = c.RandString()
|
||||
obj.ResourceContainer = "foo"
|
||||
obj.ClientConnection.ContentType = "bar"
|
||||
obj.NodePortAddresses = []string{"1.2.3.0/24"}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,14 @@ type KubeProxyConfiguration struct {
|
||||
// configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater
|
||||
// than 0.
|
||||
ConfigSyncPeriod metav1.Duration
|
||||
// nodePortAddresses is the --nodeport-addresses value for kube-proxy process. Values must be valid
|
||||
// IP blocks. These values are as a parameter to select the interfaces where nodeport works.
|
||||
// In case someone would like to expose a service on localhost for local visit and some other interfaces for
|
||||
// particular purpose, a list of IP blocks would do that.
|
||||
// If set it to "127.0.0.0/8", kube-proxy will only select the loopback interface for NodePort.
|
||||
// If set it to a non-zero IP block, kube-proxy will filter that down to just the IPs that applied to the node.
|
||||
// An empty string slice is meant to select all network interfaces.
|
||||
NodePortAddresses []string
|
||||
}
|
||||
|
||||
// Currently, three modes of proxy are available in Linux platform: 'userspace' (older, going to be EOL), 'iptables'
|
||||
|
||||
@@ -140,6 +140,14 @@ type KubeProxyConfiguration struct {
|
||||
// configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater
|
||||
// than 0.
|
||||
ConfigSyncPeriod metav1.Duration `json:"configSyncPeriod"`
|
||||
// nodePortAddresses is the --nodeport-addresses value for kube-proxy process. Values must be valid
|
||||
// IP blocks. These values are as a parameter to select the interfaces where nodeport works.
|
||||
// In case someone would like to expose a service on localhost for local visit and some other interfaces for
|
||||
// particular purpose, a list of IP blocks would do that.
|
||||
// If set it to "127.0.0.0/8", kube-proxy will only select the loopback interface for NodePort.
|
||||
// If set it to a non-zero IP block, kube-proxy will filter that down to just the IPs that applied to the node.
|
||||
// An empty string slice is meant to select all network interfaces.
|
||||
NodePortAddresses []string `json:"nodePortAddresses"`
|
||||
}
|
||||
|
||||
// Currently, three modes of proxy are available in Linux platform: 'userspace' (older, going to be EOL), 'iptables'
|
||||
|
||||
@@ -104,6 +104,7 @@ func autoConvert_v1alpha1_KubeProxyConfiguration_To_kubeproxyconfig_KubeProxyCon
|
||||
return err
|
||||
}
|
||||
out.ConfigSyncPeriod = in.ConfigSyncPeriod
|
||||
out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -138,6 +139,7 @@ func autoConvert_kubeproxyconfig_KubeProxyConfiguration_To_v1alpha1_KubeProxyCon
|
||||
return err
|
||||
}
|
||||
out.ConfigSyncPeriod = in.ConfigSyncPeriod
|
||||
out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,11 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
|
||||
out.UDPIdleTimeout = in.UDPIdleTimeout
|
||||
in.Conntrack.DeepCopyInto(&out.Conntrack)
|
||||
out.ConfigSyncPeriod = in.ConfigSyncPeriod
|
||||
if in.NodePortAddresses != nil {
|
||||
in, out := &in.NodePortAddresses, &out.NodePortAddresses
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ func Validate(config *kubeproxyconfig.KubeProxyConfiguration) field.ErrorList {
|
||||
allErrs = append(allErrs, field.Invalid(newPath.Child("PortRange"), config.PortRange, "must be a valid port range (e.g. 300-2000)"))
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, validateKubeProxyNodePortAddress(config.NodePortAddresses, newPath.Child("NodePortAddresses"))...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@@ -238,3 +240,16 @@ func validateIPVSSchedulerMethod(scheduler kubeproxyconfig.IPVSSchedulerMethod,
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateKubeProxyNodePortAddress(nodePortAddresses []string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
for i := range nodePortAddresses {
|
||||
if _, _, err := net.ParseCIDR(nodePortAddresses[i]); err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, nodePortAddresses, "must be a valid IP block"))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@@ -679,3 +679,73 @@ func TestValidateIPVSSchedulerMethod(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateKubeProxyNodePortAddress(t *testing.T) {
|
||||
newPath := field.NewPath("KubeProxyConfiguration")
|
||||
|
||||
successCases := []struct {
|
||||
addresses []string
|
||||
}{
|
||||
{[]string{}},
|
||||
{[]string{"127.0.0.0/8"}},
|
||||
{[]string{"0.0.0.0/0"}},
|
||||
{[]string{"::/0"}},
|
||||
{[]string{"127.0.0.1/32", "1.2.3.0/24"}},
|
||||
{[]string{"127.0.0.0/8"}},
|
||||
{[]string{"127.0.0.1/32"}},
|
||||
{[]string{"::1/128"}},
|
||||
{[]string{"1.2.3.4/32"}},
|
||||
{[]string{"10.20.30.0/24"}},
|
||||
{[]string{"10.20.0.0/16", "100.200.0.0/16"}},
|
||||
{[]string{"10.0.0.0/8"}},
|
||||
{[]string{"2001:db8::/32"}},
|
||||
}
|
||||
|
||||
for _, successCase := range successCases {
|
||||
if errs := validateKubeProxyNodePortAddress(successCase.addresses, newPath.Child("NodePortAddresses")); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
errorCases := []struct {
|
||||
addresses []string
|
||||
msg string
|
||||
}{
|
||||
{
|
||||
addresses: []string{"foo"},
|
||||
msg: "must be a valid IP block",
|
||||
},
|
||||
{
|
||||
addresses: []string{"1.2.3"},
|
||||
msg: "must be a valid IP block",
|
||||
},
|
||||
{
|
||||
addresses: []string{""},
|
||||
msg: "must be a valid IP block",
|
||||
},
|
||||
{
|
||||
addresses: []string{"10.20.30.40"},
|
||||
msg: "must be a valid IP block",
|
||||
},
|
||||
{
|
||||
addresses: []string{"::1"},
|
||||
msg: "must be a valid IP block",
|
||||
},
|
||||
{
|
||||
addresses: []string{"2001:db8:1"},
|
||||
msg: "must be a valid IP block",
|
||||
},
|
||||
{
|
||||
addresses: []string{"2001:db8:xyz/64"},
|
||||
msg: "must be a valid IP block",
|
||||
},
|
||||
}
|
||||
|
||||
for _, errorCase := range errorCases {
|
||||
if errs := validateKubeProxyNodePortAddress(errorCase.addresses, newPath.Child("NodePortAddresses")); len(errs) == 0 {
|
||||
t.Errorf("expected failure for %s", errorCase.msg)
|
||||
} else if !strings.Contains(errs[0].Error(), errorCase.msg) {
|
||||
t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,11 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
|
||||
out.UDPIdleTimeout = in.UDPIdleTimeout
|
||||
in.Conntrack.DeepCopyInto(&out.Conntrack)
|
||||
out.ConfigSyncPeriod = in.ConfigSyncPeriod
|
||||
if in.NodePortAddresses != nil {
|
||||
in, out := &in.NodePortAddresses, &out.NodePortAddresses
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user