Disable insecure port for apiserver

All components need a kubeconfig
This commit is contained in:
Justin Santa Barbara 2017-03-28 20:45:51 -04:00
parent c4808d1f65
commit 8b965a0ad9
15 changed files with 185 additions and 44 deletions

View File

@ -106,6 +106,18 @@ func (b *KubeAPIServerBuilder) buildPod() (*v1.Pod, error) {
}, },
} }
probeAction := &v1.HTTPGetAction{
Host: "127.0.0.1",
Path: "/healthz",
Port: intstr.FromInt(8080),
}
if kubeAPIServer.InsecurePort != 0 {
probeAction.Port = intstr.FromInt(int(kubeAPIServer.InsecurePort))
} else if kubeAPIServer.SecurePort != 0 {
probeAction.Port = intstr.FromInt(int(kubeAPIServer.SecurePort))
probeAction.Scheme = v1.URISchemeHTTPS
}
container := &v1.Container{ container := &v1.Container{
Name: "kube-apiserver", Name: "kube-apiserver",
Image: b.Cluster.Spec.KubeAPIServer.Image, Image: b.Cluster.Spec.KubeAPIServer.Image,
@ -117,11 +129,7 @@ func (b *KubeAPIServerBuilder) buildPod() (*v1.Pod, error) {
Command: redirectCommand, Command: redirectCommand,
LivenessProbe: &v1.Probe{ LivenessProbe: &v1.Probe{
Handler: v1.Handler{ Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{ HTTPGet: probeAction,
Host: "127.0.0.1",
Path: "/healthz",
Port: intstr.FromInt(8080),
},
}, },
InitialDelaySeconds: 15, InitialDelaySeconds: 15,
TimeoutSeconds: 15, TimeoutSeconds: 15,

View File

@ -0,0 +1,65 @@
/*
Copyright 2017 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 (
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/flagbuilder"
"testing"
)
func Test_KubeAPIServer_BuildFlags(t *testing.T) {
grid := []struct {
config kops.KubeAPIServerConfig
expected string
}{
{
kops.KubeAPIServerConfig{},
"--insecure-port=0 --secure-port=0",
},
{
kops.KubeAPIServerConfig{
SecurePort: 443,
},
"--insecure-port=0 --secure-port=443",
},
{
kops.KubeAPIServerConfig{
InsecurePort: 8080,
SecurePort: 443,
},
"--insecure-port=8080 --secure-port=443",
},
{
kops.KubeAPIServerConfig{
InsecurePort: 8080,
},
"--insecure-port=8080 --secure-port=0",
},
}
for _, g := range grid {
actual, err := flagbuilder.BuildFlags(&g.config)
if err != nil {
t.Errorf("error building flags for %v: %v", g.config, err)
continue
}
if actual != g.expected {
t.Errorf("flags did not match. actual=%q expected=%q", actual, g.expected)
}
}
}

View File

@ -18,6 +18,7 @@ package model
import ( import (
"fmt" "fmt"
"github.com/golang/glog"
"k8s.io/kops/nodeup/pkg/distros" "k8s.io/kops/nodeup/pkg/distros"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
@ -58,6 +59,37 @@ func (b *KubectlBuilder) Build(c *fi.ModelBuilderContext) error {
c.AddTask(t) c.AddTask(t)
} }
// Add kubeconfig
{
kubeconfig, err := b.buildPKIKubeconfig("kubecfg")
if err != nil {
return err
}
t := &nodetasks.File{
Path: "/var/lib/kubectl/kubeconfig",
Contents: fi.NewStringResource(kubeconfig),
Type: nodetasks.FileType_File,
Mode: s("0400"),
}
c.AddTask(t)
switch b.Distribution {
case distros.DistributionJessie:
c.AddTask(&nodetasks.File{
Path: "/home/admin/.kube/config",
Contents: fi.NewStringResource(kubeconfig),
Type: nodetasks.FileType_File,
Mode: s("0400"),
Owner: s("admin"),
Group: s("admin"),
})
default:
glog.Warningf("Unknown distro; won't write kubeconfig to homedir %s", b.Distribution)
}
}
return nil return nil
} }

View File

@ -37,6 +37,20 @@ type ProtokubeBuilder struct {
var _ fi.ModelBuilder = &ProtokubeBuilder{} var _ fi.ModelBuilder = &ProtokubeBuilder{}
func (b *ProtokubeBuilder) Build(c *fi.ModelBuilderContext) error { func (b *ProtokubeBuilder) Build(c *fi.ModelBuilderContext) error {
if b.IsMaster {
kubeconfig, err := b.buildPKIKubeconfig("kops")
if err != nil {
return err
}
c.AddTask(&nodetasks.File{
Path: "/var/lib/kops/kubeconfig",
Contents: fi.NewStringResource(kubeconfig),
Type: nodetasks.FileType_File,
Mode: s("0400"),
})
}
// TODO: Should we run _protokube on the nodes? // TODO: Should we run _protokube on the nodes?
service, err := b.buildSystemdService() service, err := b.buildSystemdService()
if err != nil { if err != nil {
@ -59,9 +73,19 @@ func (b *ProtokubeBuilder) buildSystemdService() (*nodetasks.Service, error) {
return nil, err return nil, err
} }
protokubeCommand := "/usr/bin/docker run -v /:/rootfs/ -v /var/run/dbus:/var/run/dbus -v /run/systemd:/run/systemd --net=host --privileged " dockerArgs := []string{
protokubeCommand += b.ProtokubeImageName() + " /usr/bin/protokube " "/usr/bin/docker",
protokubeCommand += protokubeFlagsArgs "run",
"-v", "/:/rootfs/",
"-v", "/var/run/dbus:/var/run/dbus",
"-v", "/run/systemd:/run/systemd",
"--net=host",
"--privileged",
"--env", "KUBECONFIG=/rootfs/var/lib/kops/kubeconfig",
b.ProtokubeImageName(),
"/usr/bin/protokube",
}
protokubeCommand := strings.Join(dockerArgs, " ") + " " + protokubeFlagsArgs
manifest := &systemd.Manifest{} manifest := &systemd.Manifest{}
manifest.Set("Unit", "Description", "Kubernetes Protokube Service") manifest.Set("Unit", "Description", "Kubernetes Protokube Service")

View File

@ -388,10 +388,11 @@ type KubeAPIServerConfig struct {
Image string `json:"image,omitempty"` Image string `json:"image,omitempty"`
LogLevel int32 `json:"logLevel,omitempty" flag:"v"` LogLevel int32 `json:"logLevel,omitempty" flag:"v" flag-empty:"0"`
CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"` CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"`
SecurePort int32 `json:"securePort,omitempty" flag:"secure-port"` SecurePort int32 `json:"securePort,omitempty" flag:"secure-port"`
InsecurePort int32 `json:"insecurePort,omitempty" flag:"insecure-port"`
Address string `json:"address,omitempty" flag:"address"` Address string `json:"address,omitempty" flag:"address"`
EtcdServers []string `json:"etcdServers,omitempty" flag:"etcd-servers"` EtcdServers []string `json:"etcdServers,omitempty" flag:"etcd-servers"`
EtcdServersOverrides []string `json:"etcdServersOverrides,omitempty" flag:"etcd-servers-overrides"` EtcdServersOverrides []string `json:"etcdServersOverrides,omitempty" flag:"etcd-servers-overrides"`

View File

@ -388,6 +388,7 @@ type KubeAPIServerConfig struct {
CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"` CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"`
SecurePort int32 `json:"securePort,omitempty" flag:"secure-port"` SecurePort int32 `json:"securePort,omitempty" flag:"secure-port"`
InsecurePort int32 `json:"insecurePort,omitempty" flag:"insecure-port"`
Address string `json:"address,omitempty" flag:"address"` Address string `json:"address,omitempty" flag:"address"`
EtcdServers []string `json:"etcdServers,omitempty" flag:"etcd-servers"` EtcdServers []string `json:"etcdServers,omitempty" flag:"etcd-servers"`
EtcdServersOverrides []string `json:"etcdServersOverrides,omitempty" flag:"etcd-servers-overrides"` EtcdServersOverrides []string `json:"etcdServersOverrides,omitempty" flag:"etcd-servers-overrides"`

View File

@ -1057,6 +1057,7 @@ func autoConvert_v1alpha1_KubeAPIServerConfig_To_kops_KubeAPIServerConfig(in *Ku
out.LogLevel = in.LogLevel out.LogLevel = in.LogLevel
out.CloudProvider = in.CloudProvider out.CloudProvider = in.CloudProvider
out.SecurePort = in.SecurePort out.SecurePort = in.SecurePort
out.InsecurePort = in.InsecurePort
out.Address = in.Address out.Address = in.Address
out.EtcdServers = in.EtcdServers out.EtcdServers = in.EtcdServers
out.EtcdServersOverrides = in.EtcdServersOverrides out.EtcdServersOverrides = in.EtcdServersOverrides
@ -1100,6 +1101,7 @@ func autoConvert_kops_KubeAPIServerConfig_To_v1alpha1_KubeAPIServerConfig(in *ko
out.LogLevel = in.LogLevel out.LogLevel = in.LogLevel
out.CloudProvider = in.CloudProvider out.CloudProvider = in.CloudProvider
out.SecurePort = in.SecurePort out.SecurePort = in.SecurePort
out.InsecurePort = in.InsecurePort
out.Address = in.Address out.Address = in.Address
out.EtcdServers = in.EtcdServers out.EtcdServers = in.EtcdServers
out.EtcdServersOverrides = in.EtcdServersOverrides out.EtcdServersOverrides = in.EtcdServersOverrides

View File

@ -169,6 +169,7 @@ type KubeAPIServerConfig struct {
CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"` CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"`
SecurePort int32 `json:"securePort,omitempty" flag:"secure-port"` SecurePort int32 `json:"securePort,omitempty" flag:"secure-port"`
InsecurePort int32 `json:"insecurePort,omitempty" flag:"insecure-port"`
Address string `json:"address,omitempty" flag:"address"` Address string `json:"address,omitempty" flag:"address"`
EtcdServers []string `json:"etcdServers,omitempty" flag:"etcd-servers"` EtcdServers []string `json:"etcdServers,omitempty" flag:"etcd-servers"`
EtcdServersOverrides []string `json:"etcdServersOverrides,omitempty" flag:"etcd-servers-overrides"` EtcdServersOverrides []string `json:"etcdServersOverrides,omitempty" flag:"etcd-servers-overrides"`

View File

@ -1155,6 +1155,7 @@ func autoConvert_v1alpha2_KubeAPIServerConfig_To_kops_KubeAPIServerConfig(in *Ku
out.LogLevel = in.LogLevel out.LogLevel = in.LogLevel
out.CloudProvider = in.CloudProvider out.CloudProvider = in.CloudProvider
out.SecurePort = in.SecurePort out.SecurePort = in.SecurePort
out.InsecurePort = in.InsecurePort
out.Address = in.Address out.Address = in.Address
out.EtcdServers = in.EtcdServers out.EtcdServers = in.EtcdServers
out.EtcdServersOverrides = in.EtcdServersOverrides out.EtcdServersOverrides = in.EtcdServersOverrides
@ -1198,6 +1199,7 @@ func autoConvert_kops_KubeAPIServerConfig_To_v1alpha2_KubeAPIServerConfig(in *ko
out.LogLevel = in.LogLevel out.LogLevel = in.LogLevel
out.CloudProvider = in.CloudProvider out.CloudProvider = in.CloudProvider
out.SecurePort = in.SecurePort out.SecurePort = in.SecurePort
out.InsecurePort = in.InsecurePort
out.Address = in.Address out.Address = in.Address
out.EtcdServers = in.EtcdServers out.EtcdServers = in.EtcdServers
out.EtcdServersOverrides = in.EtcdServersOverrides out.EtcdServersOverrides = in.EtcdServersOverrides

View File

@ -18,7 +18,6 @@ package components
import ( import (
"fmt" "fmt"
"github.com/blang/semver"
"k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/api/v1"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
@ -27,7 +26,7 @@ import (
// KubeAPIServerOptionsBuilder adds options for the apiserver to the model // KubeAPIServerOptionsBuilder adds options for the apiserver to the model
type KubeAPIServerOptionsBuilder struct { type KubeAPIServerOptionsBuilder struct {
Context *OptionsContext *OptionsContext
} }
var _ loader.OptionsBuilder = &KubeAPIServerOptionsBuilder{} var _ loader.OptionsBuilder = &KubeAPIServerOptionsBuilder{}
@ -38,27 +37,23 @@ func (b *KubeAPIServerOptionsBuilder) BuildOptions(o interface{}) error {
clusterSpec.KubeAPIServer = &kops.KubeAPIServerConfig{} clusterSpec.KubeAPIServer = &kops.KubeAPIServerConfig{}
} }
// TODO: Set insecure-port=0 to turn it off c := clusterSpec.KubeAPIServer
if clusterSpec.KubeAPIServer.APIServerCount == nil { if c.APIServerCount == nil {
count := b.buildAPIServerCount(clusterSpec) count := b.buildAPIServerCount(clusterSpec)
if count == 0 { if count == 0 {
return fmt.Errorf("no instance groups found") return fmt.Errorf("no instance groups found")
} }
clusterSpec.KubeAPIServer.APIServerCount = fi.Int32(int32(count)) c.APIServerCount = fi.Int32(int32(count))
} }
if clusterSpec.KubeAPIServer.StorageBackend == nil { if c.StorageBackend == nil {
// For the moment, we continue to use etcd2 // For the moment, we continue to use etcd2
clusterSpec.KubeAPIServer.StorageBackend = fi.String("etcd2") c.StorageBackend = fi.String("etcd2")
} }
k8sVersion, err := KubernetesVersion(clusterSpec) if c.KubeletPreferredAddressTypes == nil {
if err != nil { if b.IsKubernetesGTE("1.5") {
return err
}
if clusterSpec.KubeAPIServer.KubeletPreferredAddressTypes == nil {
if k8sVersion.GTE(semver.MustParse("1.5.0")) {
// Default precedence // Default precedence
//options.KubeAPIServer.KubeletPreferredAddressTypes = []string { //options.KubeAPIServer.KubeletPreferredAddressTypes = []string {
// string(api.NodeHostName), // string(api.NodeHostName),
@ -68,7 +63,7 @@ func (b *KubeAPIServerOptionsBuilder) BuildOptions(o interface{}) error {
//} //}
// We prioritize the internal IP above the hostname // We prioritize the internal IP above the hostname
clusterSpec.KubeAPIServer.KubeletPreferredAddressTypes = []string{ c.KubeletPreferredAddressTypes = []string{
string(v1.NodeInternalIP), string(v1.NodeInternalIP),
string(v1.NodeHostName), string(v1.NodeHostName),
string(v1.NodeExternalIP), string(v1.NodeExternalIP),
@ -83,6 +78,15 @@ func (b *KubeAPIServerOptionsBuilder) BuildOptions(o interface{}) error {
} }
} }
c.SecurePort = 443
// We disable the insecure port from 1.6 onwards
if b.IsKubernetesGTE("1.6") {
c.InsecurePort = 0
} else {
c.InsecurePort = 8080
}
return nil return nil
} }

View File

@ -108,7 +108,13 @@ func (b *KubeControllerManagerOptionsBuilder) BuildOptions(o interface{}) error
return fmt.Errorf("unknown cloud provider %q", clusterSpec.CloudProvider) return fmt.Errorf("unknown cloud provider %q", clusterSpec.CloudProvider)
} }
if kcm.Master == "" {
if b.Context.IsKubernetesLT("1.6") {
// As of 1.6, we find the master using kubeconfig
kcm.Master = "127.0.0.1:8080" kcm.Master = "127.0.0.1:8080"
}
}
kcm.LogLevel = 2 kcm.LogLevel = 2
image, err := Image("kube-controller-manager", clusterSpec) image, err := Image("kube-controller-manager", clusterSpec)

View File

@ -80,6 +80,16 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
c.AddTask(t) c.AddTask(t)
} }
{
// Keypair used by kops / protokube
t := &fitasks.Keypair{
Name: fi.String("kops"),
Subject: "o=" + user.SystemPrivilegedGroup + ",cn=kops",
Type: "client",
}
c.AddTask(t)
}
{ {
// TLS certificate used for apiserver // TLS certificate used for apiserver

View File

@ -278,7 +278,7 @@ func (c *populateClusterSpec) run() error {
// Note: DefaultOptionsBuilder comes first // Note: DefaultOptionsBuilder comes first
codeModels = append(codeModels, &components.DefaultsOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.DefaultsOptionsBuilder{Context: optionsContext})
codeModels = append(codeModels, &components.KubeAPIServerOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.KubeAPIServerOptionsBuilder{OptionsContext: optionsContext})
codeModels = append(codeModels, &components.DockerOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.DockerOptionsBuilder{Context: optionsContext})
codeModels = append(codeModels, &components.NetworkingOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.NetworkingOptionsBuilder{Context: optionsContext})
codeModels = append(codeModels, &components.KubeDnsOptionsBuilder{Context: optionsContext}) codeModels = append(codeModels, &components.KubeDnsOptionsBuilder{Context: optionsContext})

View File

@ -82,10 +82,12 @@ func (f *File) GetDependencies(tasks map[string]fi.Task) []fi.Task {
if f.Owner != nil { if f.Owner != nil {
ownerTask := tasks["user/"+*f.Owner] ownerTask := tasks["user/"+*f.Owner]
if ownerTask == nil { if ownerTask == nil {
glog.Fatalf("Unable to find task %q", "user/"+*f.Owner) // The user might be a pre-existing user (e.g. admin)
} glog.Warningf("Unable to find task %q", "user/"+*f.Owner)
} else {
deps = append(deps, ownerTask) deps = append(deps, ownerTask)
} }
}
// Depend on disk mounts // Depend on disk mounts
// For simplicity, we just depend on _all_ disk mounts // For simplicity, we just depend on _all_ disk mounts

View File

@ -115,7 +115,6 @@ func (t *templateFunctions) populate(dest template.FuncMap) {
dest["KubeControllerManager"] = func() *api.KubeControllerManagerConfig { dest["KubeControllerManager"] = func() *api.KubeControllerManagerConfig {
return t.cluster.Spec.KubeControllerManager return t.cluster.Spec.KubeControllerManager
} }
dest["KubeProxy"] = t.KubeProxyConfig
dest["ClusterName"] = func() string { dest["ClusterName"] = func() string {
return t.cluster.ObjectMeta.Name return t.cluster.ObjectMeta.Name
@ -159,19 +158,3 @@ func (t *templateFunctions) hasTag(tag string) bool {
_, found := t.tags[tag] _, found := t.tags[tag]
return found return found
} }
// KubeProxyConfig builds the KubeProxyConfig configuration object
func (t *templateFunctions) KubeProxyConfig() *api.KubeProxyConfig {
config := &api.KubeProxyConfig{}
*config = *t.cluster.Spec.KubeProxy
// As a special case, if this is the master, we point kube-proxy to the local IP
// This prevents a circular dependency where kube-proxy can't come up until DNS comes up,
// which would mean that DNS can't rely on API to come up
if t.isMaster() {
glog.Infof("kube-proxy running on the master; setting API endpoint to localhost")
config.Master = "http://127.0.0.1:8080"
}
return config
}