hetzner-k3s 0.5.4 → 0.5.7

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: fb01431c858c8a03b54a66d306f7d8d1422ab83eda6b0a9d144a28be93e5d292
4
- data.tar.gz: 3f94c6d0cb6f2e9ad88239842bab4e180910762d78b46e12e19a31cad03ab087
3
+ metadata.gz: 1d75621e1a64fc2a2cc874811aed89a81086943d4099d1f651ee7193f01d1add
4
+ data.tar.gz: f6b6845cc0701d771701a3ca4551722da0d8fd4e71eb63001974026a266a6a5d
5
5
  SHA512:
6
- metadata.gz: 50466a99a13a9388c978b26db83256556106b894ab2c7eb4ce6e119152efbbe16d5e89fc03b1353834ee12ffff8a3c465367eb368352a3cf5c4dcdbccc3f2ff9
7
- data.tar.gz: a823f8d1c02f0c54a9343d6cc04ae67e2771eeeab890c537f13999be2937a1a5f3345d757ab8c75abfe85fdd168f86bbf76910d3cefa40ff1d35e90661f52a89
6
+ metadata.gz: 32925df0b7b2d4af9705d8cc563ed34d8dc181ec37c5c7063504a24f56cc383fdb6871d27daa8fb456979db1f6e2310567a122455a5a53894260ba4bb65b1c92
7
+ data.tar.gz: d8374b7a45ec03331877c8307297be4fade4237ae2c5fc07545631f112106ed74e068a4605bd8414e3a6cc903838c39cad903df4278ab65f49442705b0460e2a
data/.rubocop.yml CHANGED
@@ -119,3 +119,17 @@ Metrics/ParameterLists:
119
119
  Style/FrozenStringLiteralComment:
120
120
  Exclude:
121
121
  - exe/hetzner-k3s
122
+ Lint/RefinementImportMethods: # new in 1.27
123
+ Enabled: true
124
+ Security/CompoundHash: # new in 1.28
125
+ Enabled: true
126
+ Style/EnvHome: # new in 1.29
127
+ Enabled: true
128
+ Style/FetchEnvVar: # new in 1.28
129
+ Enabled: true
130
+ Style/NestedFileDirname: # new in 1.26
131
+ Enabled: true
132
+ Style/ObjectThen: # new in 1.28
133
+ Enabled: true
134
+ Style/RedundantInitialize: # new in 1.27
135
+ Enabled: true
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.1.0
1
+ ruby-3.1.2
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:3.1.0-alpine
1
+ FROM ruby:3.1.2-alpine
2
2
 
3
3
  RUN apk update --no-cache \
4
4
  && apk add build-base git openssh-client curl bash
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hetzner-k3s (0.5.4)
4
+ hetzner-k3s (0.5.6)
5
5
  bcrypt_pbkdf
6
6
  ed25519
7
7
  http
@@ -87,4 +87,4 @@ DEPENDENCIES
87
87
  rubocop
88
88
 
89
89
  BUNDLED WITH
90
- 2.3.4
90
+ 2.3.14
data/README.md CHANGED
@@ -26,7 +26,7 @@ All that is needed to use this tool is
26
26
 
27
27
  ## Installation
28
28
 
29
- Once you have the Ruby runtime up and running (3.1.0 or newer), you just need to install the gem:
29
+ Once you have the Ruby runtime up and running (3.1.2 or newer), you just need to install the gem:
30
30
 
31
31
  ```bash
32
32
  gem install hetzner-k3s
@@ -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.4 create-cluster --config-file /cluster/test.yaml
42
+ docker run --rm -it -v ${PWD}:/cluster -v ${HOME}/.ssh:/tmp/.ssh vitobotta/hetzner-k3s:v0.5.7 create-cluster --config-file /cluster/test.yaml
43
43
  ```
44
44
 
45
45
  Replace `test.yaml` with the name of your config file.
@@ -73,6 +73,11 @@ worker_node_pools:
73
73
  instance_count: 2
