Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/kubeadm 594 etcd TLS on init/upgrade #57415

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
obj.AuthorizationModes = []string{"foo"}
obj.CertificatesDir = "foo"
obj.APIServerCertSANs = []string{"foo"}
obj.Etcd.ServerCertSANs = []string{"foo"}
obj.Etcd.PeerCertSANs = []string{"foo"}
obj.Token = "foo"
obj.CRISocket = "foo"
obj.Etcd.Image = "foo"
Expand Down
6 changes: 6 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ type Etcd struct {
Image string
// SelfHosted holds configuration for self-hosting etcd.
SelfHosted *SelfHostedEtcd
// ServerCertSANs sets extra Subject Alternative Names for the etcd server
// signing cert. This is currently used for the etcd static-pod.
ServerCertSANs []string
// PeerCertSANs sets extra Subject Alternative Names for the etcd peer
// signing cert. This is currently used for the etcd static-pod.
PeerCertSANs []string
}

// SelfHostedEtcd describes options required to configure self-hosted etcd.
Expand Down
4 changes: 4 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ type Etcd struct {
Image string `json:"image"`
// SelfHosted holds configuration for self-hosting etcd.
SelfHosted *SelfHostedEtcd `json:"selfHosted,omitempty"`
// ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert.
ServerCertSANs []string `json:"serverCertSANs,omitempty"`
// PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert.
PeerCertSANs []string `json:"peerCertSANs,omitempty"`
}

// SelfHostedEtcd describes options required to configure self-hosted etcd.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions cmd/kubeadm/app/apis/kubeadm/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList
allErrs = append(allErrs, ValidateCloudProvider(c.CloudProvider, field.NewPath("cloudprovider"))...)
allErrs = append(allErrs, ValidateAuthorizationModes(c.AuthorizationModes, field.NewPath("authorization-modes"))...)
allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...)
allErrs = append(allErrs, ValidateCertSANs(c.APIServerCertSANs, field.NewPath("api-server-cert-altnames"))...)
allErrs = append(allErrs, ValidateCertSANs(c.Etcd.ServerCertSANs, field.NewPath("etcd-server-cert-altnames"))...)
allErrs = append(allErrs, ValidateCertSANs(c.Etcd.PeerCertSANs, field.NewPath("etcd-peer-cert-altnames"))...)
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificates-dir"))...)
allErrs = append(allErrs, ValidateNodeName(c.NodeName, field.NewPath("node-name"))...)
allErrs = append(allErrs, ValidateToken(c.Token, field.NewPath("token"))...)
Expand Down Expand Up @@ -228,8 +230,8 @@ func ValidateToken(t string, fldPath *field.Path) field.ErrorList {
return allErrs
}

