From c883cea38a240438872f91efc4243a9f4acd141f Mon Sep 17 00:00:00 2001 From: Andreas Sommer Date: Tue, 13 Oct 2020 09:41:19 +0200 Subject: [PATCH 1/2] Upgrade to Kubernetes 1.19.2, Ubuntu 20.04 and Calico 3.16.x --- cmd/cluster_add_external_worker.go | 8 ++++---- pkg/clustermanager/cluster.go | 18 ++++++++++++++++-- pkg/clustermanager/configs_test.go | 6 +++--- pkg/clustermanager/provision_node.go | 12 +++++++----- pkg/hetzner/hetzner_provider.go | 2 +- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/cmd/cluster_add_external_worker.go b/cmd/cluster_add_external_worker.go index 14e83bb2..c38fac91 100644 --- a/cmd/cluster_add_external_worker.go +++ b/cmd/cluster_add_external_worker.go @@ -19,7 +19,7 @@ var clusterAddExternalWorkerCmd = &cobra.Command{ Long: `This lets you add an external server to your cluster. An external server must meet the following requirements: - - ubuntu 16.04 + - ubuntu 20.04 - a unique hostname, that doesn't collide with an existing node name - accessible with the same SSH key as used for the cluster`, PreRunE: func(cmd *cobra.Command, args []string) error { @@ -67,13 +67,13 @@ An external server must meet the following requirements: } } - // check ubuntu 16.04 + // check ubuntu 20.04 issue, err := AppConf.SSHClient.RunCmd(externalNode, "cat /etc/issue | xargs") if err != nil { return err } - if !strings.Contains(issue, "Ubuntu 16.04") { - return errors.New("target server has no Ubuntu 16.04 installed") + if !strings.Contains(issue, "Ubuntu 20.04") { + return errors.New("target server has no Ubuntu 20.04 installed") } return nil diff --git a/pkg/clustermanager/cluster.go b/pkg/clustermanager/cluster.go index f7ba2eca..efb78791 100644 --- a/pkg/clustermanager/cluster.go +++ b/pkg/clustermanager/cluster.go @@ -74,7 +74,7 @@ func (manager *Manager) Cluster() Cluster { IsolatedEtcd: manager.isolatedEtcd, CloudInitFile: manager.cloudInitFile, NodeCIDR: manager.clusterProvider.GetNodeCidr(), - KubernetesVersion: "1.16.4", + KubernetesVersion: "1.19.2", } } @@ -169,9 +169,10 @@ func (manager *Manager) SetupEncryptedNetwork() error { // InstallMasters installs the kubernetes control plane to master nodes func (manager *Manager) InstallMasters(keepCerts KeepCerts) error { commands := []NodeCommand{ + {"sysctl settings", `printf '# Strict RPF mode as required by canal/Calico\nnet.ipv4.conf.default.rp_filter=1\nnet.ipv4.conf.all.rp_filter=1\n' >/etc/sysctl.d/50-canal-calico.conf && sysctl --load=/etc/sysctl.d/50-canal-calico.conf`}, {"kubeadm init", "kubectl version > /dev/null &> /dev/null || kubeadm init --ignore-preflight-errors=all --config /root/master-config.yaml"}, {"configure kubectl", "rm -rf $HOME/.kube && mkdir -p $HOME/.kube && cp -i /etc/kubernetes/admin.conf $HOME/.kube/config && chown $(id -u):$(id -g) $HOME/.kube/config"}, - {"install canal", "kubectl apply -f https://docs.projectcalico.org/v3.10/manifests/canal.yaml"}, + {"install canal", "kubectl apply -f https://docs.projectcalico.org/v3.16/manifests/canal.yaml"}, } // inject custom commands @@ -357,6 +358,10 @@ func (manager *Manager) InstallWorkers(nodes []Node) error { return err } + commands := []NodeCommand{ + {"sysctl settings", `printf '# Strict RPF mode as required by canal/Calico\nnet.ipv4.conf.default.rp_filter=1\nnet.ipv4.conf.all.rp_filter=1\n' >/etc/sysctl.d/50-canal-calico.conf && sysctl --load=/etc/sysctl.d/50-canal-calico.conf`}, + } + // create join command joinCommand, err := manager.nodeCommunicator.RunCmd(*node, "kubeadm token create --print-join-command") if err != nil { @@ -396,6 +401,15 @@ func (manager *Manager) InstallWorkers(nodes []Node) error { errChan <- err } } + + for _, command := range commands { + manager.eventService.AddEvent(node.Name, command.EventName) + _, err := manager.nodeCommunicator.RunCmd(node, command.Command) + if err != nil { + errChan <- err + } + } + manager.eventService.AddEvent(node.Name, pkg.CompletedEvent) trueChan <- true }(node) diff --git a/pkg/clustermanager/configs_test.go b/pkg/clustermanager/configs_test.go index 753034f6..cf7e87a5 100644 --- a/pkg/clustermanager/configs_test.go +++ b/pkg/clustermanager/configs_test.go @@ -9,7 +9,7 @@ import ( func TestGenerateMasterConfiguration(t *testing.T) { expectedConf := `apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -kubernetesVersion: v1.16.4 +kubernetesVersion: v1.19.2 networking: serviceSubnet: "10.96.0.0/12" podSubnet: "10.244.0.0/16" @@ -45,7 +45,7 @@ featureGates: expectedConfWithEtcd := `apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -kubernetesVersion: v1.16.4 +kubernetesVersion: v1.19.2 networking: serviceSubnet: "10.96.0.0/12" podSubnet: "10.244.0.0/16" @@ -88,7 +88,7 @@ featureGates: {Name: "node2", IPAddress: "1.1.1.2", PrivateIPAddress: "10.0.0.2"}, } - kubernetesVersion := "1.16.4" + kubernetesVersion := "1.19.2" noEtcdConf := GenerateMasterConfiguration(nodes[0], nodes, nil, kubernetesVersion) diff --git a/pkg/clustermanager/provision_node.go b/pkg/clustermanager/provision_node.go index 8d058628..182cc309 100644 --- a/pkg/clustermanager/provision_node.go +++ b/pkg/clustermanager/provision_node.go @@ -177,14 +177,15 @@ func (provisioner *NodeProvisioner) preparePackages() error { return err } - // wireguard - _, err = provisioner.communicator.RunCmd(provisioner.node, "add-apt-repository ppa:wireguard/wireguard -y") + // Wireguard (built into Ubuntu 20.04 kernel already, tools are optional) + _, err = provisioner.communicator.RunCmd(provisioner.node, "apt install -y wireguard-tools") if err != nil { return err } return nil } + func (provisioner *NodeProvisioner) prepareKubernetes() error { // kubernetes _, err := provisioner.communicator.RunCmd(provisioner.node, "curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -") @@ -192,6 +193,7 @@ func (provisioner *NodeProvisioner) prepareKubernetes() error { return err } + // Repository doesn't have Ubuntu 20.04 (focal), but `kubernetes-xenial` works err = provisioner.communicator.WriteFile(provisioner.node, "/etc/apt/sources.list.d/kubernetes.list", `deb http://apt.kubernetes.io/ kubernetes-xenial main`, AllRead) if err != nil { return err @@ -204,7 +206,7 @@ func (provisioner *NodeProvisioner) prepareDocker() error { // docker-ce aptPreferencesDocker := ` Package: docker-ce -Pin: version 18.09.2~3-0~ubuntu-bionic +Pin: version 19.03.13~3-0~ubuntu-focal Pin-Priority: 1000 ` err := provisioner.communicator.WriteFile(provisioner.node, "/etc/apt/preferences.d/docker-ce", aptPreferencesDocker, AllRead) @@ -212,7 +214,7 @@ Pin-Priority: 1000 return err } - _, err = provisioner.communicator.RunCmd(provisioner.node, "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -") + _, err = provisioner.communicator.RunCmd(provisioner.node, `curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | apt-key add -`) if err != nil { return err } @@ -233,7 +235,7 @@ func (provisioner *NodeProvisioner) updateAndInstall() error { } provisioner.eventService.AddEvent(provisioner.node.Name, "installing packages") - command := fmt.Sprintf("apt-get install -y docker-ce kubelet=%s-00 kubeadm=%s-00 kubectl=%s-00 kubernetes-cni=0.7.5-00 wireguard linux-headers-$(uname -r) linux-headers-virtual", + command := fmt.Sprintf("apt-get install -y docker-ce kubelet=%s-00 kubeadm=%s-00 kubectl=%s-00 kubernetes-cni=0.8.7-00 wireguard linux-headers-generic linux-headers-virtual", provisioner.kubernetesVersion, provisioner.kubernetesVersion, provisioner.kubernetesVersion) _, err = provisioner.communicator.RunCmd(provisioner.node, command) if err != nil { diff --git a/pkg/hetzner/hetzner_provider.go b/pkg/hetzner/hetzner_provider.go index 21d109c4..451e639e 100644 --- a/pkg/hetzner/hetzner_provider.go +++ b/pkg/hetzner/hetzner_provider.go @@ -61,7 +61,7 @@ func (provider *Provider) CreateNodes(suffix string, template clustermanager.Nod Name: template.Type, }, Image: &hcloud.Image{ - Name: "ubuntu-18.04", + Name: "ubuntu-20.04", }, } From 82c9f36253751f4e6f3409324db69db950b922d9 Mon Sep 17 00:00:00 2001 From: Andreas Sommer Date: Tue, 13 Oct 2020 22:49:48 +0200 Subject: [PATCH 2/2] Fix printing newlines for context subcommands --- cmd/context_add.go | 2 +- cmd/context_use.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/context_add.go b/cmd/context_add.go index 95e080e0..e023c0f2 100644 --- a/cmd/context_add.go +++ b/cmd/context_add.go @@ -55,7 +55,7 @@ var addCmd = &cobra.Command{ AppConf.Config.ActiveContextName = name AppConf.Config.WriteCurrentConfig() AppConf.CurrentContext = context - fmt.Printf("added context '%s'", name) + fmt.Printf("added context '%s'\n", name) }, } diff --git a/cmd/context_use.go b/cmd/context_use.go index 150fba87..08933961 100644 --- a/cmd/context_use.go +++ b/cmd/context_use.go @@ -19,7 +19,7 @@ var useCmd = &cobra.Command{ FatalOnError(err) AppConf.Config.WriteCurrentConfig() - fmt.Printf("switched to context '%s'", contextName) + fmt.Printf("switched to context '%s'\n", contextName) }, }