mirror of
https://github.com/rancher/rke.git
synced 2025-05-05 06:47:06 +00:00
147 lines
4.4 KiB
Go
147 lines
4.4 KiB
Go
|
package dind
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/docker/docker/api/types"
|
||
|
"github.com/docker/docker/api/types/container"
|
||
|
"github.com/docker/docker/api/types/network"
|
||
|
"github.com/docker/docker/client"
|
||
|
"github.com/rancher/rke/docker"
|
||
|
"github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
DINDImage = "docker:17.03-dind"
|
||
|
DINDContainerPrefix = "rke-dind-"
|
||
|
DINDPlane = "dind"
|
||
|
DINDNetwork = "dind-network"
|
||
|
DINDSubnet = "172.18.0.0/16"
|
||
|
)
|
||
|
|
||
|
func StartUpDindContainer(ctx context.Context, dindAddress, dindNetwork string) error {
|
||
|
cli, err := client.NewEnvClient()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
// its recommended to use host's storage driver
|
||
|
dockerInfo, err := cli.Info(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
storageDriver := dockerInfo.Driver
|
||
|
// Get dind container name
|
||
|
containerName := DINDContainerPrefix + dindAddress
|
||
|
_, err = cli.ContainerInspect(ctx, containerName)
|
||
|
if err != nil {
|
||
|
if !client.IsErrNotFound(err) {
|
||
|
return err
|
||
|
}
|
||
|
if err := docker.UseLocalOrPull(ctx, cli, cli.DaemonHost(), DINDImage, DINDPlane, nil); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
binds := []string{
|
||
|
fmt.Sprintf("/var/lib/kubelet-%s:/var/lib/kubelet:shared", containerName),
|
||
|
"/etc/resolv.conf:/etc/resolv.conf",
|
||
|
}
|
||
|
imageCfg := &container.Config{
|
||
|
Image: DINDImage,
|
||
|
Entrypoint: []string{
|
||
|
"sh",
|
||
|
"-c",
|
||
|
"mount --make-shared / && " +
|
||
|
"mount --make-shared /var/lib/docker && " +
|
||
|
"dockerd-entrypoint.sh --storage-driver=" + storageDriver,
|
||
|
},
|
||
|
}
|
||
|
hostCfg := &container.HostConfig{
|
||
|
Privileged: true,
|
||
|
Binds: binds,
|
||
|
}
|
||
|
netCfg := &network.NetworkingConfig{
|
||
|
EndpointsConfig: map[string]*network.EndpointSettings{
|
||
|
dindNetwork: &network.EndpointSettings{
|
||
|
IPAMConfig: &network.EndpointIPAMConfig{
|
||
|
IPv4Address: dindAddress,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
resp, err := cli.ContainerCreate(ctx, imageCfg, hostCfg, netCfg, containerName)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Failed to create [%s] container on host [%s]: %v", containerName, cli.DaemonHost(), err)
|
||
|
}
|
||
|
|
||
|
if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
|
||
|
return fmt.Errorf("Failed to start [%s] container on host [%s]: %v", containerName, cli.DaemonHost(), err)
|
||
|
}
|
||
|
logrus.Infof("[%s] Successfully started [%s] container on host [%s]", DINDPlane, containerName, cli.DaemonHost())
|
||
|
return nil
|
||
|
}
|
||
|
logrus.Infof("[%s] container [%s] is already running on host[%s]", DINDPlane, containerName, cli.DaemonHost())
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func RmoveDindContainer(ctx context.Context, dindAddress string) error {
|
||
|
cli, err := client.NewEnvClient()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
containerName := DINDContainerPrefix + dindAddress
|
||
|
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 {
|
||
|
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
|
||
|
}
|
||
|
|
||
|
func CreateDindNetwork(ctx context.Context, dindSubnet string) error {
|
||
|
cli, err := client.NewEnvClient()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
networkList, err := cli.NetworkList(ctx, types.NetworkListOptions{})
|
||
|
for _, net := range networkList {
|
||
|
if DINDNetwork == net.Name {
|
||
|
subnetFound := false
|
||
|
for _, netConfig := range net.IPAM.Config {
|
||
|
if netConfig.Subnet == dindSubnet {
|
||
|
subnetFound = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if !subnetFound {
|
||
|
return fmt.Errorf("dind network [%s] exist but has different subnet than specified", DINDNetwork)
|
||
|
}
|
||
|
logrus.Infof("[%s] dind network [%s] with subnet [%s] already created", DINDPlane, DINDNetwork, dindSubnet)
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
logrus.Infof("[%s] creating dind network [%s] with subnet [%s]", DINDPlane, DINDNetwork, dindSubnet)
|
||
|
_, err = cli.NetworkCreate(ctx, DINDNetwork, types.NetworkCreate{
|
||
|
Driver: "bridge",
|
||
|
IPAM: &network.IPAM{
|
||
|
Config: []network.IPAMConfig{
|
||
|
network.IPAMConfig{
|
||
|
Subnet: dindSubnet,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
logrus.Infof("[%s] Successfully Created dind network [%s] with subnet [%s]", DINDPlane, DINDNetwork, dindSubnet)
|
||
|
return nil
|
||
|
}
|