// ValidateAPIServerCertSANs validates alternative names
func ValidateAPIServerCertSANs(altnames []string, fldPath *field.Path) field.ErrorList {
// ValidateCertSANs validates alternative names
func ValidateCertSANs(altnames []string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for _, altname := range altnames {
if len(validation.IsDNS1123Subdomain(altname)) != 0 && net.ParseIP(altname) == nil {
Expand Down
6 changes: 3 additions & 3 deletions cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func TestValidateCloudProvider(t *testing.T) {
}
}

func TestValidateAPIServerCertSANs(t *testing.T) {
func TestValidateCertSANs(t *testing.T) {
var tests = []struct {
sans []string
expected bool
Expand All @@ -148,10 +148,10 @@ func TestValidateAPIServerCertSANs(t *testing.T) {
{[]string{"my-hostname2", "my.other.subdomain", "2001:db8::10"}, true}, // supported
}
for _, rt := range tests {
actual := ValidateAPIServerCertSANs(rt.sans, nil)
actual := ValidateCertSANs(rt.sans, nil)
if (len(actual) == 0) != rt.expected {
t.Errorf(
"failed ValidateAPIServerCertSANs:\n\texpected: %t\n\t actual: %t",
"failed ValidateCertSANs:\n\texpected: %t\n\t actual: %t",
rt.expected,
(len(actual) == 0),
)
Expand Down
10 changes: 10 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 45 additions & 2 deletions cmd/kubeadm/app/cmd/phases/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ var (
apiServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Generates the API server serving certificate and key and saves them into %s and %s files.

The certificate includes default subject alternative names and additional sans eventually provided by the user;
default sans are: <node-name>, <apiserver-advertise-address>, kubernetes, kubernetes.default, kubernetes.default.svc,
The certificate includes default subject alternative names and additional SANs provided by the user;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe capitalize Subject Alternative Names so that it's more clear that SAN (used later) is abbreviating that (applies below too).

default SANs are: <node-name>, <apiserver-advertise-address>, kubernetes, kubernetes.default, kubernetes.default.svc,
kubernetes.default.svc.<service-dns-domain>, <internalAPIServerVirtualIP> (that is the .10 address in <service-cidr> address space).

If both files already exist, kubeadm skips the generation step and existing files will be used.
Expand All @@ -74,6 +74,31 @@ var (
If both files already exist, kubeadm skips the generation step and existing files will be used.
`+cmdutil.AlphaDisclaimer), kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName)

etcdServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Generates the etcd serving certificate and key and saves them into %s and %s files.

The certificate includes default subject alternative names and additional SANs provided by the user;
default SANs are: localhost, 127.0.0.1.

If both files already exist, kubeadm skips the generation step and existing files will be used.
`+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName)

etcdPeerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Generates the etcd peer certificate and key and saves them into %s and %s files.

The certificate includes default subject alternative names and additional SANs provided by the user;
default SANs are: <node-name>, <apiserver-advertise-address>.

If both files already exist, kubeadm skips the generation step and existing files will be used.
`+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName)

apiServerEtcdServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Generates the client certificate for the API server to connect to etcd securely and the respective key,
and saves them into %s and %s files.

If both files already exist, kubeadm skips the generation step and existing files will be used.
`+cmdutil.AlphaDisclaimer), kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName)

saKeyLongDesc = fmt.Sprintf(normalizer.LongDesc(`
Generates the private key for signing service account tokens along with its public key, and saves them into
%s and %s files.
Expand Down Expand Up @@ -157,6 +182,24 @@ func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command {
long: apiServerKubeletCertLongDesc,
cmdFunc: certsphase.CreateAPIServerKubeletClientCertAndKeyFiles,
},
{
use: "etcd-server",
short: "Generates etcd serving certificate and key",
long: etcdServerCertLongDesc,
cmdFunc: certsphase.CreateEtcdServerCertAndKeyFiles,
},
{
use: "etcd-peer",
short: "Generates etcd peer certificate and key",
long: etcdPeerCertLongDesc,
cmdFunc: certsphase.CreateEtcdPeerCertAndKeyFiles,
},
{
use: "apiserver-etcd-client",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

etcd-client-cert?

Copy link
Member Author

@stealthybox stealthybox Feb 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this match phase certs apiserver-kubelet-client.
This naming emphasizes it's an apiserver cert.

Do we want to flip this around?
We can but it won't match the other example of this relationship.
Phases are alpha, so we can also change the apiserver-kubelet-client cert command.

short: "Generates client certificate for the API server to connect to etcd securely",
long: apiServerEtcdServerCertLongDesc,
cmdFunc: certsphase.CreateAPIServerEtcdClientCertAndKeyFiles,
},
{
use: "sa",
short: "Generates a private key for signing service account tokens along with its public key",
Expand Down
27 changes: 27 additions & 0 deletions cmd/kubeadm/app/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,33 @@ const (
// APIServerKubeletClientCertCommonName defines kubelet client certificate common name (CN)
APIServerKubeletClientCertCommonName = "kube-apiserver-kubelet-client"

// EtcdServerCertAndKeyBaseName defines etcd's server certificate and key base name
EtcdServerCertAndKeyBaseName = "etcd/server"
// EtcdServerCertName defines etcd's server certificate name
EtcdServerCertName = "etcd/server.crt"
// EtcdServerKeyName defines etcd's server key name
EtcdServerKeyName = "etcd/server.key"
// EtcdServerCertCommonName defines etcd's server certificate common name (CN)
EtcdServerCertCommonName = "kube-etcd"

// EtcdPeerCertAndKeyBaseName defines etcd's peer certificate and key base name
EtcdPeerCertAndKeyBaseName = "etcd/peer"
// EtcdPeerCertName defines etcd's peer certificate name
EtcdPeerCertName = "etcd/peer.crt"
// EtcdPeerKeyName defines etcd's peer key name
EtcdPeerKeyName = "etcd/peer.key"
// EtcdPeerCertCommonName defines etcd's peer certificate common name (CN)
EtcdPeerCertCommonName = "kube-etcd-peer"

// APIServerEtcdClientCertAndKeyBaseName defines etcd client certificate and key base name
APIServerEtcdClientCertAndKeyBaseName = "apiserver-etcd-client"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just client.crt? Then multiple clients can re-use

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not positive we should generalize the usage of a cert that allows access to the cluster's data.

Copy link
Member Author

@stealthybox stealthybox Jan 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how's etcd/client-apiserver ?

edit: I ended up not nesting this client cert under the new etcd/ subdir.

// APIServerEtcdClientCertName defines etcd client certificate name
APIServerEtcdClientCertName = "apiserver-etcd-client.crt"
// APIServerEtcdClientKeyName defines etcd client key name
APIServerEtcdClientKeyName = "apiserver-etcd-client.key"
// APIServerEtcdClientCertCommonName defines etcd client certificate common name (CN)
APIServerEtcdClientCertCommonName = "kube-apiserver-etcd-client"

// ServiceAccountKeyBaseName defines SA key base name
ServiceAccountKeyBaseName = "sa"
// ServiceAccountPublicKeyName defines SA public key base name
Expand Down
2 changes: 0 additions & 2 deletions cmd/kubeadm/app/phases/certs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ go_library(
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//pkg/registry/core/service/ipallocator:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//vendor/k8s.io/client-go/util/cert:go_default_library",
],
)
Expand Down
Loading