1
0
mirror of https://github.com/rancher/rke.git synced 2025-08-31 22:46:25 +00:00

External etcd

This commit is contained in:
galal-hussein
2018-02-14 22:58:35 +02:00
parent e75df68c35
commit c2c1804500
15 changed files with 205 additions and 65 deletions

View File

@@ -222,6 +222,32 @@ ingress:
RKE will deploy Nginx Ingress controller as a DaemonSet with `hostnetwork: true`, so ports `80`, and `443` will be opened on each node where the controller is deployed. RKE will deploy Nginx Ingress controller as a DaemonSet with `hostnetwork: true`, so ports `80`, and `443` will be opened on each node where the controller is deployed.
## External etcd
RKE supports using external etcd instead of deploying etcd servers, to enable external etcd the following parameters should be populated:
```
services:
etcd:
path: /etcdcluster
external_urls:
- https://etcd-example.com:2379
ca_cert: |-
-----BEGIN CERTIFICATE-----
xxxxxxxxxx
-----END CERTIFICATE-----
cert: |-
-----BEGIN CERTIFICATE-----
xxxxxxxxxx
-----END CERTIFICATE-----
key: |-
-----BEGIN PRIVATE KEY-----
xxxxxxxxxx
-----END PRIVATE KEY-----
```
Note that RKE only supports connecting to TLS enabled etcd setup, user can enable multiple endpoints in the `external_urls` field. RKE will not accept having external urls and nodes with `etcd` role at the same time, user should only specify either etcd role for servers or external etcd but not both.
## Operating Systems Notes ## Operating Systems Notes
### Atomic OS ### Atomic OS

View File

@@ -68,9 +68,24 @@ nodes:
services: services:
etcd: etcd:
# if external etcd is used
# path: /etcdcluster
# external_urls:
# - https://etcd-example.com:2379
# ca_cert: |-
# -----BEGIN CERTIFICATE-----
# xxxxxxxxxx
# -----END CERTIFICATE-----
# cert: |-
# -----BEGIN CERTIFICATE-----
# xxxxxxxxxx
# -----END CERTIFICATE-----
# key: |-
# -----BEGIN PRIVATE KEY-----
# xxxxxxxxxx
# -----END PRIVATE KEY-----
kube-api: kube-api:
service_cluster_ip_range: 10.233.0.0/18 service_cluster_ip_range: 10.233.0.0/18
pod_security_policy: false pod_security_policy: false
extra_args: extra_args:

View File

