hetzner-k3s 0.4.4 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 153385c9fce84159b90d6b77bed3e3afebd3cb0739fbd6de1e4cc91e5f1e130f
4
- data.tar.gz: '08a51842b854c2a438012c6fde115520e32fb782524a3ddd4048a772db8aeaa3'
3
+ metadata.gz: 894c97e8725c519b223e42c190f0432bcf1808c50f6f5c636bc4db06a41ed4e2
4
+ data.tar.gz: efd986dd375e93b6ed9f84e1b1bc2742f4d7146f7db76987eb0a02df29b544ee
5
5
  SHA512:
6
- metadata.gz: 9d6ac1e71d783a6b01d77863e30fae972c0983cda9e85dfcaac5fda8da0ea7a33565404aaa8efdd0594185f31c85ebc91cf92cdfe06fd9b92422aaf8c158feee
7
- data.tar.gz: 4f93a9eb6635d2c757dfbc1205023e563bfbb564ca0b0f9b839ea4b722f9fc2d7db7978ce4ab7da70d2ce23fd3559a301342f3b222522ac4df0554a9f66317bd
6
+ metadata.gz: df042a8f3da37960b0058f2c3d88a6bfafe0b1e7c4f49eeedfe840b08dcc23c7b922e1ccca893f81caf35084770fbdad261be2d2ce50ac5aebe7c0fae88cfa82
7
+ data.tar.gz: 877feedfbe211d1b2c75ce532fa6299888e570c1425cc6168cb882e8064dff9ec1d42d572c8f80f958d21acf48e7d828466f515d540c4239d9ae12b02751f505
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hetzner-k3s (0.4.3)
4
+ hetzner-k3s (0.4.7)
5
5
  bcrypt_pbkdf
6
6
  ed25519
7
7
  http
@@ -20,12 +20,12 @@ GEM
20
20
  diff-lcs (1.4.4)
21
21
  domain_name (0.5.20190701)
22
22
  unf (>= 0.0.5, < 1.0.0)
23
- dry-configurable (0.12.1)
23
+ dry-configurable (0.13.0)
24
24
  concurrent-ruby (~> 1.0)
25
- dry-core (~> 0.5, >= 0.5.0)
26
- dry-container (0.8.0)
25
+ dry-core (~> 0.6)
26
+ dry-container (0.9.0)
27
27
  concurrent-ruby (~> 1.0)
28
- dry-configurable (~> 0.1, >= 0.1.3)
28
+ dry-configurable (~> 0.13, >= 0.13.0)
29
29
  dry-core (0.7.1)
30
30
  concurrent-ruby (~> 1.0)
31
31
  dry-equalizer (0.3.0)
@@ -47,8 +47,8 @@ GEM
47
47
  dry-inflector (~> 0.1, >= 0.1.2)
48
48
  dry-logic (~> 0.4, >= 0.4.2)
49
49
  ed25519 (1.2.4)
50
- excon (0.85.0)
51
- ffi (1.15.3)
50
+ excon (0.88.0)
51
+ ffi (1.15.4)
52
52
  ffi-compiler (1.0.1)
53
53
  ffi (>= 1.0.0)
54
54
  rake
@@ -99,7 +99,7 @@ GEM
99
99
  to_regexp (0.2.1)
100
100
  unf (0.1.4)
101
101
  unf_ext
102
- unf_ext (0.0.7.7)
102
+ unf_ext (0.0.8)
103
103
  yajl-ruby (1.4.1)
104
104
  yaml-safe_load_stream (0.1.1)
105
105
 
data/README.md CHANGED
@@ -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.4 create-cluster --config-file /cluster/test.yaml
41
+ docker run --rm -it -v ${PWD}:/cluster -v ${HOME}/.ssh:/tmp/.ssh vitobotta/hetzner-k3s:v0.4.7 create-cluster --config-file /cluster/test.yaml
42
42
  ```
43
43
 
44
44
  Replace `test.yaml` with the name of your config file.
@@ -97,8 +97,20 @@ curl \
97
97
  'https://api.hetzner.cloud/v1/server_types'
98
98
  ```
99
99
 
