ionoscloud

package
v0.0.0-...-fd14076 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 16, 2024 License: Apache-2.0 Imports: 26 Imported by: 0

README

Cluster Autoscaler on Ionos Cloud Managed Kubernetes

The cluster autoscaler for the Ionos Cloud scales worker nodes within Managed Kubernetes cluster node pools. It can be deployed as Deployment in your cluster.

Deployment

Managed

Managed autoscaling can be enabled or disabled via Kubernetes Manager in the DCD or API. In this case a Deployment is not needed, since it will be deployed in the managed Kubernetes controlplane.

In-cluster

If you don't have a token, generate one:

curl -u '<username>:<password>' https://api.ionos.com/auth/v1/tokens/generate

Store the token in a secret:

kubectl create secret generic cloud-config --from-literal=token=MY_TOKEN

Edit example-values.yaml and deploy using helm:

helm install ionoscloud-cluster-autoscaler autoscaler/cluster-autoscaler -f example-values.yaml
Configuration

The IONOS_ADDITIONAL_HEADERS environment variable can be used to configure the client to send additional headers on each Ionos Cloud API request, such as X-Contract-Number. This can be useful for users with multiple contracts. The format is a semicolon-separated list of key:value pairs, e.g. IONOS_ADDITIONAL_HEADERS="X-Contract-Number:1234657890".

Development

The unit tests use mocks generated by mockery. To update them run:

mockery --inpackage --testonly --case snake --boilerplate-file ../../../hack/boilerplate/boilerplate.generatego.txt --name APIClient
mockery --inpackage --testonly --case snake --boilerplate-file ../../../hack/boilerplate/boilerplate.generatego.txt --name IonosCloudManager
Debugging

The global logging verbosity controlled by the --v flag is passed on to the Ionos Cloud SDK client logger. Verbosity 5 maps to Debug and 7 to Trace. Do not enable this in production, as it will print full request and response data.

Build an image

Build and push a docker image in the cluster-autoscaler directory:

make build-in-docker BUILD_TAGS=ionoscloud
make make-image BUILD_TAGS=ionoscloud TAG='<tag>' REGISTRY='<registry>'
make push-image BUILD_TAGS=ionoscloud TAG='<tag>' REGISTRY='<registry>'

If you're using rootless podman, create a symlink to docker and build the image using:

make make-image BUILD_TAGS=ionoscloud TAG='<tag>' REGISTRY='<registry>' DOCKER_NETWORK=host

Documentation

Index

Constants

View Source
const (
	// K8sNodeStateReady indicates that the Kubernetes Node was provisioned and joined the cluster.
	K8sNodeStateReady = "READY"
	// K8sNodeStateProvisioning indicates that the instance backing the Kubernetes Node is being provisioned.
	K8sNodeStateProvisioning = "PROVISIONING"
	// K8sNodeStateProvisioned indicates that the instance backing the Kubernetes Node is ready
	K8sNodeStateProvisioned = "PROVISIONED"
	// K8sNodeStateTerminating indicates that the Kubernetes Node is being deleted.
	K8sNodeStateTerminating = "TERMINATING"
	// K8sNodeStateRebuilding indicates that the Kubernetes Node is being rebuilt.
	K8sNodeStateRebuilding = "REBUILDING"
)
View Source
const (
	// ProviderIDPrefix is the prefix of the provider id of a Kubernetes node object.
	ProviderIDPrefix = "ionos://"
	// ErrorCodeUnknownState is set if the IonosCloud Kubernetes instace has an unknown state.
	ErrorCodeUnknownState = "UNKNOWN_STATE"
)
View Source
const (
	// GPULabel is the label added to nodes with GPU resource.
	GPULabel = ""
)

Variables

This section is empty.

Functions

func BuildIonosCloud

BuildIonosCloud builds the IonosCloud cloud provider.

func RegisterMetrics

func RegisterMetrics()

RegisterMetrics registers all IonosCloud metrics.

Types

type APIClient

