k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kubeadm/app/phases/addons/proxy/proxy.go (about) 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 }