mirror of https://github.com/kubernetes/kops.git
Support etcd-manager v3, suitable for backporting
Add etcd-manager v3 in a way that we can safely backport.
This commit is contained in:
parent
2c20424656
commit
65e2fb2db4
|
@ -41,7 +41,7 @@ it won't change the configuration:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Enable etcd-manager
|
# Enable etcd-manager
|
||||||
kops set cluster cluster.spec.etcdClusters[*].manager.image=kopeio/etcd-manager:latest
|
kops set cluster cluster.spec.etcdClusters[*].provider=Manager
|
||||||
|
|
||||||
kops update cluster --yes
|
kops update cluster --yes
|
||||||
kops rolling-update cluster --yes
|
kops rolling-update cluster --yes
|
||||||
|
|
|
@ -10,6 +10,7 @@ go_library(
|
||||||
"directories.go",
|
"directories.go",
|
||||||
"docker.go",
|
"docker.go",
|
||||||
"etcd.go",
|
"etcd.go",
|
||||||
|
"etcd_manager_tls.go",
|
||||||
"etcd_tls.go",
|
"etcd_tls.go",
|
||||||
"file_assets.go",
|
"file_assets.go",
|
||||||
"firewall.go",
|
"firewall.go",
|
||||||
|
|
|
@ -371,8 +371,13 @@ func (c *NodeupModelContext) BuildCertificateTask(ctx *fi.ModelBuilderContext, n
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p := filename
|
||||||
|
if !filepath.IsAbs(p) {
|
||||||
|
p = filepath.Join(c.PathSrvKubernetes(), filename)
|
||||||
|
}
|
||||||
|
|
||||||
ctx.AddTask(&nodetasks.File{
|
ctx.AddTask(&nodetasks.File{
|
||||||
Path: filepath.Join(c.PathSrvKubernetes(), filename),
|
Path: p,
|
||||||
Contents: fi.NewStringResource(serialized),
|
Contents: fi.NewStringResource(serialized),
|
||||||
Type: nodetasks.FileType_File,
|
Type: nodetasks.FileType_File,
|
||||||
Mode: s("0600"),
|
Mode: s("0600"),
|
||||||
|
@ -397,8 +402,13 @@ func (c *NodeupModelContext) BuildPrivateKeyTask(ctx *fi.ModelBuilderContext, na
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p := filename
|
||||||
|
if !filepath.IsAbs(p) {
|
||||||
|
p = filepath.Join(c.PathSrvKubernetes(), filename)
|
||||||
|
}
|
||||||
|
|
||||||
ctx.AddTask(&nodetasks.File{
|
ctx.AddTask(&nodetasks.File{
|
||||||
Path: filepath.Join(c.PathSrvKubernetes(), filename),
|
Path: p,
|
||||||
Contents: fi.NewStringResource(serialized),
|
Contents: fi.NewStringResource(serialized),
|
||||||
Type: nodetasks.FileType_File,
|
Type: nodetasks.FileType_File,
|
||||||
Mode: s("0600"),
|
Mode: s("0600"),
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"k8s.io/kops/upup/pkg/fi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EtcdManagerTLSBuilder configures TLS support for etcd-manager
|
||||||
|
type EtcdManagerTLSBuilder struct {
|
||||||
|
*NodeupModelContext
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ fi.ModelBuilder = &EtcdManagerTLSBuilder{}
|
||||||
|
|
||||||
|
// Build is responsible for TLS configuration for etcd-manager
|
||||||
|
func (b *EtcdManagerTLSBuilder) Build(ctx *fi.ModelBuilderContext) error {
|
||||||
|
if !b.IsMaster {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range []string{"main", "events"} {
|
||||||
|
d := "/etc/kubernetes/pki/etcd-manager-" + k
|
||||||
|
|
||||||
|
keys := make(map[string]string)
|
||||||
|
keys["etcd-manager-ca"] = "etcd-manager-ca-" + k
|
||||||
|
|
||||||
|
for fileName, keystoreName := range keys {
|
||||||
|
cert, err := b.KeyStore.FindCert(keystoreName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if cert == nil {
|
||||||
|
glog.Warningf("keypair %q not found, won't configure", keystoreName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := b.BuildCertificateTask(ctx, keystoreName, d+"/"+fileName+".crt"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := b.BuildPrivateKeyTask(ctx, keystoreName, d+"/"+fileName+".key"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -100,6 +100,8 @@ func (b *EtcdManagerBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
format := string(fi.KeysetFormatV1Alpha2)
|
||||||
|
|
||||||
c.AddTask(&fitasks.ManagedFile{
|
c.AddTask(&fitasks.ManagedFile{
|
||||||
Contents: fi.WrapResource(fi.NewBytesResource(d)),
|
Contents: fi.WrapResource(fi.NewBytesResource(d)),
|
||||||
Lifecycle: b.Lifecycle,
|
Lifecycle: b.Lifecycle,
|
||||||
|
@ -107,14 +109,22 @@ func (b *EtcdManagerBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||||
Location: fi.String("backups/etcd/" + etcdCluster.Name + "/control/etcd-cluster-spec"),
|
Location: fi.String("backups/etcd/" + etcdCluster.Name + "/control/etcd-cluster-spec"),
|
||||||
Name: fi.String("etcd-cluster-spec-" + name),
|
Name: fi.String("etcd-cluster-spec-" + name),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// We create a CA keypair to enable secure communication
|
||||||
|
c.AddTask(&fitasks.Keypair{
|
||||||
|
Name: fi.String("etcd-manager-ca-" + etcdCluster.Name),
|
||||||
|
Subject: "cn=etcd-manager-ca-" + etcdCluster.Name,
|
||||||
|
Type: "ca",
|
||||||
|
Format: format,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type etcdClusterSpec struct {
|
type etcdClusterSpec struct {
|
||||||
MemberCount int32 `json:"member_count,omitempty"`
|
MemberCount int32 `json:"memberCount,omitempty"`
|
||||||
EtcdVersion string `json:"etcd_version,omitempty"`
|
EtcdVersion string `json:"etcdVersion,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EtcdManagerBuilder) buildManifest(etcdCluster *kops.EtcdClusterSpec) (*v1.Pod, error) {
|
func (b *EtcdManagerBuilder) buildManifest(etcdCluster *kops.EtcdClusterSpec) (*v1.Pod, error) {
|
||||||
|
@ -159,7 +169,7 @@ metadata:
|
||||||
namespace: kube-system
|
namespace: kube-system
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: kopeio/etcd-manager:1.0.20181001
|
- image: kopeio/etcd-manager:3.0.20190125
|
||||||
name: etcd-manager
|
name: etcd-manager
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
|
@ -174,6 +184,8 @@ spec:
|
||||||
# We write artificial hostnames into etc hosts for the etcd nodes, so they have stable names
|
# We write artificial hostnames into etc hosts for the etcd nodes, so they have stable names
|
||||||
- mountPath: /etc/hosts
|
- mountPath: /etc/hosts
|
||||||
name: hosts
|
name: hosts
|
||||||
|
- mountPath: /etc/kubernetes/pki/etcd-manager
|
||||||
|
name: pki
|
||||||
hostNetwork: true
|
hostNetwork: true
|
||||||
hostPID: true # helps with mounting volumes from inside a container
|
hostPID: true # helps with mounting volumes from inside a container
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -185,6 +197,10 @@ spec:
|
||||||
path: /etc/hosts
|
path: /etc/hosts
|
||||||
type: File
|
type: File
|
||||||
name: hosts
|
name: hosts
|
||||||
|
- hostPath:
|
||||||
|
path: /etc/kubernetes/pki/etcd-manager
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
name: pki
|
||||||
`
|
`
|
||||||
|
|
||||||
// buildPod creates the pod spec, based on the EtcdClusterSpec
|
// buildPod creates the pod spec, based on the EtcdClusterSpec
|
||||||
|
@ -300,6 +316,7 @@ func (b *EtcdManagerBuilder) buildPod(etcdCluster *kops.EtcdClusterSpec) (*v1.Po
|
||||||
BackupStore: backupStore,
|
BackupStore: backupStore,
|
||||||
GrpcPort: grpcPort,
|
GrpcPort: grpcPort,
|
||||||
DNSSuffix: dnsInternalSuffix,
|
DNSSuffix: dnsInternalSuffix,
|
||||||
|
EtcdInsecure: !isTLS,
|
||||||
}
|
}
|
||||||
|
|
||||||
config.LogVerbosity = 8
|
config.LogVerbosity = 8
|
||||||
|
@ -389,11 +406,29 @@ func (b *EtcdManagerBuilder) buildPod(etcdCluster *kops.EtcdClusterSpec) (*v1.Po
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
foundPKI := false
|
||||||
|
for i := range pod.Spec.Volumes {
|
||||||
|
v := &pod.Spec.Volumes[i]
|
||||||
|
if v.Name == "pki" {
|
||||||
|
if v.HostPath == nil {
|
||||||
|
return nil, fmt.Errorf("found PKI volume, but HostPath was nil")
|
||||||
|
}
|
||||||
|
dirname := "etcd-manager-" + etcdCluster.Name
|
||||||
|
v.HostPath.Path = "/etc/kubernetes/pki/" + dirname
|
||||||
|
foundPKI = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundPKI {
|
||||||
|
return nil, fmt.Errorf("did not find PKI volume")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if isTLS {
|
if isTLS {
|
||||||
return nil, fmt.Errorf("TLS not supported for etcd-manager")
|
return nil, fmt.Errorf("TLS not supported for etcd-manager")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
kubemanifest.MarkPodAsCritical(pod)
|
kubemanifest.MarkPodAsCritical(pod)
|
||||||
|
|
||||||
|
@ -408,6 +443,15 @@ type config struct {
|
||||||
// Containerized is set if etcd-manager is running in a container
|
// Containerized is set if etcd-manager is running in a container
|
||||||
Containerized bool `flag:"containerized"`
|
Containerized bool `flag:"containerized"`
|
||||||
|
|
||||||
|
// PKIDir is set to the directory for PKI keys, used to secure commucations between etcd-manager peers
|
||||||
|
PKIDir string `flag:"pki-dir"`
|
||||||
|
|
||||||
|
// Insecure can be used to turn off tls for etcd-manager (compare with EtcdInsecure)
|
||||||
|
Insecure bool `flag:"insecure"`
|
||||||
|
|
||||||
|
// EtcdInsecure can be used to turn off tls for etcd itself (compare with Insecure)
|
||||||
|
EtcdInsecure bool `flag:"etcd-insecure"`
|
||||||
|
|
||||||
Address string `flag:"address"`
|
Address string `flag:"address"`
|
||||||
PeerUrls string `flag:"peer-urls"`
|
PeerUrls string `flag:"peer-urls"`
|
||||||
GrpcPort int `flag:"grpc-port"`
|
GrpcPort int `flag:"grpc-port"`
|
||||||
|
|
|
@ -1,8 +1,26 @@
|
||||||
|
Lifecycle: null
|
||||||
|
Name: etcd-manager-ca-events
|
||||||
|
Signer: null
|
||||||
|
alternateNameTasks: null
|
||||||
|
alternateNames: null
|
||||||
|
format: v1alpha2
|
||||||
|
subject: cn=etcd-manager-ca-events
|
||||||
|
type: ca
|
||||||
|
---
|
||||||
|
Lifecycle: null
|
||||||
|
Name: etcd-manager-ca-main
|
||||||
|
Signer: null
|
||||||
|
alternateNameTasks: null
|
||||||
|
alternateNames: null
|
||||||
|
format: v1alpha2
|
||||||
|
subject: cn=etcd-manager-ca-main
|
||||||
|
type: ca
|
||||||
|
---
|
||||||
Contents:
|
Contents:
|
||||||
Name: ""
|
Name: ""
|
||||||
Resource: |-
|
Resource: |-
|
||||||
{
|
{
|
||||||
"member_count": 1
|
"memberCount": 1
|
||||||
}
|
}
|
||||||
Lifecycle: null
|
Lifecycle: null
|
||||||
Location: backups/etcd/events/control/etcd-cluster-spec
|
Location: backups/etcd/events/control/etcd-cluster-spec
|
||||||
|
@ -12,7 +30,7 @@ Contents:
|
||||||
Name: ""
|
Name: ""
|
||||||
Resource: |-
|
Resource: |-
|
||||||
{
|
{
|
||||||
"member_count": 1
|
"memberCount": 1
|
||||||
}
|
}
|
||||||
Lifecycle: null
|
Lifecycle: null
|
||||||
Location: backups/etcd/main/control/etcd-cluster-spec
|
Location: backups/etcd/main/control/etcd-cluster-spec
|
||||||
|
@ -39,11 +57,12 @@ Contents:
|
||||||
- mkfifo /tmp/pipe; (tee -a /var/log/etcd.log < /tmp/pipe & ) ; exec /etcd-manager
|
- mkfifo /tmp/pipe; (tee -a /var/log/etcd.log < /tmp/pipe & ) ; exec /etcd-manager
|
||||||
--backup-store=memfs://clusters.example.com/minimal.example.com/backups/etcd-events
|
--backup-store=memfs://clusters.example.com/minimal.example.com/backups/etcd-events
|
||||||
--client-urls=http://__name__:4002 --cluster-name=etcd-events --containerized=true
|
--client-urls=http://__name__:4002 --cluster-name=etcd-events --containerized=true
|
||||||
--dns-suffix=.internal.minimal.example.com --grpc-port=3997 --peer-urls=http://__name__:2381
|
--dns-suffix=.internal.minimal.example.com --etcd-insecure=true --grpc-port=3997
|
||||||
--quarantine-client-urls=http://__name__:3995 --v=8 --volume-name-tag=k8s.io/etcd/events
|
--insecure=false --peer-urls=http://__name__:2381 --quarantine-client-urls=http://__name__:3995
|
||||||
--volume-provider=aws --volume-tag=k8s.io/etcd/events --volume-tag=k8s.io/role/master=1
|
--v=8 --volume-name-tag=k8s.io/etcd/events --volume-provider=aws --volume-tag=k8s.io/etcd/events
|
||||||
--volume-tag=kubernetes.io/cluster/minimal.example.com=owned > /tmp/pipe 2>&1
|
--volume-tag=k8s.io/role/master=1 --volume-tag=kubernetes.io/cluster/minimal.example.com=owned
|
||||||
image: kopeio/etcd-manager:1.0.20181001
|
> /tmp/pipe 2>&1
|
||||||
|
image: kopeio/etcd-manager:3.0.20190125
|
||||||
name: etcd-manager
|
name: etcd-manager
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
|
@ -55,6 +74,8 @@ Contents:
|
||||||
name: rootfs
|
name: rootfs
|
||||||
- mountPath: /etc/hosts
|
- mountPath: /etc/hosts
|
||||||
name: hosts
|
name: hosts
|
||||||
|
- mountPath: /etc/kubernetes/pki/etcd-manager
|
||||||
|
name: pki
|
||||||
- mountPath: /var/log/etcd.log
|
- mountPath: /var/log/etcd.log
|
||||||
name: varlogetcd
|
name: varlogetcd
|
||||||
hostNetwork: true
|
hostNetwork: true
|
||||||
|
@ -71,6 +92,10 @@ Contents:
|
||||||
path: /etc/hosts
|
path: /etc/hosts
|
||||||
type: File
|
type: File
|
||||||
name: hosts
|
name: hosts
|
||||||
|
- hostPath:
|
||||||
|
path: /etc/kubernetes/pki/etcd-manager-events
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
name: pki
|
||||||
- hostPath:
|
- hostPath:
|
||||||
path: /var/log/etcd-events.log
|
path: /var/log/etcd-events.log
|
||||||
type: FileOrCreate
|
type: FileOrCreate
|
||||||
|
@ -101,11 +126,12 @@ Contents:
|
||||||
- mkfifo /tmp/pipe; (tee -a /var/log/etcd.log < /tmp/pipe & ) ; exec /etcd-manager
|
- mkfifo /tmp/pipe; (tee -a /var/log/etcd.log < /tmp/pipe & ) ; exec /etcd-manager
|
||||||
--backup-store=memfs://clusters.example.com/minimal.example.com/backups/etcd-main
|
--backup-store=memfs://clusters.example.com/minimal.example.com/backups/etcd-main
|
||||||
--client-urls=http://__name__:4001 --cluster-name=etcd --containerized=true
|
--client-urls=http://__name__:4001 --cluster-name=etcd --containerized=true
|
||||||
--dns-suffix=.internal.minimal.example.com --grpc-port=3996 --peer-urls=http://__name__:2380
|
--dns-suffix=.internal.minimal.example.com --etcd-insecure=true --grpc-port=3996
|
||||||
--quarantine-client-urls=http://__name__:3994 --v=8 --volume-name-tag=k8s.io/etcd/main
|
--insecure=false --peer-urls=http://__name__:2380 --quarantine-client-urls=http://__name__:3994
|
||||||
--volume-provider=aws --volume-tag=k8s.io/etcd/main --volume-tag=k8s.io/role/master=1
|
--v=8 --volume-name-tag=k8s.io/etcd/main --volume-provider=aws --volume-tag=k8s.io/etcd/main
|
||||||
--volume-tag=kubernetes.io/cluster/minimal.example.com=owned > /tmp/pipe 2>&1
|
--volume-tag=k8s.io/role/master=1 --volume-tag=kubernetes.io/cluster/minimal.example.com=owned
|
||||||
image: kopeio/etcd-manager:1.0.20181001
|
> /tmp/pipe 2>&1
|
||||||
|
image: kopeio/etcd-manager:3.0.20190125
|
||||||
name: etcd-manager
|
name: etcd-manager
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
|
@ -117,6 +143,8 @@ Contents:
|
||||||
name: rootfs
|
name: rootfs
|
||||||
- mountPath: /etc/hosts
|
- mountPath: /etc/hosts
|
||||||
name: hosts
|
name: hosts
|
||||||
|
- mountPath: /etc/kubernetes/pki/etcd-manager
|
||||||
|
name: pki
|
||||||
- mountPath: /var/log/etcd.log
|
- mountPath: /var/log/etcd.log
|
||||||
name: varlogetcd
|
name: varlogetcd
|
||||||
hostNetwork: true
|
hostNetwork: true
|
||||||
|
@ -133,6 +161,10 @@ Contents:
|
||||||
path: /etc/hosts
|
path: /etc/hosts
|
||||||
type: File
|
type: File
|
||||||
name: hosts
|
name: hosts
|
||||||
|
- hostPath:
|
||||||
|
path: /etc/kubernetes/pki/etcd-manager-main
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
name: pki
|
||||||
- hostPath:
|
- hostPath:
|
||||||
path: /var/log/etcd.log
|
path: /var/log/etcd.log
|
||||||
type: FileOrCreate
|
type: FileOrCreate
|
||||||
|
|
|
@ -243,6 +243,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error {
|
||||||
loader.Builders = append(loader.Builders, &model.KubeAPIServerBuilder{NodeupModelContext: modelContext})
|
loader.Builders = append(loader.Builders, &model.KubeAPIServerBuilder{NodeupModelContext: modelContext})
|
||||||
loader.Builders = append(loader.Builders, &model.KubeControllerManagerBuilder{NodeupModelContext: modelContext})
|
loader.Builders = append(loader.Builders, &model.KubeControllerManagerBuilder{NodeupModelContext: modelContext})
|
||||||
loader.Builders = append(loader.Builders, &model.KubeSchedulerBuilder{NodeupModelContext: modelContext})
|
loader.Builders = append(loader.Builders, &model.KubeSchedulerBuilder{NodeupModelContext: modelContext})
|
||||||
|
loader.Builders = append(loader.Builders, &model.EtcdManagerTLSBuilder{NodeupModelContext: modelContext})
|
||||||
if c.cluster.Spec.Networking.Kuberouter == nil {
|
if c.cluster.Spec.Networking.Kuberouter == nil {
|
||||||
loader.Builders = append(loader.Builders, &model.KubeProxyBuilder{NodeupModelContext: modelContext})
|
loader.Builders = append(loader.Builders, &model.KubeProxyBuilder{NodeupModelContext: modelContext})
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue