kubelet request certificates if at least one IP exist
A Kubernetes Node requires to have at minimum one IP address because those are used on the Pods field HostIPs and in some cases, when pods uses hostNetwork: true, as PodIPs. Nodes that use IP addresses as Hostname are interpreted as an IP address, so it is possible that are nodes that don't hane any DNSname. The feature gate AllowDNSOnlyNodeCSR will allow user to opt-in for the old behavior. Change-Id: I094531d87246f1e7a5ef4fe57bd5d9840cb1375d
This commit is contained in:
@@ -19,6 +19,8 @@ package certificate
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@@ -28,8 +30,12 @@ import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/util/cert"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
@@ -261,3 +267,142 @@ func TestKubeletServerCertificateFromFiles(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewCertificateManagerConfigGetTemplate(t *testing.T) {
|
||||
nodeName := "fake-node"
|
||||
nodeIP := netutils.ParseIPSloppy("192.168.1.1")
|
||||
tests := []struct {
|
||||
name string
|
||||
nodeAddresses []v1.NodeAddress
|
||||
want *x509.CertificateRequest
|
||||
featuregate bool
|
||||
}{
|
||||
{
|
||||
name: "node addresses or hostnames and gate enabled",
|
||||
featuregate: true,
|
||||
},
|
||||
{
|
||||
name: "node addresses or hostnames and gate disabled",
|
||||
featuregate: false,
|
||||
},
|
||||
{
|
||||
name: "only hostnames and gate enabled",
|
||||
nodeAddresses: []v1.NodeAddress{
|
||||
{
|
||||
Type: v1.NodeHostName,
|
||||
Address: nodeName,
|
||||
},
|
||||
},
|
||||
want: &x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("system:node:%s", nodeName),
|
||||
Organization: []string{"system:nodes"},
|
||||
},
|
||||
DNSNames: []string{nodeName},
|
||||
},
|
||||
featuregate: true,
|
||||
},
|
||||
{
|
||||
name: "only hostnames and gate disabled",
|
||||
nodeAddresses: []v1.NodeAddress{
|
||||
{
|
||||
Type: v1.NodeHostName,
|
||||
Address: nodeName,
|
||||
},
|
||||
},
|
||||
featuregate: false,
|
||||
},
|
||||
{
|
||||
name: "only IP addresses and gate enabled",
|
||||
nodeAddresses: []v1.NodeAddress{
|
||||
{
|
||||
Type: v1.NodeInternalIP,
|
||||
Address: nodeIP.String(),
|
||||
},
|
||||
},
|
||||
want: &x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("system:node:%s", nodeName),
|
||||
Organization: []string{"system:nodes"},
|
||||
},
|
||||
IPAddresses: []net.IP{nodeIP},
|
||||
},
|
||||
featuregate: true,
|
||||
},
|
||||
{
|
||||
name: "only IP addresses and gate disabled",
|
||||
nodeAddresses: []v1.NodeAddress{
|
||||
{
|
||||
Type: v1.NodeInternalIP,
|
||||
Address: nodeIP.String(),
|
||||
},
|
||||
},
|
||||
want: &x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("system:node:%s", nodeName),
|
||||
Organization: []string{"system:nodes"},
|
||||
},
|
||||
IPAddresses: []net.IP{nodeIP},
|
||||
},
|
||||
featuregate: false,
|
||||
},
|
||||
{
|
||||
name: "IP addresses and hostnames and gate enabled",
|
||||
nodeAddresses: []v1.NodeAddress{
|
||||
{
|
||||
Type: v1.NodeHostName,
|
||||
Address: nodeName,
|
||||
},
|
||||
{
|
||||
Type: v1.NodeInternalIP,
|
||||
Address: nodeIP.String(),
|
||||
},
|
||||
},
|
||||
want: &x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("system:node:%s", nodeName),
|
||||
Organization: []string{"system:nodes"},
|
||||
},
|
||||
DNSNames: []string{nodeName},
|
||||
IPAddresses: []net.IP{nodeIP},
|
||||
},
|
||||
featuregate: true,
|
||||
},
|
||||
{
|
||||
name: "IP addresses and hostnames and gate disabled",
|
||||
nodeAddresses: []v1.NodeAddress{
|
||||
{
|
||||
Type: v1.NodeHostName,
|
||||
Address: nodeName,
|
||||
},
|
||||
{
|
||||
Type: v1.NodeInternalIP,
|
||||
Address: nodeIP.String(),
|
||||
},
|
||||
},
|
||||
want: &x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("system:node:%s", nodeName),
|
||||
Organization: []string{"system:nodes"},
|
||||
},
|
||||
DNSNames: []string{nodeName},
|
||||
IPAddresses: []net.IP{nodeIP},
|
||||
},
|
||||
featuregate: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AllowDNSOnlyNodeCSR, tt.featuregate)
|
||||
getAddresses := func() []v1.NodeAddress {
|
||||
return tt.nodeAddresses
|
||||
}
|
||||
getTemplate := newGetTemplateFn(types.NodeName(nodeName), getAddresses)
|
||||
got := getTemplate()
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Wrong certificate, got %v expected %v", got, tt.want)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user