type APIClient interface {
	K8sNodepoolsFindById(ctx context.Context, k8sClusterId string, nodepoolId string) ionos.ApiK8sNodepoolsFindByIdRequest
	K8sNodepoolsFindByIdExecute(r ionos.ApiK8sNodepoolsFindByIdRequest) (ionos.KubernetesNodePool, *ionos.APIResponse, error)
	K8sNodepoolsNodesGet(ctx context.Context, k8sClusterId string, nodepoolId string) ionos.ApiK8sNodepoolsNodesGetRequest
	K8sNodepoolsNodesGetExecute(r ionos.ApiK8sNodepoolsNodesGetRequest) (ionos.KubernetesNodes, *ionos.APIResponse, error)
	K8sNodepoolsNodesDelete(ctx context.Context, k8sClusterId string, nodepoolId string, nodeId string) ionos.ApiK8sNodepoolsNodesDeleteRequest
	K8sNodepoolsNodesDeleteExecute(r ionos.ApiK8sNodepoolsNodesDeleteRequest) (*ionos.APIResponse, error)
	K8sNodepoolsPut(ctx context.Context, k8sClusterId string, nodepoolId string) ionos.ApiK8sNodepoolsPutRequest
	K8sNodepoolsPutExecute(r ionos.ApiK8sNodepoolsPutRequest) (ionos.KubernetesNodePool, *ionos.APIResponse, error)
}

APIClient provides a subset of API calls necessary to perform autoscaling.

func NewAPIClient

func NewAPIClient(cfg *Config, userAgent string) APIClient

NewAPIClient creates a new IonosCloud API client.

type AutoscalingClient

type AutoscalingClient struct {
	// contains filtered or unexported fields
}

AutoscalingClient is a client abstraction used for autoscaling.

func NewAutoscalingClient

func NewAutoscalingClient(config *Config, userAgent string) *AutoscalingClient

NewAutoscalingClient contructs a new autoscaling client.

func (*AutoscalingClient) DeleteNode

func (c *AutoscalingClient) DeleteNode(nodePoolID, nodeID string) error

DeleteNode starts node deletion.

func (*AutoscalingClient) GetNodePool

func (c *AutoscalingClient) GetNodePool(id string) (*ionos.KubernetesNodePool, error)

GetNodePool gets a node pool.

func (*AutoscalingClient) ListNodes

func (c *AutoscalingClient) ListNodes(nodePoolID string) ([]ionos.KubernetesNode, error)

ListNodes lists nodes.

func (*AutoscalingClient) ResizeNodePool

func (c *AutoscalingClient) ResizeNodePool(id string, targetSize int32) error

ResizeNodePool sets the target size of a node pool and starts the resize process. The node pool target size cannot be changed until this operation finishes.

func (*AutoscalingClient) WaitForNodePoolResize

func (c *AutoscalingClient) WaitForNodePoolResize(id string, size int) error

WaitForNodePoolResize polls the node pool until it is in state ACTIVE.

type Config

type Config struct {
	// ClusterID is the ID of the cluster to autoscale.
	ClusterID string
	// Token is an IonosCloud API access token.
	Token string
	// Endpoint overrides the default API URL.
	Endpoint string
	// Insecure configures the IonosCloud API client to use insecure connection.
	Insecure bool
	// PollTimeout is the timeout for polling a node pool after an update.
	PollTimeout time.Duration
	// PollInterval is the interval in which a node pool is polled after an update.
	PollInterval time.Duration
	// TokensPath points to a directory that contains token files
	TokensPath string
	// AdditionalHeaders are additional HTTP headers to append to each IonosCloud API request.
	AdditionalHeaders map[string]string
}

Config holds information necessary to construct IonosCloud API clients.

func LoadConfigFromEnv

func LoadConfigFromEnv() (*Config, error)

LoadConfigFromEnv loads the IonosCloud client config from env.

type IonosCache

type IonosCache struct {
	// contains filtered or unexported fields
}

IonosCache caches resources to reduce API calls. Cached state includes autoscaling limits, sizes and target sizes, a mapping of instances to node groups, and a simple lock mechanism to prevent invalid node group writes.

func NewIonosCache

func NewIonosCache() *IonosCache

NewIonosCache initializes a new IonosCache.

func (*IonosCache) AddNodeGroup

func (cache *IonosCache) AddNodeGroup(newPool cloudprovider.NodeGroup)

