diff --git a/cli/commands.go b/cli/commands.go
index b8e7344c..36314083 100644
--- a/cli/commands.go
+++ b/cli/commands.go
@@ -236,22 +236,23 @@ func CreateCluster(c *cli.Context) error {
* Defines, with which specifications, the cluster and the nodes inside should be created
*/
clusterSpec := &ClusterSpec{
- AgentArgs: k3AgentArgs,
- APIPort: *apiPort,
- AutoRestart: c.Bool("auto-restart"),
- ClusterName: c.String("name"),
- Env: env,
- NodeToLabelSpecMap: labelmap,
- Image: image,
- NodeToPortSpecMap: portmap,
- PortAutoOffset: c.Int("port-auto-offset"),
- RegistriesFile: registriesFile,
- RegistryEnabled: c.Bool("enable-registry"),
- RegistryName: c.String("registry-name"),
- RegistryPort: c.Int("registry-port"),
- RegistryVolume: c.String("registry-volume"),
- ServerArgs: k3sServerArgs,
- Volumes: volumesSpec,
+ AgentArgs: k3AgentArgs,
+ APIPort: *apiPort,
+ AutoRestart: c.Bool("auto-restart"),
+ ClusterName: c.String("name"),
+ Env: env,
+ NodeToLabelSpecMap: labelmap,
+ Image: image,
+ NodeToPortSpecMap: portmap,
+ PortAutoOffset: c.Int("port-auto-offset"),
+ RegistriesFile: registriesFile,
+ RegistryEnabled: c.Bool("enable-registry"),
+ RegistryCacheEnabled: c.Bool("enable-registry-cache"),
+ RegistryName: c.String("registry-name"),
+ RegistryPort: c.Int("registry-port"),
+ RegistryVolume: c.String("registry-volume"),
+ ServerArgs: k3sServerArgs,
+ Volumes: volumesSpec,
}
/******************
diff --git a/cli/registry.go b/cli/registry.go
index c6ac56db..efc96564 100644
--- a/cli/registry.go
+++ b/cli/registry.go
@@ -18,17 +18,23 @@ import (
"gopkg.in/yaml.v2"
)
-const defaultRegistryContainerName = "k3d-registry"
+const (
+ defaultRegistryContainerName = "k3d-registry"
-const defaultRegistryImage = "registry:2"
+ defaultRegistryImage = "registry:2"
-// Default registry port, both for the external and the internal ports
-// Note well, that the internal port is never changed.
-const defaultRegistryPort = 5000
+ // Default registry port, both for the external and the internal ports
+ // Note well, that the internal port is never changed.
+ defaultRegistryPort = 5000
-const defaultFullRegistriesPath = "/etc/rancher/k3s/registries.yaml"
+ defaultFullRegistriesPath = "/etc/rancher/k3s/registries.yaml"
-const defaultRegistryMountPath = "/var/lib/registry"
+ defaultRegistryMountPath = "/var/lib/registry"
+
+ defaultDockerHubAddress = "docker.io"
+
+ defaultDockerRegistryHubAddress = "registry-1.docker.io"
+)
// default labels assigned to the registry container
var defaultRegistryContainerLabels = map[string]string{
@@ -105,10 +111,17 @@ func writeRegistriesConfigInContainer(spec *ClusterSpec, ID string) error {
privRegistries.Mirrors = map[string]Mirror{}
}
- // the add the private registry
+ // then add the private registry
privRegistries.Mirrors[registryExternalAddress] = Mirror{
Endpoints: []string{fmt.Sprintf("http://%s", registryInternalAddress)},
}
+
+ // with the cache, redirect all the PULLs to the Docker Hub to the local registry
+ if spec.RegistryCacheEnabled {
+ privRegistries.Mirrors[defaultDockerHubAddress] = Mirror{
+ Endpoints: []string{fmt.Sprintf("http://%s", registryInternalAddress)},
+ }
+ }
}
d, err := yaml.Marshal(&privRegistries)
@@ -214,6 +227,15 @@ func createRegistry(spec ClusterSpec) (string, error) {
Labels: containerLabels,
}
+ // we can enable the cache in the Registry by just adding a new env variable
+ // (see https://docs.docker.com/registry/configuration/#override-specific-configuration-options)
+ if spec.RegistryCacheEnabled {
+ log.Printf("Activating pull-through cache to Docker Hub\n")
+ cacheConfigKey := "REGISTRY_PROXY_REMOTEURL"
+ cacheConfigValues := fmt.Sprintf("https://%s", defaultDockerRegistryHubAddress)
+ config.Env = []string{fmt.Sprintf("%s=%s", cacheConfigKey, cacheConfigValues)}
+ }
+
id, err := createContainer(config, hostConfig, networkingConfig, defaultRegistryContainerName)
if err != nil {
return "", fmt.Errorf(" Couldn't create registry container %s\n%w", defaultRegistryContainerName, err)
diff --git a/cli/types.go b/cli/types.go
index dac7e1c9..d3cb3c6e 100644
--- a/cli/types.go
+++ b/cli/types.go
@@ -35,22 +35,23 @@ type Cluster struct {
// ClusterSpec defines the specs for a cluster that's up for creation
type ClusterSpec struct {
- AgentArgs []string
- APIPort apiPort
- AutoRestart bool
- ClusterName string
- Env []string
- NodeToLabelSpecMap map[string][]string
- Image string
- NodeToPortSpecMap map[string][]string
- PortAutoOffset int
- RegistriesFile string
- RegistryEnabled bool
- RegistryName string
- RegistryPort int
- RegistryVolume string
- ServerArgs []string
- Volumes *Volumes
+ AgentArgs []string
+ APIPort apiPort
+ AutoRestart bool
+ ClusterName string
+ Env []string
+ NodeToLabelSpecMap map[string][]string
+ Image string
+ NodeToPortSpecMap map[string][]string
+ PortAutoOffset int
+ RegistriesFile string
+ RegistryEnabled bool
+ RegistryCacheEnabled bool
+ RegistryName string
+ RegistryPort int
+ RegistryVolume string
+ ServerArgs []string
+ Volumes *Volumes
}
// PublishedPorts is a struct used for exposing container ports on the host system
diff --git a/docs/registries.md b/docs/registries.md
index d6a1f957..e53a665b 100644
--- a/docs/registries.md
+++ b/docs/registries.md
@@ -129,6 +129,22 @@ The easiest solution for this is to add an entry in your `/etc/hosts` file like
Once again, this will only work with k3s >= v0.10.0 (see the [section below](#k3s-old)
when using k3s <= v0.9.1)
+### Local registry volume
+
+The local k3d registry uses a volume for storying the images. This volume will be destroyed
+when the k3d registry is released. In order to persist this volume and make these images survive
+the removal of the registry, you can specify a volume with the `--registry-volume` and use the
+`--keep-registry-volume` flag when deleting the cluster. This will create a volume with the given
+name the first time the registry is used, while successive invocations will just mount this
+existing volume in the k3d registry container.
+
+### Docker Hub cache
+
+The local k3d registry can also be used for caching images from the Docker Hub. You can start the
+registry as a pull-through cache when the cluster is created with `--enable-registry-cache`. Used
+in conjuction with `--registry-volume`/`--keep-registry-volume` can speed up all the downloads
+from the Hub by keeping a persistent cache of images in your local machine.
+
## Testing your registry
You should test that you can
diff --git a/main.go b/main.go
index a8c59f97..52ba0239 100644
--- a/main.go
+++ b/main.go
@@ -144,6 +144,10 @@ func main() {
Name: "registries-file",
Usage: "registries.yaml config file",
},
+ cli.BoolFlag{
+ Name: "enable-registry-cache",
+ Usage: "Use the local registry as a cache for the Docker Hub",
+ },
},
Action: run.CreateCluster,
},