Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to spin up Hetzner servers from custom snapshots #4153

Merged
merged 2 commits into from
Jun 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion cluster-autoscaler/cloudprovider/hetzner/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ The cluster autoscaler for Hetzner Cloud scales worker nodes.
# Configuration

`HCLOUD_TOKEN` Required Hetzner Cloud token.

`HCLOUD_CLOUD_INIT` Base64 encoded Cloud Init yaml with commands to join the cluster, Sample [examples/cloud-init.txt for (Kubernetes 1.20.1)](examples/cloud-init.txt)
`HCLOUD_IMAGE` Defaults to `ubuntu-20.04`, @see https://docs.hetzner.cloud/#images

`HCLOUD_IMAGE` Defaults to `ubuntu-20.04`, @see https://docs.hetzner.cloud/#images. You can also use an image ID here (e.g. `15512617`), or a label selector associated with a custom snapshot (e.g. `customized_ubuntu=true`). The most recent snapshot will be used in the latter case.

marvinpinto marked this conversation as resolved.
Show resolved Hide resolved
`HCLOUD_NETWORK` Default empty , The name of the network that is used in the cluster , @see https://docs.hetzner.cloud/#networks

`HCLOUD_SSH_KEY` Default empty , This SSH Key will have access to the fresh created server, @see https://docs.hetzner.cloud/#ssh-keys

Node groups must be defined with the `--nodes=<min-servers>:<max-servers>:<instance-type>:<region>:<name>` flag.

Multiple flags will create multiple node pools. For example:
```
--nodes=1:10:CPX51:FSN1:pool1
Expand Down
37 changes: 31 additions & 6 deletions cluster-autoscaler/cloudprovider/hetzner/hetzner_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type hetznerManager struct {
nodeGroups map[string]*hetznerNodeGroup
apiCallContext context.Context
cloudInit string
image string
image *hcloud.Image
sshKey *hcloud.SSHKey
network *hcloud.Network
}
Expand All @@ -55,18 +55,43 @@ func newManager() (*hetznerManager, error) {
return nil, errors.New("`HCLOUD_CLOUD_INIT` is not specified")
}

image := os.Getenv("HCLOUD_IMAGE")
if image == "" {
image = "ubuntu-20.04"
}

client := hcloud.NewClient(hcloud.WithToken(token))
ctx := context.Background()
cloudInit, err := base64.StdEncoding.DecodeString(cloudInitBase64)
if err != nil {
return nil, fmt.Errorf("failed to parse cloud init error: %s", err)
}

imageName := os.Getenv("HCLOUD_IMAGE")
if imageName == "" {
imageName = "ubuntu-20.04"
}

// Search for an image ID corresponding to the supplied HCLOUD_IMAGE env
// variable. This value can either be an image ID itself (an int), a name
// (e.g. "ubuntu-20.04"), or a label selector associated with an image
// snapshot. In the latter case it will use the most recent snapshot.
image, _, err := client.Image.Get(ctx, imageName)
if err != nil {
return nil, fmt.Errorf("unable to find image %s: %v", imageName, err)
}
if image == nil {
images, err := client.Image.AllWithOpts(ctx, hcloud.ImageListOpts{
Type: []hcloud.ImageType{hcloud.ImageTypeSnapshot},
Status: []hcloud.ImageStatus{hcloud.ImageStatusAvailable},
Sort: []string{"created:desc"},
ListOpts: hcloud.ListOpts{
LabelSelector: imageName,
},
})

if err != nil || len(images) == 0 {
return nil, fmt.Errorf("unable to find image %s: %v", imageName, err)
}

image = images[0]
}

var network *hcloud.Network
networkName := os.Getenv("HCLOUD_NETWORK")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ func createServer(n *hetznerNodeGroup) error {
UserData: n.manager.cloudInit,
Location: &hcloud.Location{Name: n.region},
ServerType: &hcloud.ServerType{Name: n.instanceType},
Image: &hcloud.Image{Name: n.manager.image},
Image: n.manager.image,
StartAfterCreate: &StartAfterCreate,
Labels: map[string]string{
nodeGroupLabel: n.id,
Expand Down