Skip to content

Commit

Permalink
initial support for sandboxed containers (e.g., gvisor)
Browse files Browse the repository at this point in the history
  • Loading branch information
def committed Mar 9, 2023
1 parent 4ea21f6 commit 32c6ad2
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 20 deletions.
3 changes: 2 additions & 1 deletion cgroup/cgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const (
ContainerTypeContainerd
ContainerTypeLxc
ContainerTypeSystemdService
ContainerTypeSandbox
)

func (t ContainerType) String() string {
Expand Down Expand Up @@ -144,7 +145,7 @@ func containerByCgroup(path string) (ContainerType, string, error) {
}
matches := dockerIdRegexp.FindStringSubmatch(path)
if matches == nil {
return ContainerTypeUnknown, "", fmt.Errorf("invalid docker cgroup %s", path)
return ContainerTypeSandbox, "", nil
}
return ContainerTypeDocker, matches[1], nil
}
Expand Down
37 changes: 29 additions & 8 deletions containers/registry.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package containers

import (
"bytes"
"fmt"
"github.com/coroot/coroot-node-agent/cgroup"
"github.com/coroot/coroot-node-agent/common"
Expand All @@ -11,13 +12,15 @@ import (
"github.com/vishvananda/netns"
"k8s.io/klog/v2"
"os"
"regexp"
"time"
)

var (
selfNetNs = netns.None()
hostNetNsId = netns.None().UniqueId()
agentPid = uint32(os.Getpid())
selfNetNs = netns.None()
hostNetNsId = netns.None().UniqueId()
agentPid = uint32(os.Getpid())
containerIdRegexp = regexp.MustCompile(`[a-z0-9]{64}`)
)

type Registry struct {
Expand Down Expand Up @@ -239,6 +242,16 @@ func (r *Registry) getOrCreateContainer(pid uint32) *Container {
r.containersByPid[pid] = c
return c
}
if cg.ContainerType == cgroup.ContainerTypeSandbox {
cmdline := proc.GetCmdline(pid)
parts := bytes.Split(cmdline, []byte{0})
if len(parts) > 0 {
lastArg := parts[len(parts)-1]
if bytes.HasSuffix(parts[0], []byte("runsc-sandbox")) && containerIdRegexp.Match(lastArg) {
cg.ContainerId = string(lastArg)
}
}
}
md, err := getContainerMetadata(cg)
if err != nil {
klog.Warningf("failed to get container metadata for pid %d -> %s: %s", pid, cg.Id, err)
Expand Down Expand Up @@ -291,14 +304,19 @@ func calcId(cg *cgroup.Cgroup, md *ContainerMetadata) ContainerID {
if cg.ContainerType == cgroup.ContainerTypeSystemdService {
return ContainerID(cg.ContainerId)
}
if cg.ContainerType != cgroup.ContainerTypeDocker && cg.ContainerType != cgroup.ContainerTypeContainerd {
switch cg.ContainerType {
case cgroup.ContainerTypeDocker, cgroup.ContainerTypeContainerd, cgroup.ContainerTypeSandbox:
default:
return ""
}
if md.labels["io.kubernetes.pod.name"] != "" {
pod := md.labels["io.kubernetes.pod.name"]
namespace := md.labels["io.kubernetes.pod.namespace"]
name := md.labels["io.kubernetes.container.name"]
if name == "" || name == "POD" { // skip pause|sandbox containers
if cg.ContainerType == cgroup.ContainerTypeSandbox {
name = "sandbox"
}
if name == "" || name == "POD" { // skip pause containers
return ""
}
return ContainerID(fmt.Sprintf("/k8s/%s/%s/%s", namespace, pod, name))
Expand All @@ -311,7 +329,12 @@ func calcId(cg *cgroup.Cgroup, md *ContainerMetadata) ContainerID {
}

func getContainerMetadata(cg *cgroup.Cgroup) (*ContainerMetadata, error) {
if cg.ContainerType != cgroup.ContainerTypeDocker && cg.ContainerType != cgroup.ContainerTypeContainerd {
switch cg.ContainerType {
case cgroup.ContainerTypeDocker, cgroup.ContainerTypeContainerd, cgroup.ContainerTypeSandbox:
default:
return &ContainerMetadata{}, nil
}
if cg.ContainerId == "" {
return &ContainerMetadata{}, nil
}
var dockerdErr error
Expand All @@ -320,7 +343,6 @@ func getContainerMetadata(cg *cgroup.Cgroup) (*ContainerMetadata, error) {
if err == nil {
return md, nil
}
klog.Warningf("failed to inspect container %s: %s", cg.ContainerId, err)
dockerdErr = err
}
var containerdErr error
Expand All @@ -329,7 +351,6 @@ func getContainerMetadata(cg *cgroup.Cgroup) (*ContainerMetadata, error) {
if err == nil {
return md, nil
}
klog.Warningf("failed to inspect container %s: %s", cg.ContainerId, err)
containerdErr = err
}
return nil, fmt.Errorf("failed to interact with dockerd (%s) or with containerd (%s)", dockerdErr, containerdErr)
Expand Down
18 changes: 8 additions & 10 deletions node/metadata/gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@ package metadata
import (
gcp "cloud.google.com/go/compute/metadata"
"k8s.io/klog/v2"
"net/http"
"strings"
)

func getGcpMetadata() *CloudMetadata {
hc := http.DefaultClient
hc.Timeout = metadataServiceTimeout
c := gcp.NewClient(hc)
md := &CloudMetadata{
Provider: CloudProviderGCP,
AccountId: getGcpMetadataVariable(c, "project/project-id"),
InstanceId: getGcpMetadataVariable(c, "instance/id"),
LocalIPv4: getGcpMetadataVariable(c, "instance/network-interfaces/0/ip"),
PublicIPv4: getGcpMetadataVariable(c, "instance/network-interfaces/0/access-configs/0/external-ip"),
c := gcp.NewClient(nil)
md := &CloudMetadata{Provider: CloudProviderGCP}
if md.AccountId = getGcpMetadataVariable(c, "project/project-id"); md.AccountId == "" {
return md
}
md.InstanceId = getGcpMetadataVariable(c, "instance/id")
md.LocalIPv4 = getGcpMetadataVariable(c, "instance/network-interfaces/0/ip")
md.PublicIPv4 = getGcpMetadataVariable(c, "instance/network-interfaces/0/access-configs/0/external-ip")

switch strings.ToLower(getGcpMetadataVariable(c, "instance/scheduling/preemptible")) {
case "false":
md.LifeCycle = "on-demand"
Expand Down
3 changes: 2 additions & 1 deletion proc/proc.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package proc

import (
"bytes"
"github.com/coroot/coroot-node-agent/cgroup"
"os"
"path"
Expand All @@ -23,7 +24,7 @@ func GetCmdline(pid uint32) []byte {
if err != nil {
return nil
}
return cmdline
return bytes.TrimSuffix(cmdline, []byte{0})
}

func GetNsPid(pid uint32) uint32 {
Expand Down

0 comments on commit 32c6ad2

Please sign in to comment.