lib/porkadot/configs/kubernetes.rb
module Porkadot; module Configs class Kubernetes include Porkadot::ConfigUtils attr_reader :networking attr_reader :proxy attr_reader :apiserver attr_reader :controller_manager attr_reader :scheduler def initialize config @config = config @raw = config.raw.kubernetes @networking = Networking.new(config) @proxy = Proxy.new(config) @apiserver = Apiserver.new(config) @controller_manager = ControllerManager.new(config) @scheduler = Scheduler.new(config) end def cluster_name self.raw.cluster_name || 'porkadot' end def target_path File.join(self.config.assets_dir, 'kubernetes') end def target_secrets_path File.join(self.config.secrets_root_dir, 'kubernetes') end def manifests_path File.join(self.target_path, 'manifests') end def control_plane_endpoint_host_and_port endpoint = self.config.k8s.control_plane_endpoint raise "kubernetes.control_plane_endpoint should not be nil" unless endpoint index = endpoint.rindex(':') return [endpoint[0, index], endpoint[index+1, 6]] end module Component RECOMMENDED_LABEL_PREFIX = 'app.kubernetes.io' def labels self.instance_labels.merge({ "#{RECOMMENDED_LABEL_PREFIX}/name": self.component_name, "#{RECOMMENDED_LABEL_PREFIX}/component": self.component_name, "#{RECOMMENDED_LABEL_PREFIX}/instance": "#{self.component_name}-porkadot", "#{RECOMMENDED_LABEL_PREFIX}/version": self.config.k8s.kubernetes_version, "#{RECOMMENDED_LABEL_PREFIX}/part-of": 'kubernetes', "#{RECOMMENDED_LABEL_PREFIX}/managed-by": 'porkadot', "k8s-app": self.component_name, }) end def instance_labels { "#{RECOMMENDED_LABEL_PREFIX}/component": self.component_name, "#{RECOMMENDED_LABEL_PREFIX}/instance": "#{self.component_name}-porkadot", "#{RECOMMENDED_LABEL_PREFIX}/managed-by": 'porkadot', } end def args bootstrap: false extra = {} if self.extra_args extra = self.extra_args.map{|i| i.split('=', 2)}.to_h end if bootstrap extra = self.bootstrap_args.merge(extra) end return self.default_args.merge(extra) end def log_level config.kubernetes.log_level || raw.log_level || 2 end end class Apiserver include Porkadot::ConfigUtils include Component def initialize config @config = config @raw = config.raw.kubernetes.apiserver end def component_name 'kube-apiserver' end def bootstrap_args return {} end def default_args return %W( --advertise-address=$(POD_IP) --allow-privileged=true --authorization-mode=Node,RBAC --bind-address=0.0.0.0 --client-ca-file=/etc/kubernetes/pki/kubernetes/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/etcd/etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/etcd/etcd-client.key --etcd-servers=#{config.etcd.advertise_client_urls.join(',')} --kubelet-certificate-authority=/etc/kubernetes/pki/kubernetes/ca.crt --kubelet-client-certificate=/etc/kubernetes/pki/kubernetes/kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/kubernetes/kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/kubernetes/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/kubernetes/front-proxy-client.key --requestheader-allowed-names=aggregator-client --requestheader-client-ca-file=/etc/kubernetes/pki/kubernetes/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=#{self.bind_port} --service-account-issuer=https://kubernetes.default.svc#{self.config.k8s.networking.dns_domain} --service-account-key-file=/etc/kubernetes/pki/kubernetes/sa.pub --service-account-signing-key-file=/etc/kubernetes/pki/kubernetes/sa.key --service-cluster-ip-range=#{config.k8s.networking.service_subnet} --storage-backend=etcd3 --tls-cert-file=/etc/kubernetes/pki/kubernetes/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/kubernetes/apiserver.key --v=#{self.log_level} ).map {|i| i.split('=', 2)}.to_h end end class Scheduler include Porkadot::ConfigUtils include Component def initialize config @config = config @raw = config.raw.kubernetes.scheduler end def component_name 'kube-scheduler' end def bootstrap_args return %W( --kubeconfig=/etc/kubernetes/bootstrap/kubeconfig-bootstrap.yaml --authentication-kubeconfig=/etc/kubernetes/bootstrap/kubeconfig-bootstrap.yaml --authorization-kubeconfig=/etc/kubernetes/bootstrap/kubeconfig-bootstrap.yaml ).map {|i| i.split('=', 2)}.to_h end def default_args return %W( --leader-elect=true --v=#{self.log_level} ).map {|i| i.split('=', 2)}.to_h end end class ControllerManager include Porkadot::ConfigUtils include Component def initialize config @config = config @raw = config.raw.kubernetes.controller_manager end def component_name 'kube-controller-manager' end def bootstrap_args return %W( --kubeconfig=/etc/kubernetes/bootstrap/kubeconfig-bootstrap.yaml ).map {|i| i.split('=', 2)}.to_h end def default_args return %W( --allocate-node-cidrs=true --cluster-cidr=#{config.k8s.networking.pod_subnet} --cluster-signing-cert-file=/etc/kubernetes/pki/kubernetes/ca.crt --cluster-signing-key-file=/etc/kubernetes/pki/kubernetes/ca.key --controllers=*,bootstrapsigner,tokencleaner --leader-elect=true --root-ca-file=/etc/kubernetes/pki/kubernetes/ca.crt --service-account-private-key-file=/etc/kubernetes/pki/kubernetes/sa.key --service-cluster-ip-range=#{config.k8s.networking.service_subnet} --use-service-account-credentials=true --v=#{self.log_level} ).map {|i| i.split('=', 2)}.to_h end end class Proxy include Porkadot::ConfigUtils include Component def initialize config @config = config @raw = config.raw.kubernetes.proxy end def proxy_config kubeconfig=nil self.raw.config['clusterCIDR'] = config.k8s.networking.pod_subnet if kubeconfig self.raw.config['clientConnection']['kubeconfig'] = kubeconfig end self.raw.config.to_hash.to_yaml end def component_name 'kube-proxy' end def bootstrap_args return %W( --config=/etc/kubernetes/bootstrap/kube-proxy-bootstrap.yaml ).map {|i| i.split('=', 2)}.to_h end def default_args return %W( --config=/var/lib/kube-proxy/config.conf --hostname-override=$(NODE_NAME) ).map {|i| i.split('=', 2)}.to_h end end class Networking include Porkadot::ConfigUtils def initialize config @config = config @raw = config.raw.kubernetes.networking end def kubernetes_ip cluster_ip_range = IPAddr.new(self.default_service_subnet) cluster_ip_range.to_range.first(2)[1] end def dns_ip cluster_ip_range = IPAddr.new(self.default_service_subnet) cluster_ip_range.to_range.first(11)[10] end def default_service_subnet self.service_subnet.split(',')[0] end def pod_v4subnet if ip = self._pod_subnet.find{ |net| net.ipv4? } return "#{ip.to_s}/#{ip.prefix}" end end alias enable_ipv4 pod_v4subnet def pod_v6subnet if ip = self._pod_subnet.find{ |net| net.ipv6? } return "#{ip.to_s}/#{ip.prefix}" end end alias enable_ipv6 pod_v6subnet def _pod_subnet self.pod_subnet.split(",").map{|net| IPAddr.new(net)} end end end end; end