74
74
  additional_packages:
75
75
  - somepackage
76
+ post_create_commands:
77
+ - apt update
78
+ - apt upgrade -y
79
+ - apt autoremove -y
80
+ - shutdown -r now
76
81
  enable_encryption: true
77
82
  # kube_api_server_args:
78
83
  # - arg1
@@ -109,7 +114,7 @@ If you set `masters.instance_count` to 1 then the tool will create a non highly
109
114
 
110
115
  You can specify any number of worker node pools for example to have mixed nodes with different specs for different workloads.
111
116
 
112
- 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
117
+ At the moment Hetzner Cloud has four locations: two in Germany (`nbg1`, Nuremberg and `fsn1`, Falkenstein), one in Finland (`hel1`, Helsinki) and one in the USA (`ash`, Ashburn, Virginia). Please note that the Ashburn, Virginia location has just
113
118
  been announced and it's limited to AMD instances for now.
114
119
 
115
120
  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:
@@ -194,6 +199,15 @@ Note that the API server will briefly be unavailable during the upgrade of the c
194
199
 
195
200
  To check the upgrade progress, run `watch kubectl get nodes -owide`. You will see the masters being upgraded one per time, followed by the worker nodes.
196
201
 
202
+ ## Upgrade the OS on nodes
203
+
204
+ The easiest way to upgrade the OS on existing nodes is actually to replace them, as it happens with managed Kubernetes service. To do this:
205
+
206
+ - drain one node
207
+ - delete the node from Kubernetes
208
+ - delete the node from the Hetzner console
209
+ - re-run the script to recreate the deleted node with an updated OS
210
+ - proceed with the next node
197
211
 
198
212
  ### What to do if the upgrade doesn't go smoothly
199
213
 
data/bin/build.sh CHANGED
@@ -2,13 +2,11 @@
2
2
 
3
3
  set -e
4
4
 
5
-
6
-
7
5
  IMAGE="vitobotta/hetzner-k3s"
8
6
 
9
- docker build -t ${IMAGE}:v0.5.4 \
7
+ docker build -t ${IMAGE}:v0.5.7 \
10
8
  --platform=linux/amd64 \
11
- --cache-from ${IMAGE}:v0.5.3 \
9
+ --cache-from ${IMAGE}:v0.5.6 \
12
10
  --build-arg BUILDKIT_INLINE_CACHE=1 .
13
11
 
14
- docker push vitobotta/hetzner-k3s:v0.5.4
12
+ docker push vitobotta/hetzner-k3s:v0.5.7
data/hetzner-k3s.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = 'A CLI to create a Kubernetes cluster in Hetzner Cloud very quickly using k3s.'
13
13
  spec.homepage = 'https://github.com/vitobotta/hetzner-k3s'
14
14
  spec.license = 'MIT'
15
- spec.required_ruby_version = Gem::Requirement.new('>= 3.1.0')
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.1.2')
16
16
 
17
17
  # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
18
18
 
@@ -7,8 +7,9 @@ module Hetzner
7
7
  @cluster_name = cluster_name
8
8
  end
9
9
 
10
- def create(location:, instance_type:, instance_id:, firewall_id:, network_id:, ssh_key_id:, placement_group_id:, image:, additional_packages: [])
10
+ def create(location:, instance_type:, instance_id:, firewall_id:, network_id:, ssh_key_id:, placement_group_id:, image:, additional_packages: [], additional_post_create_commands: [])
11
11
  @additional_packages = additional_packages
12
+ @additional_post_create_commands = additional_post_create_commands
12
13
 
13
14
  puts
14
15
 
@@ -74,29 +75,42 @@ module Hetzner
74
75
 
75
76
  private
76
77
 
77
- attr_reader :hetzner_client, :cluster_name, :additional_packages
78
+ attr_reader :hetzner_client, :cluster_name, :additional_packages, :additional_post_create_commands
78
79
 
