mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-05-05 07:45:27 -04:00
AB#2074: Choosable K8S Version (#277)
AB#2074: Add configurable k8s version Configurable version flow: * cli config holds/validates k8sVersion * InitCluster receive a k8sVersion arg * InitCluster creates CM "k8s-version" * kubeadm's InitConfiguration receives k8sVersion * joinservice spec mounts/reads k8s-version CM * joinservice supplies k8sVersion via JoinTicketResponse Other changes: * Remove unused test code (FakeK8SClient) * move VersionConfig map to /internal/versions * installk8sComponents is now a function instead of a method
This commit is contained in:
parent
d3466da393
commit
a68ee817ff
31 changed files with 360 additions and 191 deletions
|
@ -16,8 +16,11 @@ import (
|
|||
attestationtypes "github.com/edgelesssys/constellation/internal/attestation/types"
|
||||
"github.com/edgelesssys/constellation/internal/cloud/metadata"
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/internal/versions"
|
||||
"github.com/spf13/afero"
|
||||
"go.uber.org/zap"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
||||
)
|
||||
|
||||
|
@ -28,7 +31,7 @@ type configReader interface {
|
|||
|
||||
// configurationProvider provides kubeadm init and join configuration.
|
||||
type configurationProvider interface {
|
||||
InitConfiguration(externalCloudProvider bool) k8sapi.KubeadmInitYAML
|
||||
InitConfiguration(externalCloudProvider bool, k8sVersion string) k8sapi.KubeadmInitYAML
|
||||
JoinConfiguration(externalCloudProvider bool) k8sapi.KubeadmJoinYAML
|
||||
}
|
||||
|
||||
|
@ -79,7 +82,6 @@ func (k *KubeWrapper) InitCluster(
|
|||
ctx context.Context, autoscalingNodeGroups []string, cloudServiceAccountURI, k8sVersion string,
|
||||
id attestationtypes.ID, kmsConfig KMSConfig, sshUsers map[string]string, log *logger.Logger,
|
||||
) ([]byte, error) {
|
||||
// TODO: k8s version should be user input
|
||||
log.With(zap.String("version", k8sVersion)).Infof("Installing Kubernetes components")
|
||||
if err := k.clusterUtil.InstallComponents(ctx, k8sVersion); err != nil {
|
||||
return nil, err
|
||||
|
@ -149,7 +151,7 @@ func (k *KubeWrapper) InitCluster(
|
|||
).Infof("Setting information for node")
|
||||
|
||||
// Step 2: configure kubeadm init config
|
||||
initConfig := k.configProvider.InitConfiguration(k.cloudControllerManager.Supported())
|
||||
initConfig := k.configProvider.InitConfiguration(k.cloudControllerManager.Supported(), k8sVersion)
|
||||
initConfig.SetNodeIP(nodeIP)
|
||||
initConfig.SetCertSANs([]string{publicIP, nodeIP})
|
||||
initConfig.SetNodeName(nodeName)
|
||||
|
@ -219,16 +221,21 @@ func (k *KubeWrapper) InitCluster(
|
|||
}
|
||||
}
|
||||
|
||||
// Store the received k8sVersion in a ConfigMap, overwriting exisiting values (there shouldn't be any).
|
||||
// Joining nodes determine the kubernetes version they will install based on this ConfigMap.
|
||||
if err := k.setupK8sVersionConfigMap(ctx, k8sVersion, true); err != nil {
|
||||
return nil, fmt.Errorf("failed to setup k8s version ConfigMap: %v", err)
|
||||
}
|
||||
|
||||
k.clusterUtil.FixCilium(nodeName)
|
||||
|
||||
return k.GetKubeconfig()
|
||||
}
|
||||
|
||||
// JoinCluster joins existing Kubernetes cluster.
|
||||
func (k *KubeWrapper) JoinCluster(ctx context.Context, args *kubeadm.BootstrapTokenDiscovery, peerRole role.Role, log *logger.Logger) error {
|
||||
// TODO: k8s version should be user input
|
||||
log.With(zap.String("version", "1.23.6")).Infof("Installing Kubernetes components")
|
||||
if err := k.clusterUtil.InstallComponents(ctx, "1.23.6"); err != nil {
|
||||
func (k *KubeWrapper) JoinCluster(ctx context.Context, args *kubeadm.BootstrapTokenDiscovery, peerRole role.Role, k8sVersion string, log *logger.Logger) error {
|
||||
log.With(zap.String("version", k8sVersion)).Infof("Installing Kubernetes components")
|
||||
if err := k.clusterUtil.InstallComponents(ctx, k8sVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -357,6 +364,35 @@ func (k *KubeWrapper) setupClusterAutoscaler(instance metadata.InstanceMetadata,
|
|||
return nil
|
||||
}
|
||||
|
||||
// setupK8sVersionConfigMap applies a ConfigMap (cf. server-side apply) to consistently store the installed k8s version.
|
||||
func (k *KubeWrapper) setupK8sVersionConfigMap(ctx context.Context, k8sVersion string, forceConflicts bool) error {
|
||||
if !versions.IsSupportedK8sVersion(k8sVersion) {
|
||||
return fmt.Errorf("supplied k8s version is not supported: %v", k8sVersion)
|
||||
}
|
||||
|
||||
config := corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "k8s-version",
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
Data: map[string]string{
|
||||
"K8sVersion": k8sVersion,
|
||||
},
|
||||
}
|
||||
|
||||
// We do not use the client's Apply method here since we are handling a kubernetes-native type.
|
||||
// These types don't implement our custom Marshaler interface.
|
||||
if err := k.client.CreateConfigMap(ctx, config); err != nil {
|
||||
return fmt.Errorf("Apply in KubeWrapper.setupK8sVersionConfigMap(..) failed with: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// manuallySetLoadbalancerIP sets the loadbalancer IP of the first control plane during init.
|
||||
// The GCP guest agent does this usually, but is deployed in the cluster that doesn't exist
|
||||
// at this point. This is a workaround to set the loadbalancer IP manually, so kubeadm and kubelet
|
||||
|
@ -391,22 +427,3 @@ func k8sCompliantHostname(in string) string {
|
|||
func (k *KubeWrapper) StartKubelet() error {
|
||||
return k.clusterUtil.StartKubelet()
|
||||
}
|
||||
|
||||
type fakeK8SClient struct {
|
||||
kubeconfig []byte
|
||||
}
|
||||
|
||||
// NewFakeK8SClient creates a new, fake k8s client where apply always works.
|
||||
func NewFakeK8SClient([]byte) (k8sapi.Client, error) {
|
||||
return &fakeK8SClient{}, nil
|
||||
}
|
||||
|
||||
// Apply fakes applying Kubernetes resources.
|
||||
func (f *fakeK8SClient) Apply(resources resources.Marshaler, forceConflicts bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetKubeconfig stores the kubeconfig given to it.
|
||||
func (f *fakeK8SClient) SetKubeconfig(kubeconfig []byte) {
|
||||
f.kubeconfig = kubeconfig
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue