porkadot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/README.md +35 -0
- data/Rakefile +10 -0
- data/Vagrantfile +63 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/porkadot.yaml +25 -0
- data/config/unstable.yaml +49 -0
- data/exe/porkadot +5 -0
- data/lib/porkadot/assets/bootstrap/bootstrap/kube-proxy-bootstrap.yaml.erb +1 -0
- data/lib/porkadot/assets/bootstrap/bootstrap/kubeconfig-bootstrap.yaml.erb +18 -0
- data/lib/porkadot/assets/bootstrap/cleanup.sh.erb +12 -0
- data/lib/porkadot/assets/bootstrap/install.sh.erb +14 -0
- data/lib/porkadot/assets/bootstrap/manifests/kube-apiserver.bootstrap.yaml.erb +91 -0
- data/lib/porkadot/assets/bootstrap/manifests/kube-controller-manager.bootstrap.yaml.erb +69 -0
- data/lib/porkadot/assets/bootstrap/manifests/kube-proxy.bootstrap.yaml.erb +56 -0
- data/lib/porkadot/assets/bootstrap/manifests/kube-scheduler.bootstrap.yaml.erb +31 -0
- data/lib/porkadot/assets/bootstrap.rb +52 -0
- data/lib/porkadot/assets/certs/etcd.rb +21 -0
- data/lib/porkadot/assets/certs/front_proxy.rb +21 -0
- data/lib/porkadot/assets/certs/k8s.rb +90 -0
- data/lib/porkadot/assets/certs.rb +175 -0
- data/lib/porkadot/assets/etcd/etcd-server.yaml.erb +57 -0
- data/lib/porkadot/assets/etcd/install.sh.erb +12 -0
- data/lib/porkadot/assets/etcd.rb +109 -0
- data/lib/porkadot/assets/kubelet/bootstrap-kubelet.conf.erb +21 -0
- data/lib/porkadot/assets/kubelet/config.yaml.erb +36 -0
- data/lib/porkadot/assets/kubelet/install-deps.sh.erb +21 -0
- data/lib/porkadot/assets/kubelet/install-pkgs.sh.erb +33 -0
- data/lib/porkadot/assets/kubelet/install.sh.erb +35 -0
- data/lib/porkadot/assets/kubelet/kubelet.service.erb +22 -0
- data/lib/porkadot/assets/kubelet.rb +102 -0
- data/lib/porkadot/assets/kubernetes/install.sh.erb +7 -0
- data/lib/porkadot/assets/kubernetes/manifests/flannel.yaml.erb +602 -0
- data/lib/porkadot/assets/kubernetes/manifests/kube-apiserver.yaml.erb +129 -0
- data/lib/porkadot/assets/kubernetes/manifests/kube-controller-manager.yaml.erb +173 -0
- data/lib/porkadot/assets/kubernetes/manifests/kube-proxy.yaml.erb +132 -0
- data/lib/porkadot/assets/kubernetes/manifests/kube-scheduler.yaml.erb +162 -0
- data/lib/porkadot/assets/kubernetes/manifests/kubelet-rubber-stamp.yaml.erb +86 -0
- data/lib/porkadot/assets/kubernetes/manifests/kubelet.yaml.erb +40 -0
- data/lib/porkadot/assets/kubernetes/manifests/metallb.yaml.erb +323 -0
- data/lib/porkadot/assets/kubernetes/manifests/pod-checkpointer.yaml.erb +130 -0
- data/lib/porkadot/assets/kubernetes/manifests/porkadot.yaml.erb +69 -0
- data/lib/porkadot/assets/kubernetes.rb +39 -0
- data/lib/porkadot/assets.rb +24 -0
- data/lib/porkadot/cmd/cli.rb +45 -0
- data/lib/porkadot/cmd/install/bootstrap.rb +50 -0
- data/lib/porkadot/cmd/install.rb +36 -0
- data/lib/porkadot/cmd/render/certs.rb +68 -0
- data/lib/porkadot/cmd/render.rb +67 -0
- data/lib/porkadot/cmd.rb +4 -0
- data/lib/porkadot/config.rb +115 -0
- data/lib/porkadot/configs/bootstrap.rb +67 -0
- data/lib/porkadot/configs/certs/etcd.rb +33 -0
- data/lib/porkadot/configs/certs/front_proxy.rb +33 -0
- data/lib/porkadot/configs/certs/k8s.rb +89 -0
- data/lib/porkadot/configs/certs.rb +50 -0
- data/lib/porkadot/configs/cni.rb +22 -0
- data/lib/porkadot/configs/etcd.rb +95 -0
- data/lib/porkadot/configs/kubelet.rb +61 -0
- data/lib/porkadot/configs/kubernetes.rb +223 -0
- data/lib/porkadot/configs/loadbalancer.rb +26 -0
- data/lib/porkadot/const.rb +8 -0
- data/lib/porkadot/default.yaml +123 -0
- data/lib/porkadot/install/base.rb +5 -0
- data/lib/porkadot/install/bootstrap.rb +76 -0
- data/lib/porkadot/install/kubelet.rb +63 -0
- data/lib/porkadot/install/kubernetes.rb +33 -0
- data/lib/porkadot/utils/hash_recursive_merge.rb +73 -0
- data/lib/porkadot/utils.rb +25 -0
- data/lib/porkadot/version.rb +3 -0
- data/lib/porkadot.rb +41 -0
- data/porkadot.gemspec +42 -0
- metadata +205 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
|
2
|
+
class Porkadot::Assets::Certs::Kubernetes
|
3
|
+
include Porkadot::Assets::CertsUtils
|
4
|
+
attr_reader :global_config
|
5
|
+
attr_reader :config
|
6
|
+
attr_reader :logger
|
7
|
+
|
8
|
+
def initialize global_config
|
9
|
+
@config = Porkadot::Configs::Certs::Kubernetes.new(global_config)
|
10
|
+
@logger = config.logger
|
11
|
+
@global_config = config.config
|
12
|
+
end
|
13
|
+
|
14
|
+
def ca_name
|
15
|
+
'/CN=kube-ca'
|
16
|
+
end
|
17
|
+
|
18
|
+
def client_name
|
19
|
+
'/O=system:masters/CN=admin'
|
20
|
+
end
|
21
|
+
|
22
|
+
def apiserver_key
|
23
|
+
@apiserver_key ||= private_key(config.apiserver_key_path)
|
24
|
+
return @apiserver_key
|
25
|
+
end
|
26
|
+
|
27
|
+
def apiserver_cert(refresh=false)
|
28
|
+
return @apiserver_cert if defined?(@apiserver_cert)
|
29
|
+
if File.file?(config.apiserver_cert_path) and !refresh
|
30
|
+
self.logger.debug("--> APIserver cert already exists, skipping: #{config.apiserver_cert_path}")
|
31
|
+
@apiserver_cert = OpenSSL::X509::Certificate.new(File.read(config.apiserver_cert_path))
|
32
|
+
else
|
33
|
+
@apiserver_cert = _apiserver_cert(config.apiserver_cert_path, self.apiserver_key, self.ca_cert, self.ca_key)
|
34
|
+
end
|
35
|
+
return @apiserver_cert
|
36
|
+
end
|
37
|
+
|
38
|
+
def kubelet_client_key
|
39
|
+
@kubelet_client_key ||= private_key(config.kubelet_client_key_path)
|
40
|
+
return @kubelet_client_key
|
41
|
+
end
|
42
|
+
|
43
|
+
def kubelet_client_cert(refresh=false)
|
44
|
+
return @kubelet_client_cert if defined?(@kubelet_client_cert)
|
45
|
+
if File.file?(config.kubelet_client_cert_path) and !refresh
|
46
|
+
self.logger.debug("--> Kubelet client cert already exists, skipping: #{config.kubelet_client_cert_path}")
|
47
|
+
@kubelet_client_cert = OpenSSL::X509::Certificate.new(File.read(config.kubelet_client_cert_path))
|
48
|
+
else
|
49
|
+
@kubelet_client_cert = _client_cert(
|
50
|
+
config.kubelet_client_cert_path,
|
51
|
+
'/O=system:masters/CN=kube-kubelet-client',
|
52
|
+
self.kubelet_client_key,
|
53
|
+
self.ca_cert(false),
|
54
|
+
self.ca_key
|
55
|
+
)
|
56
|
+
end
|
57
|
+
return @kubelet_client_cert
|
58
|
+
end
|
59
|
+
|
60
|
+
def sa_private_key
|
61
|
+
@sa_private_key ||= private_key(config.sa_private_key_path)
|
62
|
+
return @sa_private_key
|
63
|
+
end
|
64
|
+
|
65
|
+
def sa_public_key
|
66
|
+
@sa_public_key ||= public_key(config.sa_public_key_path, self.sa_private_key)
|
67
|
+
return @sa_public_key
|
68
|
+
end
|
69
|
+
|
70
|
+
def _apiserver_cert(path, client_key, ca_cert, ca_key)
|
71
|
+
cert = unsigned_cert('/CN=apiserver', client_key, ca_cert, 1 * 365 * 24 * 60 * 60)
|
72
|
+
|
73
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
74
|
+
ef.subject_certificate = cert
|
75
|
+
ef.issuer_certificate = ca_cert
|
76
|
+
cert.add_extension(ef.create_extension("basicConstraints","CA:FALSE",true))
|
77
|
+
cert.add_extension(ef.create_extension("keyUsage","nonRepudiation, digitalSignature, keyEncipherment", true))
|
78
|
+
cert.add_extension(ef.create_extension("extendedKeyUsage","clientAuth, serverAuth",true))
|
79
|
+
|
80
|
+
cert.add_extension(ef.create_extension("subjectAltName", self.config.additional_sans.join(','), true))
|
81
|
+
cert.sign(ca_key, OpenSSL::Digest::SHA256.new)
|
82
|
+
|
83
|
+
File.open path, 'wb' do |f|
|
84
|
+
f.write cert.to_pem
|
85
|
+
end
|
86
|
+
|
87
|
+
return cert
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'base64'
|
4
|
+
#OpenSSL::Random.seed File.read('/dev/random', 16)
|
5
|
+
|
6
|
+
module Porkadot; module Assets
|
7
|
+
|
8
|
+
module CertsUtils
|
9
|
+
|
10
|
+
def to_pem(key_or_cert)
|
11
|
+
self.send(key_or_cert.to_sym).to_pem
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_base64(key_or_cert)
|
15
|
+
Base64.strict_encode64(self.to_pem(key_or_cert))
|
16
|
+
end
|
17
|
+
|
18
|
+
def ca_name
|
19
|
+
raise "Not implemented"
|
20
|
+
end
|
21
|
+
|
22
|
+
def ca_key
|
23
|
+
@ca_key ||= private_key(config.ca_key_path)
|
24
|
+
return @ca_key
|
25
|
+
end
|
26
|
+
|
27
|
+
def ca_cert(refresh=false)
|
28
|
+
return @ca_cert if defined?(@ca_cert)
|
29
|
+
if File.file?(config.ca_cert_path) and !refresh
|
30
|
+
self.logger.debug("--> CA cert already exists, skipping: #{config.ca_cert_path}")
|
31
|
+
@ca_cert = OpenSSL::X509::Certificate.new(File.read(config.ca_cert_path))
|
32
|
+
else
|
33
|
+
@ca_cert = _ca_cert(config.ca_cert_path, self.ca_name, self.ca_key)
|
34
|
+
end
|
35
|
+
return @ca_cert
|
36
|
+
end
|
37
|
+
|
38
|
+
def client_name
|
39
|
+
raise "Not implemented"
|
40
|
+
end
|
41
|
+
|
42
|
+
def client_key
|
43
|
+
@client_key ||= private_key(config.client_key_path)
|
44
|
+
return @client_key
|
45
|
+
end
|
46
|
+
|
47
|
+
def client_cert(refresh=false)
|
48
|
+
return @client_cert if defined?(@client_cert)
|
49
|
+
if File.file?(config.client_cert_path) and !refresh
|
50
|
+
self.logger.debug("--> Client cert already exists, skipping: #{config.client_cert_path}")
|
51
|
+
@client_cert = OpenSSL::X509::Certificate.new(File.read(config.client_cert_path))
|
52
|
+
else
|
53
|
+
@client_cert = _client_cert(config.client_cert_path, self.client_name, self.client_key, self.ca_cert(false), self.ca_key)
|
54
|
+
end
|
55
|
+
return @client_cert
|
56
|
+
end
|
57
|
+
|
58
|
+
def private_key(path)
|
59
|
+
if File.file?(path)
|
60
|
+
self.logger.debug("--> Private key already exists, skipping: #{path}")
|
61
|
+
key = OpenSSL::PKey::RSA.new File.read(path)
|
62
|
+
else
|
63
|
+
dir = File.dirname(path)
|
64
|
+
FileUtils.mkdir_p(dir)
|
65
|
+
key = OpenSSL::PKey::RSA.new 2048
|
66
|
+
File.open path, 'wb' do |f|
|
67
|
+
f.write key.export(nil, nil)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
return key
|
71
|
+
end
|
72
|
+
|
73
|
+
def public_key(path, key)
|
74
|
+
public_key = key.public_key
|
75
|
+
if File.file?(path)
|
76
|
+
self.logger.debug("--> Public key already exists, skipping: #{path}")
|
77
|
+
else
|
78
|
+
dir = File.dirname(path)
|
79
|
+
FileUtils.mkdir_p(dir)
|
80
|
+
File.open path, 'wb' do |f|
|
81
|
+
f.write public_key.export(nil, nil)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
return public_key
|
85
|
+
end
|
86
|
+
|
87
|
+
def random_number
|
88
|
+
return (0...8).map{ (0 + rand(10)) }.join.to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
def unsigned_cert(name, key, ca_cert=nil, expire=(1 * 365 * 24 * 60 * 60))
|
92
|
+
cert = OpenSSL::X509::Certificate.new
|
93
|
+
|
94
|
+
cert.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
|
95
|
+
cert.serial = self.random_number
|
96
|
+
cert.subject = OpenSSL::X509::Name.parse name
|
97
|
+
if ca_cert
|
98
|
+
cert.issuer = ca_cert.subject
|
99
|
+
else
|
100
|
+
cert.issuer = cert.subject # root CA's are "self-signed"
|
101
|
+
end
|
102
|
+
cert.public_key = key.public_key
|
103
|
+
cert.not_before = Time.now
|
104
|
+
cert.not_after = cert.not_before + expire
|
105
|
+
return cert
|
106
|
+
end
|
107
|
+
|
108
|
+
def _ca_cert(path, name, root_key)
|
109
|
+
root_ca = unsigned_cert(name, root_key, nil, 2 * 365 * 24 * 60 * 60)
|
110
|
+
|
111
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
112
|
+
ef.subject_certificate = root_ca
|
113
|
+
ef.issuer_certificate = root_ca
|
114
|
+
root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
|
115
|
+
root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
|
116
|
+
root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
117
|
+
root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
|
118
|
+
root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
|
119
|
+
|
120
|
+
File.open path, 'wb' do |f|
|
121
|
+
f.write root_ca.to_pem
|
122
|
+
end
|
123
|
+
|
124
|
+
return root_ca
|
125
|
+
end
|
126
|
+
|
127
|
+
def _client_cert(path, name, client_key, ca_cert, ca_key)
|
128
|
+
cert = unsigned_cert(name, client_key, ca_cert, 1 * 365 * 24 * 60 * 60)
|
129
|
+
|
130
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
131
|
+
ef.subject_certificate = cert
|
132
|
+
ef.issuer_certificate = ca_cert
|
133
|
+
cert.add_extension(ef.create_extension("basicConstraints","CA:FALSE",true))
|
134
|
+
cert.add_extension(ef.create_extension("keyUsage","nonRepudiation, digitalSignature, keyEncipherment", true))
|
135
|
+
cert.add_extension(ef.create_extension("extendedKeyUsage","clientAuth",true))
|
136
|
+
cert.sign(ca_key, OpenSSL::Digest::SHA256.new)
|
137
|
+
|
138
|
+
File.open path, 'wb' do |f|
|
139
|
+
f.write cert.to_pem
|
140
|
+
end
|
141
|
+
|
142
|
+
return cert
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end; end
|
148
|
+
|
149
|
+
class Porkadot::Assets::Certs
|
150
|
+
attr_reader :global_config
|
151
|
+
|
152
|
+
def initialize config
|
153
|
+
@global_config = config
|
154
|
+
end
|
155
|
+
|
156
|
+
def etcd
|
157
|
+
@etcd ||= Porkadot::Assets::Certs::Etcd.new(self.global_config)
|
158
|
+
return @etcd
|
159
|
+
end
|
160
|
+
|
161
|
+
def kubernetes
|
162
|
+
@kubernetes ||= Porkadot::Assets::Certs::Kubernetes.new(self.global_config)
|
163
|
+
return @kubernetes
|
164
|
+
end
|
165
|
+
|
166
|
+
def front_proxy
|
167
|
+
@front_proxy ||= Porkadot::Assets::Certs::FrontProxy.new(self.global_config)
|
168
|
+
return @front_proxy
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
require 'porkadot/assets/certs/etcd'
|
174
|
+
require 'porkadot/assets/certs/k8s'
|
175
|
+
require 'porkadot/assets/certs/front_proxy'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
apiVersion: v1
|
2
|
+
kind: Pod
|
3
|
+
metadata:
|
4
|
+
name: etcd
|
5
|
+
namespace: kube-system
|
6
|
+
labels:
|
7
|
+
tier: control-plane
|
8
|
+
component: etcd
|
9
|
+
spec:
|
10
|
+
hostNetwork: true
|
11
|
+
containers:
|
12
|
+
- name: etcd
|
13
|
+
image: <%= etcd.image_repository %>:<%= etcd.image_tag %>
|
14
|
+
command:
|
15
|
+
- /usr/local/bin/etcd
|
16
|
+
- --name=<%= config.member_name %>
|
17
|
+
- --advertise-client-urls=<%= config.advertise_client_urls.join(',') %>
|
18
|
+
- --initial-advertise-peer-urls=<%= config.advertise_peer_urls.join(',') %>
|
19
|
+
- --initial-cluster=<%= config.initial_cluster.map{|k,v| "#{k}=#{v}"}.join(',') %>
|
20
|
+
- --listen-client-urls=<%= config.listen_client_urls.join(',') %>
|
21
|
+
- --listen-peer-urls=<%= config.listen_peer_urls.join(',') %>
|
22
|
+
- --client-cert-auth=true
|
23
|
+
- --cert-file=/etc/etcd/pki/etcd.crt
|
24
|
+
- --key-file=/etc/etcd/pki/etcd.key
|
25
|
+
- --trusted-ca-file=/etc/etcd/pki/ca.crt
|
26
|
+
- --peer-client-cert-auth=true
|
27
|
+
- --peer-cert-file=/etc/etcd/pki/etcd.crt
|
28
|
+
- --peer-key-file=/etc/etcd/pki/etcd.key
|
29
|
+
- --peer-trusted-ca-file=/etc/etcd/pki/ca.crt
|
30
|
+
- --data-dir=/var/lib/etcd
|
31
|
+
- --heartbeat-interval=1000
|
32
|
+
- --election-timeout=10000
|
33
|
+
volumeMounts:
|
34
|
+
- mountPath: /var/lib/etcd
|
35
|
+
name: etcd
|
36
|
+
- mountPath: /etc/ssl/certs
|
37
|
+
name: ssl-certs-host
|
38
|
+
readOnly: true
|
39
|
+
- mountPath: /usr/share/ca-certificates
|
40
|
+
name: ca-certs-host
|
41
|
+
readOnly: true
|
42
|
+
- mountPath: /etc/etcd/pki
|
43
|
+
name: etcd-certs-host
|
44
|
+
readOnly: true
|
45
|
+
volumes:
|
46
|
+
- hostPath:
|
47
|
+
path: /var/lib/etcd
|
48
|
+
name: etcd
|
49
|
+
- hostPath:
|
50
|
+
path: /etc/ssl/certs
|
51
|
+
name: ssl-certs-host
|
52
|
+
- hostPath:
|
53
|
+
path: /usr/share/ca-certificates
|
54
|
+
name: ca-certs-host
|
55
|
+
- hostPath:
|
56
|
+
path: /etc/etcd/pki
|
57
|
+
name: etcd-certs-host
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -eu
|
4
|
+
export LC_ALL=C
|
5
|
+
ROOT=$(dirname "${BASH_SOURCE}")
|
6
|
+
|
7
|
+
mkdir -p /etc/etcd/pki
|
8
|
+
cp ${ROOT}/etcd.crt /etc/etcd/pki/
|
9
|
+
cp ${ROOT}/etcd.key /etc/etcd/pki/
|
10
|
+
cp ${ROOT}/ca.crt /etc/etcd/pki/
|
11
|
+
mkdir -p /etc/kubernetes/manifests
|
12
|
+
cp ${ROOT}/etcd-server.yaml /etc/kubernetes/manifests/
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'erb'
|
4
|
+
require 'base64'
|
5
|
+
|
6
|
+
module Porkadot; module Assets
|
7
|
+
class EtcdList
|
8
|
+
attr_reader :global_config
|
9
|
+
attr_reader :logger
|
10
|
+
attr_reader :nodes
|
11
|
+
|
12
|
+
def initialize global_config
|
13
|
+
@global_config = global_config
|
14
|
+
@logger = global_config.logger
|
15
|
+
@nodes = {}
|
16
|
+
global_config.etcd_nodes.each do |k, config|
|
17
|
+
@nodes[k] = EtcdNode.new(config)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def render
|
22
|
+
self.nodes.each do |_, v|
|
23
|
+
v.render
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](name)
|
28
|
+
self.nodes[name]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class EtcdNode
|
33
|
+
include Porkadot::Assets
|
34
|
+
TEMPLATE_DIR = File.join(File.dirname(__FILE__), "etcd")
|
35
|
+
|
36
|
+
attr_reader :global_config
|
37
|
+
attr_reader :config
|
38
|
+
attr_reader :logger
|
39
|
+
attr_reader :certs
|
40
|
+
|
41
|
+
def initialize config
|
42
|
+
@config = config
|
43
|
+
@logger = config.logger
|
44
|
+
@global_config = config.config
|
45
|
+
@certs = Porkadot::Assets::Certs::Etcd.new(global_config)
|
46
|
+
end
|
47
|
+
|
48
|
+
def render
|
49
|
+
logger.info "--> Rendering #{config.name} node"
|
50
|
+
unless File.directory?(config.target_path)
|
51
|
+
FileUtils.mkdir_p(config.target_path)
|
52
|
+
end
|
53
|
+
render_ca_crt
|
54
|
+
render_etcd_crt
|
55
|
+
render_erb 'etcd-server.yaml', etcd: global_config.etcd
|
56
|
+
render_erb 'install.sh', etcd: global_config.etcd
|
57
|
+
end
|
58
|
+
|
59
|
+
def render_ca_crt
|
60
|
+
logger.info "----> ca.crt"
|
61
|
+
open(config.ca_crt_path, 'w') do |out|
|
62
|
+
out.write self.certs.ca_cert(false).to_pem
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def render_etcd_crt
|
67
|
+
logger.info "----> etcd.crt"
|
68
|
+
self.etcd_key
|
69
|
+
self.etcd_cert(true)
|
70
|
+
end
|
71
|
+
|
72
|
+
def etcd_key
|
73
|
+
@etcd_key ||= certs.private_key(config.etcd_key_path)
|
74
|
+
return @etcd_key
|
75
|
+
end
|
76
|
+
|
77
|
+
def etcd_cert(refresh=false)
|
78
|
+
return @etcd_cert if defined?(@etcd_cert)
|
79
|
+
if File.file?(config.etcd_crt_path) and !refresh
|
80
|
+
self.logger.debug("--> Etcd cert already exists, skipping: #{config.etcd_cert_path}")
|
81
|
+
@etcd_cert = OpenSSL::X509::Certificate.new(File.read(config.etcd_cert_path))
|
82
|
+
else
|
83
|
+
ca_key = self.certs.ca_key
|
84
|
+
ca_cert = self.certs.ca_cert(false)
|
85
|
+
@etcd_cert = certs.unsigned_cert(
|
86
|
+
"/O=porkadot:etcd-servers/CN=porkadot:etcd-server-#{config.member_name}",
|
87
|
+
self.etcd_key, ca_cert,
|
88
|
+
1 * 365 * 24 * 60 * 60
|
89
|
+
)
|
90
|
+
|
91
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
92
|
+
ef.subject_certificate = @etcd_cert
|
93
|
+
ef.issuer_certificate = ca_cert
|
94
|
+
@etcd_cert.add_extension(ef.create_extension("basicConstraints","CA:FALSE",true))
|
95
|
+
@etcd_cert.add_extension(ef.create_extension("keyUsage","nonRepudiation, digitalSignature, keyEncipherment", true))
|
96
|
+
@etcd_cert.add_extension(ef.create_extension("extendedKeyUsage","clientAuth, serverAuth",true))
|
97
|
+
|
98
|
+
@etcd_cert.add_extension(ef.create_extension("subjectAltName", self.config.additional_sans.join(','), true))
|
99
|
+
@etcd_cert.sign(ca_key, OpenSSL::Digest::SHA256.new)
|
100
|
+
|
101
|
+
File.open config.etcd_crt_path, 'wb' do |f|
|
102
|
+
f.write @etcd_cert.to_pem
|
103
|
+
end
|
104
|
+
end
|
105
|
+
return @etcd_cert
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end; end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
apiVersion: v1
|
2
|
+
clusters:
|
3
|
+
- cluster:
|
4
|
+
certificate-authority-data: <%= ca_data %>
|
5
|
+
server: https://<%= config.control_plane_endpoint %>
|
6
|
+
name: bootstrap
|
7
|
+
contexts:
|
8
|
+
- context:
|
9
|
+
cluster: bootstrap
|
10
|
+
user: kubelet-bootstrap
|
11
|
+
name: bootstrap
|
12
|
+
current-context: bootstrap
|
13
|
+
kind: Config
|
14
|
+
preferences: {}
|
15
|
+
users:
|
16
|
+
- name: kubelet-bootstrap
|
17
|
+
user:
|
18
|
+
client-certificate: /etc/kubernetes/pki/bootstrap.crt
|
19
|
+
client-key: /etc/kubernetes/pki/bootstrap.key
|
20
|
+
|
21
|
+
# vim:filetype=yaml
|
@@ -0,0 +1,36 @@
|
|
1
|
+
apiVersion: kubelet.config.k8s.io/v1beta1
|
2
|
+
authentication:
|
3
|
+
anonymous:
|
4
|
+
enabled: false
|
5
|
+
webhook:
|
6
|
+
cacheTTL: 0s
|
7
|
+
enabled: true
|
8
|
+
x509:
|
9
|
+
clientCAFile: /etc/kubernetes/pki/ca.crt
|
10
|
+
authorization:
|
11
|
+
mode: Webhook
|
12
|
+
webhook:
|
13
|
+
cacheAuthorizedTTL: 0s
|
14
|
+
cacheUnauthorizedTTL: 0s
|
15
|
+
clusterDNS:
|
16
|
+
- <%= global_config.k8s.networking.dns_ip %>
|
17
|
+
clusterDomain: <%= global_config.k8s.networking.dns_domain %>
|
18
|
+
cpuManagerReconcilePeriod: 0s
|
19
|
+
evictionPressureTransitionPeriod: 0s
|
20
|
+
fileCheckFrequency: 0s
|
21
|
+
healthzBindAddress: 127.0.0.1
|
22
|
+
healthzPort: 10248
|
23
|
+
httpCheckFrequency: 0s
|
24
|
+
imageMinimumGCAge: 0s
|
25
|
+
kind: KubeletConfiguration
|
26
|
+
nodeStatusReportFrequency: 0s
|
27
|
+
nodeStatusUpdateFrequency: 0s
|
28
|
+
rotateCertificates: true
|
29
|
+
runtimeRequestTimeout: 0s
|
30
|
+
staticPodPath: /etc/kubernetes/manifests
|
31
|
+
streamingConnectionIdleTimeout: 0s
|
32
|
+
syncFrequency: 0s
|
33
|
+
volumeStatsAggPeriod: 0s
|
34
|
+
serverTLSBootstrap: true
|
35
|
+
|
36
|
+
# vim:filetype=yaml
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
CNI_VERSION="<%= global_config.k8s.networking.cni_version %>"
|
4
|
+
mkdir -p /opt/cni/bin
|
5
|
+
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz" | tar -C /opt/cni/bin -xz
|
6
|
+
|
7
|
+
RELEASE="<%= global_config.k8s.kubernetes_version %>"
|
8
|
+
|
9
|
+
mkdir -p /opt/bin
|
10
|
+
|
11
|
+
curl -L https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/amd64/kubectl \
|
12
|
+
-o /opt/bin/kubectl-${RELEASE}
|
13
|
+
chmod +x /opt/bin/kubectl-${RELEASE}
|
14
|
+
rm -f /opt/bin/kubectl
|
15
|
+
ln -s /opt/bin/kubectl-${RELEASE} /opt/bin/kubectl
|
16
|
+
|
17
|
+
curl -L https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/amd64/kubelet \
|
18
|
+
-o /opt/bin/kubelet-${RELEASE}
|
19
|
+
chmod +x /opt/bin/kubelet-${RELEASE}
|
20
|
+
rm -f /opt/bin/kubelet
|
21
|
+
ln -s /opt/bin/kubelet-${RELEASE} /opt/bin/kubelet
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -eu
|
3
|
+
export LC_ALL=C
|
4
|
+
ROOT=$(dirname "${BASH_SOURCE}")
|
5
|
+
|
6
|
+
if type apt-get > /dev/null 2>&1 ;then
|
7
|
+
apt-get update
|
8
|
+
apt-get install -y \
|
9
|
+
ca-certificates \
|
10
|
+
conntrack \
|
11
|
+
e2fsprogs \
|
12
|
+
xfsprogs \
|
13
|
+
ebtables \
|
14
|
+
ethtool \
|
15
|
+
git \
|
16
|
+
iptables \
|
17
|
+
ipset \
|
18
|
+
jq \
|
19
|
+
kmod \
|
20
|
+
openssh-client \
|
21
|
+
netbase \
|
22
|
+
nfs-common \
|
23
|
+
socat \
|
24
|
+
udev \
|
25
|
+
util-linux
|
26
|
+
fi
|
27
|
+
|
28
|
+
cat <<EOF > /etc/sysctl.d/k8s.conf
|
29
|
+
net.bridge.bridge-nf-call-ip6tables = 1
|
30
|
+
net.bridge.bridge-nf-call-iptables = 1
|
31
|
+
EOF
|
32
|
+
|
33
|
+
sysctl --system
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -eu
|
4
|
+
export LC_ALL=C
|
5
|
+
ROOT=$(dirname "${BASH_SOURCE}")
|
6
|
+
|
7
|
+
export KUBERNETES_PATH="/etc/kubernetes"
|
8
|
+
export KUBERNETES_PKI_PATH="${KUBERNETES_PATH}/pki"
|
9
|
+
export KUBERNETES_MANIFESTS_PATH="${KUBERNETES_PATH}/manifests"
|
10
|
+
export KUBELET_PATH="/var/lib/kubelet"
|
11
|
+
|
12
|
+
mkdir -p ${KUBERNETES_PATH}
|
13
|
+
mkdir -p ${KUBERNETES_PKI_PATH}
|
14
|
+
mkdir -p ${KUBERNETES_MANIFESTS_PATH}
|
15
|
+
mkdir -p ${KUBELET_PATH}
|
16
|
+
|
17
|
+
cp ${ROOT}/bootstrap-kubelet.conf ${KUBERNETES_PATH}/
|
18
|
+
cp ${ROOT}/bootstrap.* ${KUBERNETES_PKI_PATH}/
|
19
|
+
cp ${ROOT}/ca.crt ${KUBERNETES_PKI_PATH}/
|
20
|
+
cp ${ROOT}/config.yaml ${KUBELET_PATH}/
|
21
|
+
cp ${ROOT}/kubelet.service /etc/systemd/system/
|
22
|
+
|
23
|
+
# Install addons
|
24
|
+
for addon in $(ls ${ROOT}/addons/); do
|
25
|
+
install_sh="${ROOT}/addons/${addon}/install.sh"
|
26
|
+
if [[ -f ${install_sh} ]]; then
|
27
|
+
echo "Install: ${install_sh}"
|
28
|
+
bash ${install_sh}
|
29
|
+
fi
|
30
|
+
done
|
31
|
+
|
32
|
+
rm -f ${KUBERNETES_PATH}/kubelet.conf
|
33
|
+
systemctl daemon-reload
|
34
|
+
systemctl enable kubelet
|
35
|
+
systemctl restart kubelet
|
@@ -0,0 +1,22 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description=kubelet: The Kubernetes Node Agent
|
3
|
+
Documentation=http://kubernetes.io/docs/
|
4
|
+
|
5
|
+
[Service]
|
6
|
+
EnvironmentFile=-/etc/default/kubelet
|
7
|
+
ExecStart=/opt/bin/kubelet \
|
8
|
+
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \
|
9
|
+
--kubeconfig=/etc/kubernetes/kubelet.conf \
|
10
|
+
--config=/var/lib/kubelet/config.yaml \
|
11
|
+
--network-plugin=cni \
|
12
|
+
--pod-infra-container-image=k8s.gcr.io/pause:3.1 \
|
13
|
+
--hostname-override=<%= config.hostname %> \
|
14
|
+
--node-labels=<%= config.labels_string %> \
|
15
|
+
--register-with-taints=<%= config.taints_string %> \
|
16
|
+
--resolv-conf=/run/systemd/resolve/resolv.conf
|
17
|
+
Restart=always
|
18
|
+
StartLimitInterval=0
|
19
|
+
RestartSec=10
|
20
|
+
|
21
|
+
[Install]
|
22
|
+
WantedBy=multi-user.target
|