porkadot 0.22.2 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/hack/metallb/crds/kustomization.yaml +5 -0
  3. data/hack/metallb/exclude-l2-config.yaml +8 -0
  4. data/hack/metallb/kustomization.yaml +10 -0
  5. data/hack/update-kubelet-cert-approver.sh +6 -0
  6. data/hack/update-metallb.sh +7 -0
  7. data/lib/porkadot/assets/bootstrap/manifests/kube-apiserver.bootstrap.yaml.erb +1 -1
  8. data/lib/porkadot/assets/etcd/etcd-server.yaml.erb +17 -9
  9. data/lib/porkadot/assets/etcd/etcd.env.erb +4 -0
  10. data/lib/porkadot/assets/etcd/install.sh.erb +1 -0
  11. data/lib/porkadot/assets/etcd.rb +1 -0
  12. data/lib/porkadot/assets/kubelet/config.yaml.erb +1 -39
  13. data/lib/porkadot/assets/kubelet/initiatorname.iscsi.erb +1 -0
  14. data/lib/porkadot/assets/kubelet/kubelet.service.erb +2 -6
  15. data/lib/porkadot/assets/kubelet/metadata.json.erb +5 -0
  16. data/lib/porkadot/assets/{kubelet → kubelet-default}/install-deps.sh.erb +3 -1
  17. data/lib/porkadot/assets/{kubelet → kubelet-default}/install-pkgs.sh.erb +1 -3
  18. data/lib/porkadot/assets/kubelet-default/install.sh.erb +22 -7
  19. data/lib/porkadot/assets/kubelet-default/setup-containerd.sh.erb +22 -0
  20. data/lib/porkadot/assets/kubelet-default/setup-node.sh.erb +16 -0
  21. data/lib/porkadot/assets/kubelet.rb +14 -12
  22. data/lib/porkadot/assets/kubernetes/install.sh.erb +3 -1
  23. data/lib/porkadot/assets/kubernetes/manifests/addons/coredns/coredns.yaml.erb +1 -1
  24. data/lib/porkadot/assets/kubernetes/manifests/addons/coredns/dns-horizontal-autoscaler.yaml.erb +1 -1
  25. data/lib/porkadot/assets/kubernetes/manifests/addons/flannel/flannel.yaml.erb +12 -51
  26. data/lib/porkadot/assets/kubernetes/manifests/addons/kubelet-serving-cert-approver/kustomization.yaml.erb +3 -0
  27. data/lib/porkadot/assets/kubernetes/manifests/addons/kubelet-serving-cert-approver/src.yaml.erb +210 -0
  28. data/lib/porkadot/assets/kubernetes/manifests/addons/metallb/000-metallb.yaml.erb +3 -1
  29. data/lib/porkadot/assets/kubernetes/manifests/addons/metallb/crds.yaml +1272 -0
  30. data/lib/porkadot/assets/kubernetes/manifests/addons/metallb/kustomization.yaml.erb +2 -0
  31. data/lib/porkadot/assets/kubernetes/manifests/addons/metallb/metallb.config.yaml.erb +1 -12
  32. data/lib/porkadot/assets/kubernetes/manifests/addons/metallb/metallb.yaml.erb +520 -228
  33. data/lib/porkadot/assets/kubernetes/manifests/kube-apiserver.yaml.erb +4 -1
  34. data/lib/porkadot/assets/kubernetes/manifests/kube-controller-manager.yaml.erb +3 -0
  35. data/lib/porkadot/assets/kubernetes/manifests/kube-scheduler.yaml.erb +3 -1
  36. data/lib/porkadot/assets/kubernetes.rb +22 -3
  37. data/lib/porkadot/cmd/cli.rb +11 -0
  38. data/lib/porkadot/cmd/etcd.rb +68 -0
  39. data/lib/porkadot/config.rb +1 -1
  40. data/lib/porkadot/configs/addons.rb +4 -0
  41. data/lib/porkadot/configs/certs.rb +3 -0
  42. data/lib/porkadot/configs/etcd.rb +44 -2
  43. data/lib/porkadot/configs/kubelet.rb +25 -7
  44. data/lib/porkadot/const.rb +3 -0
  45. data/lib/porkadot/default.yaml +17 -15
  46. data/lib/porkadot/install/bootstrap.rb +1 -1
  47. data/lib/porkadot/install/kubelet.rb +123 -27
  48. data/lib/porkadot/version.rb +1 -1
  49. data/lib/porkadot.rb +2 -0
  50. data/porkadot.gemspec +1 -0
  51. metadata +33 -8
  52. data/lib/porkadot/assets/kubelet/install.sh.erb +0 -35
  53. data/lib/porkadot/assets/kubelet/setup-containerd.sh.erb +0 -17
  54. data/lib/porkadot/assets/kubernetes/manifests/addons/metallb/metallb.secrets.yaml.erb +0 -13