AddNodeGroup adds a node group to the cache.

func (*IonosCache) GetNodeGroupForNode

func (cache *IonosCache) GetNodeGroupForNode(nodeID string) cloudprovider.NodeGroup

GetNodeGroupForNode returns the node group for the given node. Returns nil if either the mapping or the node group is not cached.

func (*IonosCache) GetNodeGroupIDs

func (cache *IonosCache) GetNodeGroupIDs() []string

GetNodeGroupIDs returns an unsorted list of cached node group ids.

func (*IonosCache) GetNodeGroupSize

func (cache *IonosCache) GetNodeGroupSize(id string) (int, bool)

GetNodeGroupSize gets the node group's size. Return true if the size was in the cache.

func (*IonosCache) GetNodeGroupTargetSize

func (cache *IonosCache) GetNodeGroupTargetSize(id string) (int, bool)

GetNodeGroupTargetSize gets the node group's target size. Return true if the target size was in the cache.

func (*IonosCache) GetNodeGroups

func (cache *IonosCache) GetNodeGroups() []cloudprovider.NodeGroup

GetNodeGroups returns an unsorted list of cached node groups.

func (*IonosCache) InvalidateNodeGroupTargetSize

func (cache *IonosCache) InvalidateNodeGroupTargetSize(id string)

InvalidateNodeGroupTargetSize deletes a node group's target size entry.

func (*IonosCache) RemoveInstanceFromCache

func (cache *IonosCache) RemoveInstanceFromCache(id string)

RemoveInstanceFromCache deletes an instance and its respective mapping to the node group from the cache.

func (*IonosCache) SetInstancesCacheForNodeGroup

func (cache *IonosCache) SetInstancesCacheForNodeGroup(id string, instances []cloudprovider.Instance)

SetInstancesCacheForNodeGroup overwrites cached instances and mappings for a node group.

func (*IonosCache) SetNodeGroupSize

func (cache *IonosCache) SetNodeGroupSize(id string, size int)

SetNodeGroupSize sets the node group's size.

func (*IonosCache) SetNodeGroupTargetSize

func (cache *IonosCache) SetNodeGroupTargetSize(id string, size int)

SetNodeGroupTargetSize sets the node group's target size.

func (*IonosCache) TryLockNodeGroup

func (cache *IonosCache) TryLockNodeGroup(nodeGroup cloudprovider.NodeGroup) bool

TryLockNodeGroup tries to write a node group lock entry. Returns true if the write was successful.

func (*IonosCache) UnlockNodeGroup

func (cache *IonosCache) UnlockNodeGroup(nodeGroup cloudprovider.NodeGroup)

UnlockNodeGroup deletes a node group lock entry if it exists.

type IonosCloudCloudProvider

type IonosCloudCloudProvider struct {
	// contains filtered or unexported fields
}

IonosCloudCloudProvider implements cloudprovider.CloudProvider.

func BuildIonosCloudCloudProvider

func BuildIonosCloudCloudProvider(manager IonosCloudManager, rl *cloudprovider.ResourceLimiter) *IonosCloudCloudProvider

BuildIonosCloudCloudProvider builds CloudProvider implementation for Ionos Cloud.

func (*IonosCloudCloudProvider) Cleanup

func (ic *IonosCloudCloudProvider) Cleanup() error

Cleanup cleans up read resources before the cloud provider is destroyed, i.e. go routines etc.

func (*IonosCloudCloudProvider) GPULabel

func (ic *IonosCloudCloudProvider) GPULabel() string

GPULabel returns the label added to nodes with GPU resource.

func (*IonosCloudCloudProvider) GetAvailableGPUTypes

func (ic *IonosCloudCloudProvider) GetAvailableGPUTypes() map[string]struct{}

GetAvailableGPUTypes return all available GPU types cloud provider supports.

func (*IonosCloudCloudProvider) GetAvailableMachineTypes

func (ic *IonosCloudCloudProvider) GetAvailableMachineTypes() ([]string, error)

GetAvailableMachineTypes get all machine types that can be requested from the cloud provider. Implementation optional.

func (*IonosCloudCloudProvider) GetNodeGpuConfig

