hetzner-k3s 0.3.0 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +11 -0
- data/Gemfile.lock +5 -1
- data/README.md +29 -1
- data/cluster_config.yaml.example +1 -0
- data/entrypoint.sh +12 -0
- data/hetzner-k3s.gemspec +2 -0
- data/lib/hetzner/infra/server.rb +6 -1
- data/lib/hetzner/k3s/cli.rb +7 -0
- data/lib/hetzner/k3s/cluster.rb +17 -11
- data/lib/hetzner/k3s/version.rb +1 -1
- metadata +32 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 362875671a52928fd320f24cb0ef38728fe85f5395282f8d9df9550c8531162f
|
4
|
+
data.tar.gz: b873e5f6823a443f48577a5126c20f2b5b4db3a1e2c4fb791af059718cbf39a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecee605e0fc079b62a3cd6af152d30dbdb7ea5cb4785f8a2bcda6218996f7a86bcdcac23f0010d61f6a16e7964f6e587f0c6e0a54ba41c790af15c6490b3ecdb
|
7
|
+
data.tar.gz: 476d5dd9a39dfd45258cd32d208e3e15d6f79f6cf326d482694e6b6311259731ebb090965fc1dcefbb216ee25cd5e01cbdfb36d5a65bafa9a80e56eb047e3d7c
|
data/Dockerfile
ADDED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hetzner-k3s (0.3.
|
4
|
+
hetzner-k3s (0.3.4)
|
5
|
+
bcrypt_pbkdf
|
6
|
+
ed25519
|
5
7
|
http
|
6
8
|
k8s-ruby
|
7
9
|
net-ssh
|
@@ -13,6 +15,7 @@ GEM
|
|
13
15
|
specs:
|
14
16
|
addressable (2.8.0)
|
15
17
|
public_suffix (>= 2.0.2, < 5.0)
|
18
|
+
bcrypt_pbkdf (1.1.0)
|
16
19
|
concurrent-ruby (1.1.9)
|
17
20
|
diff-lcs (1.4.4)
|
18
21
|
domain_name (0.5.20190701)
|
@@ -43,6 +46,7 @@ GEM
|
|
43
46
|
dry-equalizer (~> 0.2)
|
44
47
|
dry-inflector (~> 0.1, >= 0.1.2)
|
45
48
|
dry-logic (~> 0.4, >= 0.4.2)
|
49
|
+
ed25519 (1.2.4)
|
46
50
|
excon (0.85.0)
|
47
51
|
ffi (1.15.3)
|
48
52
|
ffi-compiler (1.0.1)
|
data/README.md
CHANGED
@@ -33,6 +33,16 @@ gem install hetzner-k3s
|
|
33
33
|
|
34
34
|
This will install the `hetzner-k3s` executable in your PATH.
|
35
35
|
|
36
|
+
### With Docker
|
37
|
+
|
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
|
+
|
40
|
+
```bash
|
41
|
+
docker run --rm -it -v ${PWD}:/cluster -v ${HOME}/.ssh:/tmp/.ssh vitobotta/hetzner-k3s create-cluster --config-file /cluster/test.yaml
|
42
|
+
```
|
43
|
+
|
44
|
+
Replace `test.yaml` with the name of your config file.
|
45
|
+
|
36
46
|
## Creating a cluster
|
37
47
|
|
38
48
|
The tool requires a simple configuration file in order to create/upgrade/delete clusters, in the YAML format like in the example below:
|
@@ -44,6 +54,7 @@ cluster_name: test
|
|
44
54
|
kubeconfig_path: "./kubeconfig"
|
45
55
|
k3s_version: v1.21.3+k3s1
|
46
56
|
ssh_key_path: "~/.ssh/id_rsa.pub"
|
57
|
+
verify_host_key: false
|
47
58
|
location: nbg1
|
48
59
|
masters:
|
49
60
|
instance_type: cpx21
|
@@ -59,6 +70,9 @@ worker_node_pools:
|
|
59
70
|
|
60
71
|
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.
|
61
72
|
|
73
|
+
If you are using Docker, then set `kubeconfig_path` to `/cluster/kubeconfig` so that the kubeconfig is created in the same directory where your config file is.
|
74
|
+
|
75
|
+
|
62
76
|
If you set `masters.instance_count` to 1 then the tool will create a non highly available control plane; for production clusters you may want to set it to a number greater than 1. This number must be odd to avoid split brain issues with etcd and the recommended number is 3.
|
63
77
|
|
64
78
|
You can specify any number of worker node pools for example to have mixed nodes with different specs for different workloads.
|
@@ -74,6 +88,8 @@ curl \
|
|
74
88
|
```
|
75
89
|
|
76
90
|
|
91
|
+
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.
|
92
|
+
|
77
93
|
Finally, to create the cluster run:
|
78
94
|
|
79
95
|
```bash
|
@@ -211,6 +227,18 @@ Once the cluster is ready you can create persistent volumes out of the box with
|
|
211
227
|
|
212
228
|
## changelog
|
213
229
|
|
230
|
+
- 0.3.4
|
231
|
+
- Added Docker support
|
232
|
+
|
233
|
+
- 0.3.3
|
234
|
+
- Add some gems required on Linux
|
235
|
+
|
236
|
+
- 0.3.2
|
237
|
+
- Configure DNS to use Cloudflare's resolver instead of Hetzner's, since Hetzner's resolvers are not always reliable
|
238
|
+
|
239
|
+
- 0.3.1
|
240
|
+
- Allow enabling/disabling the host key verification
|
241
|
+
|
214
242
|
- 0.3.0
|
215
243
|
- Handle case when an SSH key with the given fingerprint already exists in the Hetzner project
|
216
244
|
- Handle a timeout of 5 seconds for requests to the Hetzner API
|
@@ -229,4 +257,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
229
257
|
|
230
258
|
## Code of Conduct
|
231
259
|
|
232
|
-
Everyone interacting in the hetzner-k3s project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/vitobotta/k3s/blob/
|
260
|
+
Everyone interacting in the hetzner-k3s project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/vitobotta/hetzner-k3s/blob/main/CODE_OF_CONDUCT.md).
|
data/cluster_config.yaml.example
CHANGED
data/entrypoint.sh
ADDED
data/hetzner-k3s.gemspec
CHANGED
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "net-ssh"
|
24
24
|
spec.add_dependency "k8s-ruby"
|
25
25
|
spec.add_dependency "sshkey"
|
26
|
+
spec.add_dependency "ed25519"
|
27
|
+
spec.add_dependency "bcrypt_pbkdf"
|
26
28
|
|
27
29
|
# Specify which files should be added to the gem when it is released.
|
28
30
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
data/lib/hetzner/infra/server.rb
CHANGED
@@ -74,7 +74,12 @@ module Hetzner
|
|
74
74
|
- sed -i 's/[#]*PermitRootLogin yes/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config
|
75
75
|
- sed -i 's/[#]*PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
|
76
76
|
- systemctl restart sshd
|
77
|
-
|
77
|
+
- systemctl stop systemd-resolved
|
78
|
+
- systemctl disable systemd-resolved
|
79
|
+
- rm /etc/resolv.conf
|
80
|
+
- echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
81
|
+
- echo "nameserver 1.0.0.1" >> /etc/resolv.conf
|
82
|
+
EOS
|
78
83
|
end
|
79
84
|
|
80
85
|
end
|
data/lib/hetzner/k3s/cli.rb
CHANGED
@@ -80,6 +80,7 @@ module Hetzner
|
|
80
80
|
validate_k3s_version
|
81
81
|
validate_masters
|
82
82
|
validate_worker_node_pools
|
83
|
+
validate_verify_host_key
|
83
84
|
when :delete
|
84
85
|
validate_kubeconfig_path_must_exist
|
85
86
|
when :upgrade
|
@@ -292,6 +293,12 @@ module Hetzner
|
|
292
293
|
errors << "Cannot connect to the Kubernetes cluster"
|
293
294
|
false
|
294
295
|
end
|
296
|
+
|
297
|
+
|
298
|
+
def validate_verify_host_key
|
299
|
+
return unless [true, false].include?(configuration.fetch("ssh_key_path", false))
|
300
|
+
errors << "Please set the verify_host_key option to either true or false"
|
301
|
+
end
|
295
302
|
end
|
296
303
|
end
|
297
304
|
end
|
data/lib/hetzner/k3s/cluster.rb
CHANGED
@@ -29,6 +29,7 @@ class Cluster
|
|
29
29
|
@masters_config = configuration.dig("masters")
|
30
30
|
@worker_node_pools = configuration.dig("worker_node_pools")
|
31
31
|
@location = configuration.dig("location")
|
32
|
+
@verify_host_key = configuration.fetch("verify_host_key", false)
|
32
33
|
@servers = []
|
33
34
|
|
34
35
|
create_resources
|
@@ -68,7 +69,7 @@ class Cluster
|
|
68
69
|
:masters_config, :worker_node_pools,
|
69
70
|
:location, :ssh_key_path, :kubernetes_client,
|
70
71
|
:hetzner_token, :tls_sans, :new_k3s_version, :configuration,
|
71
|
-
:config_file
|
72
|
+
:config_file, :verify_host_key
|
72
73
|
|
73
74
|
|
74
75
|
def latest_k3s_version
|
@@ -138,14 +139,14 @@ class Cluster
|
|
138
139
|
end
|
139
140
|
end
|
140
141
|
|
141
|
-
threads.each(&:join)
|
142
|
+
threads.each(&:join) unless threads.empty?
|
142
143
|
|
143
144
|
puts
|
144
145
|
threads = servers.map do |server|
|
145
146
|
Thread.new { wait_for_ssh server }
|
146
147
|
end
|
147
148
|
|
148
|
-
threads.each(&:join)
|
149
|
+
threads.each(&:join) unless threads.empty?
|
149
150
|
end
|
150
151
|
|
151
152
|
def delete_resources
|
@@ -160,22 +161,22 @@ class Cluster
|
|
160
161
|
end
|
161
162
|
end
|
162
163
|
|
163
|
-
threads.each(&:join)
|
164
|
+
threads.each(&:join) unless threads.empty?
|
164
165
|
end
|
165
|
-
rescue Timeout::Error
|
166
|
+
rescue Timeout::Error, Excon::Error::Socket
|
166
167
|
puts "Unable to fetch nodes from Kubernetes API. Is the cluster online?"
|
167
168
|
end
|
168
169
|
|
169
170
|
# Deleting nodes defined in the config file just in case there are leftovers i.e. nodes that
|
170
171
|
# were not part of the cluster for some reason
|
171
172
|
|
172
|
-
threads = all_servers.
|
173
|
+
threads = all_servers.map do |server|
|
173
174
|
Thread.new do
|
174
175
|
Hetzner::Server.new(hetzner_client: hetzner_client, cluster_name: cluster_name).delete(server_name: server["name"])
|
175
176
|
end
|
176
177
|
end
|
177
178
|
|
178
|
-
threads.each(&:join)
|
179
|
+
threads.each(&:join) unless threads.empty?
|
179
180
|
|
180
181
|
puts
|
181
182
|
|
@@ -292,7 +293,7 @@ class Cluster
|
|
292
293
|
end
|
293
294
|
end
|
294
295
|
|
295
|
-
threads.each(&:join)
|
296
|
+
threads.each(&:join) unless threads.empty?
|
296
297
|
end
|
297
298
|
|
298
299
|
threads = workers.map do |worker|
|
@@ -307,7 +308,7 @@ class Cluster
|
|
307
308
|
end
|
308
309
|
end
|
309
310
|
|
310
|
-
threads.each(&:join)
|
311
|
+
threads.each(&:join) unless threads.empty?
|
311
312
|
end
|
312
313
|
|
313
314
|
def deploy_cloud_controller_manager
|
@@ -464,18 +465,23 @@ class Cluster
|
|
464
465
|
public_ip = server.dig("public_net", "ipv4", "ip")
|
465
466
|
output = ""
|
466
467
|
|
467
|
-
Net::SSH.start(public_ip, "root", verify_host_key: :never) do |session|
|
468
|
+
Net::SSH.start(public_ip, "root", verify_host_key: (verify_host_key ? :always : :never)) do |session|
|
468
469
|
session.exec!(command) do |channel, stream, data|
|
469
470
|
output << data
|
470
471
|
puts data if print_output
|
471
472
|
end
|
472
473
|
end
|
473
|
-
|
474
474
|
output.chop
|
475
475
|
rescue Net::SSH::Disconnect => e
|
476
476
|
retry unless e.message =~ /Too many authentication failures/
|
477
477
|
rescue Net::SSH::ConnectionTimeout, Errno::ECONNREFUSED, Errno::ENETUNREACH, Errno::EHOSTUNREACH
|
478
478
|
retry
|
479
|
+
rescue Net::SSH::HostKeyMismatch
|
480
|
+
puts
|
481
|
+
puts "Cannot continue: Unable to SSH into server with IP #{public_ip} because the existing fingerprint in the known_hosts file does not match that of the actual host key."
|
482
|
+
puts "This is due to a security check but can also happen when creating a new server that gets assigned the same IP address as another server you've owned in the past."
|
483
|
+
puts "If are sure no security is being violated here and you're just creating new servers, you can eiher remove the relevant lines from your known_hosts (see IPs from the cloud console) or disable host key verification by setting the option 'verify_host_key' to false in the configuration file for the cluster."
|
484
|
+
exit 1
|
479
485
|
end
|
480
486
|
|
481
487
|
def kubernetes_client
|
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.3.
|
4
|
+
version: 0.3.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-08-
|
11
|
+
date: 2021-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -80,6 +80,34 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: ed25519
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bcrypt_pbkdf
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
83
111
|
description: A CLI to create a Kubernetes cluster in Hetzner Cloud very quickly using
|
84
112
|
k3s.
|
85
113
|
email:
|
@@ -93,6 +121,7 @@ files:
|
|
93
121
|
- ".rspec"
|
94
122
|
- ".travis.yml"
|
95
123
|
- CODE_OF_CONDUCT.md
|
124
|
+
- Dockerfile
|
96
125
|
- Gemfile
|
97
126
|
- Gemfile.lock
|
98
127
|
- LICENSE.txt
|
@@ -101,6 +130,7 @@ files:
|
|
101
130
|
- bin/console
|
102
131
|
- bin/setup
|
103
132
|
- cluster_config.yaml.example
|
133
|
+
- entrypoint.sh
|
104
134
|
- exe/hetzner-k3s
|
105
135
|
- hetzner-k3s.gemspec
|
106
136
|
- lib/hetzner.rb
|