@@ -58,7 +58,7 @@ spec:
58
58
  periodSeconds: 1
59
59
  timeoutSeconds: 15
60
60
  startupProbe:
61
- failureThreshold: 24
61
+ failureThreshold: 48
62
62
  httpGet:
63
63
  host: 127.0.0.1
64
64
  path: /livez
@@ -101,6 +101,9 @@ spec:
101
101
  - key: node-role.kubernetes.io/master
102
102
  operator: Exists
103
103
  effect: NoSchedule
104
+ - key: node-role.kubernetes.io/control-plane
105
+ operator: Exists
106
+ effect: NoSchedule
104
107
  volumes:
105
108
  - hostPath:
106
109
  path: /etc/ssl/certs
@@ -146,6 +146,9 @@ spec:
146
146
  - key: node-role.kubernetes.io/master
147
147
  operator: Exists
148
148
  effect: NoSchedule
149
+ - key: node-role.kubernetes.io/control-plane
150
+ operator: Exists
151
+ effect: NoSchedule
149
152
  volumes:
150
153
  - name: var-run-kubernetes
151
154
  emptyDir: {}
@@ -173,4 +173,6 @@ spec:
173
173
  - key: node-role.kubernetes.io/master
174
174
  operator: Exists
175
175
  effect: NoSchedule
176
-
176
+ - key: node-role.kubernetes.io/control-plane
177
+ operator: Exists
178
+ effect: NoSchedule
@@ -80,14 +80,28 @@ module Porkadot; module Assets
80
80
  secrets.each do |m|
81
81
  render_secrets_erb(m)
82
82
  end
83
+ crds = @@crds[name]
84
+ crds.each do |m|
85
+ copy_crds(m)
86
+ end
83
87
  end
84
88
  end
85
89
 
86
- def self.register_manifests name, manifests, secrets: []
90
+ def copy_crds file
91
+ logger.info "----> #{file}"
92
+ crd_path = File.join(config.target_crd_dir_path, file)
93
+ crd_dir = File.dirname(crd_path)
94
+ FileUtils.mkdir_p(crd_dir) unless File.directory?(crd_dir)
95
+ FileUtils.copy(File.join(TEMPLATE_DIR, file), crd_path)
96
+ end
97
+
98
+ def self.register_manifests name, manifests, secrets: [], crds: []
87
99
  @@manifests ||= {}
88
100
  @@manifests[name] = manifests
89
101
  @@secrets_manifests ||= {}
90
102
  @@secrets_manifests[name] = secrets
103
+ @@crds ||= {}
104
+ @@crds[name] = crds
91
105
  end
92
106
 
93
107
  register_manifests('flannel', [
@@ -106,8 +120,8 @@ module Porkadot; module Assets
106
120
  'metallb/metallb.yaml',
107
121
  'metallb/metallb.config.yaml',
108
122
  'metallb/kustomization.yaml'
109
- ], secrets: [
110
- 'metallb/metallb.secrets.yaml'
123
+ ], crds: [
124
+ 'metallb/crds.yaml'
111
125
  ])
112
126
 
113
127
 
@@ -121,5 +135,10 @@ module Porkadot; module Assets
121
135
  'storage-version-migrator/kustomization.yaml'
122
136
  ])
123
137
 
138
+ register_manifests('kubelet-serving-cert-approver', [
139
+ 'kubelet-serving-cert-approver/src.yaml',
140
+ 'kubelet-serving-cert-approver/kustomization.yaml'
141
+ ])
142
+
124
143
  end
125
144
  end; end
@@ -13,15 +13,22 @@ module Porkadot; module Cmd
13
13
  desc "install", "Install kubernetes"
14
14
  subcommand "install", Porkadot::Cmd::Install::Cli
15
15
 
