diff --git a/cluster/plan.go b/cluster/plan.go index 9ba8176a..de352bbc 100644 --- a/cluster/plan.go +++ b/cluster/plan.go @@ -8,6 +8,7 @@ import ( b64 "encoding/base64" + "github.com/rancher/rke/docker" "github.com/rancher/rke/hosts" "github.com/rancher/rke/k8s" "github.com/rancher/rke/pki" @@ -153,16 +154,19 @@ func (c *Cluster) BuildKubeAPIProcess() v3.Process { healthCheck := v3.HealthCheck{ URL: services.GetHealthCheckURL(true, services.KubeAPIPort), } + registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.Services.KubeAPI.Image, c.PrivateRegistriesMap) + return v3.Process{ - Name: services.KubeAPIContainerName, - Command: Command, - Args: args, - VolumesFrom: VolumesFrom, - Binds: Binds, - NetworkMode: "host", - RestartPolicy: "always", - Image: c.Services.KubeAPI.Image, - HealthCheck: healthCheck, + Name: services.KubeAPIContainerName, + Command: Command, + Args: args, + VolumesFrom: VolumesFrom, + Binds: Binds, + NetworkMode: "host", + RestartPolicy: "always", + Image: c.Services.KubeAPI.Image, + HealthCheck: healthCheck, + ImageRegistryAuthConfig: registryAuthConfig, } } @@ -219,16 +223,19 @@ func (c *Cluster) BuildKubeControllerProcess() v3.Process { healthCheck := v3.HealthCheck{ URL: services.GetHealthCheckURL(false, services.KubeControllerPort), } + + registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.Services.KubeController.Image, c.PrivateRegistriesMap) return v3.Process{ - Name: services.KubeControllerContainerName, - Command: Command, - Args: args, - VolumesFrom: VolumesFrom, - Binds: Binds, - NetworkMode: "host", - RestartPolicy: "always", - Image: c.Services.KubeController.Image, - HealthCheck: healthCheck, + Name: services.KubeControllerContainerName, + Command: Command, + Args: args, + VolumesFrom: VolumesFrom, + Binds: Binds, + NetworkMode: "host", + RestartPolicy: "always", + Image: c.Services.KubeController.Image, + HealthCheck: healthCheck, + ImageRegistryAuthConfig: registryAuthConfig, } } @@ -304,17 +311,20 @@ func (c *Cluster) BuildKubeletProcess(host *hosts.Host) v3.Process { healthCheck := v3.HealthCheck{ URL: services.GetHealthCheckURL(true, services.KubeletPort), } + registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.Services.Kubelet.Image, c.PrivateRegistriesMap) + return v3.Process{ - Name: services.KubeletContainerName, - Command: Command, - VolumesFrom: VolumesFrom, - Binds: Binds, - NetworkMode: "host", - RestartPolicy: "always", - Image: c.Services.Kubelet.Image, - PidMode: "host", - Privileged: true, - HealthCheck: healthCheck, + Name: services.KubeletContainerName, + Command: Command, + VolumesFrom: VolumesFrom, + Binds: Binds, + NetworkMode: "host", + RestartPolicy: "always", + Image: c.Services.Kubelet.Image, + PidMode: "host", + Privileged: true, + HealthCheck: healthCheck, + ImageRegistryAuthConfig: registryAuthConfig, } } @@ -353,6 +363,7 @@ func (c *Cluster) BuildKubeProxyProcess() v3.Process { healthCheck := v3.HealthCheck{ URL: services.GetHealthCheckURL(false, services.KubeproxyPort), } + registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.Services.Kubeproxy.Image, c.PrivateRegistriesMap) return v3.Process{ Name: services.KubeproxyContainerName, Command: Command, @@ -364,6 +375,7 @@ func (c *Cluster) BuildKubeProxyProcess() v3.Process { Privileged: true, HealthCheck: healthCheck, Image: c.Services.Kubeproxy.Image, + ImageRegistryAuthConfig: registryAuthConfig, } } @@ -377,6 +389,7 @@ func (c *Cluster) BuildProxyProcess() v3.Process { } Env := []string{fmt.Sprintf("%s=%s", services.NginxProxyEnvName, nginxProxyEnv)} + registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.SystemImages.NginxProxy, c.PrivateRegistriesMap) return v3.Process{ Name: services.NginxProxyContainerName, Env: Env, @@ -385,6 +398,7 @@ func (c *Cluster) BuildProxyProcess() v3.Process { RestartPolicy: "always", HealthCheck: v3.HealthCheck{}, Image: c.SystemImages.NginxProxy, + ImageRegistryAuthConfig: registryAuthConfig, } } @@ -424,24 +438,28 @@ func (c *Cluster) BuildSchedulerProcess() v3.Process { healthCheck := v3.HealthCheck{ URL: services.GetHealthCheckURL(false, services.SchedulerPort), } + registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.Services.Scheduler.Image, c.PrivateRegistriesMap) return v3.Process{ - Name: services.SchedulerContainerName, - Command: Command, - Binds: Binds, - VolumesFrom: VolumesFrom, - NetworkMode: "host", - RestartPolicy: "always", - Image: c.Services.Scheduler.Image, - HealthCheck: healthCheck, + Name: services.SchedulerContainerName, + Command: Command, + Binds: Binds, + VolumesFrom: VolumesFrom, + NetworkMode: "host", + RestartPolicy: "always", + Image: c.Services.Scheduler.Image, + HealthCheck: healthCheck, + ImageRegistryAuthConfig: registryAuthConfig, } } func (c *Cluster) BuildSidecarProcess() v3.Process { + registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.SystemImages.KubernetesServicesSidecar, c.PrivateRegistriesMap) return v3.Process{ - Name: services.SidekickContainerName, - NetworkMode: "none", - Image: c.SystemImages.KubernetesServicesSidecar, - HealthCheck: v3.HealthCheck{}, + Name: services.SidekickContainerName, + NetworkMode: "none", + Image: c.SystemImages.KubernetesServicesSidecar, + HealthCheck: v3.HealthCheck{}, + ImageRegistryAuthConfig: registryAuthConfig, } } @@ -503,14 +521,17 @@ func (c *Cluster) BuildEtcdProcess(host *hosts.Host, etcdHosts []*hosts.Host) v3 healthCheck := v3.HealthCheck{ URL: services.EtcdHealthCheckURL, } + registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.Services.Etcd.Image, c.PrivateRegistriesMap) + return v3.Process{ - Name: services.EtcdContainerName, - Args: args, - Binds: Binds, - NetworkMode: "host", - RestartPolicy: "always", - Image: c.Services.Etcd.Image, - HealthCheck: healthCheck, + Name: services.EtcdContainerName, + Args: args, + Binds: Binds, + NetworkMode: "host", + RestartPolicy: "always", + Image: c.Services.Etcd.Image, + HealthCheck: healthCheck, + ImageRegistryAuthConfig: registryAuthConfig, } } diff --git a/docker/docker.go b/docker/docker.go index a327c695..f7f5459c 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -159,31 +159,16 @@ func localImageExists(ctx context.Context, dClient *client.Client, hostname stri } func pullImage(ctx context.Context, dClient *client.Client, hostname string, containerImage string, prsMap map[string]v3.PrivateRegistry) error { - pullOptions := types.ImagePullOptions{} - containerNamed, err := ref.ParseNormalizedNamed(containerImage) + + regAuth, prURL, err := GetImageRegistryConfig(containerImage, prsMap) if err != nil { return err } - - regURL := ref.Domain(containerNamed) - if pr, ok := prsMap[regURL]; ok { - // We do this if we have some docker.io login information - regAuth, err := getRegistryAuth(pr) - if err != nil { - return err - } - if pr.URL == DockerRegistryURL { - pullOptions.RegistryAuth = regAuth - } else { - // We have a registry, but it's not docker.io - // this could be public or private, ImagePull() can handle it - // if we provide a PrivilegeFunc - - pullOptions.PrivilegeFunc = tryRegistryAuth(pr) - pullOptions.RegistryAuth = regAuth - } + if regAuth != "" && prURL == DockerRegistryURL { + pullOptions.PrivilegeFunc = tryRegistryAuth(prsMap[prURL]) } + pullOptions.RegistryAuth = regAuth out, err := dClient.ImagePull(ctx, containerImage, pullOptions) if err != nil { @@ -360,3 +345,17 @@ func getRegistryAuth(pr v3.PrivateRegistry) (string, error) { } return base64.URLEncoding.EncodeToString(encodedJSON), nil } + +func GetImageRegistryConfig(image string, prsMap map[string]v3.PrivateRegistry) (string, string, error) { + namedImage, err := ref.ParseNormalizedNamed(image) + if err != nil { + return "", "", err + } + regURL := ref.Domain(namedImage) + if pr, ok := prsMap[regURL]; ok { + // We do this if we have some docker.io login information + regAuth, err := getRegistryAuth(pr) + return regAuth, pr.URL, err + } + return "", "", nil +}