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

Implement core scripts and logic for running upgrades #211

Merged
merged 1 commit into from
Feb 25, 2019

Conversation

xmudrii
Copy link
Member

@xmudrii xmudrii commented Feb 22, 2019

What this PR does / why we need it:

  • implement scripts for upgrading kubeadm and kubelet (cluster upgrade scripts #198),
  • implements scripts for invoking kubeadm upgrade on both leader and follower nodes (cluster upgrade scripts #198),
  • applies kubeone.io/upgrade-in-progress label before starting the upgrade process,
  • removes kubeone.io/upgrade-in-progress label after successfully finishing the upgrade process,
  • adds function for determining the hostname (ported from installer),
  • slightly refactors the code to changes made in use github.com/pkg/errors #210

Breaking changes: I propose to rename the kubeone.io/upgrading-in-process label to kubeone.io/upgrade-in-progress because that seems more grammatically correct.

This PR is supposed to be merged once we have scripts for upgrading packages in the place, until then
/hold

This PR is based on the Kubernetes documentation: Upgrading kubeadm HA clusters from v1.12 to v1.13.

Questions for reviewers (check review comments for other questions):

  • Do we need to run kubeadm plan? To my understanding, it basically does nothing beside showing what will be changed. This can be useful with verbose, but not beside that. I done some testing and it even doesn't error if you put non-existing version or something similar. (see Implement core scripts and logic for running upgrades #211 (comment))

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #198

Release note:

NONE

/assign @kron4eg

@xmudrii xmudrii requested a review from kron4eg February 22, 2019 12:19
@kubermatic-bot kubermatic-bot added the release-note-none Denotes a PR that doesn't merit a release note. label Feb 22, 2019
@kubermatic-bot kubermatic-bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Feb 22, 2019
@kron4eg
Copy link
Member

kron4eg commented Feb 22, 2019

AFAIK, kubeadm plan is for the actual living being to interactively see what's going to happen. Thus we don't need it.

@kron4eg
Copy link
Member

kron4eg commented Feb 22, 2019

It looks like it makes sense to join this PR with #199

@xmudrii xmudrii force-pushed the upgrades/implementation branch from 054683e to f6134ec Compare February 25, 2019 10:25
@xmudrii xmudrii force-pushed the upgrades/implementation branch from f6134ec to cfa2df5 Compare February 25, 2019 10:29
@xmudrii
Copy link
Member Author

xmudrii commented Feb 25, 2019

/hold cancel

@kubermatic-bot kubermatic-bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Feb 25, 2019
@kron4eg
Copy link
Member

kron4eg commented Feb 25, 2019

/lgtm
/approve

@kubermatic-bot kubermatic-bot added the lgtm Indicates that a PR is ready to be merged. label Feb 25, 2019
@kubermatic-bot
Copy link
Contributor

LGTM label has been added.

Git tree hash: 13d2cb7982c33cd2d140e109e3aec9bace1f6bc2

@kubermatic-bot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kron4eg

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubermatic-bot kubermatic-bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 25, 2019
@kubermatic-bot kubermatic-bot merged commit 500b87e into master Feb 25, 2019
@kubermatic-bot kubermatic-bot deleted the upgrades/implementation branch February 25, 2019 13:02
Copy link
Member Author

@xmudrii xmudrii left a comment

Choose a reason for hiding this comment

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

As this PR is already reviewed, this can be a follow-up if anything needs to be changed.

return err
}

func upgradeKubeadmDebian(ctx *util.Context) error {
Copy link
Member Author

Choose a reason for hiding this comment

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

This function could actually be a single function like upgradeKubeadmExecutor(*util.Context, string). Actually, it could be reused for kubelet upgrade as well as they have the same variables and basically do the same thing.

We have similar situation in the installer package as well.

return err
}

func upgradeKubeletDebian(ctx *util.Context) error {
Copy link
Member Author

Choose a reason for hiding this comment

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

As mentioned in a comment above, this could be a single function for both kubeadm and kubelet

@@ -7,18 +7,30 @@ import (
)

const (
labelUpgradeLock = "kubeone.io/upgrading-in-process"
labelUpgradeLock = "kubeone.io/upgrade-in-progress"
Copy link
Member Author

Choose a reason for hiding this comment

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

If we decide to go with this change, the proposal should be updated as well (can be done in this PR)

{fn: determineHostname, errMsg: "unable to determine hostname"},
{fn: determineOS, errMsg: "unable to determine operating system"},
{fn: runPreflightChecks, errMsg: "preflight checks failed"},
{fn: upgradeLeader, errMsg: "unable to upgrade leader control plane"},
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 was thinking a lot how to handle this but still unsure is this the right way..

I have two big functions in upgrade_leader.go and upgrade_follower.go that contains all tasks for leader and followers. Reason for creating a big function instead of just adding task by task here is that I was not sure how to control the process correctly.

In case of the leader, it would be quite easy, as we have only leader and just listing tasks would do the job. This might not be a case for followers. I believe that if we started upgrading one follower, we should fully finish upgrade there before proceeding to the next follower. If I'd add task by task here instead of using one big function, it might not be easy to ensure that multiple tasks will finish on the same node before doing same for another.

Of course, it's possible to use different approach, but I wanted to be consistent and not expand on too much.

}

// mergeStringMap merges two string maps into destination string map
func mergeStringMap(modified *bool, destination *map[string]string, required map[string]string) {
Copy link
Member Author

Choose a reason for hiding this comment

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

We already implement this function in the template package. There are two questions: should we reuse function from another, non-upgardes related, package? Or should we instead create an util (e.g. pkg/util) package and put such functions there? Although, I'm against pkg/util because it's an anti-pattern in Go, but having packages in pkg/util, like pkg/util/merge would work.

Copy link
Member

Choose a reason for hiding this comment

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

no more utils please. and those that we already have should be dismissed, and refactored into conscientiously named packages

corev1types "k8s.io/client-go/kubernetes/typed/core/v1"
)

func determineHostname(ctx *util.Context) error {
Copy link
Member Author

Choose a reason for hiding this comment

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

determineHostname and determineOS are implemented in the installer package in a similar form. We should consider moving those functions to an utility package instead of just reimplementing them everywhere.

}

func upgradeLeaderExecutor(ctx *util.Context, node *config.HostConfig, conn ssh.Connection) error {
logger := ctx.Logger.WithField("node", node.PublicAddress)
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure is this needed, but I thought it would be nice to have on what node the task is executed.

func upgradeLeaderExecutor(ctx *util.Context, node *config.HostConfig, conn ssh.Connection) error {
logger := ctx.Logger.WithField("node", node.PublicAddress)

logger.Infoln("Labeling leader control plane…")
Copy link
Member Author

Choose a reason for hiding this comment

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

Do we need leader in logs or just go with control plane?

}

func upgradeFollowerExecutor(ctx *util.Context, node *config.HostConfig, conn ssh.Connection) error {
ctx.Logger.Infoln("Labeling follower control plane…")
Copy link
Member Author

Choose a reason for hiding this comment

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

RunTaskOnFollowers automatically modifies logger to include the IP address, so we don't need to create a new logger like for upgradeLeaderExecutor.

return errors.Wrap(err, "failed to label leader control plane node")
}

ctx.Logger.Infoln("Upgrading kubeadm on follower control plane…")
Copy link
Member Author

Choose a reason for hiding this comment

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

Similar as for leader, do we need follower in logs?

@kdomanski kdomanski mentioned this pull request Feb 26, 2019
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cluster upgrade scripts
3 participants