16
+ desc "etcd", "Interact with etcd"
17
+ subcommand "etcd", Porkadot::Cmd::Etcd::Cli
18
+
16
19
  desc "setup-containerd", "Setup containerd"
17
20
  option :node, type: :string
18
21
  option :force, type: :boolean, default: false
22
+ option :bootstrap, type: :boolean, default: false
19
23
  def setup_containerd
20
24
  logger.info "Setup containerd"
21
25
  kubelets = Porkadot::Install::KubeletList.new(self.config)
22
26
  nodes = []
23
27
  if node = options[:node]
24
28
  nodes = kubelets[node]
29
+ elsif options[:bootstrap]
30
+ bootstrap = Porkadot::Install::Bootstrap.new(self.config)
31
+ nodes = bootstrap.host
25
32
  else
26
33
  nodes = kubelets.kubelets.values
27
34
  end
@@ -32,12 +39,16 @@ module Porkadot; module Cmd
32
39
  desc "setup-node", "Setup node default settings"
33
40
  option :node, type: :string
34
41
  option :force, type: :boolean, default: false
42
+ option :bootstrap, type: :boolean, default: false
35
43
  def setup_node
36
44
  logger.info "Setup node default"
37
45
  kubelets = Porkadot::Install::KubeletList.new(self.config)
38
46
  nodes = []
39
47
  if node = options[:node]
40
48
  nodes = kubelets[node]
49
+ elsif options[:bootstrap]
50
+ bootstrap = Porkadot::Install::Bootstrap.new(self.config)
51
+ nodes = bootstrap.host
41
52
  else
42
53
  nodes = kubelets.kubelets.values
43
54
  end
@@ -0,0 +1,68 @@
1
+
2
+ module Porkadot; module Cmd; module Etcd
3
+ class Cli < Porkadot::SubCommandBase
4
+ include Porkadot::Utils
5
+
6
+ default_task :all
7
+ desc "all", "Interact with etcd"
8
+ def all
9
+ "Use restore or backup sub commands."
10
+ end
11
+
12
+ desc "backup", "Backup etcd data"
13
+ option :node, type: :string
14
+ option :path, type: :string, default: "./backup", desc: "Directory where etcd backup data will be stored."
15
+ def backup
16
+ require 'date'
17
+
18
+ filename = "etcd-#{DateTime.now.to_s}.db"
19
+ path = File.join(options[:path], filename)
20
+
21
+ logger.info "Backing up etcd data to #{path}"
22
+ kubelets = Porkadot::Install::KubeletList.new(self.config)
23
+ kubelets.backup_etcd host: options[:node], path: path
24
+ ""
25
+ end
26
+
27
+ desc "start", "Start etcd"
28
+ option :node, type: :string
29
+ def start
30
+ logger.info "Start etcd"
31
+ kubelets = Porkadot::Install::KubeletList.new(self.config)
32
+ kubelets.start_etcd hosts: options[:node]
33
+ ""
34
+ end
35
+
36
+ desc "stop", "Stop etcd"
37
+ option :node, type: :string
38
+ def stop
39
+ logger.info "Start etcd"
40
+ kubelets = Porkadot::Install::KubeletList.new(self.config)
41
+ kubelets.stop_etcd hosts: options[:node]
42
+ ""
43
+ end
44
+
45
+ desc "restore", "Restore etcd data"
46
+ option :path, type: :string, default: "./backup", desc: "Directory where etcd backup data is stored."
47
+ def restore
48
+ invoke :stop, [], options
49
+
50
+ path = Dir.glob(File.join(options[:path], "etcd-*.db")).sort.reverse[0]
51
+ unless path
52
+ return "No backup data found...: #{options[:path]}"
53
+ end
54
+
55
+ logger.info "Restore etcd from #{path}"
56
+ kubelets = Porkadot::Install::KubeletList.new(self.config)
57
+ kubelets.restore_etcd path: path
58
+
59
+ invoke :start, [], options
60
+ ""
61
+ end
62
+
63
+ def self.subcommand_prefix
64
+ 'etcd'
65
+ end
66
+ end
67
+ end; end; end
68
+
@@ -4,7 +4,7 @@ require 'logger'
4
4
 
5
5
  module Porkadot
6
6
  class Raw < ::Hashie::Mash
7
- disable_warnings :keys, :min
7
+ disable_warnings :keys, :key, :min
8
8
  end