100
+ By default, the image in use is Ubuntu 20.04, but you can specify an image to use with the `image` config option. This makes it also possible
101
+ to use a snapshot that you have already created from and existing server (for example to preinstall some tools). If you want to use a custom
102
+ snapshot you'll need to specify the **ID** of the snapshot/image, not the description you gave when you created the template server. To find
103
+ the ID of your custom image/snapshot, run:
100
104
 
101
- Note: the option `verify_host_key` is by default set to `false` to disable host key verification. This is because sometimes when creating new servers, Hetzner may assign IP addresses that were previously used by other servers you owned in the past. Therefore the host key verification would fail. If you set this option to `true` and this happens, the tool won't be able to continue creating the cluster until you resolve the issue with one of the suggestions it will give you.
105
+ ```bash
106
+ curl \
107
+ -H "Authorization: Bearer $API_TOKEN" \
108
+ 'https://api.hetzner.cloud/v1/images'
109
+ ```
110
+
111
+ Note that if you use a custom image, the creation of the servers may take longer than when using the default image.
112
+
113
+ Also note: the option `verify_host_key` is by default set to `false` to disable host key verification. This is because sometimes when creating new servers, Hetzner may assign IP addresses that were previously used by other servers you owned in the past. Therefore the host key verification would fail. If you set this option to `true` and this happens, the tool won't be able to continue creating the cluster until you resolve the issue with one of the suggestions it will give you.
102
114
 
103
115
  Finally, to create the cluster run:
104
116
 
@@ -242,6 +254,20 @@ I recommend that you create a separate Hetzner project for each cluster, because
242
254
 
243
255
  ## changelog
244
256
 
257
+ - 0.4.8
258
+ - Increase timeout with API requests to 30 seconds
259
+ - Limit number of retries for API requests to 3
260
+ - Ensure all version tags are listed for k3s (thanks @janosmiko)
261
+
262
+ - 0.4.7
263
+ - Made it possible to specify a custom image/snapshot for the servers
264
+
265
+ - 0.4.6
266
+ - Added a check to abort gracefully when for some reason one or more servers are not created, for example due to temporary problems with the Hetzner API.
267
+
268
+ - 0.4.5
269
+ - Fix network creation (bug introduced in the previous version)
270
+
245
271
  - 0.4.4
246
272
  - Add support for the new Ashburn, Virginia (USA) location
247
273
  - Automatically use a placement group so that the instances are all created on different physical hosts for high availability
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.4 \
9
+ docker build -t ${IMAGE}:v0.4.8 \
10
10
  --platform=linux/amd64 \
11
- --cache-from ${IMAGE}:v0.4.3 \
11
+ --cache-from ${IMAGE}:v0.4.7 \
12
12
  --build-arg BUILDKIT_INLINE_CACHE=1 .
13
13
 
14
- docker push vitobotta/hetzner-k3s:v0.4.4
14
+ docker push vitobotta/hetzner-k3s:v0.4.8
@@ -1,11 +1,15 @@
1
1
  ---
2
- hetzner_token: blah
2
+ hetzner_token: <your token>
3
3
  cluster_name: test
4
- kubeconfig_path: "../kubeconfig"
4
+ kubeconfig_path: "./kubeconfig"
5
5
  k3s_version: v1.21.3+k3s1
6
- ssh_key_path: "~/.ssh/id_rsa.pub"
6
+ public_ssh_key_path: "~/.ssh/id_rsa.pub"
7
+ private_ssh_key_path: "~/.ssh/id_rsa"
8
+ ssh_allowed_networks:
9
+ - 0.0.0.0/0
7
10
  verify_host_key: false
8
11
  location: nbg1
12
+ schedule_workloads_on_masters: false
9
13
  masters:
10
14
  instance_type: cpx21
11
15
  instance_count: 3
@@ -14,5 +18,5 @@ worker_node_pools:
14
18
  instance_type: cpx21
15
19
  instance_count: 4
16
20
  - name: big
17
- instance_type: cp321
21
+ instance_type: cpx31
18
22
  instance_count: 2
@@ -36,11 +36,13 @@ module Hetzner
36
36
  end
37
37
 
38
38
  def make_request &block
39
- Timeout::timeout(5) do
39
+ retries ||= 0
40
+
41
+ Timeout::timeout(30) do
40
42
  block.call
