Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Support remote podman #2235

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pkg/build/nodeimage/const_cni.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ spec:
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: kindnet
containers:
- name: kindnet-cni
Expand Down
10 changes: 7 additions & 3 deletions pkg/cluster/internal/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type ClusterOptions struct {
// Cluster creates a cluster
func Cluster(logger log.Logger, p providers.Provider, opts *ClusterOptions) error {
// validate provider first
if err := validateProvider(p); err != nil {
if err := validateProvider(p, logger); err != nil {
return err
}

Expand Down Expand Up @@ -240,7 +240,7 @@ func fixupOptions(opts *ClusterOptions) error {
return nil
}

func validateProvider(p providers.Provider) error {
func validateProvider(p providers.Provider, logger log.Logger) error {
info, err := p.Info()
if err != nil {
return err
Expand All @@ -249,7 +249,11 @@ func validateProvider(p providers.Provider) error {
if !info.Cgroup2 {
return errors.New("running kind with rootless provider requires cgroup v2, see https://kind.sigs.k8s.io/docs/user/rootless/")
}
if !info.SupportsMemoryLimit || !info.SupportsPidsLimit || !info.SupportsCPUShares {
if !*info.SupportsMemoryLimit || !*info.SupportsPidsLimit || !*info.SupportsCPUShares {
logger.Warnf("support for memory and pids limit and CPU share unknown")
logger.Warnf("running kind with rootless provider requires setting systemd property \"Delegate=yes\", see https://kind.sigs.k8s.io/docs/user/rootless/")
}
if info.SupportsMemoryLimit == nil || info.SupportsPidsLimit == nil || info.SupportsCPUShares == nil {
return errors.New("running kind with rootless provider requires setting systemd property \"Delegate=yes\", see https://kind.sigs.k8s.io/docs/user/rootless/")
}
}
Expand Down
11 changes: 8 additions & 3 deletions pkg/cluster/internal/providers/docker/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,14 @@ func info() (*providers.ProviderInfo, error) {
// values are meaningless and need to be considered false.
// https://github.com/moby/moby/issues/42151
if dInfo.CgroupDriver != "none" {
info.SupportsMemoryLimit = dInfo.MemoryLimit
info.SupportsPidsLimit = dInfo.PidsLimit
info.SupportsCPUShares = dInfo.CPUShares
info.SupportsMemoryLimit = &dInfo.MemoryLimit
info.SupportsPidsLimit = &dInfo.PidsLimit
info.SupportsCPUShares = &dInfo.CPUShares
} else {
False := false
info.SupportsMemoryLimit = &False
info.SupportsPidsLimit = &False
info.SupportsCPUShares = &False
}
for _, o := range dInfo.SecurityOptions {
// o is like "name=seccomp,profile=default", or "name=rootless",
Expand Down
76 changes: 38 additions & 38 deletions pkg/cluster/internal/providers/podman/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package podman
import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
Expand Down Expand Up @@ -358,45 +357,46 @@ func (p *provider) CollectLogs(dir string, nodes []nodes.Node) error {
// Info returns the provider info.
// The info is cached on the first time of the execution.
func (p *provider) Info() (*providers.ProviderInfo, error) {
var err error
if p.info == nil {
p.info = info(p.logger)
p.info, err = info(p.logger)
}
return p.info, nil
return p.info, err
}

func info(logger log.Logger) *providers.ProviderInfo {
euid := os.Geteuid()
info := &providers.ProviderInfo{
Rootless: euid != 0,
}
if _, err := os.Stat("/sys/fs/cgroup/cgroup.controllers"); err == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and .... do we stop handling the local podman case?

Copy link
Contributor

@aojea aojea May 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe, we just need to skip this check if we can detect is a remote podman

if !podman_remote() && _, err := os.Stat("/sys/fs/cgroup/cgroup.controllers"); err == nil {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me summon the expert,
@vrothberg can I know from the podman cli if is running remote or local?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet but I opened containers/podman#10289. @baude, do you know a workaround?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@afrittoli can we try with this approach?
containers/podman#10289 (comment)
something like

// podman_remote returns true if podman is using a remote client
// xref: https://github.com/containers/podman/issues/10289
func podman_remote() bool{
  ... check https://github.com/containers/podman/issues/10289#issuecomment-838302394 ...
}

info.Cgroup2 = true
// Unlike `docker info`, `podman info` does not print available cgroup controllers.
// So we parse "cgroup.subtree_control" file by ourselves.
subtreeControl := "/sys/fs/cgroup/cgroup.subtree_control"
if info.Rootless {
// Change subtreeControl to the path of the systemd user-instance.
// Non-systemd hosts are not supported.
subtreeControl = fmt.Sprintf("/sys/fs/cgroup/user.slice/user-%d.slice/user@%d.service/cgroup.subtree_control", euid, euid)
}
if subtreeControlBytes, err := ioutil.ReadFile(subtreeControl); err != nil {
logger.Warnf("failed to read %q: %+v", subtreeControl, err)
} else {
for _, controllerName := range strings.Fields(string(subtreeControlBytes)) {
switch controllerName {
case "cpu":
info.SupportsCPUShares = true
case "memory":
info.SupportsMemoryLimit = true
case "pids":
info.SupportsPidsLimit = true
}
}
}
} else if !info.Rootless {
info.SupportsCPUShares = true
info.SupportsMemoryLimit = true
info.SupportsPidsLimit = true
}
return info
type podmanInfo struct{
Host struct {
CGroupManager string `json:"cgroupManager"`
CGroupVersion string `json:"cgroupVersion"`
} `json:"host"`
Security struct {
Rootless bool `json:"rootless"`
} `json:"security"`
}

func info(logger log.Logger) (*providers.ProviderInfo, error) {
cmd := exec.Command("podman", "info", "--format", "{{json .}}")
out, err := exec.Output(cmd)
if err != nil {
return nil, errors.Wrap(err, "failed to get podman info")
}
var pInfo podmanInfo
if err := json.Unmarshal(out, &pInfo); err != nil {
return nil, err
}
info := providers.ProviderInfo{
Cgroup2: pInfo.Host.CGroupVersion == "v2",
}
info.Rootless = pInfo.Security.Rootless
// When CgroupManager == "none", the MemoryLimit/PidsLimit/CPUShares
// values are meaningless and need to be considered false.
// https://github.com/moby/moby/issues/42151
// When CGroupManager is set, we leave the default "nil" which we use as "unknown"
if pInfo.Host.CGroupManager == "none" {
False := false
info.SupportsMemoryLimit = &False
info.SupportsPidsLimit = &False
info.SupportsCPUShares = &False
}
return &info, nil
}
7 changes: 4 additions & 3 deletions pkg/cluster/internal/providers/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ type Provider interface {
type ProviderInfo struct {
Rootless bool
Cgroup2 bool
SupportsMemoryLimit bool
SupportsPidsLimit bool
SupportsCPUShares bool
// true if supported, false if not supported, nil if unknown
SupportsMemoryLimit *bool
SupportsPidsLimit *bool
SupportsCPUShares *bool
}
2 changes: 1 addition & 1 deletion pkg/internal/apis/config/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
// and suffix this name, we can relax it a little
// see NewContext() for usage
// https://godoc.org/github.com/docker/docker/daemon/names#pkg-constants
var validNameRE = regexp.MustCompile(`^[a-z0-9_.-]+$`)
var validNameRE = regexp.MustCompile(`^[a-z0-9.-]+$`)

// Validate returns a ConfigErrors with an entry for each problem
// with the config, or nil if there are none
Expand Down