9
9
 
10
10
  class Config
@@ -16,6 +16,10 @@ module Porkadot; module Configs
16
16
  File.join(self.config.secrets_root_dir, 'kubernetes', 'manifests', 'addons')
17
17
  end
18
18
 
19
+ def target_crd_dir_path
20
+ File.join(self.config.assets_dir, 'kubernetes', 'manifests', 'crds')
21
+ end
22
+
19
23
  end
20
24
  end; end
21
25
 
@@ -9,6 +9,9 @@ module Porkadot; module Configs
9
9
  end
10
10
 
11
11
  def ipaddr?(addr)
12
+ if addr.nil?
13
+ return false
14
+ end
12
15
  IPAddr.new(addr)
13
16
  return true
14
17
  rescue IPAddr::InvalidAddressError
@@ -39,6 +39,33 @@ module Porkadot; module Configs
39
39
  return (self.raw.labels && self.raw.labels[Porkadot::ETCD_ADDRESS_LABEL]) || self.raw.hostname || self.name
40
40
  end
41
41
 
42
+ def listen_address label_key
43
+ listen_address = nil
44
+ if self.raw.labels
45
+ listen_address = self.raw.labels[label_key] || self.raw.labels[Porkadot::ETCD_LISTEN_ADDRESS_LABEL]
46
+ end
47
+
48
+ if !listen_adress
49
+ if self.ipaddr?(self.raw.hostname)
50
+ listen_address = self.raw.hostname
51
+ elsif self.ipaddr?(self.raw.name)
52
+ listen_address = self.raw.name
53
+ else
54
+ listen_address = '0.0.0.0'
55
+ end
56
+ end
57
+
58
+ return listen_address
59
+ end
60
+
61
+ def listen_client_address
62
+ return self.listen_address(Porkadot::ETCD_LISTEN_CLIENT_ADDRESS_LABEL)
63
+ end
64
+
65
+ def listen_peer_address
66
+ return self.listen_address(Porkadot::ETCD_LISTEN_PEER_ADDRESS_LABEL)
67
+ end
68
+
42
69
  def advertise_client_urls
43
70
  ["https://#{member_address}:2379"]
44
71
  end
@@ -48,11 +75,25 @@ module Porkadot; module Configs
48
75
  end
49
76
 
50
77
  def listen_client_urls
51
- self.advertise_client_urls + ["https://127.0.0.1:2379"]
78
+ address = self.listen_client_address
79
+ if address != '0.0.0.0'
80
+ return ["https://#{address}:2379", "https://127.0.0.1:2379"]
81
+ else
82
+ return ["https://#{address}:2379"]
83
+ end
52
84
  end
53
85
 
54
86
  def listen_peer_urls
55
- self.advertise_peer_urls
87
+ ["https://#{self.listen_client_address}:2380"]
88
+ end
89
+
90
+ def listen_metrics_urls
91
+ address = self.listen_client_address
92
+ if address != '0.0.0.0'
93
+ return ["http://#{address}:2381", "http://127.0.0.1:2381"]
94
+ else
95
+ return ["http://#{address}:2381"]
96
+ end
56
97
  end
57
98
 
58
99
  def initial_cluster
@@ -72,6 +113,7 @@ module Porkadot; module Configs
72
113
  sans << "DNS:#{san}"
73
114
  end
74
115
  end
116
+ sans << "IP:127.0.0.1"
75
117
  return sans
76
118
  end
77
119
 
@@ -23,6 +23,14 @@ module Porkadot; module Configs
23
23
  File.join(self.target_secrets_path, 'addons')
24
24
  end
25
25
 
26
+ def ca_crt_path
27
+ File.join(self.target_path, 'ca.crt')
28
+ end
29
+
30
+ def control_plane_endpoint
31
+ (self.raw.kubernetes && self.raw.kubernetes.control_plane_endpoint) || self.config.k8s.control_plane_endpoint
32
+ end
33
+
26
34
  end
27
35
 
28
36
  class Kubelet
@@ -54,9 +62,23 @@ module Porkadot; module Configs
54
62
  return self.raw.labels.map{|v| v.compact.join('=')}.join(',')
55
63
  end
56
64
 
