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

Commit a2d3c8b

Browse files
committed
pkg,cmd: Add Kubernetes pod and service CIDR customziation
* Add cmd flags --pod-cidr and --service-cidr * Pick an appropriate DNS Service IP from the service range
1 parent 9f0664d commit a2d3c8b

File tree

6 files changed

+105
-26
lines changed

6 files changed

+105
-26
lines changed

cmd/bootkube/render.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ import (
1616
"github.com/kubernetes-incubator/bootkube/pkg/tlsutil"
1717
)
1818

19+
const (
20+
apiOffset = 1
21+
dnsOffset = 10
22+
etcdOffset = 15
23+
defaultDNSServiceIP = "10.3.0.10"
24+
)
25+
1926
var (
2027
cmdRender = &cobra.Command{
2128
Use: "render",
@@ -33,6 +40,8 @@ var (
3340
etcdServers string
3441
apiServers string
3542
altNames string
43+
podCIDR string
44+
serviceCIDR string
3645
selfHostKubelet bool
3746
cloudProvider string
3847
selfHostedEtcd bool
@@ -47,6 +56,8 @@ func init() {
4756
cmdRender.Flags().StringVar(&renderOpts.etcdServers, "etcd-servers", "http://127.0.0.1:2379", "List of etcd servers URLs including host:port, comma separated")
4857
cmdRender.Flags().StringVar(&renderOpts.apiServers, "api-servers", "https://127.0.0.1:443", "List of API server URLs including host:port, commma seprated")
4958
cmdRender.Flags().StringVar(&renderOpts.altNames, "api-server-alt-names", "", "List of SANs to use in api-server certificate. Example: 'IP=127.0.0.1,IP=127.0.0.2,DNS=localhost'. If empty, SANs will be extracted from the --api-servers flag.")
59+
cmdRender.Flags().StringVar(&renderOpts.podCIDR, "pod-cidr", "10.2.0.0/16", "The CIDR range of cluster pods.")
60+
cmdRender.Flags().StringVar(&renderOpts.serviceCIDR, "service-cidr", "10.3.0.0/24", "The CIDR range of cluster services.")
5061
cmdRender.Flags().BoolVar(&renderOpts.selfHostKubelet, "self-host-kubelet", false, "Create a self-hosted kubelet daemonset.")
5162
cmdRender.Flags().StringVar(&renderOpts.cloudProvider, "cloud-provider", "", "The provider for cloud services. Empty string for no provider")
5263
cmdRender.Flags().BoolVar(&renderOpts.selfHostedEtcd, "experimental-self-hosted-etcd", false, "Create self-hosted etcd assets.")
@@ -111,12 +122,51 @@ func flagsToAssetConfig() (c *asset.Config, err error) {
111122
return nil, err
112123
}
113124
}
125+
126+
_, podNet, err := net.ParseCIDR(renderOpts.podCIDR)
127+
if err != nil {
128+
return nil, err
129+
}
130+
131+
_, serviceNet, err := net.ParseCIDR(renderOpts.serviceCIDR)
132+
if err != nil {
133+
return nil, err
134+
}
135+
136+
if podNet.Contains(serviceNet.IP) || serviceNet.Contains(podNet.IP) {
137+
return nil, fmt.Errorf("Pod CIDR %s and service CIDR %s must not overlap", podNet.String(), serviceNet.String())
138+
}
139+
140+
apiServiceIP, err := offsetServiceIP(serviceNet, apiOffset)
141+
if err != nil {
142+
return nil, err
143+
}
144+
145+
dnsServiceIP, err := offsetServiceIP(serviceNet, dnsOffset)
146+
if err != nil {
147+
return nil, err
148+
}
149+
150+
etcdServiceIP, err := offsetServiceIP(serviceNet, etcdOffset)
151+
if err != nil {
152+
return nil, err
153+
}
154+
155+
if dnsServiceIP.String() != defaultDNSServiceIP {
156+
fmt.Printf("You have selected a non-default service CIDR %s - be sure your kubelet service file uses --cluster-dns=%s\n", serviceNet.String(), dnsServiceIP.String())
157+
}
158+
114159
return &asset.Config{
115160
EtcdServers: etcdServers,
116161
CACert: caCert,
117162
CAPrivKey: caPrivKey,
118163
APIServers: apiServers,
119164
AltNames: altNames,
165+
PodCIDR: podNet,
166+
ServiceCIDR: serviceNet,
167+
APIServiceIP: apiServiceIP,
168+
DNSServiceIP: dnsServiceIP,
169+
ETCDServiceIP: etcdServiceIP,
120170
SelfHostKubelet: renderOpts.selfHostKubelet,
121171
CloudProvider: renderOpts.cloudProvider,
122172
SelfHostedEtcd: renderOpts.selfHostedEtcd,
@@ -195,3 +245,26 @@ func altNamesFromURLs(urls []*url.URL) *tlsutil.AltNames {
195245
}
196246
return &an
197247
}
248+
249+
// offsetServiceIP returns an IP offset by up to 255.
250+
// TODO: do numeric conversion to generalize this utility.
251+
func offsetServiceIP(ipnet *net.IPNet, offset int) (net.IP, error) {
252+
ip := make(net.IP, len(ipnet.IP))
253+
copy(ip, ipnet.IP)
254+
for i := 0; i < offset; i++ {
255+
incIPv4(ip)
256+
}
257+
if ipnet.Contains(ip) {
258+
return ip, nil
259+
}
260+
return net.IP([]byte("")), fmt.Errorf("Service IP %v is not in %s", ip, ipnet)
261+
}
262+
263+
func incIPv4(ip net.IP) {
264+
for j := len(ip) - 1; j >= 0; j-- {
265+
ip[j]++
266+
if ip[j] > 0 {
267+
break
268+
}
269+
}
270+
}

hack/multi-node/Vagrantfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ if $worker_vm_memory < 1024
1818
puts "Workers should have at least 1024 MB of memory"
1919
end
2020

21-
CONTROLLER_CLUSTER_IP="10.3.0.1"
2221
CONTROLLER_USER_DATA_PATH = File.expand_path("./cluster/user-data-controller")
2322
WORKER_USER_DATA_PATH = File.expand_path("./cluster/user-data-worker")
2423

pkg/asset/asset.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"crypto/x509"
66
"fmt"
77
"io/ioutil"
8+
"net"
89
"net/url"
910
"os"
1011
"path/filepath"
@@ -50,6 +51,11 @@ type Config struct {
5051
CACert *x509.Certificate
5152
CAPrivKey *rsa.PrivateKey
5253
AltNames *tlsutil.AltNames
54+
PodCIDR *net.IPNet
55+
ServiceCIDR *net.IPNet
56+
APIServiceIP net.IP
57+
DNSServiceIP net.IP
58+
ETCDServiceIP net.IP
5359
SelfHostKubelet bool
5460
SelfHostedEtcd bool
5561
CloudProvider string
@@ -59,9 +65,12 @@ type Config struct {
5965
// configured via a user provided AssetConfig. Default assets include
6066
// TLS assets (certs, keys and secrets), and k8s component manifests.
6167
func NewDefaultAssets(conf Config) (Assets, error) {
62-
as := newStaticAssets(conf.SelfHostKubelet, conf.SelfHostedEtcd)
68+
as := newStaticAssets()
6369
as = append(as, newDynamicAssets(conf)...)
6470

71+
// Add kube-apiserver service IP
72+
conf.AltNames.IPs = append(conf.AltNames.IPs, conf.APIServiceIP)
73+
6574
// TLS assets
6675
tlsAssets, err := newTLSAssets(conf.CACert, conf.CAPrivKey, *conf.AltNames)
6776
if err != nil {

pkg/asset/internal/templates.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ spec:
4545
- --pod-manifest-path=/etc/kubernetes/manifests
4646
- --allow-privileged
4747
- --hostname-override=$(NODE_NAME)
48-
- --cluster-dns=10.3.0.10
48+
- --cluster-dns={{ .DNSServiceIP }}
4949
- --cluster-domain=cluster.local
5050
- --kubeconfig=/etc/kubernetes/kubeconfig
5151
- --require-kubeconfig
@@ -147,7 +147,7 @@ spec:
147147
- --etcd-servers={{ range $i, $e := .EtcdServers }}{{ if $i }},{{end}}{{ $e }}{{end}}
148148
- --storage-backend=etcd3
149149
- --allow-privileged=true
150-
- --service-cluster-ip-range=10.3.0.0/24
150+
- --service-cluster-ip-range={{ .ServiceCIDR }}
151151
- --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota
152152
- --runtime-config=api/all=true
153153
- --tls-cert-file=/etc/kubernetes/secrets/apiserver.crt
@@ -235,7 +235,7 @@ spec:
235235
- controller-manager
236236
- --allocate-node-cidrs=true
237237
- --configure-cloud-routes=false
238-
- --cluster-cidr=10.2.0.0/16
238+
- --cluster-cidr={{ .PodCIDR }}
239239
- --root-ca-file=/etc/kubernetes/secrets/ca.crt
240240
- --service-account-private-key-file=/etc/kubernetes/secrets/service-account.key
241241
- --leader-elect=true
@@ -326,7 +326,7 @@ spec:
326326
- --kubeconfig=/etc/kubernetes/kubeconfig
327327
- --proxy-mode=iptables
328328
- --hostname-override=$(NODE_NAME)
329-
- --cluster-cidr=10.2.0.0/16
329+
- --cluster-cidr={{ .PodCIDR }}
330330
env:
331331
- name: NODE_NAME
332332
valueFrom:
@@ -513,7 +513,7 @@ metadata:
513513
spec:
514514
selector:
515515
k8s-app: kube-dns
516-
clusterIP: 10.3.0.10
516+
clusterIP: {{ .DNSServiceIP }}
517517
ports:
518518
- name: dns
519519
port: 53
@@ -556,7 +556,7 @@ spec:
556556
selector:
557557
app: etcd
558558
etcd_cluster: kube-etcd
559-
clusterIP: 10.3.0.15
559+
clusterIP: {{ .ETCDServiceIP }}
560560
ports:
561561
- name: client
562562
port: 2379
@@ -582,7 +582,7 @@ data:
582582
}
583583
net-conf.json: |
584584
{
585-
"Network": "10.2.0.0/16",
585+
"Network": "{{ .PodCIDR }}",
586586
"Backend": {
587587
"Type": "vxlan"
588588
}

pkg/asset/k8s.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,37 @@ const (
1717
secretCMName = "kube-controller-manager"
1818
)
1919

20-
func newStaticAssets(selfHostKubelet, selfHostedEtcd bool) Assets {
20+
func newStaticAssets() Assets {
2121
var noData interface{}
2222
assets := Assets{
2323
mustCreateAssetFromTemplate(AssetPathScheduler, internal.SchedulerTemplate, noData),
2424
mustCreateAssetFromTemplate(AssetPathSchedulerDisruption, internal.SchedulerDisruptionTemplate, noData),
2525
mustCreateAssetFromTemplate(AssetPathControllerManagerDisruption, internal.ControllerManagerDisruptionTemplate, noData),
26-
mustCreateAssetFromTemplate(AssetPathProxy, internal.ProxyTemplate, noData),
2726
mustCreateAssetFromTemplate(AssetPathKubeDNSDeployment, internal.DNSDeploymentTemplate, noData),
28-
mustCreateAssetFromTemplate(AssetPathKubeDNSSvc, internal.DNSSvcTemplate, noData),
2927
mustCreateAssetFromTemplate(AssetPathCheckpointer, internal.CheckpointerTemplate, noData),
3028
mustCreateAssetFromTemplate(AssetPathKubeFlannel, internal.KubeFlannelTemplate, noData),
31-
mustCreateAssetFromTemplate(AssetPathKubeFlannelCfg, internal.KubeFlannelCfgTemplate, noData),
3229
}
33-
if selfHostKubelet {
34-
assets = append(assets, mustCreateAssetFromTemplate(AssetPathKubelet, internal.KubeletTemplate, noData))
35-
}
36-
if selfHostedEtcd {
37-
assets = append(assets,
38-
mustCreateAssetFromTemplate(AssetPathEtcdOperator, internal.EtcdOperatorTemplate, noData),
39-
mustCreateAssetFromTemplate(AssetPathEtcdSvc, internal.EtcdSvcTemplate, noData),
40-
)
41-
}
42-
4330
return assets
4431
}
4532

4633
func newDynamicAssets(conf Config) Assets {
47-
return Assets{
34+
assets := Assets{
4835
mustCreateAssetFromTemplate(AssetPathControllerManager, internal.ControllerManagerTemplate, conf),
4936
mustCreateAssetFromTemplate(AssetPathAPIServer, internal.APIServerTemplate, conf),
37+
mustCreateAssetFromTemplate(AssetPathProxy, internal.ProxyTemplate, conf),
38+
mustCreateAssetFromTemplate(AssetPathKubeFlannelCfg, internal.KubeFlannelCfgTemplate, conf),
39+
mustCreateAssetFromTemplate(AssetPathKubeDNSSvc, internal.DNSSvcTemplate, conf),
5040
}
41+
if conf.SelfHostKubelet {
42+
assets = append(assets, mustCreateAssetFromTemplate(AssetPathKubelet, internal.KubeletTemplate, conf))
43+
}
44+
if conf.SelfHostedEtcd {
45+
assets = append(assets,
46+
mustCreateAssetFromTemplate(AssetPathEtcdOperator, internal.EtcdOperatorTemplate, conf),
47+
mustCreateAssetFromTemplate(AssetPathEtcdSvc, internal.EtcdSvcTemplate, conf),
48+
)
49+
}
50+
return assets
5151
}
5252

5353
func newKubeConfigAsset(assets Assets, conf Config) (Asset, error) {

pkg/asset/tls.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package asset
33
import (
44
"crypto/rsa"
55
"crypto/x509"
6-
"net"
76

87
"github.com/kubernetes-incubator/bootkube/pkg/tlsutil"
98
)
@@ -78,7 +77,6 @@ func newAPIKeyAndCert(caCert *x509.Certificate, caPrivKey *rsa.PrivateKey, altNa
7877
if err != nil {
7978
return nil, nil, err
8079
}
81-
altNames.IPs = append(altNames.IPs, net.ParseIP("10.3.0.1"))
8280
altNames.DNSNames = append(altNames.DNSNames, []string{
8381
"kubernetes",
8482
"kubernetes.default",

0 commit comments

Comments
 (0)