Skip to content

Commit

Permalink
Add support for Hetzner Private Networking (#596)
Browse files Browse the repository at this point in the history
* Hetzner private networking

Signed-off-by: Artiom Diomin <[email protected]>

* Finish Hetzner Networks support

* Fix cluster-cidr flag for Hetzner CCM

* Update CHANGELOG.md

* Address review comments
  • Loading branch information
kron4eg authored and kubermatic-bot committed Oct 9, 2019
1 parent f545579 commit 23c5fbb
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
* Add an optional `TrustDevicePath` field to the worker spec for OpenStack ([#686](https://github.com/kubermatic/kubeone/pull/686))
* Add optional `BillingCycle` and `Tags` fields to the worker spec for Packet ([#686](https://github.com/kubermatic/kubeone/pull/686))
* Add ability to use AWS spot instances for worker nodes using the `isSpotInstance` field ([#686](https://github.com/kubermatic/kubeone/pull/686))
* Add support for Hetzner Private Networking ([#596](https://github.com/kubermatic/kubeone/pull/596))
* Add `ShortNames` and `AdditionalPrinterColumns` for Cluster-API CRDs ([#689](https://github.com/kubermatic/kubeone/pull/689))
* Add an example KubeOne Ansible playbook ([#576](https://github.com/kubermatic/kubeone/pull/576))

Expand Down
27 changes: 25 additions & 2 deletions examples/terraform/hetzner/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ resource "hcloud_ssh_key" "kubeone" {
public_key = file(var.ssh_public_key_file)
}

resource "hcloud_network" "net" {
name = var.cluster_name
ip_range = var.ip_range
}

resource "hcloud_network_subnet" "kubeone" {
network_id = hcloud_network.net.id
type = "server"
network_zone = var.network_zone
ip_range = var.ip_range
}

resource "hcloud_server_network" "control_plane" {
count = 3
server_id = element(hcloud_server.control_plane.*.id, count.index)
network_id = hcloud_network.net.id
}

resource "hcloud_server" "control_plane" {
count = 3
name = "${var.cluster_name}-control-plane-${count.index + 1}"
Expand All @@ -36,6 +54,11 @@ resource "hcloud_server" "control_plane" {
}
}

resource "hcloud_server_network" "lb" {
server_id = hcloud_server.lb.id
network_id = hcloud_network.net.id
}

resource "hcloud_server" "lb" {
name = "${var.cluster_name}-lb"
server_type = var.lb_type
Expand Down Expand Up @@ -63,13 +86,13 @@ resource "hcloud_server" "lb" {

locals {
rendered_lb_config = templatefile("./etc_gobetween.tpl", {
lb_targets = hcloud_server.control_plane.*.ipv4_address,
lb_targets = hcloud_server_network.control_plane.*.ip,
})
}

resource "null_resource" "lb_config" {
triggers = {
cluster_instance_ids = join(",", hcloud_server.control_plane.*.id)
cluster_instance_ids = join(",", hcloud_server_network.control_plane.*.ip)
config = local.rendered_lb_config
}

Expand Down
6 changes: 5 additions & 1 deletion examples/terraform/hetzner/output.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ output "kubeone_hosts" {
control_plane = {
cluster_name = var.cluster_name
cloud_provider = "hetzner"
private_address = [] # hetzner doesn't provide private addressed
private_address = hcloud_server_network.control_plane.*.ip
public_address = hcloud_server.control_plane.*.ipv4_address
network_id = hcloud_network.net.id
ssh_agent_socket = var.ssh_agent_socket
ssh_port = var.ssh_port
ssh_private_key_file = var.ssh_private_key_file
Expand Down Expand Up @@ -59,6 +60,9 @@ output "kubeone_workers" {
# https://github.com/kubermatic/machine-controller/blob/master/examples/hetzner-machinedeployment.yaml
serverType = var.worker_type
location = var.datacenter
networks = [
hcloud_network.net.id
]
labels = {
"${var.cluster_name}-workers" = "pool1"
}
Expand Down
9 changes: 9 additions & 0 deletions examples/terraform/hetzner/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,12 @@ variable "image" {
default = "ubuntu-18.04"
}

variable "ip_range" {
default = "192.168.0.0/16"
description = "ip range to use for private network"
}

variable "network_zone" {
default = "eu-central"
description = "network zone to use for private network"
}
3 changes: 3 additions & 0 deletions pkg/apis/kubeone/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ type ClusterNetworkConfig struct {
ServiceDomainName string `json:"serviceDomainName"`
NodePortRange string `json:"nodePortRange"`
CNI *CNI `json:"cni,omitempty"`

// +optional
NetworkID string `json:"networkID,omitempty"`
}

// CNIProvider type
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/kubeone/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ type ClusterNetworkConfig struct {
ServiceDomainName string `json:"serviceDomainName"`
NodePortRange string `json:"nodePortRange"`
CNI *CNI `json:"cni,omitempty"`

// +optional
NetworkID string `json:"networkID,omitempty"`
}

// CNIProvider type
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kubeone/v1alpha1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 26 additions & 13 deletions pkg/templates/externalccm/hetzner.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package externalccm

import (
"context"
"fmt"

"github.com/Masterminds/semver"
"github.com/pkg/errors"
Expand All @@ -36,7 +37,7 @@ import (
)

const (
hetznerCCMVersion = "v1.3.0"
hetznerCCMVersion = "v1.4.0"
hetznerSAName = "cloud-controller-manager"
hetznerDeploymentName = "hcloud-cloud-controller-manager"
)
Expand All @@ -58,7 +59,7 @@ func ensureHetzner(s *state.State) error {
}
}

dep := hetznerDeployment()
dep := hetznerDeployment(s.Cluster.ClusterNetwork.NetworkID, s.Cluster.ClusterNetwork.PodSubnet)
want, err := semver.NewConstraint("<= " + hetznerCCMVersion)
if err != nil {
return errors.Wrap(err, "failed to parse hetzner CCM version constraint")
Expand Down Expand Up @@ -104,11 +105,23 @@ func hetznerClusterRoleBinding() *rbacv1.ClusterRoleBinding {
}
}

func hetznerDeployment() *appsv1.Deployment {
func hetznerDeployment(networkID, podSubnet string) *appsv1.Deployment {
var (
replicas int32 = 1
revisions int32 = 2
replicas int32 = 1
revisions int32 = 2
hostNetwork = false
cmd = []string{
"/bin/hcloud-cloud-controller-manager",
"--cloud-provider=hcloud",
"--leader-elect=false",
"--allow-untagged-cloud",
}
)
if len(networkID) > 0 {
cmd = append(cmd, "--allocate-node-cidrs=true")
cmd = append(cmd, fmt.Sprintf("--cluster-cidr=%s", podSubnet))
hostNetwork = true
}

return &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -153,16 +166,12 @@ func hetznerDeployment() *appsv1.Deployment {
Operator: corev1.TolerationOpExists,
},
},
HostNetwork: hostNetwork,
Containers: []corev1.Container{
{
Name: "hcloud-cloud-controller-manager",
Image: "hetznercloud/hcloud-cloud-controller-manager:" + hetznerCCMVersion,
Command: []string{
"/bin/hcloud-cloud-controller-manager",
"--cloud-provider=hcloud",
"--leader-elect=false",
"--allow-untagged-cloud",
},
Name: "hcloud-cloud-controller-manager",
Image: "hetznercloud/hcloud-cloud-controller-manager:" + hetznerCCMVersion,
Command: cmd,
Env: []corev1.EnvVar{
{
Name: "NODE_NAME",
Expand All @@ -183,6 +192,10 @@ func hetznerDeployment() *appsv1.Deployment {
},
},
},
{
Name: "HCLOUD_NETWORK",
Value: networkID,
},
},
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
Expand Down
1 change: 1 addition & 0 deletions pkg/templates/machinecontroller/cloudprovider_specs.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ type HetznerSpec struct {
ServerType string `json:"serverType"`
Datacenter string `json:"datacenter"`
Location string `json:"location"`
Networks []string `json:"networks"`
Labels map[string]string `json:"labels,omitempty"`
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/terraform/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type controlPlane struct {
Bastion string `json:"bastion"`
BastionPort int `json:"bastion_port"`
BastionUser string `json:"bastion_user"`
NetworkID string `json:"network_id"`
}

// Config represents configuration in the terraform output format
Expand Down Expand Up @@ -121,6 +122,10 @@ func (c *Config) Apply(cluster *kubeonev1alpha1.KubeOneCluster) error {
cluster.Hosts = hosts
}

if len(cp.NetworkID) > 0 {
cluster.ClusterNetwork.NetworkID = cp.NetworkID
}

// Walk through all configued workersets from terraform and apply their config
// by either merging it into an existing workerSet or creating a new one
for workersetName, workersetValue := range c.KubeOneWorkers.Value {
Expand Down Expand Up @@ -320,6 +325,7 @@ func (c *Config) updateHetznerWorkerset(existingWorkerSet *kubeonev1alpha1.Worke
{key: "serverType", value: hetznerConfig.ServerType},
{key: "datacenter", value: hetznerConfig.Datacenter},
{key: "location", value: hetznerConfig.Location},
{key: "networks", value: hetznerConfig.Networks},
{key: "labels", value: hetznerConfig.Labels},
}

Expand Down

0 comments on commit 23c5fbb

Please sign in to comment.