sigs.k8s.io/cluster-api@v1.6.3/bootstrap/kubeadm/api/v1alpha4/kubeadm_types.go (about) 1 /* 2 Copyright 2021 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 v1alpha4 18 19 import ( 20 "fmt" 21 "strings" 22 23 "github.com/pkg/errors" 24 corev1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 bootstrapapi "k8s.io/cluster-bootstrap/token/api" 27 bootstraputil "k8s.io/cluster-bootstrap/token/util" 28 ) 29 30 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 31 32 // InitConfiguration contains a list of elements that is specific "kubeadm init"-only runtime 33 // information. 34 type InitConfiguration struct { 35 metav1.TypeMeta `json:",inline"` 36 37 // BootstrapTokens is respected at `kubeadm init` time and describes a set of Bootstrap Tokens to create. 38 // This information IS NOT uploaded to the kubeadm cluster configmap, partly because of its sensitive nature 39 // +optional 40 BootstrapTokens []BootstrapToken `json:"bootstrapTokens,omitempty"` 41 42 // NodeRegistration holds fields that relate to registering the new control-plane node to the cluster. 43 // When used in the context of control plane nodes, NodeRegistration should remain consistent 44 // across both InitConfiguration and JoinConfiguration 45 // +optional 46 NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"` 47 48 // LocalAPIEndpoint represents the endpoint of the API server instance that's deployed on this control plane node 49 // In HA setups, this differs from ClusterConfiguration.ControlPlaneEndpoint in the sense that ControlPlaneEndpoint 50 // is the global endpoint for the cluster, which then loadbalances the requests to each individual API server. This 51 // configuration object lets you customize what IP/DNS name and port the local API server advertises it's accessible 52 // on. By default, kubeadm tries to auto-detect the IP of the default interface and use that, but in case that process 53 // fails you may set the desired value here. 54 // +optional 55 LocalAPIEndpoint APIEndpoint `json:"localAPIEndpoint,omitempty"` 56 } 57 58 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 59 60 // ClusterConfiguration contains cluster-wide configuration for a kubeadm cluster. 61 type ClusterConfiguration struct { 62 metav1.TypeMeta `json:",inline"` 63 64 // Etcd holds configuration for etcd. 65 // NB: This value defaults to a Local (stacked) etcd 66 // +optional 67 Etcd Etcd `json:"etcd,omitempty"` 68 69 // Networking holds configuration for the networking topology of the cluster. 70 // NB: This value defaults to the Cluster object spec.clusterNetwork. 71 // +optional 72 Networking Networking `json:"networking,omitempty"` 73 74 // KubernetesVersion is the target version of the control plane. 75 // NB: This value defaults to the Machine object spec.version 76 // +optional 77 KubernetesVersion string `json:"kubernetesVersion,omitempty"` 78 79 // ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it 80 // can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port. 81 // In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort 82 // are used; in case the ControlPlaneEndpoint is specified but without a TCP port, 83 // the BindPort is used. 84 // Possible usages are: 85 // e.g. In a cluster with more than one control plane instances, this field should be 86 // assigned the address of the external load balancer in front of the 87 // control plane instances. 88 // e.g. in environments with enforced node recycling, the ControlPlaneEndpoint 89 // could be used for assigning a stable DNS to the control plane. 90 // NB: This value defaults to the first value in the Cluster object status.apiEndpoints array. 91 // +optional 92 ControlPlaneEndpoint string `json:"controlPlaneEndpoint,omitempty"` 93 94 // APIServer contains extra settings for the API server control plane component 95 // +optional 96 APIServer APIServer `json:"apiServer,omitempty"` 97 98 // ControllerManager contains extra settings for the controller manager control plane component 99 // +optional 100 ControllerManager ControlPlaneComponent `json:"controllerManager,omitempty"` 101 102 // Scheduler contains extra settings for the scheduler control plane component 103 // +optional 104 Scheduler ControlPlaneComponent `json:"scheduler,omitempty"` 105 106 // DNS defines the options for the DNS add-on installed in the cluster. 107 // +optional 108 DNS DNS `json:"dns,omitempty"` 109 110 // CertificatesDir specifies where to store or look for all required certificates. 111 // NB: if not provided, this will default to `/etc/kubernetes/pki` 112 // +optional 113 CertificatesDir string `json:"certificatesDir,omitempty"` 114 115 // ImageRepository sets the container registry to pull images from. 116 // If empty, `registry.k8s.io` will be used by default; in case of kubernetes version is a CI build (kubernetes version starts with `ci/` or `ci-cross/`) 117 // `gcr.io/k8s-staging-ci-images` will be used as a default for control plane components and for kube-proxy, while `registry.k8s.io` 118 // will be used for all the other images. 119 // +optional 120 ImageRepository string `json:"imageRepository,omitempty"` 121 122 // FeatureGates enabled by the user. 123 // +optional 124 FeatureGates map[string]bool `json:"featureGates,omitempty"` 125 126 // The cluster name 127 // +optional 128 ClusterName string `json:"clusterName,omitempty"` 129 } 130 131 // ControlPlaneComponent holds settings common to control plane component of the cluster. 132 type ControlPlaneComponent struct { 133 // ExtraArgs is an extra set of flags to pass to the control plane component. 134 // TODO: This is temporary and ideally we would like to switch all components to 135 // use ComponentConfig + ConfigMaps. 136 // +optional 137 ExtraArgs map[string]string `json:"extraArgs,omitempty"` 138 139 // ExtraVolumes is an extra set of host volumes, mounted to the control plane component. 140 // +optional 141 ExtraVolumes []HostPathMount `json:"extraVolumes,omitempty"` 142 } 143 144 // APIServer holds settings necessary for API server deployments in the cluster. 145 type APIServer struct { 146 ControlPlaneComponent `json:",inline"` 147 148 // CertSANs sets extra Subject Alternative Names for the API Server signing cert. 149 // +optional 150 CertSANs []string `json:"certSANs,omitempty"` 151 152 // TimeoutForControlPlane controls the timeout that we use for API server to appear 153 // +optional 154 TimeoutForControlPlane *metav1.Duration `json:"timeoutForControlPlane,omitempty"` 155 } 156 157 // DNS defines the DNS addon that should be used in the cluster. 158 type DNS struct { 159 // ImageMeta allows to customize the image used for the DNS component 160 ImageMeta `json:",inline"` 161 } 162 163 // ImageMeta allows to customize the image used for components that are not 164 // originated from the Kubernetes/Kubernetes release process. 165 type ImageMeta struct { 166 // ImageRepository sets the container registry to pull images from. 167 // if not set, the ImageRepository defined in ClusterConfiguration will be used instead. 168 // +optional 169 ImageRepository string `json:"imageRepository,omitempty"` 170 171 // ImageTag allows to specify a tag for the image. 172 // In case this value is set, kubeadm does not change automatically the version of the above components during upgrades. 173 // +optional 174 ImageTag string `json:"imageTag,omitempty"` 175 176 //TODO: evaluate if we need also a ImageName based on user feedbacks 177 } 178 179 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 180 181 // ClusterStatus contains the cluster status. The ClusterStatus will be stored in the kubeadm-config 182 // ConfigMap in the cluster, and then updated by kubeadm when additional control plane instance joins or leaves the cluster. 183 // 184 // Deprecated: ClusterStatus has been removed from kubeadm v1beta3 API; This type is preserved only to support 185 // conversion to older versions of the kubeadm API. 186 type ClusterStatus struct { 187 metav1.TypeMeta `json:",inline"` 188 189 // APIEndpoints currently available in the cluster, one for each control plane/api server instance. 190 // The key of the map is the IP of the host's default interface 191 APIEndpoints map[string]APIEndpoint `json:"apiEndpoints"` 192 } 193 194 // APIEndpoint struct contains elements of API server instance deployed on a node. 195 type APIEndpoint struct { 196 // AdvertiseAddress sets the IP address for the API server to advertise. 197 // +optional 198 AdvertiseAddress string `json:"advertiseAddress,omitempty"` 199 200 // BindPort sets the secure port for the API Server to bind to. 201 // Defaults to 6443. 202 // +optional 203 BindPort int32 `json:"bindPort,omitempty"` 204 } 205 206 // NodeRegistrationOptions holds fields that relate to registering a new control-plane or node to the cluster, either via "kubeadm init" or "kubeadm join". 207 type NodeRegistrationOptions struct { 208 209 // Name is the `.Metadata.Name` field of the Node API object that will be created in this `kubeadm init` or `kubeadm join` operation. 210 // This field is also used in the CommonName field of the kubelet's client certificate to the API server. 211 // Defaults to the hostname of the node if not provided. 212 // +optional 213 Name string `json:"name,omitempty"` 214 215 // CRISocket is used to retrieve container runtime info. This information will be annotated to the Node API object, for later re-use 216 // +optional 217 CRISocket string `json:"criSocket,omitempty"` 218 219 // Taints specifies the taints the Node API object should be registered with. If this field is unset, i.e. nil, in the `kubeadm init` process 220 // it will be defaulted to []v1.Taint{'node-role.kubernetes.io/master=""'}. If you don't want to taint your control-plane node, set this field to an 221 // empty slice, i.e. `taints: {}` in the YAML file. This field is solely used for Node registration. 222 Taints []corev1.Taint `json:"taints,omitempty"` 223 224 // KubeletExtraArgs passes through extra arguments to the kubelet. The arguments here are passed to the kubelet command line via the environment file 225 // kubeadm writes at runtime for the kubelet to source. This overrides the generic base-level configuration in the kubelet-config-1.X ConfigMap 226 // Flags have higher priority when parsing. These values are local and specific to the node kubeadm is executing on. 227 // +optional 228 KubeletExtraArgs map[string]string `json:"kubeletExtraArgs,omitempty"` 229 230 // IgnorePreflightErrors provides a slice of pre-flight errors to be ignored when the current node is registered. 231 // +optional 232 IgnorePreflightErrors []string `json:"ignorePreflightErrors,omitempty"` 233 } 234 235 // Networking contains elements describing cluster's networking configuration. 236 type Networking struct { 237 // ServiceSubnet is the subnet used by k8s services. 238 // Defaults to a comma-delimited string of the Cluster object's spec.clusterNetwork.pods.cidrBlocks, or 239 // to "10.96.0.0/12" if that's unset. 240 // +optional 241 ServiceSubnet string `json:"serviceSubnet,omitempty"` 242 // PodSubnet is the subnet used by pods. 243 // If unset, the API server will not allocate CIDR ranges for every node. 244 // Defaults to a comma-delimited string of the Cluster object's spec.clusterNetwork.services.cidrBlocks if that is set 245 // +optional 246 PodSubnet string `json:"podSubnet,omitempty"` 247 // DNSDomain is the dns domain used by k8s services. Defaults to "cluster.local". 248 // +optional 249 DNSDomain string `json:"dnsDomain,omitempty"` 250 } 251 252 // BootstrapToken describes one bootstrap token, stored as a Secret in the cluster. 253 type BootstrapToken struct { 254 // Token is used for establishing bidirectional trust between nodes and control-planes. 255 // Used for joining nodes in the cluster. 256 Token *BootstrapTokenString `json:"token"` 257 // Description sets a human-friendly message why this token exists and what it's used 258 // for, so other administrators can know its purpose. 259 // +optional 260 Description string `json:"description,omitempty"` 261 // TTL defines the time to live for this token. Defaults to 24h. 262 // Expires and TTL are mutually exclusive. 263 // +optional 264 TTL *metav1.Duration `json:"ttl,omitempty"` 265 // Expires specifies the timestamp when this token expires. Defaults to being set 266 // dynamically at runtime based on the TTL. Expires and TTL are mutually exclusive. 267 // +optional 268 Expires *metav1.Time `json:"expires,omitempty"` 269 // Usages describes the ways in which this token can be used. Can by default be used 270 // for establishing bidirectional trust, but that can be changed here. 271 // +optional 272 Usages []string `json:"usages,omitempty"` 273 // Groups specifies the extra groups that this token will authenticate as when/if 274 // used for authentication 275 // +optional 276 Groups []string `json:"groups,omitempty"` 277 } 278 279 // Etcd contains elements describing Etcd configuration. 280 type Etcd struct { 281 282 // Local provides configuration knobs for configuring the local etcd instance 283 // Local and External are mutually exclusive 284 // +optional 285 Local *LocalEtcd `json:"local,omitempty"` 286 287 // External describes how to connect to an external etcd cluster 288 // Local and External are mutually exclusive 289 // +optional 290 External *ExternalEtcd `json:"external,omitempty"` 291 } 292 293 // LocalEtcd describes that kubeadm should run an etcd cluster locally. 294 type LocalEtcd struct { 295 // ImageMeta allows to customize the container used for etcd 296 ImageMeta `json:",inline"` 297 298 // DataDir is the directory etcd will place its data. 299 // Defaults to "/var/lib/etcd". 300 // +optional 301 DataDir string `json:"dataDir,omitempty"` 302 303 // ExtraArgs are extra arguments provided to the etcd binary 304 // when run inside a static pod. 305 // +optional 306 ExtraArgs map[string]string `json:"extraArgs,omitempty"` 307 308 // ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert. 309 // +optional 310 ServerCertSANs []string `json:"serverCertSANs,omitempty"` 311 // PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert. 312 // +optional 313 PeerCertSANs []string `json:"peerCertSANs,omitempty"` 314 } 315 316 // ExternalEtcd describes an external etcd cluster. 317 // Kubeadm has no knowledge of where certificate files live and they must be supplied. 318 type ExternalEtcd struct { 319 // Endpoints of etcd members. Required for ExternalEtcd. 320 Endpoints []string `json:"endpoints"` 321 322 // CAFile is an SSL Certificate Authority file used to secure etcd communication. 323 // Required if using a TLS connection. 324 CAFile string `json:"caFile"` 325 326 // CertFile is an SSL certification file used to secure etcd communication. 327 // Required if using a TLS connection. 328 CertFile string `json:"certFile"` 329 330 // KeyFile is an SSL key file used to secure etcd communication. 331 // Required if using a TLS connection. 332 KeyFile string `json:"keyFile"` 333 } 334 335 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 336 337 // JoinConfiguration contains elements describing a particular node. 338 type JoinConfiguration struct { 339 metav1.TypeMeta `json:",inline"` 340 341 // NodeRegistration holds fields that relate to registering the new control-plane node to the cluster. 342 // When used in the context of control plane nodes, NodeRegistration should remain consistent 343 // across both InitConfiguration and JoinConfiguration 344 // +optional 345 NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"` 346 347 // CACertPath is the path to the SSL certificate authority used to 348 // secure comunications between node and control-plane. 349 // Defaults to "/etc/kubernetes/pki/ca.crt". 350 // +optional 351 // TODO: revisit when there is defaulting from k/k 352 CACertPath string `json:"caCertPath,omitempty"` 353 354 // Discovery specifies the options for the kubelet to use during the TLS Bootstrap process 355 // +optional 356 // TODO: revisit when there is defaulting from k/k 357 Discovery Discovery `json:"discovery,omitempty"` 358 359 // ControlPlane defines the additional control plane instance to be deployed on the joining node. 360 // If nil, no additional control plane instance will be deployed. 361 // +optional 362 ControlPlane *JoinControlPlane `json:"controlPlane,omitempty"` 363 } 364 365 // JoinControlPlane contains elements describing an additional control plane instance to be deployed on the joining node. 366 type JoinControlPlane struct { 367 // LocalAPIEndpoint represents the endpoint of the API server instance to be deployed on this node. 368 // +optional 369 LocalAPIEndpoint APIEndpoint `json:"localAPIEndpoint,omitempty"` 370 } 371 372 // Discovery specifies the options for the kubelet to use during the TLS Bootstrap process. 373 type Discovery struct { 374 // BootstrapToken is used to set the options for bootstrap token based discovery 375 // BootstrapToken and File are mutually exclusive 376 // +optional 377 BootstrapToken *BootstrapTokenDiscovery `json:"bootstrapToken,omitempty"` 378 379 // File is used to specify a file or URL to a kubeconfig file from which to load cluster information 380 // BootstrapToken and File are mutually exclusive 381 // +optional 382 File *FileDiscovery `json:"file,omitempty"` 383 384 // TLSBootstrapToken is a token used for TLS bootstrapping. 385 // If .BootstrapToken is set, this field is defaulted to .BootstrapToken.Token, but can be overridden. 386 // If .File is set, this field **must be set** in case the KubeConfigFile does not contain any other authentication information 387 // +optional 388 TLSBootstrapToken string `json:"tlsBootstrapToken,omitempty"` 389 390 // Timeout modifies the discovery timeout 391 // +optional 392 Timeout *metav1.Duration `json:"timeout,omitempty"` 393 } 394 395 // BootstrapTokenDiscovery is used to set the options for bootstrap token based discovery. 396 type BootstrapTokenDiscovery struct { 397 // Token is a token used to validate cluster information 398 // fetched from the control-plane. 399 Token string `json:"token"` 400 401 // APIServerEndpoint is an IP or domain name to the API server from which info will be fetched. 402 // +optional 403 APIServerEndpoint string `json:"apiServerEndpoint,omitempty"` 404 405 // CACertHashes specifies a set of public key pins to verify 406 // when token-based discovery is used. The root CA found during discovery 407 // must match one of these values. Specifying an empty set disables root CA 408 // pinning, which can be unsafe. Each hash is specified as "<type>:<value>", 409 // where the only currently supported type is "sha256". This is a hex-encoded 410 // SHA-256 hash of the Subject Public Key Info (SPKI) object in DER-encoded 411 // ASN.1. These hashes can be calculated using, for example, OpenSSL: 412 // openssl x509 -pubkey -in ca.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex 413 // +optional 414 CACertHashes []string `json:"caCertHashes,omitempty"` 415 416 // UnsafeSkipCAVerification allows token-based discovery 417 // without CA verification via CACertHashes. This can weaken 418 // the security of kubeadm since other nodes can impersonate the control-plane. 419 // +optional 420 UnsafeSkipCAVerification bool `json:"unsafeSkipCAVerification,omitempty"` 421 } 422 423 // FileDiscovery is used to specify a file or URL to a kubeconfig file from which to load cluster information. 424 type FileDiscovery struct { 425 // KubeConfigPath is used to specify the actual file path or URL to the kubeconfig file from which to load cluster information 426 KubeConfigPath string `json:"kubeConfigPath"` 427 } 428 429 // HostPathMount contains elements describing volumes that are mounted from the 430 // host. 431 type HostPathMount struct { 432 // Name of the volume inside the pod template. 433 Name string `json:"name"` 434 // HostPath is the path in the host that will be mounted inside 435 // the pod. 436 HostPath string `json:"hostPath"` 437 // MountPath is the path inside the pod where hostPath will be mounted. 438 MountPath string `json:"mountPath"` 439 // ReadOnly controls write access to the volume 440 // +optional 441 ReadOnly bool `json:"readOnly,omitempty"` 442 // PathType is the type of the HostPath. 443 // +optional 444 PathType corev1.HostPathType `json:"pathType,omitempty"` 445 } 446 447 // BootstrapTokenString is a token of the format abcdef.abcdef0123456789 that is used 448 // for both validation of the practically of the API server from a joining node's point 449 // of view and as an authentication method for the node in the bootstrap phase of 450 // "kubeadm join". This token is and should be short-lived. 451 // 452 // +kubebuilder:validation:Type=string 453 type BootstrapTokenString struct { 454 ID string `json:"-"` 455 Secret string `json:"-"` 456 } 457 458 // MarshalJSON implements the json.Marshaler interface. 459 func (bts BootstrapTokenString) MarshalJSON() ([]byte, error) { 460 return []byte(fmt.Sprintf("%q", bts.String())), nil 461 } 462 463 // UnmarshalJSON implements the json.Unmarshaller interface. 464 func (bts *BootstrapTokenString) UnmarshalJSON(b []byte) error { 465 // If the token is represented as "", just return quickly without an error 466 if len(b) == 0 { 467 return nil 468 } 469 470 // Remove unnecessary " characters coming from the JSON parser 471 token := strings.ReplaceAll(string(b), `"`, ``) 472 // Convert the string Token to a BootstrapTokenString object 473 newbts, err := NewBootstrapTokenString(token) 474 if err != nil { 475 return err 476 } 477 bts.ID = newbts.ID 478 bts.Secret = newbts.Secret 479 return nil 480 } 481 482 // String returns the string representation of the BootstrapTokenString. 483 func (bts BootstrapTokenString) String() string { 484 if len(bts.ID) > 0 && len(bts.Secret) > 0 { 485 return bootstraputil.TokenFromIDAndSecret(bts.ID, bts.Secret) 486 } 487 return "" 488 } 489 490 // NewBootstrapTokenString converts the given Bootstrap Token as a string 491 // to the BootstrapTokenString object used for serialization/deserialization 492 // and internal usage. It also automatically validates that the given token 493 // is of the right format. 494 func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) { 495 substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token) 496 // TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works) 497 if len(substrs) != 3 { 498 return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern) 499 } 500 501 return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil 502 }