57
- def taints_string
58
- return '' unless self.raw.taints
59
- return self.raw.taints.map{|v| v.compact.join('=')}.join(',')
65
+ def labels
66
+ return self.raw.labels || {}
67
+ end
68
+
69
+ def annotations
70
+ return self.raw.annotations || {}
71
+ end
72
+
73
+ def kubelet_config
74
+ kc = self.raw.config || ::Porkadot::Raw.new
75
+ kc = kc.merge(self.config.kubernetes.kubelet.config)
76
+ kc.clusterDNS << self.config.k8s.networking.dns_ip.to_s
77
+ kc.clusterDomain = self.config.k8s.networking.dns_domain
78
+ if self.raw.taints
79
+ kc.registerWithTaints = self.raw.taints
80
+ end
81
+ return kc
60
82
  end
61
83
 
62
84
  def hostname
@@ -79,10 +101,6 @@ module Porkadot; module Configs
79
101
  File.join(self.target_secrets_path, 'addons')
80
102
  end
81
103
 
82
- def ca_crt_path
83
- File.join(self.target_path, 'ca.crt')
84
- end
85
-
86
104
  def bootstrap_key_path
87
105
  File.join(self.target_secrets_path, 'bootstrap.key')
88
106
  end
@@ -5,4 +5,7 @@ module Porkadot
5
5
  K8S_MASTER_LABEL = "k8s.unstable.cloud/master"
6
6
  ETCD_MEMBER_LABEL = "etcd.unstable.cloud/member"
7
7
  ETCD_ADDRESS_LABEL = "etcd.unstable.cloud/address"
8
+ ETCD_LISTEN_ADDRESS_LABEL = "etcd.unstable.cloud/listen-address"
9
+ ETCD_LISTEN_CLIENT_ADDRESS_LABEL = "etcd.unstable.cloud/listen-client-address"
10
+ ETCD_LISTEN_PEER_ADDRESS_LABEL = "etcd.unstable.cloud/listen-client-address"
8
11
  end
@@ -11,14 +11,14 @@ nodes: {}
11
11
  bootstrap: {}
12
12
 
13
13
  addons:
14
- enabled: [flannel, coredns, metallb, kubelet-rubber-stamp, storage-version-migrator]
14
+ enabled: [flannel, coredns, metallb, kubelet-serving-cert-approver, storage-version-migrator]
15
15
 
16
16
  flannel:
17
17
  backend: vxlan
18
- plugin_image_repository: rancher/mirrored-flannelcni-flannel-cni-plugin
19
- plugin_image_tag: v1.0.1
20
- daemon_image_repository: rancher/mirrored-flannelcni-flannel
21
- daemon_image_tag: v0.17.0
18
+ plugin_image_repository: flannel/flannel-cni-plugin
19
+ plugin_image_tag: v1.4.1-flannel1
20
+ daemon_image_repository: flannel/flannel
21
+ daemon_image_tag: v0.25.1
22
22
  resources:
23
23
  requests:
24
24
  cpu: "100m"
@@ -39,20 +39,22 @@ addons:
39
39
 
40
40
  kubelet-rubber-stamp: {}
41
41
 
42
+ kubelet-serving-cert-approver: {}
43
+
42
44
  storage-version-migrator: {}
43
45
 
44
46
  etcd:
45
- image_repository: gcr.io/etcd-development/etcd
46
- image_tag: v3.4.13
47
+ image_repository: registry.k8s.io/etcd
48
+ image_tag: 3.5.5-0
47
49
  extra_env: []
48
50
 
49
51
  kubernetes:
50
- kubernetes_version: v1.22.8
51
- crictl_version: v1.22.0
52
- image_repository: k8s.gcr.io
52
+ kubernetes_version: v1.25.15
53
+ crictl_version: v1.25.0
54
+ image_repository: registry.k8s.io
53
55
 
54
56
  networking:
55
- cni_version: v1.0.1
57
+ cni_version: v1.2.0
56
58
  service_subnet: '10.254.0.0/24'
57
59
  pod_subnet: '10.244.0.0/16'
58
60
  dns_domain: 'cluster.local'
@@ -96,7 +98,7 @@ kubernetes:
96
98
  minSyncPeriod: 0s
97
99
  scheduler: ""
98
100
  syncPeriod: 30s
99
- metricsBindAddress: 127.0.0.1:10249
101
+ metricsBindAddress: 0.0.0.0:10249
100
102
  mode: "iptables"
