2018-07-10 19:21:27 +00:00
|
|
|
package dind
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/container"
|
|
|
|
"github.com/docker/docker/client"
|
|
|
|
"github.com/rancher/rke/docker"
|
2019-01-22 00:46:08 +00:00
|
|
|
"github.com/rancher/rke/util"
|
2018-07-10 19:21:27 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2020-07-07 14:33:34 +00:00
|
|
|
DINDImage = "docker:19.03.12-dind"
|
2018-08-14 22:04:56 +00:00
|
|
|
DINDContainerPrefix = "rke-dind"
|
2018-07-10 19:21:27 +00:00
|
|
|
DINDPlane = "dind"
|
|
|
|
DINDNetwork = "dind-network"
|
|
|
|
DINDSubnet = "172.18.0.0/16"
|
|
|
|
)
|
|
|
|
|
2019-01-22 00:46:08 +00:00
|
|
|
func StartUpDindContainer(ctx context.Context, dindAddress, dindNetwork, dindStorageDriver, dindDNS string) (string, error) {
|
2018-07-10 19:21:27 +00:00
|
|
|
cli, err := client.NewEnvClient()
|
|
|
|
if err != nil {
|
2018-08-14 22:04:56 +00:00
|
|
|
return "", err
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
|
|
|
// its recommended to use host's storage driver
|
|
|
|
dockerInfo, err := cli.Info(ctx)
|
|
|
|
if err != nil {
|
2018-08-14 22:04:56 +00:00
|
|
|
return "", err
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
2018-09-10 23:17:45 +00:00
|
|
|
storageDriver := dindStorageDriver
|
|
|
|
if len(storageDriver) == 0 {
|
|
|
|
storageDriver = dockerInfo.Driver
|
|
|
|
}
|
|
|
|
|
2018-07-10 19:21:27 +00:00
|
|
|
// Get dind container name
|
2018-08-14 22:04:56 +00:00
|
|
|
containerName := fmt.Sprintf("%s-%s", DINDContainerPrefix, dindAddress)
|
2018-07-10 19:21:27 +00:00
|
|
|
_, err = cli.ContainerInspect(ctx, containerName)
|
|
|
|
if err != nil {
|
|
|
|
if !client.IsErrNotFound(err) {
|
2018-08-14 22:04:56 +00:00
|
|
|
return "", err
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
|
|
|
if err := docker.UseLocalOrPull(ctx, cli, cli.DaemonHost(), DINDImage, DINDPlane, nil); err != nil {
|
2018-08-14 22:04:56 +00:00
|
|
|
return "", err
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
|
|
|
binds := []string{
|
|
|
|
fmt.Sprintf("/var/lib/kubelet-%s:/var/lib/kubelet:shared", containerName),
|
2021-06-23 11:15:03 +00:00
|
|
|
"/etc/machine-id:/etc/machine-id:ro",
|
2019-01-22 00:46:08 +00:00
|
|
|
}
|
|
|
|
isLink, err := util.IsSymlink("/etc/resolv.conf")
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
if isLink {
|
|
|
|
logrus.Infof("[%s] symlinked [/etc/resolv.conf] file detected. Using [%s] as DNS server.", DINDPlane, dindDNS)
|
|
|
|
} else {
|
|
|
|
binds = append(binds, "/etc/resolv.conf:/etc/resolv.conf")
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
|
|
|
imageCfg := &container.Config{
|
|
|
|
Image: DINDImage,
|
|
|
|
Entrypoint: []string{
|
|
|
|
"sh",
|
|
|
|
"-c",
|
|
|
|
"mount --make-shared / && " +
|
2020-05-29 12:43:24 +00:00
|
|
|
"mount --make-shared /sys && " +
|
2018-07-10 19:21:27 +00:00
|
|
|
"mount --make-shared /var/lib/docker && " +
|
|
|
|
"dockerd-entrypoint.sh --storage-driver=" + storageDriver,
|
|
|
|
},
|
2018-08-14 22:04:56 +00:00
|
|
|
Hostname: dindAddress,
|
2020-07-07 14:33:34 +00:00
|
|
|
Env: []string{"DOCKER_TLS_CERTDIR="},
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
|
|
|
hostCfg := &container.HostConfig{
|
|
|
|
Privileged: true,
|
|
|
|
Binds: binds,
|
2019-01-22 00:46:08 +00:00
|
|
|
// this gets ignored if resolv.conf is bind mounted. So it's ok to have it anyway.
|
|
|
|
DNS: []string{dindDNS},
|
|
|
|
// Calico needs this
|
|
|
|
Sysctls: map[string]string{
|
|
|
|
"net.ipv4.conf.all.rp_filter": "1",
|
|
|
|
},
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
2021-04-29 21:07:38 +00:00
|
|
|
resp, err := cli.ContainerCreate(ctx, imageCfg, hostCfg, nil, nil, containerName)
|
2018-07-10 19:21:27 +00:00
|
|
|
if err != nil {
|
2018-08-14 22:04:56 +00:00
|
|
|
return "", fmt.Errorf("Failed to create [%s] container on host [%s]: %v", containerName, cli.DaemonHost(), err)
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
|
2018-08-14 22:04:56 +00:00
|
|
|
return "", fmt.Errorf("Failed to start [%s] container on host [%s]: %v", containerName, cli.DaemonHost(), err)
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
|
|
|
logrus.Infof("[%s] Successfully started [%s] container on host [%s]", DINDPlane, containerName, cli.DaemonHost())
|
2018-08-14 22:04:56 +00:00
|
|
|
dindContainer, err := cli.ContainerInspect(ctx, containerName)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("Failed to get the address of container [%s] on host [%s]: %v", containerName, cli.DaemonHost(), err)
|
|
|
|
}
|
|
|
|
dindIPAddress := dindContainer.NetworkSettings.IPAddress
|
|
|
|
|
|
|
|
return dindIPAddress, nil
|
|
|
|
}
|
|
|
|
dindContainer, err := cli.ContainerInspect(ctx, containerName)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("Failed to get the address of container [%s] on host [%s]: %v", containerName, cli.DaemonHost(), err)
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
2018-08-14 22:04:56 +00:00
|
|
|
dindIPAddress := dindContainer.NetworkSettings.IPAddress
|
2018-07-10 19:21:27 +00:00
|
|
|
logrus.Infof("[%s] container [%s] is already running on host[%s]", DINDPlane, containerName, cli.DaemonHost())
|
2018-08-14 22:04:56 +00:00
|
|
|
return dindIPAddress, nil
|
2018-07-10 19:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func RmoveDindContainer(ctx context.Context, dindAddress string) error {
|
|
|
|
cli, err := client.NewEnvClient()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-08-14 22:04:56 +00:00
|
|
|
containerName := fmt.Sprintf("%s-%s", DINDContainerPrefix, dindAddress)
|
2018-07-10 19:21:27 +00:00
|
|
|
logrus.Infof("[%s] Removing dind container [%s] on host [%s]", DINDPlane, containerName, cli.DaemonHost())
|
|
|
|
_, err = cli.ContainerInspect(ctx, containerName)
|
|
|
|
if err != nil {
|
|
|
|
if !client.IsErrNotFound(err) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err := cli.ContainerRemove(ctx, containerName, types.ContainerRemoveOptions{
|
|
|
|
Force: true,
|
|
|
|
RemoveVolumes: true}); err != nil {
|
2020-07-15 08:53:05 +00:00
|
|
|
if client.IsErrNotFound(err) {
|
|
|
|
logrus.Debugf("[remove/%s] Container doesn't exist on host [%s]", containerName, cli.DaemonHost())
|
|
|
|
return nil
|
|
|
|
}
|
2018-07-10 19:21:27 +00:00
|
|
|
return fmt.Errorf("Failed to remove dind container [%s] on host [%s]: %v", containerName, cli.DaemonHost(), err)
|
|
|
|
}
|
|
|
|
logrus.Infof("[%s] Successfully Removed dind container [%s] on host [%s]", DINDPlane, containerName, cli.DaemonHost())
|
|
|
|
return nil
|
|
|
|
}
|