...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/proxy.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package proxy
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  
    24  	"github.com/pkg/errors"
    25  
    26  	apps "k8s.io/api/apps/v1"
    27  	v1 "k8s.io/api/core/v1"
    28  	rbac "k8s.io/api/rbac/v1"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  	kuberuntime "k8s.io/apimachinery/pkg/runtime"
    31  	"k8s.io/apimachinery/pkg/runtime/schema"
    32  	clientset "k8s.io/client-go/kubernetes"
    33  	clientsetscheme "k8s.io/client-go/kubernetes/scheme"
    34  
    35  	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
    36  	"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
    37  	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
    38  	"k8s.io/kubernetes/cmd/kubeadm/app/images"
    39  	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
    40  	"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
    41  )
    42  
    43  const (
    44  	// KubeProxyServiceAccountName describes the name of the ServiceAccount for the kube-proxy addon
    45  	KubeProxyServiceAccountName = "kube-proxy"
    46  
    47  	// KubeProxyConfigMapRoleName sets the name of ClusterRole for ConfigMap
    48  	KubeProxyConfigMapRoleName = "kube-proxy"
    49  )
    50  
    51  // EnsureProxyAddon creates the kube-proxy addons
    52  func EnsureProxyAddon(cfg *kubeadmapi.ClusterConfiguration, localEndpoint *kubeadmapi.APIEndpoint, client clientset.Interface, out io.Writer, printManifest bool) error {
    53  	cmByte, err := createKubeProxyConfigMap(cfg, localEndpoint, client, printManifest)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	dsByte, err := createKubeProxyAddon(cfg, client, printManifest)
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	if err := printOrCreateKubeProxyObjects(cmByte, dsByte, client, out, printManifest); err != nil {
    64  		return err
    65  	}
    66  
    67  	return nil
    68  }
    69  
    70  // Create SA, RBACRules or print manifests of them to out if printManifest is true
    71  func printOrCreateKubeProxyObjects(cmByte []byte, dsByte []byte, client clientset.Interface, out io.Writer, printManifest bool) error {
    72  	var saBytes, crbBytes, roleBytes, roleBindingBytes []byte
    73  	var err error
    74  
    75  	sa := &v1.ServiceAccount{
    76  		ObjectMeta: metav1.ObjectMeta{
    77  			Name:      KubeProxyServiceAccountName,
    78  			Namespace: metav1.NamespaceSystem,
    79  		},
    80  	}
    81  
    82  	crb := &rbac.ClusterRoleBinding{
    83  		ObjectMeta: metav1.ObjectMeta{
    84  			Name: constants.KubeProxyClusterRoleBindingName,
    85  		},
    86  		RoleRef: rbac.RoleRef{
    87  			APIGroup: rbac.GroupName,
    88  			Kind:     "ClusterRole",
    89  			Name:     constants.KubeProxyClusterRoleName,
    90  		},
    91  		Subjects: []rbac.Subject{
    92  			{
    93  				Kind:      rbac.ServiceAccountKind,
    94  				Name:      KubeProxyServiceAccountName,
    95  				Namespace: metav1.NamespaceSystem,
    96  			},
    97  		},
    98  	}
    99  
   100  	role := &rbac.Role{
   101  		ObjectMeta: metav1.ObjectMeta{
   102  			Name:      KubeProxyConfigMapRoleName,
   103  			Namespace: metav1.NamespaceSystem,
   104  		},
   105  		Rules: []rbac.PolicyRule{
   106  			{
   107  				Verbs:         []string{"get"},
   108  				APIGroups:     []string{""},
   109  				Resources:     []string{"configmaps"},
   110  				ResourceNames: []string{constants.KubeProxyConfigMap},
   111  			},
   112  		},
   113  	}
   114  
   115  	rb := &rbac.RoleBinding{
   116  		ObjectMeta: metav1.ObjectMeta{
   117  			Name:      KubeProxyConfigMapRoleName,
   118  			Namespace: metav1.NamespaceSystem,
   119  		},
   120  		RoleRef: rbac.RoleRef{
   121  			APIGroup: rbac.GroupName,
   122  			Kind:     "Role",
   123  			Name:     KubeProxyConfigMapRoleName,
   124  		},
   125  		Subjects: []rbac.Subject{
   126  			{
   127  				Kind: rbac.GroupKind,
   128  				Name: constants.NodeBootstrapTokenAuthGroup,
   129  			},
   130  		},
   131  	}
   132  
   133  	// Create the objects if printManifest is false
   134  	if !printManifest {
   135  		if err := apiclient.CreateOrUpdateServiceAccount(client, sa); err != nil {
   136  			return errors.Wrap(err, "error when creating kube-proxy service account")
   137  		}
   138  
   139  		if err := apiclient.CreateOrUpdateClusterRoleBinding(client, crb); err != nil {
   140  			return err
   141  		}
   142  
   143  		if err := apiclient.CreateOrUpdateRole(client, role); err != nil {
   144  			return err
   145  		}
   146  
   147  		if err := apiclient.CreateOrUpdateRoleBinding(client, rb); err != nil {
   148  			return err
   149  		}
   150  
   151  		fmt.Fprintln(out, "[addons] Applied essential addon: kube-proxy")
   152  
   153  		return nil
   154  
   155  	}
   156  
   157  	gv := schema.GroupVersion{Group: "", Version: "v1"}
   158  	if saBytes, err = kubeadmutil.MarshalToYaml(sa, gv); err != nil {
   159  		return err
   160  	}
   161  
   162  	gv = schema.GroupVersion{Group: "rbac.authorization.k8s.io", Version: "v1"}
   163  	if crbBytes, err = kubeadmutil.MarshalToYaml(crb, gv); err != nil {
   164  		return err
   165  	}
   166  
   167  	if roleBytes, err = kubeadmutil.MarshalToYaml(role, gv); err != nil {
   168  		return err
   169  	}
   170  
   171  	if roleBindingBytes, err = kubeadmutil.MarshalToYaml(rb, gv); err != nil {
   172  		return err
   173  	}
   174  
   175  	fmt.Fprintln(out, "---")
   176  	fmt.Fprintf(out, "%s", saBytes)
   177  	fmt.Fprintln(out, "---")
   178  	fmt.Fprintf(out, "%s", crbBytes)
   179  	fmt.Fprintln(out, "---")
   180  	fmt.Fprintf(out, "%s", roleBytes)
   181  	fmt.Fprintln(out, "---")
   182  	fmt.Fprintf(out, "%s", roleBindingBytes)
   183  	fmt.Fprint(out, "---")
   184  	fmt.Fprintf(out, "%s", cmByte)
   185  	fmt.Fprint(out, "---")
   186  	fmt.Fprintf(out, "%s", dsByte)
   187  
   188  	return nil
   189  }
   190  
   191  func createKubeProxyConfigMap(cfg *kubeadmapi.ClusterConfiguration, localEndpoint *kubeadmapi.APIEndpoint, client clientset.Interface, printManifest bool) ([]byte, error) {
   192  	// Generate ControlPlane Endpoint kubeconfig file
   193  	controlPlaneEndpoint, err := kubeadmutil.GetControlPlaneEndpoint(cfg.ControlPlaneEndpoint, localEndpoint)
   194  	if err != nil {
   195  		return []byte(""), err
   196  	}
   197  
   198  	kubeProxyCfg, ok := cfg.ComponentConfigs[componentconfigs.KubeProxyGroup]
   199  	if !ok {
   200  		return []byte(""), errors.New("no kube-proxy component config found in the active component config set")
   201  	}
   202  
   203  	proxyBytes, err := kubeProxyCfg.Marshal()
   204  	if err != nil {
   205  		return []byte(""), errors.Wrap(err, "error when marshaling")
   206  	}
   207  	var prefixBytes bytes.Buffer
   208  	apiclient.PrintBytesWithLinePrefix(&prefixBytes, proxyBytes, "    ")
   209  	configMapBytes, err := kubeadmutil.ParseTemplate(KubeProxyConfigMap19,
   210  		struct {
   211  			ControlPlaneEndpoint string
   212  			ProxyConfig          string
   213  			ProxyConfigMap       string
   214  			ProxyConfigMapKey    string
   215  		}{
   216  			ControlPlaneEndpoint: controlPlaneEndpoint,
   217  			ProxyConfig:          prefixBytes.String(),
   218  			ProxyConfigMap:       constants.KubeProxyConfigMap,
   219  			ProxyConfigMapKey:    constants.KubeProxyConfigMapKey,
   220  		})
   221  	if err != nil {
   222  		return []byte(""), errors.Wrap(err, "error when parsing kube-proxy configmap template")
   223  	}
   224  
   225  	if printManifest {
   226  		return configMapBytes, nil
   227  	}
   228  
   229  	kubeproxyConfigMap := &v1.ConfigMap{}
   230  	if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), configMapBytes, kubeproxyConfigMap); err != nil {
   231  		return []byte(""), errors.Wrap(err, "unable to decode kube-proxy configmap")
   232  	}
   233  
   234  	if !kubeProxyCfg.IsUserSupplied() {
   235  		componentconfigs.SignConfigMap(kubeproxyConfigMap)
   236  	}
   237  
   238  	// Create the ConfigMap for kube-proxy or update it in case it already exists
   239  	return []byte(""), apiclient.CreateOrUpdateConfigMap(client, kubeproxyConfigMap)
   240  }
   241  
   242  func createKubeProxyAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface, printManifest bool) ([]byte, error) {
   243  	daemonSetbytes, err := kubeadmutil.ParseTemplate(KubeProxyDaemonSet19, struct{ Image, ProxyConfigMap, ProxyConfigMapKey string }{
   244  		Image:             images.GetKubernetesImage(constants.KubeProxy, cfg),
   245  		ProxyConfigMap:    constants.KubeProxyConfigMap,
   246  		ProxyConfigMapKey: constants.KubeProxyConfigMapKey,
   247  	})
   248  	if err != nil {
   249  		return []byte(""), errors.Wrap(err, "error when parsing kube-proxy daemonset template")
   250  	}
   251  
   252  	if printManifest {
   253  		return daemonSetbytes, nil
   254  	}
   255  
   256  	kubeproxyDaemonSet := &apps.DaemonSet{}
   257  	if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), daemonSetbytes, kubeproxyDaemonSet); err != nil {
   258  		return []byte(""), errors.Wrap(err, "unable to decode kube-proxy daemonset")
   259  	}
   260  	// Propagate the http/https proxy host environment variables to the container
   261  	env := &kubeproxyDaemonSet.Spec.Template.Spec.Containers[0].Env
   262  	*env = append(*env, kubeadmutil.MergeKubeadmEnvVars(kubeadmutil.GetProxyEnvVars())...)
   263  
   264  	// Create the DaemonSet for kube-proxy or update it in case it already exists
   265  	return []byte(""), apiclient.CreateOrUpdateDaemonSet(client, kubeproxyDaemonSet)
   266  }
   267  

View as plain text