hetzner-k3s 0.5.3 → 0.5.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 +20 -1
- data/bin/build.sh +3 -3
- data/lib/hetzner/k3s/cli.rb +66 -4
- data/lib/hetzner/k3s/cluster.rb +65 -8
- data/lib/hetzner/k3s/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb01431c858c8a03b54a66d306f7d8d1422ab83eda6b0a9d144a28be93e5d292
|
4
|
+
data.tar.gz: 3f94c6d0cb6f2e9ad88239842bab4e180910762d78b46e12e19a31cad03ab087
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50466a99a13a9388c978b26db83256556106b894ab2c7eb4ce6e119152efbbe16d5e89fc03b1353834ee12ffff8a3c465367eb368352a3cf5c4dcdbccc3f2ff9
|
7
|
+
data.tar.gz: a823f8d1c02f0c54a9343d6cc04ae67e2771eeeab890c537f13999be2937a1a5f3345d757ab8c75abfe85fdd168f86bbf76910d3cefa40ff1d35e90661f52a89
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -39,7 +39,7 @@ This will install the `hetzner-k3s` executable in your PATH.
|
|
39
39
|
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):
|
40
40
|
|
41
41
|
```bash
|
42
|
-
docker run --rm -it -v ${PWD}:/cluster -v ${HOME}/.ssh:/tmp/.ssh vitobotta/hetzner-k3s:v0.5.
|
42
|
+
docker run --rm -it -v ${PWD}:/cluster -v ${HOME}/.ssh:/tmp/.ssh vitobotta/hetzner-k3s:v0.5.4 create-cluster --config-file /cluster/test.yaml
|
43
43
|
```
|
44
44
|
|
45
45
|
Replace `test.yaml` with the name of your config file.
|
@@ -74,6 +74,25 @@ worker_node_pools:
|
|
74
74
|
additional_packages:
|
75
75
|
- somepackage
|
76
76
|
enable_encryption: true
|
77
|
+
# kube_api_server_args:
|
78
|
+
# - arg1
|
79
|
+
# - ...
|
80
|
+
# kube_scheduler_args:
|
81
|
+
# - arg1
|
82
|
+
# - ...
|
83
|
+
# kube_controller_manager_args:
|
84
|
+
# - arg1
|
85
|
+
# - ...
|
86
|
+
# kube_cloud_controller_manager_args:
|
87
|
+
# - arg1
|
88
|
+
# - ...
|
89
|
+
# kubelet_args:
|
90
|
+
# - arg1
|
91
|
+
# - ...
|
92
|
+
# kube_proxy_args:
|
93
|
+
# - arg1
|
94
|
+
# - ...
|
95
|
+
|
77
96
|
```
|
78
97
|
|
79
98
|
It should hopefully be self explanatory; you can run `hetzner-k3s releases` to see a list of the available releases from the most recent to the oldest available.
|
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.5.
|
9
|
+
docker build -t ${IMAGE}:v0.5.4 \
|
10
10
|
--platform=linux/amd64 \
|
11
|
-
--cache-from ${IMAGE}:v0.5.
|
11
|
+
--cache-from ${IMAGE}:v0.5.3 \
|
12
12
|
--build-arg BUILDKIT_INLINE_CACHE=1 .
|
13
13
|
|
14
|
-
docker push vitobotta/hetzner-k3s:v0.5.
|
14
|
+
docker push vitobotta/hetzner-k3s:v0.5.4
|
data/lib/hetzner/k3s/cli.rb
CHANGED
@@ -178,11 +178,16 @@ module Hetzner
|
|
178
178
|
[]
|
179
179
|
end
|
180
180
|
|
181
|
-
def
|
181
|
+
def valid_location?(location)
|
182
182
|
return if locations.empty? && !valid_token?
|
183
|
-
return if locations.include? configuration['location']
|
184
183
|
|
185
|
-
|
184
|
+
locations.include? location
|
185
|
+
end
|
186
|
+
|
187
|
+
def validate_masters_location
|
188
|
+
return if valid_location?(configuration['location'])
|
189
|
+
|
190
|
+
errors << 'Invalid location for master nodes - valid locations: nbg1 (Nuremberg, Germany), fsn1 (Falkenstein, Germany), hel1 (Helsinki, Finland) or ash (Ashburn, Virginia, USA)'
|
186
191
|
end
|
187
192
|
|
188
193
|
def available_releases
|
@@ -261,6 +266,14 @@ module Hetzner
|
|
261
266
|
|
262
267
|
instance_group_errors << "#{instance_group_type} has an invalid instance type" unless !valid_token? || server_types.include?(instance_group['instance_type'])
|
263
268
|
|
269
|
+
if workers
|
270
|
+
location = instance_group.fetch('location', configuration['location'])
|
271
|
+
instance_group_errors << "#{instance_group_type} has an invalid location - valid locations: nbg1 (Nuremberg, Germany), fsn1 (Falkenstein, Germany), hel1 (Helsinki, Finland) or ash (Ashburn, Virginia, USA)" unless valid_location?(location)
|
272
|
+
|
273
|
+
in_network_zone = configuration['location'] == 'ash' ? location == 'ash' : location != 'ash'
|
274
|
+
instance_group_errors << "#{instance_group_type} must be in the same network zone as the masters. If the masters are located in Ashburn, all the node pools must be located in Ashburn too, otherwise none of the node pools should be located in Ashburn." unless in_network_zone
|
275
|
+
end
|
276
|
+
|
264
277
|
if instance_group['instance_count'].is_a? Integer
|
265
278
|
if instance_group['instance_count'] < 1
|
266
279
|
instance_group_errors << "#{instance_group_type} must have at least one node"
|
@@ -343,12 +356,19 @@ module Hetzner
|
|
343
356
|
validate_public_ssh_key
|
344
357
|
validate_private_ssh_key
|
345
358
|
validate_ssh_allowed_networks
|
346
|
-
|
359
|
+
validate_masters_location
|
347
360
|
validate_k3s_version
|
348
361
|
validate_masters
|
349
362
|
validate_worker_node_pools
|
350
363
|
validate_verify_host_key
|
351
364
|
validate_additional_packages
|
365
|
+
validate_kube_api_server_args
|
366
|
+
validate_kube_scheduler_args
|
367
|
+
validate_kube_controller_manager_args
|
368
|
+
validate_kube_cloud_controller_manager_args
|
369
|
+
validate_kubelet_args
|
370
|
+
validate_kube_proxy_args
|
371
|
+
validate_network_zone
|
352
372
|
end
|
353
373
|
|
354
374
|
def validate_upgrade
|
@@ -375,6 +395,48 @@ module Hetzner
|
|
375
395
|
exit 1
|
376
396
|
end
|
377
397
|
end
|
398
|
+
|
399
|
+
def validate_kube_api_server_args
|
400
|
+
kube_api_server_args = configuration['kube_api_server_args']
|
401
|
+
return unless kube_api_server_args
|
402
|
+
|
403
|
+
errors << 'kube_api_server_args must be an array of arguments' unless kube_api_server_args.is_a? Array
|
404
|
+
end
|
405
|
+
|
406
|
+
def validate_kube_scheduler_args
|
407
|
+
kube_scheduler_args = configuration['kube_scheduler_args']
|
408
|
+
return unless kube_scheduler_args
|
409
|
+
|
410
|
+
errors << 'kube_scheduler_args must be an array of arguments' unless kube_scheduler_args.is_a? Array
|
411
|
+
end
|
412
|
+
|
413
|
+
def validate_kube_controller_manager_args
|
414
|
+
kube_controller_manager_args = configuration['kube_controller_manager_args']
|
415
|
+
return unless kube_controller_manager_args
|
416
|
+
|
417
|
+
errors << 'kube_controller_manager_args must be an array of arguments' unless kube_controller_manager_args.is_a? Array
|
418
|
+
end
|
419
|
+
|
420
|
+
def validate_kube_cloud_controller_manager_args
|
421
|
+
kube_cloud_controller_manager_args = configuration['kube_cloud_controller_manager_args']
|
422
|
+
return unless kube_cloud_controller_manager_args
|
423
|
+
|
424
|
+
errors << 'kube_cloud_controller_manager_args must be an array of arguments' unless kube_cloud_controller_manager_args.is_a? Array
|
425
|
+
end
|
426
|
+
|
427
|
+
def validate_kubelet_args
|
428
|
+
kubelet_args = configuration['kubelet_args']
|
429
|
+
return unless kubelet_args
|
430
|
+
|
431
|
+
errors << 'kubelet_args must be an array of arguments' unless kubelet_args.is_a? Array
|
432
|
+
end
|
433
|
+
|
434
|
+
def validate_kube_proxy_args
|
435
|
+
kube_proxy_args = configuration['kube_proxy_args']
|
436
|
+
return unless kube_proxy_args
|
437
|
+
|
438
|
+
errors << 'kube_proxy_args must be an array of arguments' unless kube_proxy_args.is_a? Array
|
439
|
+
end
|
378
440
|
end
|
379
441
|
end
|
380
442
|
end
|
data/lib/hetzner/k3s/cluster.rb
CHANGED
@@ -34,11 +34,17 @@ class Cluster
|
|
34
34
|
@k3s_version = configuration['k3s_version']
|
35
35
|
@masters_config = configuration['masters']
|
36
36
|
@worker_node_pools = find_worker_node_pools(configuration)
|
37
|
-
@
|
37
|
+
@masters_location = configuration['location']
|
38
38
|
@verify_host_key = configuration.fetch('verify_host_key', false)
|
39
39
|
@servers = []
|
40
40
|
@networks = configuration['ssh_allowed_networks']
|
41
41
|
@enable_encryption = configuration.fetch('enable_encryption', false)
|
42
|
+
@kube_api_server_args = configuration.fetch('kube_api_server_args', [])
|
43
|
+
@kube_scheduler_args = configuration.fetch('kube_scheduler_args', [])
|
44
|
+
@kube_controller_manager_args = configuration.fetch('kube_controller_manager_args', [])
|
45
|
+
@kube_cloud_controller_manager_args = configuration.fetch('kube_cloud_controller_manager_args', [])
|
46
|
+
@kubelet_args = configuration.fetch('kubelet_args', [])
|
47
|
+
@kube_proxy_args = configuration.fetch('kube_proxy_args', [])
|
42
48
|
|
43
49
|
create_resources
|
44
50
|
|
@@ -78,10 +84,12 @@ class Cluster
|
|
78
84
|
|
79
85
|
attr_reader :hetzner_client, :cluster_name, :kubeconfig_path, :k3s_version,
|
80
86
|
:masters_config, :worker_node_pools,
|
81
|
-
:
|
87
|
+
:masters_location, :public_ssh_key_path,
|
82
88
|
:hetzner_token, :new_k3s_version, :configuration,
|
83
89
|
:config_file, :verify_host_key, :networks, :private_ssh_key_path,
|
84
|
-
:enable_encryption
|
90
|
+
:enable_encryption, :kube_api_server_args, :kube_scheduler_args,
|
91
|
+
:kube_controller_manager_args, :kube_cloud_controller_manager_args,
|
92
|
+
:kubelet_args, :kube_proxy_args
|
85
93
|
|
86
94
|
def find_worker_node_pools(configuration)
|
87
95
|
configuration.fetch('worker_node_pools', [])
|
@@ -191,7 +199,7 @@ class Cluster
|
|
191
199
|
server = master == first_master ? ' --cluster-init ' : " --server https://#{api_server_ip}:6443 "
|
192
200
|
flannel_interface = find_flannel_interface(master)
|
193
201
|
flannel_wireguard = enable_encryption ? ' --flannel-backend=wireguard ' : ' '
|
194
|
-
|
202
|
+
extra_args = "#{kube_api_server_args_list} #{kube_scheduler_args_list} #{kube_controller_manager_args_list} #{kube_cloud_controller_manager_args_list} #{kubelet_args_list} #{kube_proxy_args_list}"
|
195
203
|
taint = schedule_workloads_on_masters? ? ' ' : ' --node-taint CriticalAddonsOnly=true:NoExecute '
|
196
204
|
|
197
205
|
<<~SCRIPT
|
@@ -211,7 +219,7 @@ class Cluster
|
|
211
219
|
--kube-proxy-arg="metrics-bind-address=0.0.0.0" \
|
212
220
|
--kube-scheduler-arg="address=0.0.0.0" \
|
213
221
|
--kube-scheduler-arg="bind-address=0.0.0.0" \
|
214
|
-
#{taint} \
|
222
|
+
#{taint} #{extra_args} \
|
215
223
|
--kubelet-arg="cloud-provider=external" \
|
216
224
|
--advertise-address=$(hostname -I | awk '{print $2}') \
|
217
225
|
--node-ip=$(hostname -I | awk '{print $2}') \
|
@@ -467,7 +475,7 @@ class Cluster
|
|
467
475
|
end
|
468
476
|
|
469
477
|
def network_id
|
470
|
-
@network_id ||= Hetzner::Network.new(hetzner_client:, cluster_name:).create(location:)
|
478
|
+
@network_id ||= Hetzner::Network.new(hetzner_client:, cluster_name:).create(location: masters_location)
|
471
479
|
end
|
472
480
|
|
473
481
|
def ssh_key_id
|
@@ -481,8 +489,8 @@ class Cluster
|
|
481
489
|
definitions << {
|
482
490
|
instance_type: master_instance_type,
|
483
491
|
instance_id: "master#{i + 1}",
|
492
|
+
location: masters_location,
|
484
493
|
placement_group_id:,
|
485
|
-
location:,
|
486
494
|
firewall_id:,
|
487
495
|
network_id:,
|
488
496
|
ssh_key_id:,
|
@@ -511,6 +519,7 @@ class Cluster
|
|
511
519
|
worker_node_pool_name = worker_node_pool['name']
|
512
520
|
worker_instance_type = worker_node_pool['instance_type']
|
513
521
|
worker_count = worker_node_pool['instance_count']
|
522
|
+
worker_location = worker_node_pool['location'] || masters_location
|
514
523
|
|
515
524
|
definitions = []
|
516
525
|
|
@@ -519,7 +528,7 @@ class Cluster
|
|
519
528
|
instance_type: worker_instance_type,
|
520
529
|
instance_id: "pool-#{worker_node_pool_name}-worker#{i + 1}",
|
521
530
|
placement_group_id: placement_group_id(worker_node_pool_name),
|
522
|
-
location
|
531
|
+
location: worker_location,
|
523
532
|
firewall_id:,
|
524
533
|
network_id:,
|
525
534
|
ssh_key_id:,
|
@@ -580,4 +589,52 @@ class Cluster
|
|
580
589
|
|
581
590
|
threads.each(&:join) unless threads.empty?
|
582
591
|
end
|
592
|
+
|
593
|
+
def kube_api_server_args_list
|
594
|
+
return '' if kube_api_server_args.empty?
|
595
|
+
|
596
|
+
kube_api_server_args.map do |arg|
|
597
|
+
" --kube-apiserver-arg=\"#{arg}\" "
|
598
|
+
end.join
|
599
|
+
end
|
600
|
+
|
601
|
+
def kube_scheduler_args_list
|
602
|
+
return '' if kube_scheduler_args.empty?
|
603
|
+
|
604
|
+
kube_scheduler_args.map do |arg|
|
605
|
+
" --kube-scheduler-arg=\"#{arg}\" "
|
606
|
+
end.join
|
607
|
+
end
|
608
|
+
|
609
|
+
def kube_controller_manager_args_list
|
610
|
+
return '' if kube_controller_manager_args.empty?
|
611
|
+
|
612
|
+
kube_controller_manager_args.map do |arg|
|
613
|
+
" --kube-controller-manager-arg=\"#{arg}\" "
|
614
|
+
end.join
|
615
|
+
end
|
616
|
+
|
617
|
+
def kube_cloud_controller_manager_args_list
|
618
|
+
return '' if kube_cloud_controller_manager_args.empty?
|
619
|
+
|
620
|
+
kube_cloud_controller_manager_args.map do |arg|
|
621
|
+
" --kube-cloud-controller-manager-arg=\"#{arg}\" "
|
622
|
+
end.join
|
623
|
+
end
|
624
|
+
|
625
|
+
def kubelet_args_list
|
626
|
+
return '' if kubelet_args.empty?
|
627
|
+
|
628
|
+
kubelet_args.map do |arg|
|
629
|
+
" --kubelet-arg=\"#{arg}\" "
|
630
|
+
end.join
|
631
|
+
end
|
632
|
+
|
633
|
+
def kube_proxy_args_list
|
634
|
+
return '' if kube_proxy_args.empty?
|
635
|
+
|
636
|
+
kube_api_server_args.map do |arg|
|
637
|
+
" --kube-proxy-arg=\"#{arg}\" "
|
638
|
+
end.join
|
639
|
+
end
|
583
640
|
end
|
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.5.
|
4
|
+
version: 0.5.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: 2022-02-
|
11
|
+
date: 2022-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bcrypt_pbkdf
|