feat(init): create CNI mounts (#226)

This change requires explicit declaration of a CNI plugin.
This commit is contained in:
Andrew Rynhard 2018-11-22 06:00:10 -08:00 committed by GitHub
parent 9c77b490e0
commit aa08f15659
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 33 deletions

View File

@ -23,6 +23,12 @@ const (
// PATH defines all locations where executables are stored.
PATH = "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/opt/cni/bin"
// CNICalico is used to specify Calico CNI.
CNICalico = "calico"
// CNIFlannel is used to specify Flannel CNI.
CNIFlannel = "flannel"
// ContainerdSocket is the path to the containerd socket.
ContainerdSocket = "/run/containerd/containerd.sock"

View File

@ -0,0 +1,57 @@
package cni
import (
"os"
"path"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/constants"
"github.com/autonomy/talos/src/initramfs/pkg/userdata"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
// Setup prepares the root file system for the requested CNI plugin.
func Setup(s string, data *userdata.UserData) error {
paths := []string{"/var/etc/cni/net.d"}
switch data.Services.Init.CNI {
case constants.CNICalico:
paths = append(paths, "/run/calico", "/var/lib/calico", "/var/opt/cni/bin")
case constants.CNIFlannel:
paths = append(paths, "/run/flannel")
default:
return errors.Errorf("unknown CNI %s", data.Services.Init.CNI)
}
for _, p := range paths {
if err := os.MkdirAll(path.Join(s, p), os.ModeDir); err != nil {
return errors.Wrapf(err, "failed to create directory %s", path.Join(s, p))
}
}
return nil
}
// Mounts returns the set of mounts required by the requested CNI plugin. All
// paths are relative to the root file system after switching the root.
func Mounts(data *userdata.UserData) ([]specs.Mount, error) {
mounts := []specs.Mount{
{Type: "bind", Destination: "/etc/cni", Source: "/var/etc/cni", Options: []string{"rbind", "rshared", "rw"}},
}
switch data.Services.Init.CNI {
case constants.CNICalico:
calicoMounts := []specs.Mount{
{Type: "bind", Destination: "/var/lib/calico", Source: "/var/lib/calico", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/opt/cni", Source: "/var/opt/cni", Options: []string{"rbind", "rshared", "rw"}},
}
mounts = append(mounts, calicoMounts...)
case constants.CNIFlannel:
// Nothing to do.
default:
return nil, errors.Errorf("unknown CNI %s", data.Services.Init.CNI)
}
return mounts, nil
}

View File

@ -7,6 +7,7 @@ import (
"path"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/constants"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/rootfs/cni"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/rootfs/etc"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/rootfs/proc"
"github.com/autonomy/talos/src/initramfs/pkg/userdata"
@ -30,7 +31,7 @@ func ip() string {
}
// Prepare creates the files required by the installed binaries and libraries.
func Prepare(s string, userdata userdata.UserData) (err error) {
func Prepare(s string, data userdata.UserData) (err error) {
// Enable IP forwarding.
if err = proc.WriteSystemProperty(&proc.SystemProperty{Key: "net.ipv4.ip_forward", Value: "1"}); err != nil {
return
@ -56,12 +57,16 @@ func Prepare(s string, userdata userdata.UserData) (err error) {
if err = etc.OSRelease(s); err != nil {
return
}
// Setup directories required by the CNI plugin.
if err = cni.Setup(s, &data); err != nil {
return
}
// Save the user data to disk.
data, err := yaml.Marshal(&userdata)
dataBytes, err := yaml.Marshal(&data)
if err != nil {
return
}
if err = ioutil.WriteFile(path.Join(constants.NewRoot, constants.UserDataPath), data, 0400); err != nil {
if err = ioutil.WriteFile(path.Join(constants.NewRoot, constants.UserDataPath), dataBytes, 0400); err != nil {
return
}

View File

@ -6,6 +6,7 @@ import (
"os"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/constants"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/rootfs/cni"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/system/conditions"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/system/runner"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/system/runner/containerd"
@ -66,21 +67,12 @@ func (c *CRT) PreFunc(data *userdata.UserData) error {
if err := ioutil.WriteFile("/var/etc/crio/seccomp.json", []byte(seccompProfile), 0644); err != nil {
return fmt.Errorf("failed to write seccomp.json: %v", err)
}
if err := os.MkdirAll("/var/etc/cni/net.d", os.ModeDir); err != nil {
return fmt.Errorf("create /var/etc/cni/net.d: %s", err.Error())
}
if err := os.MkdirAll("/var/opt/cni/bin", os.ModeDir); err != nil {
return fmt.Errorf("create /var/opt/cni/bin: %s", err.Error())
}
if err := os.MkdirAll("/var/etc/kubernetes/manifests", os.ModeDir); err != nil {
return fmt.Errorf("create /var/etc/kubernetes/manifests: %s", err.Error())
}
if err := os.MkdirAll("/var/lib/kubelet", os.ModeDir); err != nil {
return fmt.Errorf("create /var/lib/kubelet: %s", err.Error())
}
if err := os.MkdirAll("/var/lib/calico", os.ModeDir); err != nil {
return fmt.Errorf("create /var/lib/calico: %s", err.Error())
}
if err := os.MkdirAll("/var/libexec/kubernetes", os.ModeDir); err != nil {
return fmt.Errorf("create /var/libexec/kubernetes: %s", err.Error())
}
@ -110,11 +102,8 @@ func (c *CRT) Start(data *userdata.UserData) error {
{Type: "cgroup", Destination: "/sys/fs/cgroup", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/dev", Source: "/dev", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/etc/kubernetes", Source: "/var/etc/kubernetes", Options: []string{"bind", "rw"}},
{Type: "bind", Destination: "/etc/cni", Source: "/var/etc/cni", Options: []string{"bind", "rw"}},
{Type: "bind", Destination: "/opt/cni", Source: "/var/opt/cni", Options: []string{"bind", "rw"}},
{Type: "bind", Destination: "/run", Source: "/run", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/var/lib/kubelet", Source: "/var/lib/kubelet", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/var/lib/calico", Source: "/var/lib/calico", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/usr/libexec/kubernetes", Source: "/var/libexec/kubernetes", Options: []string{"rbind", "rshared", "rw"}},
}
env = []string{}
@ -167,6 +156,12 @@ func (c *CRT) Start(data *userdata.UserData) error {
return fmt.Errorf("unknown container runtime %q", data.Services.Init.ContainerRuntime)
}
cniMounts, err := cni.Mounts(data)
if err != nil {
return err
}
mounts = append(mounts, cniMounts...)
if data.Services.CRT != nil && data.Services.CRT.Image != "" {
image = data.Services.CRT.Image
}

View File

@ -7,6 +7,7 @@ import (
"strings"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/constants"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/rootfs/cni"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/system/conditions"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/system/runner"
"github.com/autonomy/talos/src/initramfs/cmd/init/pkg/system/runner/containerd"
@ -26,27 +27,12 @@ func (k *Kubelet) ID(data *userdata.UserData) string {
// PreFunc implements the Service interface.
func (k *Kubelet) PreFunc(data *userdata.UserData) error {
if err := os.Mkdir("/run/flannel", os.ModeDir); err != nil {
return fmt.Errorf("create /run/flannel: %s", err.Error())
}
if err := os.Mkdir("/run/calico", os.ModeDir); err != nil {
return fmt.Errorf("create /run/calico: %s", err.Error())
}
if err := os.MkdirAll("/var/etc/cni/net.d", os.ModeDir); err != nil {
return fmt.Errorf("create /var/etc/cni/net.d: %s", err.Error())
}
if err := os.MkdirAll("/var/opt/cni/bin", os.ModeDir); err != nil {
return fmt.Errorf("create /var/opt/cni/bin: %s", err.Error())
}
if err := os.MkdirAll("/var/etc/kubernetes/manifests", os.ModeDir); err != nil {
return fmt.Errorf("create /var/etc/kubernetes/manifests: %s", err.Error())
}
if err := os.MkdirAll("/var/lib/kubelet", os.ModeDir); err != nil {
return fmt.Errorf("create /var/lib/kubelet: %s", err.Error())
}
if err := os.MkdirAll("/var/lib/calico", os.ModeDir); err != nil {
return fmt.Errorf("create /var/lib/calico: %s", err.Error())
}
if err := os.MkdirAll("/var/libexec/kubernetes", os.ModeDir); err != nil {
return fmt.Errorf("create /var/libexec/kubernetes: %s", err.Error())
}
@ -111,14 +97,17 @@ func (k *Kubelet) Start(data *userdata.UserData) error {
{Type: "bind", Destination: "/dev", Source: "/dev", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/var/run", Source: "/run", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/var/lib/kubelet", Source: "/var/lib/kubelet", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/var/lib/calico", Source: "/var/lib/calico", Options: []string{"rbind", "rshared", "rw"}},
{Type: "bind", Destination: "/etc/kubernetes", Source: "/var/etc/kubernetes", Options: []string{"bind", "rw"}},
{Type: "bind", Destination: "/etc/cni", Source: "/var/etc/cni", Options: []string{"rbind", "rshared", "ro"}},
{Type: "bind", Destination: "/opt/cni", Source: "/var/opt/cni", Options: []string{"rbind", "rshared", "ro"}},
{Type: "bind", Destination: "/etc/os-release", Source: "/etc/os-release", Options: []string{"bind", "ro"}},
{Type: "bind", Destination: "/usr/libexec/kubernetes", Source: "/var/libexec/kubernetes", Options: []string{"rbind", "rshared", "rw"}},
}
cniMounts, err := cni.Mounts(data)
if err != nil {
return err
}
mounts = append(mounts, cniMounts...)
switch data.Services.Init.ContainerRuntime {
case constants.ContainerRuntimeDocker:
mounts = append(mounts, specs.Mount{Type: "bind", Destination: "/var/lib/docker", Source: "/var/lib/docker", Options: []string{"rbind", "rshared", "rw"}})

View File

@ -79,6 +79,7 @@ type File struct {
// Init describes the configuration of the init service.
type Init struct {
ContainerRuntime string `yaml:"containerRuntime,omitempty"`
CNI string `yaml:"cni,omitempty"`
}
// Kubelet describes the configuration of the kubelet service.