Skip to content

Commit

Permalink
Add the ability to spin up Hetzner servers from custom snapshots
Browse files Browse the repository at this point in the history
This comes in handy when using tools such as Packer to generate customized
images.
  • Loading branch information
marvinpinto committed Jun 21, 2021
1 parent 1d4e6df commit 4344a17
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
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`).

`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
41 changes: 35 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,47 @@ 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 || image == nil {
images, err := client.Image.AllWithOpts(ctx, hcloud.ImageListOpts{
Type: []hcloud.ImageType{hcloud.ImageTypeSnapshot},
Status: []hcloud.ImageStatus{hcloud.ImageStatusAvailable},
Sort: []string{"created:desc"},
})

labelSelector := strings.Split(imageName, "=")
if len(labelSelector) != 2 {
return nil, fmt.Errorf("unable to find image %s: invalid label selector", imageName)
}

for _, i := range images {
if i.Labels[labelSelector[0]] == labelSelector[1] {
image = i
break
}
}

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

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

0 comments on commit 4344a17

Please sign in to comment.