101
103
  nodePortAddresses: null
102
104
  oomScoreAdj: -999
@@ -106,7 +108,6 @@ kubernetes:
106
108
  kubelet:
107
109
  config:
108
110
  apiVersion: kubelet.config.k8s.io/v1beta1
109
- kind: KubeletConfiguration
110
111
  authentication:
111
112
  anonymous:
112
113
  enabled: false
@@ -122,7 +123,7 @@ kubernetes:
122
123
  cacheUnauthorizedTTL: 0s
123
124
  cgroupDriver: systemd
124
125
  clusterDNS: []
125
- clusterDomain: cluster.local
126
+ clusterDomain: ""
126
127
  cpuManagerReconcilePeriod: 0s
127
128
  evictionPressureTransitionPeriod: 0s
128
129
  fileCheckFrequency: 0s
@@ -130,13 +131,14 @@ kubernetes:
130
131
  healthzPort: 10248
131
132
  httpCheckFrequency: 0s
132
133
  imageMinimumGCAge: 0s
134
+ kind: KubeletConfiguration
133
135
  nodeStatusReportFrequency: 0s
134
136
  nodeStatusUpdateFrequency: 0s
135
137
  resolvConf: /run/systemd/resolve/resolv.conf
136
138
  rotateCertificates: true
137
139
  runtimeRequestTimeout: 0s
138
- serverTLSBootstrap: true
139
140
  staticPodPath: /etc/kubernetes/manifests
140
141
  streamingConnectionIdleTimeout: 0s
141
142
  syncFrequency: 0s
142
143
  volumeStatsAggPeriod: 0s
144
+ serverTLSBootstrap: true
@@ -32,7 +32,7 @@ module Porkadot; module Install
32
32
  execute(:bash, File.join(KUBE_TEMP, 'install.sh'))
33
33
  end
34
34
 
35
- endpoint = "https://127.0.0.1:#{global_config.k8s.apiserver.bind_port}/healthz"
35
+ endpoint = "https://127.0.0.1:#{global_config.k8s.apiserver.bind_port}/readyz"
36
36
  info "Start to wait for Bootstrapping Kubernetes API: #{endpoint}"
37
37
  while !test('curl', '-skf', endpoint)
38
38
  info "Still wating for Bootstrapping Kubernetes API..."
@@ -3,6 +3,8 @@ module Porkadot; module Install
3
3
  KUBE_TEMP = File.join(Porkadot::Install::KUBE_TEMP, 'kubelet')
4
4
  KUBE_SECRETS_TEMP = File.join(Porkadot::Install::KUBE_TEMP, '.kubelet')
5
5
  KUBE_DEFAULT_TEMP = File.join(Porkadot::Install::KUBE_TEMP, '.default')
6
+ KUBE_SECRETS_DEFAULT_TEMP = File.join(Porkadot::Install::KUBE_TEMP, '.default.kubelet')
7
+ ETCD_TEMP = '/opt/porkadot'
6
8
  include SSHKit::DSL
7
9
  attr_reader :global_config
8
10
  attr_reader :logger
@@ -18,30 +20,37 @@ module Porkadot; module Install
18
20
  end
19
21
 
20
22
  def setup_containerd hosts: nil, force: false
21
- unless hosts
22
- hosts = []
23
- self.kubelets.each do |_, v|
24
- hosts << v
23
+ hosts = self.exec hosts: hosts
24
+ on(hosts) do |host|
25
+ as user: 'root' do
26
+ execute(:bash, File.join(KUBE_TEMP, 'setup-containerd.sh'))
25
27
  end
26
28
  end
29
+ end
27
30
 
31
+ def setup_default hosts: nil, force: false
32
+ hosts = self.exec hosts: hosts
28
33
  on(hosts) do |host|
29
- execute(:mkdir, '-p', Porkadot::Install::KUBE_TEMP)
30
- if test("[ -d #{KUBE_TEMP} ]")
31
- execute(:rm, '-rf', KUBE_TEMP)
32
- execute(:rm, '-rf', KUBE_SECRETS_TEMP)
34
+ as user: 'root' do
35
+ execute(:bash, File.join(KUBE_TEMP, 'setup-node.sh'))
33
36
  end