@@ -22,26 +22,26 @@ func SetUpAuthentication(ctx context.Context, kubeCluster, currentCluster *Clust
if currentCluster != nil { if currentCluster != nil {
kubeCluster.Certificates = currentCluster.Certificates kubeCluster.Certificates = currentCluster.Certificates
} else { } else {
log.Infof(ctx, "[certificates] Attempting to recover certificates from backup on host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] Attempting to recover certificates from backup on host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
kubeCluster.Certificates, err = pki.FetchCertificatesFromHost(ctx, kubeCluster.EtcdHosts, kubeCluster.EtcdHosts[0], kubeCluster.SystemImages.Alpine, kubeCluster.LocalKubeConfigPath, kubeCluster.PrivateRegistriesMap) kubeCluster.Certificates, err = pki.FetchCertificatesFromHost(ctx, kubeCluster.EtcdHosts, kubeCluster.ControlPlaneHosts[0], kubeCluster.SystemImages.Alpine, kubeCluster.LocalKubeConfigPath, kubeCluster.PrivateRegistriesMap)
if err != nil { if err != nil {
return err return err
} }
if kubeCluster.Certificates != nil { if kubeCluster.Certificates != nil {
log.Infof(ctx, "[certificates] Certificate backup found on host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] Certificate backup found on host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
return nil return nil
} }
log.Infof(ctx, "[certificates] No Certificate backup found on host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] No Certificate backup found on host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
kubeCluster.Certificates, err = pki.GenerateRKECerts(ctx, kubeCluster.RancherKubernetesEngineConfig, kubeCluster.LocalKubeConfigPath, "") kubeCluster.Certificates, err = pki.GenerateRKECerts(ctx, kubeCluster.RancherKubernetesEngineConfig, kubeCluster.LocalKubeConfigPath, "")
if err != nil { if err != nil {
return fmt.Errorf("Failed to generate Kubernetes certificates: %v", err) return fmt.Errorf("Failed to generate Kubernetes certificates: %v", err)
} }
log.Infof(ctx, "[certificates] Temporarily saving certs to etcd host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] Temporarily saving certs to control host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
if err := pki.DeployCertificatesOnHost(ctx, kubeCluster.EtcdHosts[0], kubeCluster.Certificates, kubeCluster.SystemImages.CertDownloader, pki.TempCertPath, kubeCluster.PrivateRegistriesMap); err != nil { if err := pki.DeployCertificatesOnHost(ctx, kubeCluster.ControlPlaneHosts[0], kubeCluster.Certificates, kubeCluster.SystemImages.CertDownloader, pki.TempCertPath, kubeCluster.PrivateRegistriesMap); err != nil {
return err return err
} }
log.Infof(ctx, "[certificates] Saved certs to etcd host [%s]", kubeCluster.EtcdHosts[0].Address) log.Infof(ctx, "[certificates] Saved certs to control host [%s]", kubeCluster.ControlPlaneHosts[0].Address)
} }
} }
return nil return nil
@@ -123,11 +123,14 @@ func saveCertToKubernetes(kubeClient *kubernetes.Clientset, crtName string, crt
timeout := make(chan bool, 1) timeout := make(chan bool, 1)
// build secret Data // build secret Data
secretData := map[string][]byte{ secretData := make(map[string][]byte)
"Certificate": cert.EncodeCertPEM(crt.Certificate), if crt.Certificate != nil {
"Key": cert.EncodePrivateKeyPEM(crt.Key), secretData["Certificate"] = cert.EncodeCertPEM(crt.Certificate)
"EnvName": []byte(crt.EnvName), secretData["EnvName"] = []byte(crt.EnvName)
"KeyEnvName": []byte(crt.KeyEnvName), }
if crt.Key != nil {
secretData["Key"] = cert.EncodePrivateKeyPEM(crt.Key)
secretData["KeyEnvName"] = []byte(crt.KeyEnvName)
} }
if len(crt.Config) > 0 { if len(crt.Config) > 0 {
secretData["ConfigEnvName"] = []byte(crt.ConfigEnvName) secretData["ConfigEnvName"] = []byte(crt.ConfigEnvName)

View File

@@ -55,10 +55,14 @@ const (
func (c *Cluster) DeployControlPlane(ctx context.Context) error { func (c *Cluster) DeployControlPlane(ctx context.Context) error {
// Deploy Etcd Plane // Deploy Etcd Plane
etcdProcessHostMap := c.getEtcdProcessHostMap(nil) etcdProcessHostMap := c.getEtcdProcessHostMap(nil)
if len(c.Services.Etcd.ExternalURLs) > 0 {
if err := services.RunEtcdPlane(ctx, c.EtcdHosts, etcdProcessHostMap, c.LocalConnDialerFactory, c.PrivateRegistriesMap); err != nil { log.Infof(ctx, "[etcd] External etcd connection string has been specified, skipping etcd plane")
return fmt.Errorf("[etcd] Failed to bring up Etcd Plane: %v", err) } else {
if err := services.RunEtcdPlane(ctx, c.EtcdHosts, etcdProcessHostMap, c.LocalConnDialerFactory, c.PrivateRegistriesMap); err != nil {
return fmt.Errorf("[etcd] Failed to bring up Etcd Plane: %v", err)
}
} }
// Deploy Control plane // Deploy Control plane
processMap := map[string]v3.Process{ processMap := map[string]v3.Process{
services.SidekickContainerName: c.BuildSidecarProcess(), services.SidekickContainerName: c.BuildSidecarProcess(),

View File

@@ -21,7 +21,7 @@ const (
func (c *Cluster) TunnelHosts(ctx context.Context, local bool) error { func (c *Cluster) TunnelHosts(ctx context.Context, local bool) error {
if local { if local {
if err := c.EtcdHosts[0].TunnelUpLocal(ctx); err != nil { if err := c.ControlPlaneHosts[0].TunnelUpLocal(ctx); err != nil {
return fmt.Errorf("Failed to connect to docker for local host [%s]: %v", c.EtcdHosts[0].Address, err) return fmt.Errorf("Failed to connect to docker for local host [%s]: %v", c.EtcdHosts[0].Address, err)
} }
return nil return nil

View File

@@ -73,11 +73,15 @@ const (
APIRoot = "APIRoot" APIRoot = "APIRoot"
// kubernetes client certificates and kubeconfig paths // kubernetes client certificates and kubeconfig paths
ClientCert = "ClientCert" EtcdClientCert = "EtcdClientCert"
EtcdClientKey = "EtcdClientKey"
EtcdClientCA = "EtcdClientCA"
EtcdClientCertPath = "EtcdClientCertPath"
EtcdClientKeyPath = "EtcdClientKeyPath"
EtcdClientCAPath = "EtcdClientCAPath"
ClientCertPath = "ClientCertPath" ClientCertPath = "ClientCertPath"
ClientKey = "ClientKey"
ClientKeyPath = "ClientKeyPath" ClientKeyPath = "ClientKeyPath"
ClientCA = "ClientCA"
ClientCAPath = "ClientCAPath" ClientCAPath = "ClientCAPath"
KubeCfg = "KubeCfg" KubeCfg = "KubeCfg"
@@ -144,27 +148,36 @@ func (c *Cluster) doFlannelDeploy(ctx context.Context) error {
} }
func (c *Cluster) doCalicoDeploy(ctx context.Context) error { func (c *Cluster) doCalicoDeploy(ctx context.Context) error {
clientCert := b64.StdEncoding.EncodeToString(cert.EncodeCertPEM(c.Certificates[pki.KubeNodeCertName].Certificate))
clientkey := b64.StdEncoding.EncodeToString(cert.EncodePrivateKeyPEM(c.Certificates[pki.KubeNodeCertName].Key)) etcdEndpoints := services.GetEtcdConnString(c.EtcdHosts)
etcdClientCert := b64.StdEncoding.EncodeToString(cert.EncodeCertPEM(c.Certificates[pki.KubeNodeCertName].Certificate))
etcdClientkey := b64.StdEncoding.EncodeToString(cert.EncodePrivateKeyPEM(c.Certificates[pki.KubeNodeCertName].Key))
etcdCaCert := b64.StdEncoding.EncodeToString(cert.EncodeCertPEM(c.Certificates[pki.CACertName].Certificate))
clientConfig := pki.GetConfigPath(pki.KubeNodeCertName) clientConfig := pki.GetConfigPath(pki.KubeNodeCertName)
caCert := b64.StdEncoding.EncodeToString(cert.EncodeCertPEM(c.Certificates[pki.CACertName].Certificate)) // handling external etcd
if len(c.Services.Etcd.ExternalURLs) > 0 {
etcdClientCert = b64.StdEncoding.EncodeToString([]byte(c.Services.Etcd.Cert))
etcdClientkey = b64.StdEncoding.EncodeToString([]byte(c.Services.Etcd.Key))
etcdCaCert = b64.StdEncoding.EncodeToString([]byte(c.Services.Etcd.CACert))
etcdEndpoints = strings.Join(c.Services.Etcd.ExternalURLs, ",")
}
calicoConfig := map[string]string{ calicoConfig := map[string]string{
EtcdEndpoints: services.GetEtcdConnString(c.EtcdHosts), EtcdEndpoints: etcdEndpoints,
APIRoot: "https://127.0.0.1:6443", APIRoot: "https://127.0.0.1:6443",
ClientCert: clientCert, EtcdClientCA: etcdCaCert,
ClientCertPath: pki.GetCertPath(pki.KubeNodeCertName), EtcdClientCert: etcdClientCert,
ClientKey: clientkey, EtcdClientKey: etcdClientkey,
ClientKeyPath: pki.GetKeyPath(pki.KubeNodeCertName), EtcdClientKeyPath: pki.GetKeyPath(pki.EtcdClientCertName),
ClientCA: caCert, EtcdClientCertPath: pki.GetCertPath(pki.EtcdClientCertName),
ClientCAPath: pki.GetCertPath(pki.CACertName), EtcdClientCAPath: pki.GetCertPath(pki.EtcdClientCACertName),
KubeCfg: clientConfig, KubeCfg: clientConfig,
ClusterCIDR: c.ClusterCIDR, ClusterCIDR: c.ClusterCIDR,
CNIImage: c.SystemImages.CalicoCNI, CNIImage: c.SystemImages.CalicoCNI,
NodeImage: c.SystemImages.CalicoNode, NodeImage: c.SystemImages.CalicoNode,
ControllersImage: c.SystemImages.CalicoControllers, ControllersImage: c.SystemImages.CalicoControllers,
Calicoctl: c.SystemImages.CalicoCtl, Calicoctl: c.SystemImages.CalicoCtl,
CloudProvider: c.Network.Options[CalicoCloudProvider], CloudProvider: c.Network.Options[CalicoCloudProvider],
RBACConfig: c.Authorization.Mode, RBACConfig: c.Authorization.Mode,
} }
pluginYaml, err := c.getNetworkPluginManifest(calicoConfig) pluginYaml, err := c.getNetworkPluginManifest(calicoConfig)
if err != nil { if err != nil {

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"strconv" "strconv"
"strings"
"github.com/rancher/rke/hosts" "github.com/rancher/rke/hosts"
"github.com/rancher/rke/pki" "github.com/rancher/rke/pki"
@@ -11,6 +12,10 @@ import (
"github.com/rancher/types/apis/management.cattle.io/v3" "github.com/rancher/types/apis/management.cattle.io/v3"
) )
const (
EtcdPathPrefix = "/registry"
)
func GeneratePlan(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig) (v3.RKEPlan, error) { func GeneratePlan(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig) (v3.RKEPlan, error) {
clusterPlan := v3.RKEPlan{} clusterPlan := v3.RKEPlan{}
myCluster, _ := ParseCluster(ctx, rkeConfig, "", "", nil, nil) myCluster, _ := ParseCluster(ctx, rkeConfig, "", "", nil, nil)
@@ -55,8 +60,20 @@ func BuildRKEConfigNodePlan(ctx context.Context, myCluster *Cluster, host *hosts
} }
func (c *Cluster) BuildKubeAPIProcess() v3.Process { func (c *Cluster) BuildKubeAPIProcess() v3.Process {
etcdConnString := services.GetEtcdConnString(c.EtcdHosts) // check if external etcd is used
args := []string{} etcdConnectionString := services.GetEtcdConnString(c.EtcdHosts)
etcdPathPrefix := EtcdPathPrefix
etcdClientCert := pki.GetCertPath(pki.KubeNodeCertName)
etcdClientKey := pki.GetKeyPath(pki.KubeNodeCertName)
etcdCAClientCert := pki.GetCertPath(pki.CACertName)
if len(c.Services.Etcd.ExternalURLs) > 0 {
etcdConnectionString = strings.Join(c.Services.Etcd.ExternalURLs, ",")
etcdPathPrefix = c.Services.Etcd.Path
etcdClientCert = pki.GetCertPath(pki.EtcdClientCertName)
etcdClientKey = pki.GetKeyPath(pki.EtcdClientCertName)
etcdCAClientCert = pki.GetCertPath(pki.EtcdClientCACertName)
}
Command := []string{ Command := []string{
"/opt/rke/entrypoint.sh", "/opt/rke/entrypoint.sh",
"kube-apiserver", "kube-apiserver",
@@ -76,11 +93,14 @@ func (c *Cluster) BuildKubeAPIProcess() v3.Process {
"--tls-cert-file=" + pki.GetCertPath(pki.KubeAPICertName), "--tls-cert-file=" + pki.GetCertPath(pki.KubeAPICertName),
"--tls-private-key-file=" + pki.GetKeyPath(pki.KubeAPICertName), "--tls-private-key-file=" + pki.GetKeyPath(pki.KubeAPICertName),
"--service-account-key-file=" + pki.GetKeyPath(pki.KubeAPICertName), "--service-account-key-file=" + pki.GetKeyPath(pki.KubeAPICertName),
"--etcd-cafile=" + pki.GetCertPath(pki.CACertName),
"--etcd-certfile=" + pki.GetCertPath(pki.KubeAPICertName),
"--etcd-keyfile=" + pki.GetKeyPath(pki.KubeAPICertName),
} }
args = append(args, "--etcd-servers="+etcdConnString) args := []string{
"--etcd-cafile=" + etcdCAClientCert,
"--etcd-certfile=" + etcdClientCert,
"--etcd-keyfile=" + etcdClientKey,
"--etcd-servers=" + etcdConnectionString,
"--etcd-prefix=" + etcdPathPrefix,
}
if c.Authorization.Mode == services.RBACAuthorizationMode { if c.Authorization.Mode == services.RBACAuthorizationMode {
args = append(args, "--authorization-mode=RBAC") args = append(args, "--authorization-mode=RBAC")

View File

@@ -10,6 +10,10 @@ import (
) )
func (c *Cluster) ClusterRemove(ctx context.Context) error { func (c *Cluster) ClusterRemove(ctx context.Context) error {
externalEtcd := false
if len(c.Services.Etcd.ExternalURLs) > 0 {
externalEtcd = true
}
// Remove Worker Plane // Remove Worker Plane
if err := services.RemoveWorkerPlane(ctx, c.WorkerHosts, true); err != nil { if err := services.RemoveWorkerPlane(ctx, c.WorkerHosts, true); err != nil {
return err return err
@@ -26,7 +30,7 @@ func (c *Cluster) ClusterRemove(ctx context.Context) error {
} }
// Clean up all hosts // Clean up all hosts
if err := cleanUpHosts(ctx, c.ControlPlaneHosts, c.WorkerHosts, c.EtcdHosts, c.SystemImages.Alpine, c.PrivateRegistriesMap); err != nil { if err := cleanUpHosts(ctx, c.ControlPlaneHosts, c.WorkerHosts, c.EtcdHosts, c.SystemImages.Alpine, c.PrivateRegistriesMap, externalEtcd); err != nil {
return err return err
} }
@@ -34,14 +38,14 @@ func (c *Cluster) ClusterRemove(ctx context.Context) error {
return nil return nil
} }
func cleanUpHosts(ctx context.Context, cpHosts, workerHosts, etcdHosts []*hosts.Host, cleanerImage string, prsMap map[string]v3.PrivateRegistry) error { func cleanUpHosts(ctx context.Context, cpHosts, workerHosts, etcdHosts []*hosts.Host, cleanerImage string, prsMap map[string]v3.PrivateRegistry, externalEtcd bool) error {
allHosts := []*hosts.Host{} allHosts := []*hosts.Host{}
allHosts = append(allHosts, cpHosts...) allHosts = append(allHosts, cpHosts...)
allHosts = append(allHosts, workerHosts...) allHosts = append(allHosts, workerHosts...)
allHosts = append(allHosts, etcdHosts...) allHosts = append(allHosts, etcdHosts...)
for _, host := range allHosts { for _, host := range allHosts {
if err := host.CleanUpAll(ctx, cleanerImage, prsMap); err != nil { if err := host.CleanUpAll(ctx, cleanerImage, prsMap, externalEtcd); err != nil {
return err return err
} }
} }

View File

@@ -12,9 +12,12 @@ func (c *Cluster) ValidateCluster() error {
if len(c.ControlPlaneHosts) == 0 { if len(c.ControlPlaneHosts) == 0 {
return fmt.Errorf("Cluster must have at least one control plane host") return fmt.Errorf("Cluster must have at least one control plane host")
} }
if len(c.EtcdHosts) == 0 { if len(c.EtcdHosts) == 0 && len(c.Services.Etcd.ExternalURLs) == 0 {
return fmt.Errorf("Cluster must have at least one etcd plane host") return fmt.Errorf("Cluster must have at least one etcd plane host")
} }
if len(c.EtcdHosts) > 0 && len(c.Services.Etcd.ExternalURLs) > 0 {
return fmt.Errorf("Cluster can't have both internal and external etcd")
}
// validate hosts options // validate hosts options
if err := validateHostsOptions(c); err != nil { if err := validateHostsOptions(c); err != nil {
@@ -94,6 +97,21 @@ func validateServicesOptions(c *Cluster) error {
return fmt.Errorf("%s can't be empty", strings.Join(strings.Split(optionName, "_"), " ")) return fmt.Errorf("%s can't be empty", strings.Join(strings.Split(optionName, "_"), " "))
} }
} }
// Validate external etcd information
if len(c.Services.Etcd.ExternalURLs) > 0 {
if len(c.Services.Etcd.CACert) == 0 {
return fmt.Errorf("External CA Certificate for etcd can't be empty")
}
if len(c.Services.Etcd.Cert) == 0 {
return fmt.Errorf("External Client Certificate for etcd can't be empty")
}
if len(c.Services.Etcd.Key) == 0 {
return fmt.Errorf("External Client Key for etcd can't be empty")
}
if len(c.Services.Etcd.Path) == 0 {
return fmt.Errorf("External etcd path can't be empty")
}
}
return nil return nil
} }

View File

@@ -41,16 +41,18 @@ const (
CleanerContainerName = "kube-cleaner" CleanerContainerName = "kube-cleaner"
) )
func (h *Host) CleanUpAll(ctx context.Context, cleanerImage string, prsMap map[string]v3.PrivateRegistry) error { func (h *Host) CleanUpAll(ctx context.Context, cleanerImage string, prsMap map[string]v3.PrivateRegistry, externalEtcd bool) error {
log.Infof(ctx, "[hosts] Cleaning up host [%s]", h.Address) log.Infof(ctx, "[hosts] Cleaning up host [%s]", h.Address)
toCleanPaths := []string{ toCleanPaths := []string{
ToCleanEtcdDir,
ToCleanSSLDir, ToCleanSSLDir,
ToCleanCNIConf, ToCleanCNIConf,
ToCleanCNIBin, ToCleanCNIBin,
ToCleanCalicoRun, ToCleanCalicoRun,
ToCleanTempCertPath, ToCleanTempCertPath,
} }
if externalEtcd {
toCleanPaths = append(toCleanPaths, ToCleanEtcdDir)
}
return h.CleanUp(ctx, toCleanPaths, cleanerImage, prsMap) return h.CleanUp(ctx, toCleanPaths, cleanerImage, prsMap)
} }

View File

@@ -16,6 +16,8 @@ const (
KubeProxyCertName = "kube-proxy" KubeProxyCertName = "kube-proxy"
KubeNodeCertName = "kube-node" KubeNodeCertName = "kube-node"
EtcdCertName = "kube-etcd" EtcdCertName = "kube-etcd"
EtcdClientCACertName = "kube-etcd-client-ca"
EtcdClientCertName = "kube-etcd-client"
KubeNodeCommonName = "system:node" KubeNodeCommonName = "system:node"
KubeNodeOrganizationName = "system:nodes" KubeNodeOrganizationName = "system:nodes"

View File

@@ -111,9 +111,27 @@ func GenerateRKECerts(ctx context.Context, rkeConfig v3.RancherKubernetesEngineC
kubeAdminCertObj := ToCertObject(KubeAdminCertName, KubeAdminCertName, KubeAdminOrganizationName, kubeAdminCrt, kubeAdminKey) kubeAdminCertObj := ToCertObject(KubeAdminCertName, KubeAdminCertName, KubeAdminOrganizationName, kubeAdminCrt, kubeAdminKey)
kubeAdminCertObj.Config = kubeAdminConfig kubeAdminCertObj.Config = kubeAdminConfig
kubeAdminCertObj.ConfigPath = localKubeConfigPath kubeAdminCertObj.ConfigPath = localKubeConfigPath
kubeAdminCertObj.ConfigEnvName = ""
certs[KubeAdminCertName] = kubeAdminCertObj certs[KubeAdminCertName] = kubeAdminCertObj
// generate etcd certificate and key // generate etcd certificate and key
if len(rkeConfig.Services.Etcd.ExternalURLs) > 0 {
clientCert, err := cert.ParseCertsPEM([]byte(rkeConfig.Services.Etcd.Cert))
if err != nil {
return nil, err
}
clientKey, err := cert.ParsePrivateKeyPEM([]byte(rkeConfig.Services.Etcd.Key))
if err != nil {
return nil, err
}
certs[EtcdClientCertName] = ToCertObject(EtcdClientCertName, "", "", clientCert[0], clientKey.(*rsa.PrivateKey))
caCert, err := cert.ParseCertsPEM([]byte(rkeConfig.Services.Etcd.CACert))
if err != nil {
return nil, err
}
certs[EtcdClientCACertName] = ToCertObject(EtcdClientCACertName, "", "", caCert[0], nil)
}
etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole) etcdHosts := hosts.NodesToHosts(rkeConfig.Nodes, etcdRole)
etcdAltNames := GetAltNames(etcdHosts, clusterDomain, kubernetesServiceIP) etcdAltNames := GetAltNames(etcdHosts, clusterDomain, kubernetesServiceIP)
for _, host := range etcdHosts { for _, host := range etcdHosts {

View File

@@ -107,11 +107,14 @@ func GetAltNames(cpHosts []*hosts.Host, clusterDomain string, KubernetesServiceI
} }
func (c *CertificatePKI) ToEnv() []string { func (c *CertificatePKI) ToEnv() []string {
env := []string{ env := []string{}
c.CertToEnv(), if c.Key != nil {
c.KeyToEnv(), env = append(env, c.KeyToEnv())
} }
if c.Config != "" { if c.Certificate != nil {
env = append(env, c.CertToEnv())
}
if c.Config != "" && c.ConfigEnvName != "" {
env = append(env, c.ConfigToEnv()) env = append(env, c.ConfigToEnv())
} }
return env return env
@@ -218,6 +221,8 @@ func getControlCertKeys() []string {
KubeSchedulerCertName, KubeSchedulerCertName,
KubeProxyCertName, KubeProxyCertName,
KubeNodeCertName, KubeNodeCertName,
EtcdClientCertName,
EtcdClientCACertName,
} }
} }
@@ -226,6 +231,8 @@ func getWorkerCertKeys() []string {
CACertName, CACertName,
KubeProxyCertName, KubeProxyCertName,
KubeNodeCertName, KubeNodeCertName,
EtcdClientCertName,
EtcdClientCACertName,
} }
} }
@@ -267,3 +274,12 @@ func GetLocalKubeConfig(configPath, configDir string) string {
baseDir += "/" baseDir += "/"
return fmt.Sprintf("%s%s%s", baseDir, KubeAdminConfigPrefix, fileName) return fmt.Sprintf("%s%s%s", baseDir, KubeAdminConfigPrefix, fileName)
} }
func strCrtToEnv(crtName, crt string) string {
return fmt.Sprintf("%s=%s", getEnvFromName(crtName), crt)
}
func strKeyToEnv(crtName, key string) string {
envName := getEnvFromName(crtName)
return fmt.Sprintf("%s=%s", getKeyEnvFromEnv(envName), key)
}

View File

@@ -9,6 +9,7 @@ import (
) )
func runKubeAPI(ctx context.Context, host *hosts.Host, df hosts.DialerFactory, prsMap map[string]v3.PrivateRegistry, kubeAPIProcess v3.Process) error { func runKubeAPI(ctx context.Context, host *hosts.Host, df hosts.DialerFactory, prsMap map[string]v3.PrivateRegistry, kubeAPIProcess v3.Process) error {
imageCfg, hostCfg, healthCheckURL := getProcessConfig(kubeAPIProcess) imageCfg, hostCfg, healthCheckURL := getProcessConfig(kubeAPIProcess)
if err := docker.DoRunContainer(ctx, host.DClient, imageCfg, hostCfg, KubeAPIContainerName, host.Address, ControlRole, prsMap); err != nil { if err := docker.DoRunContainer(ctx, host.DClient, imageCfg, hostCfg, KubeAPIContainerName, host.Address, ControlRole, prsMap); err != nil {
return err return err

View File

@@ -104,9 +104,9 @@ data:
{ {
"type": "calico", "type": "calico",
"etcd_endpoints": "{{.EtcdEndpoints}}", "etcd_endpoints": "{{.EtcdEndpoints}}",
"etcd_key_file": "{{.ClientKeyPath}}", "etcd_key_file": "{{.EtcdClientKeyPath}}",
"etcd_cert_file": "{{.ClientCertPath}}", "etcd_cert_file": "{{.EtcdClientCertPath}}",
"etcd_ca_cert_file": "{{.ClientCAPath}}", "etcd_ca_cert_file": "{{.EtcdClientCAPath}}",
"log_level": "info", "log_level": "info",
"mtu": 1500, "mtu": 1500,
"ipam": { "ipam": {
@@ -114,10 +114,8 @@ data:
}, },
"policy": { "policy": {
"type": "k8s", "type": "k8s",
"k8s_api_root": "{{.APIRoot}}", "k8s_api_root": "https://__KUBERNETES_SERVICE_HOST__:__KUBERNETES_SERVICE_PORT__",
"k8s_client_certificate": "{{.ClientCertPath}}", "k8s_auth_token": "__SERVICEACCOUNT_TOKEN__"
"k8s_client_key": "{{.ClientKeyPath}}",
"k8s_certificate_authority": "{{.ClientCAPath}}"
}, },
"kubernetes": { "kubernetes": {
"kubeconfig": "{{.KubeCfg}}" "kubeconfig": "{{.KubeCfg}}"
@@ -144,9 +142,9 @@ metadata:
name: calico-etcd-secrets name: calico-etcd-secrets
namespace: kube-system namespace: kube-system
data: data:
etcd-key: {{.ClientKey}} etcd-key: {{.EtcdClientKey}}
etcd-cert: {{.ClientCert}} etcd-cert: {{.EtcdClientCert}}
etcd-ca: {{.ClientCA}} etcd-ca: {{.EtcdClientCA}}
--- ---