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_containers
pull/3714/head
Zhongcheng Lao 2019-02-18 01:00:12 +08:00
parent aad78ea071
commit 7cbe253ef6
13 changed files with 241 additions and 114 deletions

View File

@ -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(&registryMirror, "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,

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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"),
}

View File

@ -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
}

View File

@ -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{}
}

View File

@ -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) {

View File

@ -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

View File

@ -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]
`))

View File

@ -69,6 +69,7 @@ type KubernetesConfig struct {
NetworkPlugin string
FeatureGates string
ServiceCIDR string
ImageRepository string
ExtraOptions util.ExtraOptionSlice
ShouldLoadCachedImages bool

View File

@ -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")

View File

@ -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)