Merge pull request #35124 from errordeveloper/fix-33916

Automatic merge from submit-queue

Eliminate half-baked multi-architecture support

**What this PR does / why we need it**:

We have release `kubeadm` with half-baked support for clusters with nodes of different CPU architectures. The problem with the code as it stand is that user will notice pending daemonsets of `kube-proxy` for machines with architectures that they don't have. At the same time, the code as it stand did not pick up correct images for architectures it wanted to allow. Additionally, it only treated `kube-proxy` in such a way, but didn't do anything about `kube-dns`. This removes multiple daemonesets, but ensures that whichever resources we deploy have node affinity set to the architecture native to the master. Users wishing to use mixed architectures can still create extra daemonsets via the API.

**Which issue this PR fixes**: fixes #33916

**Release note**:
```release-note
Remove support for multi-architecture code in `kubeadm`, which was released untested.
```
This commit is contained in:
Kubernetes Submit Queue 2016-10-21 15:19:05 -07:00 committed by GitHub
commit 73e89ba0ec
3 changed files with 27 additions and 24 deletions

View File

@ -20,7 +20,6 @@ import (
"fmt"
"net"
"path"
"runtime"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/images"
@ -31,15 +30,11 @@ import (
"k8s.io/kubernetes/pkg/util/intstr"
)
// TODO(phase1+): kube-proxy should be a daemonset, three different daemonsets should not be here
func createKubeProxyPodSpec(cfg *kubeadmapi.MasterConfiguration, architecture string) api.PodSpec {
func createKubeProxyPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
envParams := kubeadmapi.GetEnvParams()
privilegedTrue := true
return api.PodSpec{
SecurityContext: &api.PodSecurityContext{HostNetwork: true},
NodeSelector: map[string]string{
"beta.kubernetes.io/arch": architecture,
},
Containers: []api.Container{{
Name: kubeProxy,
Image: images.GetCoreImage(images.KubeProxyImage, cfg, envParams["hyperkube_image"]),
@ -108,9 +103,6 @@ func createKubeDNSPodSpec(cfg *kubeadmapi.MasterConfiguration) api.PodSpec {
)
return api.PodSpec{
NodeSelector: map[string]string{
"beta.kubernetes.io/arch": runtime.GOARCH,
},
Containers: []api.Container{
// DNS server
{
@ -237,21 +229,19 @@ func createKubeDNSServiceSpec(cfg *kubeadmapi.MasterConfiguration) (*api.Service
}
func CreateEssentialAddons(cfg *kubeadmapi.MasterConfiguration, client *clientset.Clientset) error {
arches := [3]string{"amd64", "arm", "arm64"}
for _, arch := range arches {
kubeProxyDaemonSet := NewDaemonSet(kubeProxy+"-"+arch, createKubeProxyPodSpec(cfg, arch))
kubeProxyDaemonSet := NewDaemonSet(kubeProxy, createKubeProxyPodSpec(cfg))
SetMasterTaintTolerations(&kubeProxyDaemonSet.Spec.Template.ObjectMeta)
SetNodeAffinity(&kubeProxyDaemonSet.Spec.Template.ObjectMeta, NativeArchitectureNodeAffinity())
if _, err := client.Extensions().DaemonSets(api.NamespaceSystem).Create(kubeProxyDaemonSet); err != nil {
return fmt.Errorf("<master/addons> failed creating essential kube-proxy addon [%v]", err)
}
}
fmt.Println("<master/addons> created essential addon: kube-proxy")
kubeDNSDeployment := NewDeployment("kube-dns", 1, createKubeDNSPodSpec(cfg))
SetMasterTaintTolerations(&kubeDNSDeployment.Spec.Template.ObjectMeta)
SetNodeAffinity(&kubeDNSDeployment.Spec.Template.ObjectMeta, NativeArchitectureNodeAffinity())
if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kubeDNSDeployment); err != nil {
return fmt.Errorf("<master/addons> failed creating essential kube-dns addon [%v]", err)

View File

@ -19,6 +19,7 @@ package master
import (
"encoding/json"
"fmt"
"runtime"
"time"
"k8s.io/kubernetes/cmd/kubeadm/app/images"
@ -206,14 +207,11 @@ func SetMasterTaintTolerations(meta *api.ObjectMeta) {
meta.Annotations[api.TolerationsAnnotationKey] = string(tolerationsAnnotation)
}
func SetMasterNodeAffinity(meta *api.ObjectMeta) {
// SetNodeAffinity is a basic helper to set meta.Annotations[api.AffinityAnnotationKey] for one or more api.NodeSelectorRequirement(s)
func SetNodeAffinity(meta *api.ObjectMeta, expr ...api.NodeSelectorRequirement) {
nodeAffinity := &api.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
NodeSelectorTerms: []api.NodeSelectorTerm{{
MatchExpressions: []api.NodeSelectorRequirement{{
Key: "kubeadm.alpha.kubernetes.io/role", Operator: api.NodeSelectorOpIn, Values: []string{"master"},
}},
}},
NodeSelectorTerms: []api.NodeSelectorTerm{{MatchExpressions: expr}},
},
}
affinityAnnotation, _ := json.Marshal(api.Affinity{NodeAffinity: nodeAffinity})
@ -223,6 +221,21 @@ func SetMasterNodeAffinity(meta *api.ObjectMeta) {
meta.Annotations[api.AffinityAnnotationKey] = string(affinityAnnotation)
}
// MasterNodeAffinity returns api.NodeSelectorRequirement to be used with SetNodeAffinity to set affinity to master node
func MasterNodeAffinity() api.NodeSelectorRequirement {
return api.NodeSelectorRequirement{
Key: "kubeadm.alpha.kubernetes.io/role", Operator: api.NodeSelectorOpIn, Values: []string{"master"},
}
}
// NativeArchitectureNodeAffinity returns api.NodeSelectorRequirement to be used with SetNodeAffinity to nodes with CPU architecture
// the same as master node
func NativeArchitectureNodeAffinity() api.NodeSelectorRequirement {
return api.NodeSelectorRequirement{
Key: "beta.kubernetes.io/arch", Operator: api.NodeSelectorOpIn, Values: []string{runtime.GOARCH},
}
}
func createDummyDeployment(client *clientset.Clientset) {
fmt.Println("<master/apiclient> attempting a test deployment")
dummyDeployment := NewDeployment("dummy", 1, api.PodSpec{

View File

@ -112,7 +112,7 @@ func newKubeDiscovery(cfg *kubeadmapi.MasterConfiguration, caCert *x509.Certific
}
SetMasterTaintTolerations(&kd.Deployment.Spec.Template.ObjectMeta)
SetMasterNodeAffinity(&kd.Deployment.Spec.Template.ObjectMeta)
SetNodeAffinity(&kd.Deployment.Spec.Template.ObjectMeta, MasterNodeAffinity(), NativeArchitectureNodeAffinity())
return kd
}