apiVersion: cluster.x-k8s.io/v1beta1 kind: Cluster metadata: labels: cluster.x-k8s.io/cluster-name: {{.clusterName}} name: {{.clusterName}} namespace: {{.eksaSystemNamespace}} spec: clusterNetwork: pods: cidrBlocks: {{.podCidrs}} services: cidrBlocks: {{.serviceCidrs}} controlPlaneEndpoint: host: {{.controlPlaneEndpointIp}} port: 6443 controlPlaneRef: apiVersion: controlplane.cluster.x-k8s.io/v1beta1 kind: KubeadmControlPlane name: {{.clusterName}} infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: TinkerbellCluster name: {{.clusterName}} {{- if .externalEtcd }} managedExternalEtcdRef: apiVersion: etcdcluster.cluster.x-k8s.io/v1beta1 kind: EtcdadmCluster name: {{.clusterName}}-etcd {{- end }} --- apiVersion: controlplane.cluster.x-k8s.io/v1beta1 kind: KubeadmControlPlane metadata: name: {{.clusterName}} namespace: {{.eksaSystemNamespace}} spec: kubeadmConfigSpec: clusterConfiguration: imageRepository: {{.kubernetesRepository}} etcd: {{- if .externalEtcd }} external: endpoints: [] {{- if (eq .format "bottlerocket") }} caFile: "/var/lib/kubeadm/pki/etcd/ca.crt" certFile: "/var/lib/kubeadm/pki/server-etcd-client.crt" keyFile: "/var/lib/kubeadm/pki/apiserver-etcd-client.key" {{- else }} caFile: "/etc/kubernetes/pki/etcd/ca.crt" certFile: "/etc/kubernetes/pki/apiserver-etcd-client.crt" keyFile: "/etc/kubernetes/pki/apiserver-etcd-client.key" {{- end }} {{- else }} local: imageRepository: {{.etcdRepository}} imageTag: {{.etcdImageTag}} {{- end }} dns: imageRepository: {{.corednsRepository}} imageTag: {{.corednsVersion}} {{- if (eq .format "bottlerocket") }} pause: imageRepository: {{.pauseRepository}} imageTag: {{.pauseVersion}} bottlerocketBootstrap: imageRepository: {{.bottlerocketBootstrapRepository}} imageTag: {{.bottlerocketBootstrapVersion}} {{- end }} {{- if and .proxyConfig (eq .format "bottlerocket") }} proxy: httpsProxy: {{.httpsProxy}} noProxy: {{ range .noProxy }} - {{ . }} {{- end }} {{- end }} {{- if and .registryMirrorMap (eq .format "bottlerocket") }} registryMirror: endpoint: {{ .publicMirror }} {{- if .registryCACert }} caCert: | {{ .registryCACert | indent 10 }} {{- end }} {{- end }} {{- if .bottlerocketSettings }} {{ .bottlerocketSettings | indent 6 }} {{- end -}} {{- if .certBundles }} certBundles: {{- range .certBundles }} - name: "{{ .Name }}" data: | {{ .Data | indent 10 }} {{- end }} {{- end}} {{- if .apiserverExtraArgs }} apiServer: extraArgs: {{ .apiserverExtraArgs.ToYaml | indent 10 }} {{- end }} {{- if .awsIamAuth}} extraVolumes: - hostPath: /var/lib/kubeadm/aws-iam-authenticator/ mountPath: /etc/kubernetes/aws-iam-authenticator/ name: authconfig readOnly: false - hostPath: /var/lib/kubeadm/aws-iam-authenticator/pki/ mountPath: /var/aws-iam-authenticator/ name: awsiamcert readOnly: false {{- end}} {{- /* BottleRocket uses different host paths for kubeconfigs requiring host mount path overwrites for the scheduler and controller-manager static pods. */}} {{- if ( eq .format "bottlerocket" ) }} controllerManager: extraVolumes: - hostPath: /var/lib/kubeadm/controller-manager.conf mountPath: /etc/kubernetes/controller-manager.conf name: kubeconfig pathType: File readOnly: true {{- end }} {{- if ( eq .format "bottlerocket" ) }} scheduler: extraVolumes: - hostPath: /var/lib/kubeadm/scheduler.conf mountPath: /etc/kubernetes/scheduler.conf name: kubeconfig pathType: File readOnly: true certificatesDir: /var/lib/kubeadm/pki {{- end }} initConfiguration: nodeRegistration: kubeletExtraArgs: provider-id: PROVIDER_ID read-only-port: "0" anonymous-auth: "false" {{- if .kubeletExtraArgs }} {{ .kubeletExtraArgs.ToYaml | indent 10 }} {{- end }} {{- if not .workerNodeGroupConfigurations }} taints: [] {{- end }} {{- if and .workerNodeGroupConfigurations .controlPlaneTaints }} taints: {{- range .controlPlaneTaints}} - key: {{ .Key }} value: {{ .Value }} effect: {{ .Effect }} {{- if .TimeAdded }} timeAdded: {{ .TimeAdded }} {{- end }} {{- end }} {{- end }} joinConfiguration: {{- if (eq .format "bottlerocket") }} pause: imageRepository: {{.pauseRepository}} imageTag: {{.pauseVersion}} bottlerocketBootstrap: imageRepository: {{.bottlerocketBootstrapRepository}} imageTag: {{.bottlerocketBootstrapVersion}} {{- end }} {{- if and .registryMirrorMap (eq .format "bottlerocket") }} registryMirror: endpoint: {{ .publicMirror }} {{- if .registryCACert }} caCert: | {{ .registryCACert | indent 10 }} {{- end }} {{- end }} {{- if .bottlerocketSettings }} {{ .bottlerocketSettings | indent 6 }} {{- end }} {{- if .certBundles }} certBundles: {{- range .certBundles }} - name: "{{ .Name }}" data: | {{ .Data | indent 10 }} {{- end }} {{- end}} {{- if and .proxyConfig (eq .format "bottlerocket") }} proxy: httpsProxy: {{.httpsProxy}} noProxy: {{ range .noProxy }} - {{ . }} {{- end }} {{- end }} nodeRegistration: ignorePreflightErrors: - DirAvailable--etc-kubernetes-manifests kubeletExtraArgs: provider-id: PROVIDER_ID read-only-port: "0" anonymous-auth: "false" {{- if .kubeletExtraArgs }} {{ .kubeletExtraArgs.ToYaml | indent 10 }} {{- end }} {{- if not .workerNodeGroupConfigurations }} taints: [] {{- end }} {{- if and .workerNodeGroupConfigurations .controlPlaneTaints }} taints: {{- range .controlPlaneTaints}} - key: {{ .Key }} value: {{ .Value }} effect: {{ .Effect }} {{- if .TimeAdded }} timeAdded: {{ .TimeAdded }} {{- end }} {{- end }} {{- end }} files: {{- if not .cpSkipLoadBalancerDeployment }} - content: | apiVersion: v1 kind: Pod metadata: creationTimestamp: null name: kube-vip namespace: kube-system spec: containers: - args: - manager env: - name: vip_arp value: "true" - name: port value: "6443" - name: vip_cidr value: "32" - name: cp_enable value: "true" - name: cp_namespace value: kube-system - name: vip_ddns value: "false" - name: vip_leaderelection value: "true" - name: vip_leaseduration value: "15" - name: vip_renewdeadline value: "10" - name: vip_retryperiod value: "2" - name: address value: {{.controlPlaneEndpointIp}} {{- if and (not .workerNodeGroupConfigurations) (not .skipLoadBalancerDeployment) }} # kube-vip daemon in worker node watches for LoadBalancer services. # When there is no worker node, make kube-vip in control-plane nodes watch - name: svc_enable value: "true" {{- end }} image: {{ .kubeVipImage }} imagePullPolicy: IfNotPresent name: kube-vip resources: {} securityContext: capabilities: add: - NET_ADMIN - NET_RAW volumeMounts: - mountPath: /etc/kubernetes/admin.conf name: kubeconfig hostNetwork: true volumes: - hostPath: path: /etc/kubernetes/admin.conf name: kubeconfig status: {} owner: root:root path: /etc/kubernetes/manifests/kube-vip.yaml {{- end }} {{- if .awsIamAuth}} - content: | # clusters refers to the remote service. clusters: - name: aws-iam-authenticator cluster: certificate-authority: /var/aws-iam-authenticator/cert.pem server: https://localhost:21362/authenticate # users refers to the API Server's webhook configuration # (we don't need to authenticate the API server). users: - name: apiserver # kubeconfig files require a context. Provide one for the API Server. current-context: webhook contexts: - name: webhook context: cluster: aws-iam-authenticator user: apiserver permissions: "0640" owner: root:root path: /var/lib/kubeadm/aws-iam-authenticator/kubeconfig.yaml - contentFrom: secret: name: {{.clusterName}}-aws-iam-authenticator-ca key: cert.pem permissions: "0640" owner: root:root path: /var/lib/kubeadm/aws-iam-authenticator/pki/cert.pem - contentFrom: secret: name: {{.clusterName}}-aws-iam-authenticator-ca key: key.pem permissions: "0640" owner: root:root path: /var/lib/kubeadm/aws-iam-authenticator/pki/key.pem {{- end}} {{- if (ne .format "bottlerocket") }} {{- if .proxyConfig }} - content: | [Service] Environment="HTTP_PROXY={{.httpProxy}}" Environment="HTTPS_PROXY={{.httpsProxy}}" Environment="NO_PROXY={{ stringsJoin .noProxy "," }}" owner: root:root path: /etc/systemd/system/containerd.service.d/http-proxy.conf {{- end }} {{- if .registryCACert }} - content: | {{ .registryCACert | indent 10 }} owner: root:root path: "/etc/containerd/certs.d/{{ .mirrorBase }}/ca.crt" {{- end }} {{- if .registryMirrorMap }} - content: | [plugins."io.containerd.grpc.v1.cri".registry.mirrors] {{- range $orig, $mirror := .registryMirrorMap }} [plugins."io.containerd.grpc.v1.cri".registry.mirrors."{{ $orig }}"] endpoint = ["https://{{ $mirror }}"] {{- end }} {{- if or .registryCACert .insecureSkip }} [plugins."io.containerd.grpc.v1.cri".registry.configs."{{ .mirrorBase }}".tls] {{- if .registryCACert }} ca_file = "/etc/containerd/certs.d/{{ .mirrorBase }}/ca.crt" {{- end }} {{- if .insecureSkip }} insecure_skip_verify = {{.insecureSkip}} {{- end }} {{- end }} {{- if .registryAuth }} [plugins."io.containerd.grpc.v1.cri".registry.configs."{{ .mirrorBase }}".auth] username = "{{.registryUsername}}" password = "{{.registryPassword}}" {{- end }} owner: root:root path: "/etc/containerd/config_append.toml" {{- end }} {{- end }} {{- if .cpNtpServers }} ntp: enabled: true servers: {{ range .cpNtpServers }} - {{ . }} {{- end }} {{- end }} {{- if and (or .proxyConfig .registryMirrorMap) (ne .format "bottlerocket") }} preKubeadmCommands: {{- if .registryMirrorMap }} - cat /etc/containerd/config_append.toml >> /etc/containerd/config.toml {{- end}} - sudo systemctl daemon-reload - sudo systemctl restart containerd {{- end }} users: - name: {{.controlPlaneSshUsername}} sshAuthorizedKeys: - '{{.controlPlaneSshAuthorizedKey}}' sudo: ALL=(ALL) NOPASSWD:ALL format: {{.format}} machineTemplate: infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: TinkerbellMachineTemplate name: {{.controlPlaneTemplateName}} replicas: {{.controlPlaneReplicas}} {{- if .upgradeRolloutStrategy }} rolloutStrategy: rollingUpdate: maxSurge: {{.maxSurge}} {{- end }} version: {{.kubernetesVersion}} --- {{- if .externalEtcd }} kind: EtcdadmCluster apiVersion: etcdcluster.cluster.x-k8s.io/v1beta1 metadata: name: {{.clusterName}}-etcd namespace: {{.eksaSystemNamespace}} spec: replicas: {{.externalEtcdReplicas}} etcdadmConfigSpec: etcdadmBuiltin: true format: {{.format}} {{- if (eq .format "bottlerocket") }} bottlerocketConfig: etcdImage: {{.etcdImage}} bootstrapImage: {{.bottlerocketBootstrapRepository}}:{{.bottlerocketBootstrapVersion}} pauseImage: {{.pauseRepository}}:{{.pauseVersion}} {{- else}} cloudInitConfig: version: {{.externalEtcdVersion}} installDir: "/usr/bin" preEtcdadmCommands: - hostname "{{`{{ ds.meta_data.hostname }}`}}" - echo "::1 ipv6-localhost ipv6-loopback" >/etc/hosts - echo "127.0.0.1 localhost" >>/etc/hosts - echo "127.0.0.1 {{`{{ ds.meta_data.hostname }}`}}" >>/etc/hosts - echo "{{`{{ ds.meta_data.hostname }}`}}" >/etc/hostname {{- end }} {{- if .etcdCipherSuites }} cipherSuites: {{.etcdCipherSuites}} {{- end }} users: - name: {{.etcdSshUsername}} sshAuthorizedKeys: - '{{.etcdSshAuthorizedKey}}' sudo: ALL=(ALL) NOPASSWD:ALL {{- if .proxyConfig }} proxy: httpProxy: {{ .httpProxy }} httpsProxy: {{ .httpsProxy }} noProxy: {{ range .noProxy }} - {{ . }} {{- end }} {{- end }} {{- if .registryMirrorMap }} registryMirror: endpoint: {{ .publicMirror }} {{- if .registryCACert }} caCert: | {{ .registryCACert | indent 8 }} {{- end }} {{- end }} infrastructureTemplate: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: TinkerbellMachineTemplate name: {{.etcdTemplateName}} --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: TinkerbellMachineTemplate metadata: name: {{.etcdTemplateName}} namespace: {{.eksaSystemNamespace}} spec: template: {{- if and .etcdTemplateOverride (ne .format "")}} spec: hardwareAffinity: required: - labelSelector: matchLabels: {{ range $key, $value := .etcdHardwareSelector}} {{ $key }}: {{ $value}} {{- end }} templateOverride: | {{.etcdTemplateOverride | indent 8}} {{- end }} {{- if (eq .etcdTemplateOverride "") }} spec: {} {{- end }} --- {{- end }} apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: TinkerbellMachineTemplate metadata: name: {{.controlPlaneTemplateName}} namespace: {{.eksaSystemNamespace}} spec: template: {{- if and .controlPlanetemplateOverride (ne .format "")}} spec: hardwareAffinity: required: - labelSelector: matchLabels: {{ range $key, $value := .hardwareSelector}} {{ $key }}: {{ $value}} {{- end }} templateOverride: | {{.controlPlanetemplateOverride | indent 8}} {{- end }} {{- if (eq .controlPlanetemplateOverride "") }} spec: {} {{- end }} --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: TinkerbellCluster metadata: name: {{.clusterName}} namespace: {{.eksaSystemNamespace}} spec: imageLookupFormat: {{.osDistro}}-{{.osVersion}}-kube-{{.kubernetesVersion}}.raw.gz imageLookupBaseRegistry: {{.baseRegistry}}/ {{- if .registryAuth }} --- apiVersion: v1 kind: Secret metadata: name: registry-credentials namespace: {{.eksaSystemNamespace}} labels: clusterctl.cluster.x-k8s.io/move: "true" stringData: username: "{{.registryUsername}}" password: "{{.registryPassword}}" {{- end }}