79
80
  def find_server(server_name)
80
81
  hetzner_client.get('/servers?sort=created:desc')['servers'].detect { |network| network['name'] == server_name }
81
82
  end
82
83
 
83
84
  def user_data
84
- packages = ['fail2ban', 'wireguard']
85
+ packages = %w[fail2ban wireguard]
85
86
  packages += additional_packages if additional_packages
86
87
  packages = "'#{packages.join("', '")}'"
87
88
 
89
+ post_create_commands = [
90
+ 'crontab -l > /etc/cron_bkp',
91
+ 'echo "@reboot echo true > /etc/ready" >> /etc/cron_bkp',
92
+ 'crontab /etc/cron_bkp',
93
+ 'sed -i \'s/[#]*PermitRootLogin yes/PermitRootLogin prohibit-password/g\' /etc/ssh/sshd_config',
94
+ 'sed -i \'s/[#]*PasswordAuthentication yes/PasswordAuthentication no/g\' /etc/ssh/sshd_config',
95
+ 'systemctl restart sshd',
96
+ 'systemctl stop systemd-resolved',
97
+ 'systemctl disable systemd-resolved',
98
+ 'rm /etc/resolv.conf',
99
+ 'echo \'nameserver 1.1.1.1\' > /etc/resolv.conf',
100
+ 'echo \'nameserver 1.0.0.1\' >> /etc/resolv.conf'
101
+ ]
102
+
103
+ post_create_commands += additional_post_create_commands if additional_post_create_commands
104
+
105
+ post_create_commands += ['shutdown -r now'] if post_create_commands.grep(/shutdown|reboot/).grep_v(/@reboot/).empty?
106
+
107
+ post_create_commands = " - #{post_create_commands.join("\n - ")}"
108
+
88
109
  <<~YAML
89
110
  #cloud-config
90
111
  packages: [#{packages}]
91
112
  runcmd:
92
- - sed -i 's/[#]*PermitRootLogin yes/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config
93
- - sed -i 's/[#]*PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
94
- - systemctl restart sshd
95
- - systemctl stop systemd-resolved
96
- - systemctl disable systemd-resolved
97
- - rm /etc/resolv.conf
98
- - echo "nameserver 1.1.1.1" > /etc/resolv.conf
99
- - echo "nameserver 1.0.0.1" >> /etc/resolv.conf
113
+ #{post_create_commands}
100
114
  YAML
101
115
  end
102
116
  end
@@ -298,8 +298,8 @@ module Hetzner
298
298
  end
299
299
 
300
300
  def hetzner_token
301
- @token = ENV['HCLOUD_TOKEN']
302
- return @token if @token
301
+ @token = ENV.fetch('HCLOUD_TOKEN', nil)
302
+ return @token unless @token.nil?
303
303
 
304
304
  @token = configuration['hetzner_token']
305
305
  end
@@ -352,6 +352,11 @@ module Hetzner
352
352
  errors << 'Invalid additional packages configuration - it should be an array' if additional_packages && !additional_packages.is_a?(Array)
353
353
  end
354
354
 
355
+ def validate_post_create_commands
356
+ post_create_commands = configuration['post_create_commands']
357
+ errors << 'Invalid post create commands configuration - it should be an array' if post_create_commands && !post_create_commands.is_a?(Array)
358
+ end
359
+
355
360
  def validate_create
356
361
  validate_public_ssh_key
357
362
  validate_private_ssh_key
@@ -362,13 +367,13 @@ module Hetzner
362
367
  validate_worker_node_pools
363
368
  validate_verify_host_key
364
369
  validate_additional_packages
370
+ validate_post_create_commands
365
371
  validate_kube_api_server_args
366
372
  validate_kube_scheduler_args
367
373
  validate_kube_controller_manager_args
368
374
  validate_kube_cloud_controller_manager_args
369
375
  validate_kubelet_args
370
376
  validate_kube_proxy_args
371
- validate_network_zone
372
377
  end
373
378
 
374
379
  def validate_upgrade
@@ -450,6 +450,10 @@ class Cluster
450
450
  configuration['additional_packages'] || []
451
451
  end
452
452
 
453
+ def additional_post_create_commands
454
+ configuration['post_create_commands'] || []
455
+ end
456
+
453
457
  def check_kubectl
454
458
  return if which('kubectl')
455
459
 
@@ -495,7 +499,8 @@ class Cluster
495
499
  network_id:,
496
500
  ssh_key_id:,
497
501
  image:,
498
- additional_packages:
502
+ additional_packages:,
503
+ additional_post_create_commands:
499
504
  }
