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

Use keypair IDs for non-kops-controller-issued worker node certs #11998

Merged
merged 2 commits into from
Jul 16, 2021
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
13 changes: 9 additions & 4 deletions docs/operations/rotate-secrets.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

# How to rotate all secrets / credentials

There are two types of credentials managed by kOps:
Expand Down Expand Up @@ -71,11 +72,15 @@ Promote the new keypairs to primary with:
```shell
kops promote keypair all
kops update cluster --yes
kops rolling-update cluster --force --yes
kops rolling-update cluster --yes
```

As of the writing of this document, rolling-update will not necessarily identify all
relevant nodes as needing update, so should be invoked with the `--force` flag.
On cloud providers, such as AWS, that use kops-controller to bootstrap worker nodes, after
the `kops update cluster --yes` step there is a temporary impediment to node scale-up.
Instances using the new launch template will not be able to bootstrap off of old kops-controllers.
Similarly, instances using the old launch template and which have not yet bootstrapped will not
be able to bootstrap off of new kops-controllers. The subsequent rolling update will eventually
replace all instances using the old launch template.

#### Rollback procedure

Expand All @@ -89,7 +94,7 @@ To roll back this change:
most likely by identifying the issue dates.
* Then use `kops promote keypair` to promote each of them by keyset and ID.
* Then use `kops update cluster --yes`
* Then use `kops rolling-update cluster --force --yes`
* Then use `kops rolling-update cluster --yes`

### Export and distribute new kubeconfig admin credentials

Expand Down
42 changes: 20 additions & 22 deletions nodeup/pkg/model/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,26 @@ func (c *NodeupModelContext) BuildBootstrapKubeconfig(name string, ctx *fi.Model

return kubeConfig.GetConfig(), nil
} else {
cert, key, err := c.GetPrimaryKeypair(name)
keyset, err := c.KeyStore.FindKeyset(name)
if err != nil {
return nil, fmt.Errorf("error fetching keyset: %v from keystore: %v", name, err)
}

keypairID := c.NodeupConfig.KeypairIDs[name]
if keypairID == "" {
return nil, fmt.Errorf("keypairID for %s missing from NodeupConfig", name)
}
item := keyset.Items[keypairID]
if item == nil {
return nil, fmt.Errorf("keypairID %s missing from %s keyset", keypairID, name)
}

cert, err := item.Certificate.AsBytes()
if err != nil {
return nil, err
}

key, err := item.PrivateKey.AsBytes()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -632,27 +651,6 @@ func EvaluateHostnameOverride(hostnameOverride string) (string, error) {
return *(result.Reservations[0].Instances[0].PrivateDnsName), nil
}

// GetPrimaryKeypair is a helper method to retrieve a primary keypair from the store.
// TODO: Use the KeysetID in NodeupConfig instead of the Primary keypair.
func (c *NodeupModelContext) GetPrimaryKeypair(name string) (cert []byte, key []byte, err error) {
keyset, err := c.KeyStore.FindKeyset(name)
if err != nil {
return nil, nil, fmt.Errorf("error fetching keyset: %v from keystore: %v", name, err)
}

cert, err = keyset.Primary.Certificate.AsBytes()
if err != nil {
return nil, nil, err
}

key, err = keyset.Primary.PrivateKey.AsBytes()
if err != nil {
return nil, nil, err
}

return cert, key, nil
}

func (b *NodeupModelContext) AddCNIBinAssets(c *fi.ModelBuilderContext, assetNames []string) error {
for _, assetName := range assetNames {
re, err := regexp.Compile(fmt.Sprintf("^%s$", regexp.QuoteMeta(assetName)))
Expand Down
2 changes: 1 addition & 1 deletion nodeup/pkg/model/networking/kube_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (b *KuberouterBuilder) Build(c *fi.ModelBuilderContext) error {
var kubeconfig fi.Resource
var err error

if b.IsMaster {
if b.HasAPIServer {
kubeconfig = b.BuildIssuedKubeconfig("kube-router", nodetasks.PKIXName{CommonName: rbac.KubeRouter}, c)
} else {
kubeconfig, err = b.BuildBootstrapKubeconfig("kube-router", c)
Expand Down
6 changes: 6 additions & 0 deletions upup/pkg/fi/cloudup/apply_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,12 @@ func (n *nodeUpConfigBuilder) BuildConfig(ig *kops.InstanceGroup, apiserverAddit
if err != nil {
return nil, nil, fmt.Errorf("encoding service-account keys: %w", err)
}
} else {
for _, key := range []string{"kubelet", "kube-proxy", "kube-router"} {
if caTasks[key] != nil {
config.KeypairIDs[key] = caTasks[key].Keyset().Primary.Id
}
}
}

if isMaster || useGossip {
Expand Down