34
- upload! host.config.target_path, KUBE_TEMP, recursive: true
35
- upload! host.config.target_secrets_path, KUBE_SECRETS_TEMP, recursive: true
36
- execute(:cp, '-r', KUBE_SECRETS_TEMP + '/*', KUBE_TEMP)
37
+ end
38
+ end
37
39
 
40
+ def install hosts: nil, force: false
41
+ hosts = self.exec hosts: hosts
42
+ on(hosts) do |host|
38
43
  as user: 'root' do
39
- execute(:bash, File.join(KUBE_TEMP, 'setup-containerd.sh'))
44
+ unless test("[ -f /opt/bin/kubelet-#{host.global_config.k8s.kubernetes_version} ]") && !force
45
+ execute(:bash, File.join(KUBE_TEMP, 'install-deps.sh'))
46
+ end
47
+ execute(:bash, File.join(KUBE_TEMP, 'install-pkgs.sh'))
48
+ execute(:bash, File.join(KUBE_TEMP, 'install.sh'))
40
49
  end
41
50
  end
42
51
  end
43
52
 
44
- def setup_default hosts: nil, force: false
53
+ def exec hosts: nil
45
54
  unless hosts
46
55
  hosts = []
47
56
  self.kubelets.each do |_, v|
@@ -54,45 +63,129 @@ module Porkadot; module Install
54
63
  if test("[ -d #{KUBE_TEMP} ]")
55
64
  execute(:rm, '-rf', KUBE_TEMP)
56
65
  execute(:rm, '-rf', KUBE_SECRETS_TEMP)
66
+ execute(:rm, '-rf', KUBE_DEFAULT_TEMP)
67
+ execute(:rm, '-rf', KUBE_SECRETS_DEFAULT_TEMP)
57
68
  end
58
69
  upload! host.global_config.kubelet_default.target_path, KUBE_TEMP, recursive: true
59
70
  upload! host.global_config.kubelet_default.target_secrets_path, KUBE_SECRETS_TEMP, recursive: true
71
+ upload! host.config.target_path, KUBE_DEFAULT_TEMP, recursive: true
72
+ upload! host.config.target_secrets_path, KUBE_SECRETS_DEFAULT_TEMP, recursive: true
60
73
  execute(:cp, '-r', KUBE_SECRETS_TEMP + '/*', KUBE_TEMP)
74
+ execute(:cp, '-r', KUBE_DEFAULT_TEMP + '/*', KUBE_TEMP)
75
+ execute(:cp, '-r', KUBE_SECRETS_DEFAULT_TEMP + '/*', KUBE_TEMP)
76
+ end
77
+
78
+ return hosts
79
+ end
80
+
81
+ def backup_etcd host: nil, path: "./backup/etcd.db"
82
+ unless host
83
+ self.kubelets.each do |_, v|
84
+ if v.etcd?
85
+ host = v
86
+ end
87
+ end
88
+ end
89
+
90
+ on(:local) do |local|
91
+ execute(:mkdir, '-p', File.dirname(path))
92
+ end
93
+
94
+ options = self.etcd_options
95
+ on(host) do |host|
96
+ execute(:mkdir, '-p', KUBE_TEMP)
97
+ execute(:"/opt/bin/etcdctl", *options, "snapshot", "save", "#{KUBE_TEMP}/etcd.db")
98
+ download! "#{KUBE_TEMP}/etcd.db", path
99
+ end
100
+ end
101
+
102
+ def restore_etcd path: "./backup/etcd.db"
103
+ require 'date'
104
+ hosts = []
105
+ self.kubelets.each do |_, v|
106
+ hosts << v if v.etcd?
107
+ end
108
+
109
+ options = self.etcd_options
110
+ on(hosts) do |host|
111
+ if test("[ -d #{KUBE_TEMP} ]")
112
+ execute(:rm, '-rf', KUBE_TEMP)
113
+ execute(:rm, '-rf', KUBE_SECRETS_TEMP)
114
+ end
115
+ execute(:mkdir, '-p', KUBE_TEMP)
116
+ upload! path, "#{KUBE_TEMP}/etcd.db"
61
117
 
62
118
  as user: 'root' do
63
- execute(:bash, File.join(KUBE_TEMP, 'install.sh'))
119
+ execute(:mkdir, '-p', ETCD_TEMP)
120
+ if test('[ -d /var/lib/etcd ]')
121
+ execute(:mv, '/var/lib/etcd', "${ETCD_TEMP}/data-#{DateTime.now.to_s}")
122
+ end
123
+ execute(:"/opt/bin/etcdctl", *options, "snapshot", "restore", "#{KUBE_TEMP}/etcd.db")
64
124
  end
