hetzner-k3s 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +8 -3
- data/bin/build.sh +3 -3
- data/lib/hetzner/infra/network.rb +4 -3
- data/lib/hetzner/infra/placement_group.rb +55 -0
- data/lib/hetzner/infra/server.rb +3 -2
- data/lib/hetzner/k3s/cli.rb +1 -1
- data/lib/hetzner/k3s/cluster.rb +16 -3
- data/lib/hetzner/k3s/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 153385c9fce84159b90d6b77bed3e3afebd3cb0739fbd6de1e4cc91e5f1e130f
|
|
4
|
+
data.tar.gz: '08a51842b854c2a438012c6fde115520e32fb782524a3ddd4048a772db8aeaa3'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d6ac1e71d783a6b01d77863e30fae972c0983cda9e85dfcaac5fda8da0ea7a33565404aaa8efdd0594185f31c85ebc91cf92cdfe06fd9b92422aaf8c158feee
|
|
7
|
+
data.tar.gz: 4f93a9eb6635d2c757dfbc1205023e563bfbb564ca0b0f9b839ea4b722f9fc2d7db7978ce4ab7da70d2ce23fd3559a301342f3b222522ac4df0554a9f66317bd
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This is a CLI tool - based on a Ruby gem - to quickly create and manage Kubernetes clusters in [Hetzner Cloud](https://www.hetzner.com/cloud) using the lightweight Kubernetes distribution [k3s](https://k3s.io/) from [Rancher](https://rancher.com/).
|
|
4
4
|
|
|
5
|
-
Hetzner Cloud is an awesome cloud provider which offers a truly great service with the best performance/cost ratio in the market.
|
|
5
|
+
Hetzner Cloud is an awesome cloud provider which offers a truly great service with the best performance/cost ratio in the market. With Hetzner's Cloud Controller Manager and CSI driver you can provision load balancers and persistent volumes very easily.
|
|
6
6
|
|
|
7
7
|
k3s is my favorite Kubernetes distribution now because it uses much less memory and CPU, leaving more resources to workloads. It is also super quick to deploy because it's a single binary.
|
|
8
8
|
|
|
@@ -38,7 +38,7 @@ This will install the `hetzner-k3s` executable in your PATH.
|
|
|
38
38
|
Alternatively, if you don't want to set up a Ruby runtime but have Docker installed, you can use a container. Run the following from inside the directory where you have the config file for the cluster (described in the next section):
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
docker run --rm -it -v ${PWD}:/cluster -v ${HOME}/.ssh:/tmp/.ssh vitobotta/hetzner-k3s:v0.4.
|
|
41
|
+
docker run --rm -it -v ${PWD}:/cluster -v ${HOME}/.ssh:/tmp/.ssh vitobotta/hetzner-k3s:v0.4.4 create-cluster --config-file /cluster/test.yaml
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Replace `test.yaml` with the name of your config file.
|
|
@@ -86,7 +86,8 @@ If you set `masters.instance_count` to 1 then the tool will create a non highly
|
|
|
86
86
|
|
|
87
87
|
You can specify any number of worker node pools for example to have mixed nodes with different specs for different workloads.
|
|
88
88
|
|
|
89
|
-
At the moment Hetzner Cloud has
|
|
89
|
+
At the moment Hetzner Cloud has four locations: two in Germany (`nbg1`, Nuremberg and `fsn1`, Falkensteing), one in Finland (`hel1`, Helsinki) and one in the USA (`ash`, Ashburn, Virginia). Please note that the Ashburn, Virginia location has just
|
|
90
|
+
been announced and it's limited to AMD instances for now.
|
|
90
91
|
|
|
91
92
|
For the available instance types and their specs, either check from inside a project when adding a server manually or run the following with your Hetzner token:
|
|
92
93
|
|
|
@@ -241,6 +242,10 @@ I recommend that you create a separate Hetzner project for each cluster, because
|
|
|
241
242
|
|
|
242
243
|
## changelog
|
|
243
244
|
|
|
245
|
+
- 0.4.4
|
|
246
|
+
- Add support for the new Ashburn, Virginia (USA) location
|
|
247
|
+
- Automatically use a placement group so that the instances are all created on different physical hosts for high availability
|
|
248
|
+
|
|
244
249
|
- 0.4.3
|
|
245
250
|
- Fix an issue with SSH key creation
|
|
246
251
|
|
data/bin/build.sh
CHANGED
|
@@ -6,9 +6,9 @@ set -e
|
|
|
6
6
|
|
|
7
7
|
IMAGE="vitobotta/hetzner-k3s"
|
|
8
8
|
|
|
9
|
-
docker build -t ${IMAGE}:v0.4.
|
|
9
|
+
docker build -t ${IMAGE}:v0.4.4 \
|
|
10
10
|
--platform=linux/amd64 \
|
|
11
|
-
--cache-from ${IMAGE}:v0.4.
|
|
11
|
+
--cache-from ${IMAGE}:v0.4.3 \
|
|
12
12
|
--build-arg BUILDKIT_INLINE_CACHE=1 .
|
|
13
13
|
|
|
14
|
-
docker push vitobotta/hetzner-k3s:v0.4.
|
|
14
|
+
docker push vitobotta/hetzner-k3s:v0.4.4
|
|
@@ -5,7 +5,8 @@ module Hetzner
|
|
|
5
5
|
@cluster_name = cluster_name
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def create
|
|
8
|
+
def create(location:)
|
|
9
|
+
@location = location
|
|
9
10
|
puts
|
|
10
11
|
|
|
11
12
|
if network = find_network
|
|
@@ -38,7 +39,7 @@ module Hetzner
|
|
|
38
39
|
|
|
39
40
|
private
|
|
40
41
|
|
|
41
|
-
attr_reader :hetzner_client, :cluster_name
|
|
42
|
+
attr_reader :hetzner_client, :cluster_name, :location
|
|
42
43
|
|
|
43
44
|
def network_config
|
|
44
45
|
{
|
|
@@ -47,7 +48,7 @@ module Hetzner
|
|
|
47
48
|
subnets: [
|
|
48
49
|
{
|
|
49
50
|
ip_range: "10.0.0.0/16",
|
|
50
|
-
network_zone: "eu-central",
|
|
51
|
+
network_zone: (location ? "us-east" : "eu-central"),
|
|
51
52
|
type: "cloud"
|
|
52
53
|
}
|
|
53
54
|
]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Hetzner
|
|
2
|
+
class PlacementGroup
|
|
3
|
+
def initialize(hetzner_client:, cluster_name:)
|
|
4
|
+
@hetzner_client = hetzner_client
|
|
5
|
+
@cluster_name = cluster_name
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def create
|
|
9
|
+
puts
|
|
10
|
+
|
|
11
|
+
if (placement_group = find_placement_group)
|
|
12
|
+
puts "Placement group already exists, skipping."
|
|
13
|
+
puts
|
|
14
|
+
return placement_group["id"]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
puts "Creating placement group..."
|
|
18
|
+
|
|
19
|
+
response = hetzner_client.post("/placement_groups", placement_group_config).body
|
|
20
|
+
|
|
21
|
+
puts "...placement group created."
|
|
22
|
+
puts
|
|
23
|
+
|
|
24
|
+
JSON.parse(response)["placement_group"]["id"]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def delete
|
|
28
|
+
if (placement_group = find_placement_group)
|
|
29
|
+
puts "Deleting placement group..."
|
|
30
|
+
hetzner_client.delete("/placement_groups", placement_group["id"])
|
|
31
|
+
puts "...placement group deleted."
|
|
32
|
+
else
|
|
33
|
+
puts "Placement group no longer exists, skipping."
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
puts
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
attr_reader :hetzner_client, :cluster_name
|
|
42
|
+
|
|
43
|
+
def placement_group_config
|
|
44
|
+
{
|
|
45
|
+
name: cluster_name,
|
|
46
|
+
type: "spread"
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def find_placement_group
|
|
51
|
+
hetzner_client.get("/placement_groups")["placement_groups"].detect{ |placement_group| placement_group["name"] == cluster_name }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/hetzner/infra/server.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Hetzner
|
|
|
5
5
|
@cluster_name = cluster_name
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def create(location:, instance_type:, instance_id:, firewall_id:, network_id:, ssh_key_id:)
|
|
8
|
+
def create(location:, instance_type:, instance_id:, firewall_id:, network_id:, ssh_key_id:, placement_group_id:)
|
|
9
9
|
puts
|
|
10
10
|
|
|
11
11
|
server_name = "#{cluster_name}-#{instance_type}-#{instance_id}"
|
|
@@ -36,7 +36,8 @@ module Hetzner
|
|
|
36
36
|
labels: {
|
|
37
37
|
cluster: cluster_name,
|
|
38
38
|
role: (server_name =~ /master/ ? "master" : "worker")
|
|
39
|
-
}
|
|
39
|
+
},
|
|
40
|
+
placement_group: placement_group_id
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
response = hetzner_client.post("/servers", server_config).body
|
data/lib/hetzner/k3s/cli.rb
CHANGED
|
@@ -193,7 +193,7 @@ module Hetzner
|
|
|
193
193
|
|
|
194
194
|
def validate_location
|
|
195
195
|
return if locations.empty? && !valid_token?
|
|
196
|
-
errors << "Invalid location - available locations: nbg1 (Nuremberg, Germany), fsn1 (Falkenstein, Germany), hel1 (Helsinki, Finland)" unless locations.include? configuration.dig("location")
|
|
196
|
+
errors << "Invalid location - available locations: nbg1 (Nuremberg, Germany), fsn1 (Falkenstein, Germany), hel1 (Helsinki, Finland) or ash (Ashburn, Virginia, USA)" unless locations.include? configuration.dig("location")
|
|
197
197
|
end
|
|
198
198
|
|
|
199
199
|
def find_available_releases
|
data/lib/hetzner/k3s/cluster.rb
CHANGED
|
@@ -11,6 +11,7 @@ require_relative "../infra/network"
|
|
|
11
11
|
require_relative "../infra/ssh_key"
|
|
12
12
|
require_relative "../infra/server"
|
|
13
13
|
require_relative "../infra/load_balancer"
|
|
14
|
+
require_relative "../infra/placement_group"
|
|
14
15
|
|
|
15
16
|
require_relative "../k3s/client_patch"
|
|
16
17
|
|
|
@@ -89,6 +90,11 @@ class Cluster
|
|
|
89
90
|
master_instance_type = masters_config["instance_type"]
|
|
90
91
|
masters_count = masters_config["instance_count"]
|
|
91
92
|
|
|
93
|
+
placement_group_id = Hetzner::PlacementGroup.new(
|
|
94
|
+
hetzner_client: hetzner_client,
|
|
95
|
+
cluster_name: cluster_name
|
|
96
|
+
).create
|
|
97
|
+
|
|
92
98
|
firewall_id = Hetzner::Firewall.new(
|
|
93
99
|
hetzner_client: hetzner_client,
|
|
94
100
|
cluster_name: cluster_name
|
|
@@ -97,7 +103,7 @@ class Cluster
|
|
|
97
103
|
network_id = Hetzner::Network.new(
|
|
98
104
|
hetzner_client: hetzner_client,
|
|
99
105
|
cluster_name: cluster_name
|
|
100
|
-
).create
|
|
106
|
+
).create(location: location)
|
|
101
107
|
|
|
102
108
|
ssh_key_id = Hetzner::SSHKey.new(
|
|
103
109
|
hetzner_client: hetzner_client,
|
|
@@ -113,7 +119,8 @@ class Cluster
|
|
|
113
119
|
instance_id: "master#{i+1}",
|
|
114
120
|
firewall_id: firewall_id,
|
|
115
121
|
network_id: network_id,
|
|
116
|
-
ssh_key_id: ssh_key_id
|
|
122
|
+
ssh_key_id: ssh_key_id,
|
|
123
|
+
placement_group_id: placement_group_id
|
|
117
124
|
}
|
|
118
125
|
end
|
|
119
126
|
|
|
@@ -136,7 +143,8 @@ class Cluster
|
|
|
136
143
|
instance_id: "pool-#{worker_node_pool_name}-worker#{i+1}",
|
|
137
144
|
firewall_id: firewall_id,
|
|
138
145
|
network_id: network_id,
|
|
139
|
-
ssh_key_id: ssh_key_id
|
|
146
|
+
ssh_key_id: ssh_key_id,
|
|
147
|
+
placement_group_id: placement_group_id
|
|
140
148
|
}
|
|
141
149
|
end
|
|
142
150
|
end
|
|
@@ -158,6 +166,11 @@ class Cluster
|
|
|
158
166
|
end
|
|
159
167
|
|
|
160
168
|
def delete_resources
|
|
169
|
+
Hetzner::PlacementGroup.new(
|
|
170
|
+
hetzner_client: hetzner_client,
|
|
171
|
+
cluster_name: cluster_name
|
|
172
|
+
).delete
|
|
173
|
+
|
|
161
174
|
Hetzner::LoadBalancer.new(
|
|
162
175
|
hetzner_client: hetzner_client,
|
|
163
176
|
cluster_name: cluster_name
|
data/lib/hetzner/k3s/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hetzner-k3s
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vito Botta
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-11-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: thor
|
|
@@ -140,6 +140,7 @@ files:
|
|
|
140
140
|
- lib/hetzner/infra/firewall.rb
|
|
141
141
|
- lib/hetzner/infra/load_balancer.rb
|
|
142
142
|
- lib/hetzner/infra/network.rb
|
|
143
|
+
- lib/hetzner/infra/placement_group.rb
|
|
143
144
|
- lib/hetzner/infra/server.rb
|
|
144
145
|
- lib/hetzner/infra/ssh_key.rb
|
|
145
146
|
- lib/hetzner/k3s/cli.rb
|