500
505
  end
501
506
 
@@ -533,7 +538,8 @@ class Cluster
533
538
  network_id:,
534
539
  ssh_key_id:,
535
540
  image:,
536
- additional_packages:
541
+ additional_packages:,
542
+ additional_post_create_commands:
537
543
  }
538
544
  end
539
545
 
@@ -541,7 +547,7 @@ class Cluster
541
547
  end
542
548
 
543
549
  def create_load_balancer
544
- Hetzner::LoadBalancer.new(hetzner_client:, cluster_name:).create(location:, network_id:)
550
+ Hetzner::LoadBalancer.new(hetzner_client:, cluster_name:).create(location: masters_location, network_id:)
545
551
  end
546
552
 
547
553
  def server_configs
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Hetzner
4
4
  module K3s
5
- VERSION = '0.5.4'
5
+ VERSION = '0.5.7'
6
6
  end
7
7
  end
data/lib/hetzner/utils.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Utils
2
4
  CMD_FILE_PATH = '/tmp/cli.cmd'
3
5
 
@@ -32,6 +34,7 @@ module Utils
32
34
  at_exit do
33
35
  process&.send_signal('SIGTERM')
34
36
  rescue Errno::ESRCH, Interrupt
37
+ # ignore
35
38
  end
36
39
 
37
40
  Subprocess.check_call(['bash', '-c', CMD_FILE_PATH], env:) do |p|
@@ -55,13 +58,13 @@ module Utils
55
58
  puts "Waiting for server #{server_name} to be up..."
56
59
 
57
60
  loop do
58
- result = ssh(server, 'echo UP')
59
- break if result == 'UP'
61
+ result = ssh(server, 'cat /etc/ready')
62
+ break if result == 'true'
60
63
  end
61
64
 
62
65
  puts "...server #{server_name} is now up."
63
66
  end
64
- rescue Errno::ENETUNREACH, Errno::EHOSTUNREACH, Timeout::Error, IOError
67
+ rescue Errno::ENETUNREACH, Errno::EHOSTUNREACH, Timeout::Error, IOError, Errno::ECONNRESET
65
68
  retries += 1
66
69
  retry if retries <= 15
67
70
  end
@@ -78,7 +81,7 @@ module Utils
78
81
 
79
82
  Net::SSH.start(public_ip, 'root', params) do |session|
80
83
  session.exec!(command) do |_channel, _stream, data|
81
- output << data
84
+ output = "#{output}#{data}"
82
85
  puts data if print_output
83
86
  end
84
87
  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.5.4
4
+ version: 0.5.7
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-21 00:00:00.000000000 Z
11
+ date: 2022-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt_pbkdf
@@ -179,14 +179,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
179
179
  requirements:
180
180
  - - ">="
181
181
  - !ruby/object:Gem::Version
182
- version: 3.1.0
182
+ version: 3.1.2
183
183
  required_rubygems_version: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - ">="
186
186
  - !ruby/object:Gem::Version
187
187
  version: '0'
188
188
  requirements: []
189
- rubygems_version: 3.3.3
189
+ rubygems_version: 3.3.7
190
190
  signing_key:
191
191
  specification_version: 4
192
192
  summary: A CLI to create a Kubernetes cluster in Hetzner Cloud very quickly using