Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

Commit f5236e5

Browse files
authored
Disable insecure apiserver access. (#459)
This disables the insecure apiserver port for both the bootstrap and self-hosted control planes. In so doing I migrated all of bootkube to use the kubeconfig rather than a static local port. This assumes that the temporary control plane is also addressable at the same IP as the the final control plane. If this is a faulty assumption then this part likely won't work. While I was at it I changed some dependencies to point at client-go to help us move off of vendoring all of kubernetes in the future. Fixes #324.
1 parent 072c772 commit f5236e5

File tree

8 files changed

+90
-65
lines changed

8 files changed

+90
-65
lines changed

cmd/bootkube/start.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ func runCmdStart(cmd *cobra.Command, args []string) error {
4747
util.InitLogs()
4848
defer util.FlushLogs()
4949

50-
return bk.Run()
50+
if err := bk.Run(); err != nil {
51+
// Always report errors.
52+
bootkube.UserOutput("Error: %v\n", err)
53+
}
54+
return nil
5155
}
5256

5357
func validateStartOpts(cmd *cobra.Command, args []string) error {

pkg/asset/asset.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net"
99
"net/url"
1010
"os"
11+
"path"
1112
"path/filepath"
1213

1314
"github.com/kubernetes-incubator/bootkube/pkg/tlsutil"
@@ -60,31 +61,31 @@ const (
6061
// AssetConfig holds all configuration needed when generating
6162
// the default set of assets.
6263
type Config struct {
63-
EtcdCACert *x509.Certificate
64-
EtcdClientCert *x509.Certificate
65-
EtcdClientKey *rsa.PrivateKey
66-
EtcdServers []*url.URL
67-
EtcdUseTLS bool
68-
APIServers []*url.URL
69-
CACert *x509.Certificate
70-
CAPrivKey *rsa.PrivateKey
71-
AltNames *tlsutil.AltNames
72-
PodCIDR *net.IPNet
73-
ServiceCIDR *net.IPNet
74-
APIServiceIP net.IP
75-
DNSServiceIP net.IP
76-
EtcdServiceIP net.IP
77-
SelfHostKubelet bool
78-
SelfHostedEtcd bool
79-
CloudProvider string
80-
BootstrapSecretsDir string
64+
EtcdCACert *x509.Certificate
65+
EtcdClientCert *x509.Certificate
66+
EtcdClientKey *rsa.PrivateKey
67+
EtcdServers []*url.URL
68+
EtcdUseTLS bool
69+
APIServers []*url.URL
70+
CACert *x509.Certificate
71+
CAPrivKey *rsa.PrivateKey
72+
AltNames *tlsutil.AltNames
73+
PodCIDR *net.IPNet
74+
ServiceCIDR *net.IPNet
75+
APIServiceIP net.IP
76+
DNSServiceIP net.IP
77+
EtcdServiceIP net.IP
78+
SelfHostKubelet bool
79+
SelfHostedEtcd bool
80+
CloudProvider string
81+
BootstrapSecretsSubdir string
8182
}
8283

8384
// NewDefaultAssets returns a list of default assets, optionally
8485
// configured via a user provided AssetConfig. Default assets include
8586
// TLS assets (certs, keys and secrets), and k8s component manifests.
8687
func NewDefaultAssets(conf Config) (Assets, error) {
87-
conf.BootstrapSecretsDir = BootstrapSecretsDir
88+
conf.BootstrapSecretsSubdir = path.Base(BootstrapSecretsDir)
8889

8990
as := newStaticAssets()
9091
as = append(as, newDynamicAssets(conf)...)

pkg/asset/internal/templates.go

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,20 +168,21 @@ spec:
168168
- --authorization-mode=RBAC
169169
- --bind-address=0.0.0.0
170170
- --client-ca-file=/etc/kubernetes/secrets/ca.crt
171-
- --cloud-provider={{ .CloudProvider }}
171+
- --cloud-provider={{ .CloudProvider }}
172172
{{- if .EtcdUseTLS }}
173173
- --etcd-cafile=/etc/kubernetes/secrets/etcd-ca.crt
174174
- --etcd-certfile=/etc/kubernetes/secrets/etcd-client.crt
175175
- --etcd-keyfile=/etc/kubernetes/secrets/etcd-client.key
176176
{{- end }}
177177
- --etcd-servers={{ range $i, $e := .EtcdServers }}{{ if $i }},{{end}}{{ $e }}{{end}}
178-
- --insecure-port=8080
178+
- --insecure-port=0
179179
- --kubelet-client-certificate=/etc/kubernetes/secrets/apiserver.crt
180180
- --kubelet-client-key=/etc/kubernetes/secrets/apiserver.key
181181
- --secure-port=443
182182
- --service-account-key-file=/etc/kubernetes/secrets/service-account.pub
183183
- --service-cluster-ip-range={{ .ServiceCIDR }}
184184
- --storage-backend=etcd3
185+
- --tls-ca-file=/etc/kubernetes/secrets/ca.crt
185186
- --tls-cert-file=/etc/kubernetes/secrets/apiserver.crt
186187
- --tls-private-key-file=/etc/kubernetes/secrets/apiserver.key
187188
env:
@@ -247,13 +248,14 @@ spec:
247248
- --etcd-keyfile=/etc/kubernetes/secrets/etcd-client.key
248249
{{- end }}
249250
- --etcd-servers={{ range $i, $e := .EtcdServers }}{{ if $i }},{{end}}{{ $e }}{{end}}{{ if .SelfHostedEtcd }},http://127.0.0.1:12379{{end}}
250-
- --insecure-port=8080
251+
- --insecure-port=0
251252
- --kubelet-client-certificate=/etc/kubernetes/secrets/apiserver.crt
252253
- --kubelet-client-key=/etc/kubernetes/secrets/apiserver.key
253254
- --secure-port=443
254255
- --service-account-key-file=/etc/kubernetes/secrets/service-account.pub
255256
- --service-cluster-ip-range={{ .ServiceCIDR }}
256257
- --storage-backend=etcd3
258+
- --tls-ca-file=/etc/kubernetes/secrets/ca.crt
257259
- --tls-cert-file=/etc/kubernetes/secrets/apiserver.crt
258260
- --tls-private-key-file=/etc/kubernetes/secrets/apiserver.key
259261
volumeMounts:
@@ -270,7 +272,7 @@ spec:
270272
volumes:
271273
- name: secrets
272274
hostPath:
273-
path: {{ .BootstrapSecretsDir }}
275+
path: /etc/kubernetes/{{ .BootstrapSecretsSubdir }}
274276
- name: ssl-certs-host
275277
hostPath:
276278
path: /usr/share/ca-certificates
@@ -429,7 +431,7 @@ spec:
429431
- ./hyperkube
430432
- controller-manager
431433
- --allocate-node-cidrs=true
432-
- --cloud-provider={{ .CloudProvider }}
434+
- --cloud-provider={{ .CloudProvider }}
433435
- --cluster-cidr={{ .PodCIDR }}
434436
- --configure-cloud-routes=false
435437
- --leader-elect=true
@@ -481,22 +483,22 @@ spec:
481483
- --allocate-node-cidrs=true
482484
- --cluster-cidr={{ .PodCIDR }}
483485
- --configure-cloud-routes=false
486+
- --kubeconfig=/etc/kubernetes/kubeconfig
484487
- --leader-elect=true
485-
- --master=http://127.0.0.1:8080
486-
- --root-ca-file=/etc/kubernetes/secrets/ca.crt
487-
- --service-account-private-key-file=/etc/kubernetes/secrets/service-account.key
488+
- --root-ca-file=/etc/kubernetes/{{ .BootstrapSecretsSubdir }}/ca.crt
489+
- --service-account-private-key-file=/etc/kubernetes/{{ .BootstrapSecretsSubdir }}/service-account.key
488490
volumeMounts:
489-
- name: secrets
490-
mountPath: /etc/kubernetes/secrets
491+
- name: kubernetes
492+
mountPath: /etc/kubernetes
491493
readOnly: true
492494
- name: ssl-host
493495
mountPath: /etc/ssl/certs
494496
readOnly: true
495497
hostNetwork: true
496498
volumes:
497-
- name: secrets
499+
- name: kubernetes
498500
hostPath:
499-
path: {{ .BootstrapSecretsDir }}
501+
path: /etc/kubernetes
500502
- name: ssl-host
501503
hostPath:
502504
path: /usr/share/ca-certificates
@@ -582,9 +584,17 @@ spec:
582584
command:
583585
- ./hyperkube
584586
- scheduler
587+
- --kubeconfig=/etc/kubernetes/kubeconfig
585588
- --leader-elect=true
586-
- --master=http://127.0.0.1:8080
589+
volumeMounts:
590+
- name: kubernetes
591+
mountPath: /etc/kubernetes
592+
readOnly: true
587593
hostNetwork: true
594+
volumes:
595+
- name: kubernetes
596+
hostPath:
597+
path: /etc/kubernetes
588598
`)
589599
SchedulerDisruptionTemplate = []byte(`apiVersion: policy/v1beta1
590600
kind: PodDisruptionBudget

pkg/bootkube/bootkube.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ import (
55
"path/filepath"
66
"time"
77

8+
"k8s.io/client-go/tools/clientcmd"
9+
810
"github.com/coreos/etcd/pkg/fileutil"
911
"github.com/kubernetes-incubator/bootkube/pkg/asset"
1012
"github.com/kubernetes-incubator/bootkube/pkg/util/etcdutil"
1113
)
1214

13-
const (
14-
assetTimeout = 20 * time.Minute
15-
insecureAPIAddr = "http://127.0.0.1:8080"
16-
)
15+
const assetTimeout = 20 * time.Minute
16+
17+
var kubeConfig clientcmd.ClientConfig
1718

1819
var requiredPods = []string{
1920
"pod-checkpointer",
@@ -49,6 +50,12 @@ func (b *bootkube) Run() error {
4950
}
5051
}()
5152

53+
// TODO(diegs): create and share a single client rather than the kubeconfig once all uses of it
54+
// are migrated to client-go.
55+
kubeConfig = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
56+
&clientcmd.ClientConfigLoadingRules{ExplicitPath: filepath.Join(b.assetDir, asset.AssetPathKubeConfig)},
57+
&clientcmd.ConfigOverrides{})
58+
5259
var err error
5360
defer func() {
5461
// Always report errors.
@@ -80,7 +87,7 @@ func (b *bootkube) Run() error {
8087
if err != nil {
8188
return err
8289
}
83-
if err = etcdutil.Migrate(insecureAPIAddr, etcdServiceIP); err != nil {
90+
if err = etcdutil.Migrate(kubeConfig, etcdServiceIP); err != nil {
8491
return err
8592
}
8693
}

pkg/bootkube/create.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,16 @@ import (
99
apierrors "k8s.io/apimachinery/pkg/api/errors"
1010
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1111
"k8s.io/apimachinery/pkg/util/wait"
12-
restclient "k8s.io/client-go/rest"
12+
"k8s.io/client-go/kubernetes"
13+
"k8s.io/client-go/pkg/api"
1314
"k8s.io/client-go/tools/clientcmd"
14-
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
15-
"k8s.io/kubernetes/pkg/api"
16-
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
1715
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
1816
"k8s.io/kubernetes/pkg/kubectl/resource"
1917

2018
"github.com/kubernetes-incubator/bootkube/pkg/util"
2119
)
2220

2321
func CreateAssets(manifestDir string, timeout time.Duration) error {
24-
2522
upFn := func() (bool, error) {
2623
if err := apiTest(); err != nil {
2724
glog.Warningf("Unable to determine api-server readiness: %v", err)
@@ -65,11 +62,7 @@ func CreateAssets(manifestDir string, timeout time.Duration) error {
6562
}
6663

6764
func createAssets(manifestDir string) error {
68-
config := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
69-
&clientcmd.ClientConfigLoadingRules{},
70-
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: insecureAPIAddr}},
71-
)
72-
f := cmdutil.NewFactory(config)
65+
f := cmdutil.NewFactory(kubeConfig)
7366

7467
shouldValidate := true
7568
schema, err := f.Validator(shouldValidate, fmt.Sprintf("~/%s/%s", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName))
@@ -135,7 +128,11 @@ func createAssets(manifestDir string) error {
135128
}
136129

137130
func apiTest() error {
138-
client, err := clientset.NewForConfig(&restclient.Config{Host: insecureAPIAddr})
131+
config, err := kubeConfig.ClientConfig()
132+
if err != nil {
133+
return err
134+
}
135+
client, err := kubernetes.NewForConfig(config)
139136
if err != nil {
140137
return err
141138
}

pkg/bootkube/parse.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77

88
"github.com/ghodss/yaml"
99
"github.com/kubernetes-incubator/bootkube/pkg/asset"
10-
"k8s.io/kubernetes/pkg/api/v1"
10+
"k8s.io/client-go/pkg/api/v1"
1111
)
1212

1313
// detectEtcdIP deserializes the etcd-service ClusterIP.

pkg/bootkube/status.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ import (
1212
"k8s.io/apimachinery/pkg/runtime"
1313
"k8s.io/apimachinery/pkg/util/wait"
1414
"k8s.io/apimachinery/pkg/watch"
15-
restclient "k8s.io/client-go/rest"
15+
"k8s.io/client-go/kubernetes"
16+
"k8s.io/client-go/pkg/api"
17+
"k8s.io/client-go/pkg/api/v1"
1618
"k8s.io/client-go/tools/cache"
17-
"k8s.io/kubernetes/pkg/api"
18-
"k8s.io/kubernetes/pkg/api/v1"
19-
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
2019
)
2120

2221
const (
@@ -39,14 +38,18 @@ func WaitUntilPodsRunning(pods []string, timeout time.Duration) error {
3938
}
4039

4140
type statusController struct {
42-
client clientset.Interface
41+
client kubernetes.Interface
4342
podStore cache.Store
4443
watchPods []string
4544
lastPodPhases map[string]v1.PodPhase
4645
}
4746

4847
func NewStatusController(pods []string) (*statusController, error) {
49-
client, err := clientset.NewForConfig(&restclient.Config{Host: insecureAPIAddr})
48+
config, err := kubeConfig.ClientConfig()
49+
if err != nil {
50+
return nil, err
51+
}
52+
client, err := kubernetes.NewForConfig(config)
5053
if err != nil {
5154
return nil, err
5255
}

pkg/util/etcdutil/migrate.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ import (
1414
apierrors "k8s.io/apimachinery/pkg/api/errors"
1515
"k8s.io/apimachinery/pkg/apis/meta/v1"
1616
"k8s.io/apimachinery/pkg/util/wait"
17+
"k8s.io/client-go/kubernetes"
18+
"k8s.io/client-go/pkg/api"
1719
restclient "k8s.io/client-go/rest"
18-
"k8s.io/kubernetes/pkg/api"
19-
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
20+
"k8s.io/client-go/tools/clientcmd"
2021
)
2122

2223
const (
@@ -28,10 +29,12 @@ var (
2829
waitBootEtcdRemovedTime = 300 * time.Second
2930
)
3031

31-
func Migrate(apiserverAddr, etcdServiceIP string) error {
32-
kubecli, err := clientset.NewForConfig(&restclient.Config{
33-
Host: apiserverAddr,
34-
})
32+
func Migrate(kubeConfig clientcmd.ClientConfig, etcdServiceIP string) error {
33+
config, err := kubeConfig.ClientConfig()
34+
if err != nil {
35+
return fmt.Errorf("fail to create kube client: %v", err)
36+
}
37+
kubecli, err := kubernetes.NewForConfig(config)
3538
if err != nil {
3639
return fmt.Errorf("fail to create kube client: %v", err)
3740
}
@@ -49,7 +52,7 @@ func Migrate(apiserverAddr, etcdServiceIP string) error {
4952
}
5053
glog.Infof("boot-etcd pod IP is: %s", ip)
5154

52-
if err := createMigratedEtcdCluster(restClient, apiserverAddr, ip); err != nil {
55+
if err := createMigratedEtcdCluster(restClient, ip); err != nil {
5356
return fmt.Errorf("fail to create migrated etcd cluster: %v", err)
5457
}
5558
glog.Infof("etcd cluster for migration is created")
@@ -88,7 +91,7 @@ func waitEtcdTPRReady(restClient restclient.Interface, interval, timeout time.Du
8891
return nil
8992
}
9093

91-
func getBootEtcdPodIP(kubecli clientset.Interface) (string, error) {
94+
func getBootEtcdPodIP(kubecli kubernetes.Interface) (string, error) {
9295
var ip string
9396
err := wait.Poll(5*time.Second, 60*time.Second, func() (bool, error) {
9497
podList, err := kubecli.CoreV1().Pods(api.NamespaceSystem).List(v1.ListOptions{
@@ -113,7 +116,7 @@ func getBootEtcdPodIP(kubecli clientset.Interface) (string, error) {
113116
return ip, err
114117
}
115118

116-
func createMigratedEtcdCluster(restclient restclient.Interface, host, podIP string) error {
119+
func createMigratedEtcdCluster(restclient restclient.Interface, podIP string) error {
117120
b := []byte(fmt.Sprintf(`{
118121
"apiVersion": "%s/%s",
119122
"kind": "%s",

0 commit comments

Comments
 (0)