41
43
  end
42
44
  rescue Timeout::Error
43
- retry
45
+ retry if (retries += 1) < 3
44
46
  end
45
47
  end
46
48
  end
@@ -48,7 +48,7 @@ module Hetzner
48
48
  subnets: [
49
49
  {
50
50
  ip_range: "10.0.0.0/16",
51
- network_zone: (location ? "us-east" : "eu-central"),
51
+ network_zone: (location == "ash" ? "us-east" : "eu-central"),
52
52
  type: "cloud"
53
53
  }
54
54
  ]
@@ -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:, placement_group_id:)
8
+ def create(location:, instance_type:, instance_id:, firewall_id:, network_id:, ssh_key_id:, placement_group_id:, image:)
9
9
  puts
10
10
 
11
11
  server_name = "#{cluster_name}-#{instance_type}-#{instance_id}"
@@ -21,7 +21,7 @@ module Hetzner
21
21
  server_config = {
22
22
  name: server_name,
23
23
  location: location,
24
- image: "ubuntu-20.04",
24
+ image: image,
25
25
  firewalls: [
26
26
  { firewall: firewall_id }
27
27
  ],
@@ -40,12 +40,22 @@ module Hetzner
40
40
  placement_group: placement_group_id
41
41
  }
42
42
 
43
- response = hetzner_client.post("/servers", server_config).body
43
+ response = hetzner_client.post("/servers", server_config)
44
+ response_body = response.body
45
+
46
+ server = JSON.parse(response_body)["server"]
47
+
48
+ unless server
49
+ puts "Error creating server #{server_name}. Response details below:"
50
+ puts
51
+ p response
52
+ return
53
+ end
44
54
 
45
55
  puts "...server #{server_name} created."
46
56
  puts
47
57
 
48
- JSON.parse(response)["server"]
58
+ server
49
59
  end
50
60
 
51
61
  def delete(server_name:)
@@ -198,7 +198,7 @@ module Hetzner
198
198
 
199
199
  def find_available_releases
200
200
  @available_releases ||= begin
201
- response = HTTP.get("https://api.github.com/repos/k3s-io/k3s/tags").body
201
+ response = HTTP.get("https://api.github.com/repos/k3s-io/k3s/tags?per_page=999").body
202
202
  JSON.parse(response).map { |hash| hash["name"] }
203
203
  end
204
204
  rescue
@@ -120,7 +120,8 @@ class Cluster
120
120
  firewall_id: firewall_id,
121
121
  network_id: network_id,
122
122
  ssh_key_id: ssh_key_id,
123
- placement_group_id: placement_group_id
123
+ placement_group_id: placement_group_id,
124
+ image: image
124
125
  }
125
126
  end
126
127
 
@@ -144,7 +145,8 @@ class Cluster
144
145
  firewall_id: firewall_id,
145
146
  network_id: network_id,
146
147
  ssh_key_id: ssh_key_id,
147
- placement_group_id: placement_group_id
148
+ placement_group_id: placement_group_id,
149
+ image: image
148
150
  }
149
151
  end
150
152
  end
@@ -157,6 +159,10 @@ class Cluster
157
159
 
158
160
  threads.each(&:join) unless threads.empty?
159
161
 
162
+ while servers.size != server_configs.size
163
+ sleep 1
164
+ end
165
+
160
166
  puts
161
167
  threads = servers.map do |server|
162
168
  Thread.new { wait_for_ssh server }
@@ -230,28 +236,28 @@ class Cluster
230
236
  taint = schedule_workloads_on_masters? ? " " : " --node-taint CriticalAddonsOnly=true:NoExecute "
231
237
 
232
238
  <<~EOF