65
125
  end
66
126
  end
67
127
 
68
- def install hosts: nil, force: false
128
+ def start_etcd hosts: nil
69
129
  unless hosts
70
130
  hosts = []
71
131
  self.kubelets.each do |_, v|
72
- hosts << v
132
+ hosts << v if v.etcd?
73
133
  end
74
134
  end
75
135
 
76
136
  on(hosts) do |host|
77
- execute(:mkdir, '-p', Porkadot::Install::KUBE_TEMP)
78
- if test("[ -d #{KUBE_TEMP} ]")
79
- execute(:rm, '-rf', KUBE_TEMP)
80
- execute(:rm, '-rf', KUBE_SECRETS_TEMP)
137
+ as user: 'root' do
138
+ execute(:mkdir, '-p', ETCD_TEMP)
139
+
140
+ result = capture(:"/opt/bin/crictl", 'ps', '-q', '--name', 'etcd')
141
+ with(container_runtime_endpoint: "unix:///run/containerd/containerd.sock") do
142
+ if result.empty?
143
+ info 'Trying to start etcd'
144
+ execute(:mv, "${ETCD_TEMP}/etcd-server.yaml", "/etc/kubernetes/manifests/etcd-server.yaml")
145
+ else
146
+ info 'etcd is already started...'
147
+ end
148
+ end
81
149
  end
82
- upload! host.config.target_path, KUBE_TEMP, recursive: true
83
- upload! host.config.target_secrets_path, KUBE_SECRETS_TEMP, recursive: true
84
- execute(:cp, '-r', KUBE_SECRETS_TEMP + '/*', KUBE_TEMP)
150
+ end
151
+ end
152
+
153
+ def stop_etcd hosts: nil
154
+ unless hosts
155
+ hosts = []
156
+ self.kubelets.each do |_, v|
157
+ hosts << v if v.etcd?
158
+ end
159
+ end
85
160
 
161
+ on(hosts) do |host|
86
162
  as user: 'root' do
87
- unless test("[ -f /opt/bin/kubelet-#{host.global_config.k8s.kubernetes_version} ]") && !force
88
- execute(:bash, File.join(KUBE_TEMP, 'install-deps.sh'))
163
+ execute(:mkdir, '-p', ETCD_TEMP)
164
+
165
+ info "Waiting for etcd to stop..."
166
+ with(container_runtime_endpoint: "unix:///run/containerd/containerd.sock") do
167
+ unless capture(:"/opt/bin/crictl", 'ps', '-q', '--name', 'etcd').empty?
168
+ execute(:mv, "/etc/kubernetes/manifests/etcd-server.yaml", "${ETCD_TEMP}/etcd-server.yaml")
169
+ while capture(:"/opt/bin/crictl", 'ps', '-q', '--name', 'etcd') != ''
170
+ info 'Still waiting for stopping etcd...'
171
+ sleep 5
172
+ end
173
+ end
89
174
  end
90
- execute(:bash, File.join(KUBE_TEMP, 'install-pkgs.sh'))
91
- execute(:bash, File.join(KUBE_TEMP, 'install.sh'))
175
+ info 'etcd was stopped.'
92
176
  end
93
177
  end
94
178
  end
95
179
 
180
+ def etcd_options
181
+ %w(
182
+ --cacert /etc/etcd/pki/ca.crt
183
+ --cert /etc/etcd/pki/etcd.crt
184
+ --key /etc/etcd/pki/etcd.key
185
+ --endpoints=https://127.0.0.1:2379
186
+ )
187
+ end
188
+
96
189
  def [](name)
97
190
  self.kubelets[name]
98
191
  end
@@ -112,5 +205,8 @@ module Porkadot; module Install
112
205
  super(@connection)
113
206
  end
114
207
 
208
+ def etcd?
209
+ return self.config.raw.labels && self.config.raw.labels[Porkadot::ETCD_MEMBER_LABEL]
210
+ end
115
211
  end
116
212
  end; end
@@ -1,3 +1,3 @@
1
1
  module Porkadot
2
- VERSION = "0.22.2"
2
+ VERSION = "0.25.0"
3
3
  end