func (ic *IonosCloudCloudProvider) GetNodeGpuConfig(node *apiv1.Node) *cloudprovider.GpuConfig

GetNodeGpuConfig returns the label, type and resource name for the GPU added to node. If node doesn't have any GPUs, it returns nil.

func (*IonosCloudCloudProvider) GetResourceLimiter

func (ic *IonosCloudCloudProvider) GetResourceLimiter() (*cloudprovider.ResourceLimiter, error)

GetResourceLimiter returns struct containing limits (max, min) for resources (cores, memory etc.).

func (*IonosCloudCloudProvider) HasInstance

func (ic *IonosCloudCloudProvider) HasInstance(node *apiv1.Node) (bool, error)

HasInstance returns whether a given node has a corresponding instance in this cloud provider

func (*IonosCloudCloudProvider) Name

func (ic *IonosCloudCloudProvider) Name() string

Name returns name of the cloud provider.

func (*IonosCloudCloudProvider) NewNodeGroup

func (ic *IonosCloudCloudProvider) NewNodeGroup(
	machineType string,
	labels map[string]string,
	systemLabels map[string]string,
	taints []apiv1.Taint,
	extraResources map[string]resource.Quantity,
) (cloudprovider.NodeGroup, error)

NewNodeGroup builds a theoretical node group based on the node definition provided. The node group is not automatically created on the cloud provider side. The node group is not returned by NodeGroups() until it is created. Implementation optional.

func (*IonosCloudCloudProvider) NodeGroupForNode

func (ic *IonosCloudCloudProvider) NodeGroupForNode(node *apiv1.Node) (cloudprovider.NodeGroup, error)

NodeGroupForNode returns the node group for the given node, nil if the node should not be processed by cluster autoscaler, or non-nil error if such occurred. Must be implemented.

func (*IonosCloudCloudProvider) NodeGroups

func (ic *IonosCloudCloudProvider) NodeGroups() []cloudprovider.NodeGroup

NodeGroups returns all node groups configured for this cloud provider.

func (*IonosCloudCloudProvider) Pricing

Pricing returns pricing model for this cloud provider or error if not available. Implementation optional.

func (*IonosCloudCloudProvider) Refresh

func (ic *IonosCloudCloudProvider) Refresh() error

Refresh is called before every main loop and can be used to dynamically update cloud provider state. In particular the list of node groups returned by NodeGroups() can change as a result of CloudProvider.Refresh().

type IonosCloudManager

type IonosCloudManager interface {
	// GetNodeGroupTargetSize gets node group target size.
	GetNodeGroupTargetSize(nodeGroup cloudprovider.NodeGroup) (int, error)
	// GetNodeGroupSize gets node group size.
	GetNodeGroupSize(nodeGroup cloudprovider.NodeGroup) (int, error)
	// SetNodeGroupSize sets the node group size.
	SetNodeGroupSize(nodeGroup cloudprovider.NodeGroup, size int) error
	// DeleteNode deletes a single node.
	DeleteNode(nodeGroup cloudprovider.NodeGroup, nodeId string) error
	// GetInstancesForNodeGroup returns the instances for the given node group.
	GetInstancesForNodeGroup(nodeGroup cloudprovider.NodeGroup) ([]cloudprovider.Instance, error)
	// GetNodeGroupForNode returns the node group that the node belongs to.
	GetNodeGroupForNode(node *apiv1.Node) cloudprovider.NodeGroup
	// TryLockNodeGroup tries to acquire a lock for a node group.
	TryLockNodeGroup(nodeGroup cloudprovider.NodeGroup) bool
	// UnlockNodeGroup releases a node group lock.
	UnlockNodeGroup(nodeGroup cloudprovider.NodeGroup)
	// GetNodeGroups returns the list of managed node groups.
	GetNodeGroups() []cloudprovider.NodeGroup
}

IonosCloudManager handles IonosCloud communication and data caching of node groups.

func CreateIonosCloudManager

func CreateIonosCloudManager(nodeGroupsConfig []string, userAgent string) (IonosCloudManager, error)

CreateIonosCloudManager initializes a new IonosCloudManager.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL