Allow specifying image repository for docker images
Some users (especially for those in mainland China) may have issue accessing the default image repository. This patchset allows users to override the default image repository gcr.io to a different repository by specifying --image-repository option in the command line as a simple workaround. Images will be pulled from the specified image repository instead of the default ones. Example (using mirror by Aliyun): minikube start ... --image-repository registry.cn-hangzhou.aliyuncs.com/google_containerspull/3714/head
parent
aad78ea071
commit
7cbe253ef6
|
@ -77,6 +77,7 @@ const (
|
|||
apiServerPort = "apiserver-port"
|
||||
dnsDomain = "dns-domain"
|
||||
serviceCIDR = "service-cluster-ip-range"
|
||||
imageRepository = "image-repository"
|
||||
mountString = "mount-string"
|
||||
disableDriverMounts = "disable-driver-mounts"
|
||||
cacheImages = "cache-images"
|
||||
|
@ -123,6 +124,7 @@ func init() {
|
|||
startCmd.Flags().String(serviceCIDR, pkgutil.DefaultServiceCIDR, "The CIDR to be used for service cluster IPs.")
|
||||
startCmd.Flags().StringSliceVar(&insecureRegistry, "insecure-registry", nil, "Insecure Docker registries to pass to the Docker daemon. The default service CIDR range will automatically be added.")
|
||||
startCmd.Flags().StringSliceVar(®istryMirror, "registry-mirror", nil, "Registry mirrors to pass to the Docker daemon")
|
||||
startCmd.Flags().String(imageRepository, "", "Image repository to pull down docker images.")
|
||||
startCmd.Flags().String(containerRuntime, "docker", "The container runtime to be used (docker, crio, containerd)")
|
||||
startCmd.Flags().String(criSocket, "", "The cri socket path to be used")
|
||||
startCmd.Flags().String(kubernetesVersion, constants.DefaultKubernetesVersion, "The kubernetes version that the minikube VM will use (ex: v1.2.3)")
|
||||
|
@ -237,7 +239,7 @@ func beginCacheImages(g *errgroup.Group, kVersion string) {
|
|||
}
|
||||
console.OutStyle("caching", "Caching images in the background ...")
|
||||
g.Go(func() error {
|
||||
return machine.CacheImagesForBootstrapper(kVersion, viper.GetString(cmdcfg.Bootstrapper))
|
||||
return machine.CacheImagesForBootstrapper(viper.GetString(imageRepository), kVersion, viper.GetString(cmdcfg.Bootstrapper))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -296,6 +298,7 @@ func generateConfig(cmd *cobra.Command, kVersion string) (cfg.Config, error) {
|
|||
CRISocket: viper.GetString(criSocket),
|
||||
NetworkPlugin: selectedNetworkPlugin,
|
||||
ServiceCIDR: viper.GetString(serviceCIDR),
|
||||
ImageRepository: viper.GetString(imageRepository),
|
||||
ExtraOptions: extraOptions,
|
||||
ShouldLoadCachedImages: viper.GetBool(cacheImages),
|
||||
EnableDefaultCNI: selectedEnableDefaultCNI,
|
||||
|
|
|
@ -25,7 +25,7 @@ spec:
|
|||
hostNetwork: true
|
||||
containers:
|
||||
- name: kube-addon-manager
|
||||
image: k8s.gcr.io/kube-addon-manager:v8.6
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/kube-addon-manager:v8.6
|
||||
env:
|
||||
- name: KUBECONFIG
|
||||
value: /var/lib/minikube/kubeconfig
|
||||
|
|
|
@ -37,7 +37,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: kubernetes-dashboard
|
||||
image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/kubernetes-dashboard-amd64:v1.10.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 9090
|
||||
|
|
|
@ -51,7 +51,7 @@ spec:
|
|||
hostNetwork: true
|
||||
containers:
|
||||
- name: storage-provisioner
|
||||
image: gcr.io/k8s-minikube/storage-provisioner:v1.8.1
|
||||
image: {{default "gcr.io/k8s-minikube" .ImageRepository}}/storage-provisioner:v1.8.1
|
||||
command: ["/storage-provisioner"]
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
|
|
|
@ -62,222 +62,260 @@ var Addons = map[string]*Addon{
|
|||
"deploy/addons/addon-manager.yaml",
|
||||
"/etc/kubernetes/manifests/",
|
||||
"addon-manager.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
true),
|
||||
}, true, "addon-manager"),
|
||||
"dashboard": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/dashboard/dashboard-dp.yaml",
|
||||
constants.AddonsPath,
|
||||
"dashboard-dp.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
true),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/dashboard/dashboard-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"dashboard-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "dashboard"),
|
||||
"default-storageclass": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/storageclass/storageclass.yaml",
|
||||
constants.AddonsPath,
|
||||
"storageclass.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, true, "default-storageclass"),
|
||||
"storage-provisioner": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/storage-provisioner/storage-provisioner.yaml",
|
||||
constants.AddonsPath,
|
||||
"storage-provisioner.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
true),
|
||||
}, true, "storage-provisioner"),
|
||||
"storage-provisioner-gluster": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/storage-provisioner-gluster/storage-gluster-ns.yaml",
|
||||
constants.AddonsPath,
|
||||
"storage-gluster-ns.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/storage-provisioner-gluster/glusterfs-daemonset.yaml",
|
||||
constants.AddonsPath,
|
||||
"glusterfs-daemonset.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/storage-provisioner-gluster/heketi-deployment.yaml",
|
||||
constants.AddonsPath,
|
||||
"heketi-deployment.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/storage-provisioner-gluster/storage-provisioner-glusterfile.yaml",
|
||||
constants.AddonsPath,
|
||||
"storage-privisioner-glusterfile.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "storage-provisioner-gluster"),
|
||||
"heapster": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/heapster/influx-grafana-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"influxGrafana-rc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/heapster/grafana-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"grafana-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/heapster/influxdb-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"influxdb-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/heapster/heapster-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"heapster-rc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/heapster/heapster-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"heapster-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "heapster"),
|
||||
"efk": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/efk/elasticsearch-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"elasticsearch-rc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/efk/elasticsearch-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"elasticsearch-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/efk/fluentd-es-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"fluentd-es-rc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/efk/fluentd-es-configmap.yaml",
|
||||
constants.AddonsPath,
|
||||
"fluentd-es-configmap.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/efk/kibana-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"kibana-rc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/efk/kibana-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"kibana-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "efk"),
|
||||
"ingress": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/ingress/ingress-configmap.yaml",
|
||||
constants.AddonsPath,
|
||||
"ingress-configmap.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/ingress/ingress-rbac.yaml",
|
||||
constants.AddonsPath,
|
||||
"ingress-rbac.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/ingress/ingress-dp.yaml",
|
||||
constants.AddonsPath,
|
||||
"ingress-dp.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/ingress/ingress-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"ingress-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "ingress"),
|
||||
"metrics-server": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/metrics-server/metrics-apiservice.yaml",
|
||||
constants.AddonsPath,
|
||||
"metrics-apiservice.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/metrics-server/metrics-server-deployment.yaml",
|
||||
constants.AddonsPath,
|
||||
"metrics-server-deployment.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/metrics-server/metrics-server-service.yaml",
|
||||
constants.AddonsPath,
|
||||
"metrics-server-service.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "metrics-server"),
|
||||
"registry": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/registry/registry-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"registry-rc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/registry/registry-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"registry-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "registry"),
|
||||
"registry-creds": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/registry-creds/registry-creds-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"registry-creds-rc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "registry-creds"),
|
||||
"freshpod": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/freshpod/freshpod-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"freshpod-rc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "freshpod"),
|
||||
"nvidia-driver-installer": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/gpu/nvidia-driver-installer.yaml",
|
||||
constants.AddonsPath,
|
||||
"nvidia-driver-installer.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "nvidia-driver-installer"),
|
||||
"nvidia-gpu-device-plugin": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/gpu/nvidia-gpu-device-plugin.yaml",
|
||||
constants.AddonsPath,
|
||||
"nvidia-gpu-device-plugin.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "nvidia-gpu-device-plugin"),
|
||||
"logviewer": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/logviewer/logviewer-dp-and-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"logviewer-dp-and-svc.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/logviewer/logviewer-rbac.yaml",
|
||||
constants.AddonsPath,
|
||||
"logviewer-rbac.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "logviewer"),
|
||||
"gvisor": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/gvisor/gvisor-pod.yaml",
|
||||
constants.AddonsPath,
|
||||
"gvisor-pod.yaml",
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/gvisor/gvisor-config.toml",
|
||||
constants.GvisorFilesPath,
|
||||
constants.GvisorConfigTomlTargetName,
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
NewBinDataAsset(
|
||||
"deploy/addons/gvisor/gvisor-containerd-shim.toml",
|
||||
constants.GvisorFilesPath,
|
||||
constants.GvisorContainerdShimTargetName,
|
||||
"0640"),
|
||||
"0640",
|
||||
false),
|
||||
}, false, "gvisor"),
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package assets
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"html/template"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
|
@ -134,32 +135,73 @@ func NewMemoryAsset(d []byte, targetDir, targetName, permissions string) *Memory
|
|||
|
||||
type BinDataAsset struct {
|
||||
BaseAsset
|
||||
template *template.Template
|
||||
}
|
||||
|
||||
func NewBinDataAsset(assetName, targetDir, targetName, permissions string) *BinDataAsset {
|
||||
func NewBinDataAsset(assetName, targetDir, targetName, permissions string, isTemplate bool) *BinDataAsset {
|
||||
m := &BinDataAsset{
|
||||
BaseAsset{
|
||||
BaseAsset: BaseAsset{
|
||||
AssetName: assetName,
|
||||
TargetDir: targetDir,
|
||||
TargetName: targetName,
|
||||
Permissions: permissions,
|
||||
},
|
||||
template: nil,
|
||||
}
|
||||
m.loadData()
|
||||
m.loadData(isTemplate)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *BinDataAsset) loadData() error {
|
||||
func defaultValue(defValue string, val interface{}) string {
|
||||
if val == nil {
|
||||
return defValue
|
||||
}
|
||||
strVal, ok := val.(string)
|
||||
if !ok || strVal == "" {
|
||||
return defValue
|
||||
}
|
||||
return strVal
|
||||
}
|
||||
|
||||
func (m *BinDataAsset) loadData(isTemplate bool) error {
|
||||
contents, err := Asset(m.AssetName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isTemplate {
|
||||
tpl, err := template.New(m.AssetName).Funcs(template.FuncMap{"default": defaultValue}).Parse(string(contents))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.template = tpl
|
||||
}
|
||||
|
||||
m.data = contents
|
||||
m.Length = len(contents)
|
||||
m.reader = bytes.NewReader(m.data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BinDataAsset) IsTemplate() bool {
|
||||
return m.template != nil
|
||||
}
|
||||
|
||||
func (m *BinDataAsset) Evaluate(data interface{}) (*MemoryAsset, error){
|
||||
if !m.IsTemplate() {
|
||||
return nil, errors.Errorf("the asset %s is not a template", m.AssetName)
|
||||
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := m.template.Execute(&buf, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewMemoryAsset(buf.Bytes(), m.GetTargetDir(), m.GetTargetName(), m.GetPermissions()), nil
|
||||
}
|
||||
|
||||
func (m *BinDataAsset) GetLength() int {
|
||||
return m.Length
|
||||
}
|
||||
|
|
|
@ -50,10 +50,11 @@ const (
|
|||
BootstrapperTypeKubeadm = "kubeadm"
|
||||
)
|
||||
|
||||
func GetCachedImageList(version string, bootstrapper string) []string {
|
||||
func GetCachedImageList(imageRepository string, version string, bootstrapper string) []string {
|
||||
switch bootstrapper {
|
||||
case BootstrapperTypeKubeadm:
|
||||
return constants.GetKubeadmCachedImages(version)
|
||||
_, images := constants.GetKubeadmImages(imageRepository, version)
|
||||
return images
|
||||
default:
|
||||
return []string{}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import (
|
|||
"github.com/docker/machine/libmachine"
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"github.com/golang/glog"
|
||||
download "github.com/jimmidyson/go-download"
|
||||
"github.com/jimmidyson/go-download"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
|
@ -184,7 +184,7 @@ func (k *KubeadmBootstrapper) StartCluster(k8s config.KubernetesConfig) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func addAddons(files *[]assets.CopyableFile) error {
|
||||
func addAddons(files *[]assets.CopyableFile, data interface{}) error {
|
||||
// add addons to file list
|
||||
// custom addons
|
||||
if err := assets.AddMinikubeDirAssets(files); err != nil {
|
||||
|
@ -194,7 +194,16 @@ func addAddons(files *[]assets.CopyableFile) error {
|
|||
for _, addonBundle := range assets.Addons {
|
||||
if isEnabled, err := addonBundle.IsEnabled(); err == nil && isEnabled {
|
||||
for _, addon := range addonBundle.Assets {
|
||||
*files = append(*files, addon)
|
||||
if addon.IsTemplate() {
|
||||
addonFile, err := addon.Evaluate(data)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "evaluate bundled addon %s asset", addon.GetAssetName())
|
||||
}
|
||||
|
||||
*files = append(*files, addonFile)
|
||||
} else {
|
||||
*files = append(*files, addon)
|
||||
}
|
||||
}
|
||||
} else if err != nil {
|
||||
return nil
|
||||
|
@ -286,7 +295,10 @@ func NewKubeletConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string,
|
|||
extraOpts["network-plugin"] = k8s.NetworkPlugin
|
||||
}
|
||||
|
||||
extraFlags := convertToFlags(extraOpts)
|
||||
podInfraContainerImage, _ := constants.GetKubeadmImages(k8s.ImageRepository, k8s.KubernetesVersion)
|
||||
if _, ok := extraOpts["pod-infra-container-image"]; !ok && k8s.ImageRepository != "" && podInfraContainerImage != "" {
|
||||
extraOpts["pod-infra-container-image"] = podInfraContainerImage
|
||||
}
|
||||
|
||||
// parses a map of the feature gates for kubelet
|
||||
_, kubeletFeatureArgs, err := ParseFeatureArgs(k8s.FeatureGates)
|
||||
|
@ -294,14 +306,18 @@ func NewKubeletConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string,
|
|||
return "", errors.Wrap(err, "parses feature gate config for kubelet")
|
||||
}
|
||||
|
||||
if kubeletFeatureArgs != "" {
|
||||
extraOpts["feature-gates"] = kubeletFeatureArgs
|
||||
}
|
||||
|
||||
extraFlags := convertToFlags(extraOpts)
|
||||
|
||||
b := bytes.Buffer{}
|
||||
opts := struct {
|
||||
ExtraOptions string
|
||||
FeatureGates string
|
||||
ContainerRuntime string
|
||||
}{
|
||||
ExtraOptions: extraFlags,
|
||||
FeatureGates: kubeletFeatureArgs,
|
||||
ContainerRuntime: k8s.ContainerRuntime,
|
||||
}
|
||||
if err := kubeletSystemdTemplate.Execute(&b, opts); err != nil {
|
||||
|
@ -312,8 +328,9 @@ func NewKubeletConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string,
|
|||
}
|
||||
|
||||
func (k *KubeadmBootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
|
||||
_, images := constants.GetKubeadmImages(cfg.ImageRepository, cfg.KubernetesVersion)
|
||||
if cfg.ShouldLoadCachedImages {
|
||||
err := machine.LoadImages(k.c, constants.GetKubeadmCachedImages(cfg.KubernetesVersion), constants.ImageCacheDir)
|
||||
err := machine.LoadImages(k.c, images, constants.ImageCacheDir)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "loading cached images")
|
||||
}
|
||||
|
@ -322,7 +339,7 @@ func (k *KubeadmBootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "runtime")
|
||||
}
|
||||
kubeadmCfg, err := generateConfig(cfg, r)
|
||||
kubeadmCfg, opts, err := generateConfig(cfg, r)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "generating kubeadm cfg")
|
||||
}
|
||||
|
@ -370,7 +387,7 @@ func (k *KubeadmBootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
|
|||
return errors.Wrap(err, "downloading binaries")
|
||||
}
|
||||
|
||||
if err := addAddons(&files); err != nil {
|
||||
if err := addAddons(&files, opts); err != nil {
|
||||
return errors.Wrap(err, "adding addons")
|
||||
}
|
||||
|
||||
|
@ -391,22 +408,22 @@ sudo systemctl start kubelet
|
|||
return nil
|
||||
}
|
||||
|
||||
func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, error) {
|
||||
func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, interface{}, error) {
|
||||
version, err := ParseKubernetesVersion(k8s.KubernetesVersion)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "parsing kubernetes version")
|
||||
return "", nil, errors.Wrap(err, "parsing kubernetes version")
|
||||
}
|
||||
|
||||
// parses a map of the feature gates for kubeadm and component
|
||||
kubeadmFeatureArgs, componentFeatureArgs, err := ParseFeatureArgs(k8s.FeatureGates)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "parses feature gate config for kubeadm and component")
|
||||
return "", nil, errors.Wrap(err, "parses feature gate config for kubeadm and component")
|
||||
}
|
||||
|
||||
// generates a map of component to extra args for apiserver, controller-manager, and scheduler
|
||||
extraComponentConfig, err := NewComponentExtraArgs(k8s.ExtraOptions, version, componentFeatureArgs)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "generating extra component config for kubeadm")
|
||||
return "", nil, errors.Wrap(err, "generating extra component config for kubeadm")
|
||||
}
|
||||
|
||||
// In case of no port assigned, use util.APIServerPort
|
||||
|
@ -424,6 +441,7 @@ func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, er
|
|||
EtcdDataDir string
|
||||
NodeName string
|
||||
CRISocket string
|
||||
ImageRepository string
|
||||
ExtraArgs []ComponentExtraArgs
|
||||
FeatureArgs map[string]bool
|
||||
NoTaintMaster bool
|
||||
|
@ -436,6 +454,7 @@ func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, er
|
|||
EtcdDataDir: "/data/minikube", //TODO(r2d4): change to something else persisted
|
||||
NodeName: k8s.NodeName,
|
||||
CRISocket: r.SocketPath(),
|
||||
ImageRepository: k8s.ImageRepository,
|
||||
ExtraArgs: extraComponentConfig,
|
||||
FeatureArgs: kubeadmFeatureArgs,
|
||||
NoTaintMaster: false, // That does not work with k8s 1.12+
|
||||
|
@ -455,10 +474,10 @@ func generateConfig(k8s config.KubernetesConfig, r cruntime.Manager) (string, er
|
|||
kubeadmConfigTemplate = kubeadmConfigTemplateV1Alpha3
|
||||
}
|
||||
if err := kubeadmConfigTemplate.Execute(&b, opts); err != nil {
|
||||
return "", err
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return b.String(), nil
|
||||
return b.String(), opts, nil
|
||||
}
|
||||
|
||||
func maybeDownloadAndCache(binary, version string) (string, error) {
|
||||
|
|
|
@ -264,7 +264,7 @@ apiServerExtraArgs:
|
|||
}
|
||||
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
actualCfg, err := generateConfig(test.cfg, runtime)
|
||||
actualCfg, _, err := generateConfig(test.cfg, runtime)
|
||||
if err != nil && !test.shouldErr {
|
||||
t.Errorf("got unexpected error generating config: %v", err)
|
||||
return
|
||||
|
|
|
@ -38,7 +38,8 @@ networking:
|
|||
etcd:
|
||||
dataDir: {{.EtcdDataDir}}
|
||||
nodeName: {{.NodeName}}
|
||||
{{if .CRISocket}}criSocket: {{.CRISocket}}
|
||||
{{if .ImageRepository}}imageRepository: {{.ImageRepository}}
|
||||
{{end}}{{if .CRISocket}}criSocket: {{.CRISocket}}
|
||||
{{end}}{{range .ExtraArgs}}{{.Component}}:{{range $i, $val := printMapInOrder .Options ": " }}
|
||||
{{$val}}{{end}}
|
||||
{{end}}{{if .FeatureArgs}}featureGates: {{range $i, $val := .FeatureArgs}}
|
||||
|
@ -67,7 +68,8 @@ nodeRegistration:
|
|||
---
|
||||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
kind: ClusterConfiguration
|
||||
{{range .ExtraArgs}}{{.Component}}:{{range $i, $val := printMapInOrder .Options ": " }}
|
||||
{{if .ImageRepository}}imageRepository: {{.ImageRepository}}
|
||||
{{end}}{{range .ExtraArgs}}{{.Component}}:{{range $i, $val := printMapInOrder .Options ": " }}
|
||||
{{$val}}{{end}}
|
||||
{{end}}{{if .FeatureArgs}}featureGates: {{range $i, $val := .FeatureArgs}}
|
||||
{{$i}}: {{$val}}{{end}}
|
||||
|
@ -101,7 +103,7 @@ var kubeletSystemdTemplate = template.Must(template.New("kubeletSystemdTemplate"
|
|||
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/bin/kubelet {{.ExtraOptions}} {{if .FeatureGates}}--feature-gates={{.FeatureGates}}{{end}}
|
||||
ExecStart=/usr/bin/kubelet{{if .ExtraOptions}} {{.ExtraOptions}}{{end}}
|
||||
|
||||
[Install]
|
||||
`))
|
||||
|
|
|
@ -69,6 +69,7 @@ type KubernetesConfig struct {
|
|||
NetworkPlugin string
|
||||
FeatureGates string
|
||||
ServiceCIDR string
|
||||
ImageRepository string
|
||||
ExtraOptions util.ExtraOptionSlice
|
||||
|
||||
ShouldLoadCachedImages bool
|
||||
|
|
|
@ -176,13 +176,24 @@ const IsMinikubeChildProcess = "IS_MINIKUBE_CHILD_PROCESS"
|
|||
const DriverNone = "none"
|
||||
const FileScheme = "file"
|
||||
|
||||
func GetKubeadmCachedImages(kubernetesVersionStr string) []string {
|
||||
func GetKubeadmImages(imageRepository string, kubernetesVersionStr string) (string, []string) {
|
||||
minikubeRepository := imageRepository
|
||||
if imageRepository == "" {
|
||||
imageRepository = "k8s.gcr.io"
|
||||
minikubeRepository = "gcr.io/k8s-minikube"
|
||||
}
|
||||
if !strings.HasSuffix(imageRepository, "/") {
|
||||
imageRepository += "/"
|
||||
}
|
||||
if !strings.HasSuffix(minikubeRepository, "/") {
|
||||
minikubeRepository += "/"
|
||||
}
|
||||
|
||||
var images = []string{
|
||||
"k8s.gcr.io/kube-proxy-amd64:" + kubernetesVersionStr,
|
||||
"k8s.gcr.io/kube-scheduler-amd64:" + kubernetesVersionStr,
|
||||
"k8s.gcr.io/kube-controller-manager-amd64:" + kubernetesVersionStr,
|
||||
"k8s.gcr.io/kube-apiserver-amd64:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-proxy-amd64:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-scheduler-amd64:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-controller-manager-amd64:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-apiserver-amd64:" + kubernetesVersionStr,
|
||||
}
|
||||
|
||||
ge_v1_13 := semver.MustParseRange(">=1.13.0")
|
||||
|
@ -197,74 +208,84 @@ func GetKubeadmCachedImages(kubernetesVersionStr string) []string {
|
|||
glog.Errorln("Error parsing version semver: ", err)
|
||||
}
|
||||
|
||||
var podInfraContainerImage string
|
||||
if ge_v1_13(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause-amd64:3.1"
|
||||
images = append(images, []string{
|
||||
"k8s.gcr.io/pause-amd64:3.1",
|
||||
"k8s.gcr.io/pause:3.1",
|
||||
"k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.8",
|
||||
"k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
"k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.8",
|
||||
"k8s.gcr.io/etcd-amd64:3.2.24",
|
||||
"k8s.gcr.io/coredns:1.2.6",
|
||||
podInfraContainerImage,
|
||||
imageRepository + "pause:3.1",
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.8",
|
||||
imageRepository + "etcd-amd64:3.2.24",
|
||||
imageRepository + "coredns:1.2.6",
|
||||
}...)
|
||||
|
||||
} else if v1_12(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause-amd64:3.1"
|
||||
images = append(images, []string{
|
||||
"k8s.gcr.io/pause-amd64:3.1",
|
||||
"k8s.gcr.io/pause:3.1",
|
||||
"k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.8",
|
||||
"k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
"k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.8",
|
||||
"k8s.gcr.io/etcd-amd64:3.2.24",
|
||||
"k8s.gcr.io/coredns:1.2.2",
|
||||
podInfraContainerImage,
|
||||
imageRepository + "pause:3.1",
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.8",
|
||||
imageRepository + "etcd-amd64:3.2.24",
|
||||
imageRepository + "coredns:1.2.2",
|
||||
}...)
|
||||
|
||||
} else if v1_11(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause-amd64:3.1"
|
||||
images = append(images, []string{
|
||||
"k8s.gcr.io/pause-amd64:3.1",
|
||||
"k8s.gcr.io/pause:3.1",
|
||||
"k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.8",
|
||||
"k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
"k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.8",
|
||||
"k8s.gcr.io/etcd-amd64:3.2.18",
|
||||
"k8s.gcr.io/coredns:1.1.3",
|
||||
podInfraContainerImage,
|
||||
imageRepository + "pause:3.1",
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.8",
|
||||
imageRepository + "etcd-amd64:3.2.18",
|
||||
imageRepository + "coredns:1.1.3",
|
||||
}...)
|
||||
|
||||
} else if v1_10(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause-amd64:3.1"
|
||||
images = append(images, []string{
|
||||
"k8s.gcr.io/pause-amd64:3.1",
|
||||
"k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.8",
|
||||
"k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
"k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.8",
|
||||
"k8s.gcr.io/etcd-amd64:3.1.12",
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.8",
|
||||
imageRepository + "etcd-amd64:3.1.12",
|
||||
}...)
|
||||
|
||||
} else if v1_9(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause-amd64:3.0"
|
||||
images = append(images, []string{
|
||||
"k8s.gcr.io/pause-amd64:3.0",
|
||||
"k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.7",
|
||||
"k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.7",
|
||||
"k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.7",
|
||||
"k8s.gcr.io/etcd-amd64:3.1.10",
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.7",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.7",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.7",
|
||||
imageRepository + "etcd-amd64:3.1.10",
|
||||
}...)
|
||||
|
||||
} else if v1_8(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause-amd64:3.0"
|
||||
images = append(images, []string{
|
||||
"k8s.gcr.io/pause-amd64:3.0",
|
||||
"k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.5",
|
||||
"k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.5",
|
||||
"k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.5",
|
||||
"k8s.gcr.io/etcd-amd64:3.0.17",
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.5",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.5",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.5",
|
||||
imageRepository + "etcd-amd64:3.0.17",
|
||||
}...)
|
||||
|
||||
} else {
|
||||
podInfraContainerImage = imageRepository + "/pause-amd64:3.0"
|
||||
}
|
||||
|
||||
images = append(images, []string{
|
||||
"k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1",
|
||||
"k8s.gcr.io/kube-addon-manager:v8.6",
|
||||
"gcr.io/k8s-minikube/storage-provisioner:v1.8.1",
|
||||
imageRepository + "kubernetes-dashboard-amd64:v1.10.1",
|
||||
imageRepository + "kube-addon-manager:v8.6",
|
||||
minikubeRepository + "storage-provisioner:v1.8.1",
|
||||
}...)
|
||||
|
||||
return images
|
||||
return podInfraContainerImage, images
|
||||
}
|
||||
|
||||
var ImageCacheDir = MakeMiniPath("cache", "images")
|
||||
|
|
|
@ -48,8 +48,8 @@ var getWindowsVolumeName = getWindowsVolumeNameCmd
|
|||
// loadImageLock is used to serialize image loads to avoid overloading the guest VM
|
||||
var loadImageLock sync.Mutex
|
||||
|
||||
func CacheImagesForBootstrapper(version string, clusterBootstrapper string) error {
|
||||
images := bootstrapper.GetCachedImageList(version, clusterBootstrapper)
|
||||
func CacheImagesForBootstrapper(imageRepository string, version string, clusterBootstrapper string) error {
|
||||
images := bootstrapper.GetCachedImageList(imageRepository, version, clusterBootstrapper)
|
||||
|
||||
if err := CacheImages(images, constants.ImageCacheDir); err != nil {
|
||||
return errors.Wrapf(err, "Caching images for %s", clusterBootstrapper)
|
||||
|
|
Loading…
Reference in New Issue