hetzner-k3s 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|