Skip to content

Commit 70c396d

Browse files
feat: direct image build on containerd via docker-env
1 parent 9095247 commit 70c396d

File tree

5 files changed

+125
-8
lines changed

5 files changed

+125
-8
lines changed

Diff for: cmd/minikube/cmd/docker-env.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,16 @@ docker-cli install instructions: https://minikube.sigs.k8s.io/docs/tutorials/doc
287287
exit.Message(reason.EnvMultiConflict, `The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/`)
288288
}
289289

290-
if co.Config.KubernetesConfig.ContainerRuntime != constants.Docker {
291-
exit.Message(reason.Usage, `The docker-env command is only compatible with the "docker" runtime, but this cluster was configured to use the "{{.runtime}}" runtime.`,
290+
if co.Config.KubernetesConfig.ContainerRuntime != constants.Docker && co.Config.KubernetesConfig.ContainerRuntime != constants.Containerd {
291+
exit.Message(reason.Usage, `The docker-env command is only compatible with the "docker" runtime or "containerd" runtime, but this cluster was configured to use the "{{.runtime}}" runtime.`,
292292
out.V{"runtime": co.Config.KubernetesConfig.ContainerRuntime})
293293
}
294294

295295
r := co.CP.Runner
296-
ensureDockerd(cname, r)
296+
297+
if co.Config.KubernetesConfig.ContainerRuntime == constants.Docker {
298+
ensureDockerd(cname, r)
299+
}
297300

298301
d := co.CP.Host.Driver
299302
port := constants.DockerDaemonPort

Diff for: cmd/minikube/cmd/start.go

+65
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ import (
2626
"os"
2727
"os/exec"
2828
"os/user"
29+
"path/filepath"
2930
"regexp"
3031
"runtime"
3132
"sort"
3233
"strconv"
3334
"strings"
35+
"time"
3436

3537
"github.com/Delta456/box-cli-maker/v2"
3638
"github.com/blang/semver/v4"
@@ -440,6 +442,11 @@ func startWithDriver(cmd *cobra.Command, starter node.Starter, existing *config.
440442

441443
pause.RemovePausedFile(starter.Runner)
442444

445+
//for the sake of docker-env command, download and start nerdctl and nerdctld
446+
if starter.Cfg.KubernetesConfig.ContainerRuntime == constants.Containerd {
447+
startNerdctld()
448+
}
449+
443450
return kubeconfig, nil
444451
}
445452

@@ -1779,3 +1786,61 @@ func exitGuestProvision(err error) {
17791786
}
17801787
exit.Error(reason.GuestProvision, "error provisioning guest", err)
17811788
}
1789+
1790+
func startNerdctld() {
1791+
//create a temporary directory
1792+
tmpDirName := "/tmp/minikube-nerdctld"
1793+
if err := os.Mkdir(tmpDirName, os.ModePerm); err != nil && !os.IsExist(err) {
1794+
exit.Error(reason.IfSSHClient, "Error with creating "+tmpDirName, err)
1795+
}
1796+
1797+
// for containerd runtime using ssh, we need to install nerdctld and nerdctl within os
1798+
if err := download.DownloadNerdctl(tmpDirName); err != nil {
1799+
exit.Error(reason.IfSSHClient, "Error with downloading nerdctl", err)
1800+
}
1801+
if err := download.DownloadNerdctld(tmpDirName); err != nil {
1802+
exit.Error(reason.IfSSHClient, "Error with downloading nerdctld", err)
1803+
}
1804+
1805+
//copy these binaries to the path of the containerd node
1806+
co := mustload.Running(ClusterFlagValue())
1807+
runner := co.CP.Runner
1808+
src := newRemotePath(filepath.Join(tmpDirName, "nerdctl"))
1809+
dst := newRemotePath("/usr/local/bin/nerdctl")
1810+
if err := runner.Copy(copyableFile(&co, src, dst)); err != nil {
1811+
exit.Error(reason.InternalCommandRunner, "Fail to copy file nerctl", err)
1812+
}
1813+
1814+
src = newRemotePath(filepath.Join(tmpDirName, "nerdctld"))
1815+
dst = newRemotePath("/usr/local/bin/nerdctld")
1816+
if err := runner.Copy(copyableFile(&co, src, dst)); err != nil {
1817+
exit.Error(reason.InternalCommandRunner, "Fail to copy file nerctld", err)
1818+
}
1819+
1820+
//and set 777 to these files
1821+
if out, err := runner.RunCmd(exec.Command("sudo", "chmod", "777", "/usr/local/bin/nerdctl", "/usr/local/bin/nerdctld")); err != nil {
1822+
exit.Error(reason.InternalCommandRunner, fmt.Sprintf("Fail to giver nerdctl proper permission: %s", out.Output()), err)
1823+
}
1824+
1825+
//start nerdctld
1826+
nerdctldDaemonCommand := exec.Command("/bin/bash", "-c", "sudo env CONTAINERD_NAMESPACE=k8s.io nohup nerdctld --socket=/var/run/nerdctld.sock >/dev/null 2>&1 &")
1827+
if out, err := runner.RunCmd(nerdctldDaemonCommand); err != nil {
1828+
exit.Error(reason.InternalCommandRunner, fmt.Sprintf("Fail to start nerdctld: %s", out.Output()), err)
1829+
}
1830+
1831+
//set up environment variable on remote machine. docker client uses 'non-login & non-interactive shell' therefore the only way is to modify .bashrc file of user 'docker'
1832+
// insert this at 4th line
1833+
envSetupCommand := exec.Command("/bin/bash", "-c", "sed -i '4i export DOCKER_HOST=unix:///var/run/nerdctld.sock' .bashrc")
1834+
if out, err := runner.RunCmd(envSetupCommand); err != nil {
1835+
exit.Error(reason.InternalCommandRunner, fmt.Sprintf("Fail to set up DOCKER_HOST: %s", out.Output()), err)
1836+
}
1837+
1838+
//need to wait for nerdctld to be started
1839+
time.Sleep(1 * time.Second)
1840+
1841+
//grant this socket proper permission. Docker daemon will automatically do that, but nerdctld won't
1842+
//user docker belongs to group "docker", while nerdctld.d doesn't , therefore nerdctld.sock needs to be visible outside the group
1843+
if out, err := runner.RunCmd(exec.Command("sudo", "chmod", "666", "/var/run/nerdctld.sock")); err != nil {
1844+
exit.Error(reason.InternalCommandRunner, fmt.Sprintf("Fail to grant permission to docker.sock: %s", out.Output()), err)
1845+
}
1846+
}

Diff for: pkg/minikube/download/docker_env.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package download
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"path/filepath"
8+
)
9+
10+
// DownloadNerdctl downloads nerdctl to directory specified by the param
11+
func DownloadNerdctl(dir string) error {
12+
//check whether nerdctl exists
13+
if _, err := os.Stat(filepath.Join(dir, "nerdctl")); err == nil {
14+
//file exists
15+
return nil
16+
}
17+
fileName := filepath.Join(dir, "nerdctl-1.0.0-linux-amd64.tar.gz")
18+
if err := download("https://github.com/containerd/nerdctl/releases/download/v1.0.0/nerdctl-1.0.0-linux-amd64.tar.gz", fileName); err != nil {
19+
return err
20+
}
21+
if err := exec.Command("tar", "-xvzf", fileName, "-C", dir).Run(); err != nil {
22+
return fmt.Errorf("failed to untar nerdctl: %v", err)
23+
}
24+
return nil
25+
}
26+
27+
// DownloadNerdctld downloads nerdctld to directory specified by the param
28+
func DownloadNerdctld(dir string) error {
29+
//check whether nerdctld exists
30+
if _, err := os.Stat(filepath.Join(dir, "nerdctld")); err == nil {
31+
//file exists
32+
return nil
33+
}
34+
fileName := filepath.Join(dir, "nerdctld-0.2.0-linux-amd64.tar.gz")
35+
if err := download("https://github.com/afbjorklund/nerdctld/releases/download/v0.2.0/nerdctld-0.2.0-linux-amd64.tar.gz", fileName); err != nil {
36+
return err
37+
}
38+
if err := exec.Command("tar", "-xvzf", fileName, "-C", dir).Run(); err != nil {
39+
return fmt.Errorf("failed to untar nerdctd: %v", err)
40+
}
41+
return nil
42+
}

Diff for: pkg/minikube/download/download.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ func download(src string, dst string) error {
7272
}
7373
tmpDst := dst + ".download"
7474
client := &getter.Client{
75-
Src: src,
76-
Dst: tmpDst,
77-
Dir: false,
78-
Mode: getter.ClientModeFile,
79-
Options: clientOptions,
75+
Src: src,
76+
Dst: tmpDst,
77+
Dir: false,
78+
Mode: getter.ClientModeFile,
79+
Options: clientOptions,
80+
Decompressors: map[string]getter.Decompressor{},
8081
Getters: map[string]getter.Getter{
8182
"file": &getter.FileGetter{Copy: false},
8283
"http": &getter.HttpGetter{Netrc: false},

Diff for: test.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
aaaaaaaaaaaaaaaaaaa
2+
123qaz
3+
bbbbbbbbbbbbbbbbbbbb
4+
ccccccccccccccccccc
5+
ddddddddddddddddd
6+
eeeeeeeeeeeeeeeeeee

0 commit comments

Comments
 (0)