233
- curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="#{k3s_version}" K3S_TOKEN="#{k3s_token}" INSTALL_K3S_EXEC="server \
234
- --disable-cloud-controller \
235
- --disable servicelb \
236
- --disable traefik \
237
- --disable local-storage \
238
- --disable metrics-server \
239
- --write-kubeconfig-mode=644 \
240
- --node-name="$(hostname -f)" \
241
- --cluster-cidr=10.244.0.0/16 \
242
- --etcd-expose-metrics=true \
243
- --kube-controller-manager-arg="address=0.0.0.0" \
244
- --kube-controller-manager-arg="bind-address=0.0.0.0" \
245
- --kube-proxy-arg="metrics-bind-address=0.0.0.0" \
246
- --kube-scheduler-arg="address=0.0.0.0" \
247
- --kube-scheduler-arg="bind-address=0.0.0.0" \
248
- #{taint} \
249
- --kubelet-arg="cloud-provider=external" \
250
- --advertise-address=$(hostname -I | awk '{print $2}') \
251
- --node-ip=$(hostname -I | awk '{print $2}') \
252
- --node-external-ip=$(hostname -I | awk '{print $1}') \
253
- --flannel-iface=#{flannel_interface} \
254
- #{server} #{tls_sans}" sh -
239
+ curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="#{k3s_version}" K3S_TOKEN="#{k3s_token}" INSTALL_K3S_EXEC="server \
240
+ --disable-cloud-controller \
241
+ --disable servicelb \
242
+ --disable traefik \
243
+ --disable local-storage \
244
+ --disable metrics-server \
245
+ --write-kubeconfig-mode=644 \
246
+ --node-name="$(hostname -f)" \
247
+ --cluster-cidr=10.244.0.0/16 \
248
+ --etcd-expose-metrics=true \
249
+ --kube-controller-manager-arg="address=0.0.0.0" \
250
+ --kube-controller-manager-arg="bind-address=0.0.0.0" \
251
+ --kube-proxy-arg="metrics-bind-address=0.0.0.0" \
252
+ --kube-scheduler-arg="address=0.0.0.0" \
253
+ --kube-scheduler-arg="bind-address=0.0.0.0" \
254
+ #{taint} \
255
+ --kubelet-arg="cloud-provider=external" \
256
+ --advertise-address=$(hostname -I | awk '{print $2}') \
257
+ --node-ip=$(hostname -I | awk '{print $2}') \
258
+ --node-external-ip=$(hostname -I | awk '{print $1}') \
259
+ --flannel-iface=#{flannel_interface} \
260
+ #{server} #{tls_sans}" sh -
255
261
  EOF
256
262
  end
257
263
 
@@ -259,12 +265,12 @@ class Cluster
259
265
  flannel_interface = find_flannel_interface(worker)
260
266
 
261
267
  <<~EOF
262
- curl -sfL https://get.k3s.io | K3S_TOKEN="#{k3s_token}" INSTALL_K3S_VERSION="#{k3s_version}" K3S_URL=https://#{first_master_private_ip}:6443 INSTALL_K3S_EXEC="agent \
263
- --node-name="$(hostname -f)" \
264
- --kubelet-arg="cloud-provider=external" \
265
- --node-ip=$(hostname -I | awk '{print $2}') \
266
- --node-external-ip=$(hostname -I | awk '{print $1}') \
267
- --flannel-iface=#{flannel_interface}" sh -
268
+ curl -sfL https://get.k3s.io | K3S_TOKEN="#{k3s_token}" INSTALL_K3S_VERSION="#{k3s_version}" K3S_URL=https://#{first_master_private_ip}:6443 INSTALL_K3S_EXEC="agent \
269
+ --node-name="$(hostname -f)" \
270
+ --kubelet-arg="cloud-provider=external" \
271
+ --node-ip=$(hostname -I | awk '{print $2}') \
272
+ --node-external-ip=$(hostname -I | awk '{print $1}') \
273
+ --flannel-iface=#{flannel_interface}" sh -
268
274
  EOF
269
275
  end
270
276
 
@@ -651,4 +657,8 @@ class Cluster
651
657
  schedule_workloads_on_masters ? !!schedule_workloads_on_masters : false
652
658
  end
653
659
 
660
+ def image
661
+ configuration.dig("image") || "ubuntu-20.04"
662
+ end
663
+
654
664
  end
@@ -1,5 +1,5 @@
1
1
  module Hetzner
2
2
  module K3s
3
- VERSION = "0.4.4"
3
+ VERSION = "0.4.8"
4
4
  end
5
5
  end
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
4
+ version: 0.4.8
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-03 00:00:00.000000000 Z
11
+ date: 2021-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor