Skip to content

Commit 32c6ad2

Browse files
committed
initial support for sandboxed containers (e.g., gvisor)
1 parent 4ea21f6 commit 32c6ad2

File tree

4 files changed

+41
-20
lines changed

4 files changed

+41
-20
lines changed

cgroup/cgroup.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const (
4242
ContainerTypeContainerd
4343
ContainerTypeLxc
4444
ContainerTypeSystemdService
45+
ContainerTypeSandbox
4546
)
4647

4748
func (t ContainerType) String() string {
@@ -144,7 +145,7 @@ func containerByCgroup(path string) (ContainerType, string, error) {
144145
}
145146
matches := dockerIdRegexp.FindStringSubmatch(path)
146147
if matches == nil {
147-
return ContainerTypeUnknown, "", fmt.Errorf("invalid docker cgroup %s", path)
148+
return ContainerTypeSandbox, "", nil
148149
}
149150
return ContainerTypeDocker, matches[1], nil
150151
}

containers/registry.go

+29-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package containers
22

33
import (
4+
"bytes"
45
"fmt"
56
"github.com/coroot/coroot-node-agent/cgroup"
67
"github.com/coroot/coroot-node-agent/common"
@@ -11,13 +12,15 @@ import (
1112
"github.com/vishvananda/netns"
1213
"k8s.io/klog/v2"
1314
"os"
15+
"regexp"
1416
"time"
1517
)
1618

1719
var (
18-
selfNetNs = netns.None()
19-
hostNetNsId = netns.None().UniqueId()
20-
agentPid = uint32(os.Getpid())
20+
selfNetNs = netns.None()
21+
hostNetNsId = netns.None().UniqueId()
22+
agentPid = uint32(os.Getpid())
23+
containerIdRegexp = regexp.MustCompile(`[a-z0-9]{64}`)
2124
)
2225

2326
type Registry struct {
@@ -239,6 +242,16 @@ func (r *Registry) getOrCreateContainer(pid uint32) *Container {
239242
r.containersByPid[pid] = c
240243
return c
241244
}
245+
if cg.ContainerType == cgroup.ContainerTypeSandbox {
246+
cmdline := proc.GetCmdline(pid)
247+
parts := bytes.Split(cmdline, []byte{0})
248+
if len(parts) > 0 {
249+
lastArg := parts[len(parts)-1]
250+
if bytes.HasSuffix(parts[0], []byte("runsc-sandbox")) && containerIdRegexp.Match(lastArg) {
251+
cg.ContainerId = string(lastArg)
252+
}
253+
}
254+
}
242255
md, err := getContainerMetadata(cg)
243256
if err != nil {
244257
klog.Warningf("failed to get container metadata for pid %d -> %s: %s", pid, cg.Id, err)
@@ -291,14 +304,19 @@ func calcId(cg *cgroup.Cgroup, md *ContainerMetadata) ContainerID {
291304
if cg.ContainerType == cgroup.ContainerTypeSystemdService {
292305
return ContainerID(cg.ContainerId)
293306
}
294-
if cg.ContainerType != cgroup.ContainerTypeDocker && cg.ContainerType != cgroup.ContainerTypeContainerd {
307+
switch cg.ContainerType {
308+
case cgroup.ContainerTypeDocker, cgroup.ContainerTypeContainerd, cgroup.ContainerTypeSandbox:
309+
default:
295310
return ""
296311
}
297312
if md.labels["io.kubernetes.pod.name"] != "" {
298313
pod := md.labels["io.kubernetes.pod.name"]
299314
namespace := md.labels["io.kubernetes.pod.namespace"]
300315
name := md.labels["io.kubernetes.container.name"]
301-
if name == "" || name == "POD" { // skip pause|sandbox containers
316+
if cg.ContainerType == cgroup.ContainerTypeSandbox {
317+
name = "sandbox"
318+
}
319+
if name == "" || name == "POD" { // skip pause containers
302320
return ""
303321
}
304322
return ContainerID(fmt.Sprintf("/k8s/%s/%s/%s", namespace, pod, name))
@@ -311,7 +329,12 @@ func calcId(cg *cgroup.Cgroup, md *ContainerMetadata) ContainerID {
311329
}
312330

313331
func getContainerMetadata(cg *cgroup.Cgroup) (*ContainerMetadata, error) {
314-
if cg.ContainerType != cgroup.ContainerTypeDocker && cg.ContainerType != cgroup.ContainerTypeContainerd {
332+
switch cg.ContainerType {
333+
case cgroup.ContainerTypeDocker, cgroup.ContainerTypeContainerd, cgroup.ContainerTypeSandbox:
334+
default:
335+
return &ContainerMetadata{}, nil
336+
}
337+
if cg.ContainerId == "" {
315338
return &ContainerMetadata{}, nil
316339
}
317340
var dockerdErr error
@@ -320,7 +343,6 @@ func getContainerMetadata(cg *cgroup.Cgroup) (*ContainerMetadata, error) {
320343
if err == nil {
321344
return md, nil
322345
}
323-
klog.Warningf("failed to inspect container %s: %s", cg.ContainerId, err)
324346
dockerdErr = err
325347
}
326348
var containerdErr error
@@ -329,7 +351,6 @@ func getContainerMetadata(cg *cgroup.Cgroup) (*ContainerMetadata, error) {
329351
if err == nil {
330352
return md, nil
331353
}
332-
klog.Warningf("failed to inspect container %s: %s", cg.ContainerId, err)
333354
containerdErr = err
334355
}
335356
return nil, fmt.Errorf("failed to interact with dockerd (%s) or with containerd (%s)", dockerdErr, containerdErr)

node/metadata/gcp.go

+8-10
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,19 @@ package metadata
33
import (
44
gcp "cloud.google.com/go/compute/metadata"
55
"k8s.io/klog/v2"
6-
"net/http"
76
"strings"
87
)
98

109
func getGcpMetadata() *CloudMetadata {
11-
hc := http.DefaultClient
12-
hc.Timeout = metadataServiceTimeout
13-
c := gcp.NewClient(hc)
14-
md := &CloudMetadata{
15-
Provider: CloudProviderGCP,
16-
AccountId: getGcpMetadataVariable(c, "project/project-id"),
17-
InstanceId: getGcpMetadataVariable(c, "instance/id"),
18-
LocalIPv4: getGcpMetadataVariable(c, "instance/network-interfaces/0/ip"),
19-
PublicIPv4: getGcpMetadataVariable(c, "instance/network-interfaces/0/access-configs/0/external-ip"),
10+
c := gcp.NewClient(nil)
11+
md := &CloudMetadata{Provider: CloudProviderGCP}
12+
if md.AccountId = getGcpMetadataVariable(c, "project/project-id"); md.AccountId == "" {
13+
return md
2014
}
15+
md.InstanceId = getGcpMetadataVariable(c, "instance/id")
16+
md.LocalIPv4 = getGcpMetadataVariable(c, "instance/network-interfaces/0/ip")
17+
md.PublicIPv4 = getGcpMetadataVariable(c, "instance/network-interfaces/0/access-configs/0/external-ip")
18+
2119
switch strings.ToLower(getGcpMetadataVariable(c, "instance/scheduling/preemptible")) {
2220
case "false":
2321
md.LifeCycle = "on-demand"

proc/proc.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package proc
22

33
import (
4+
"bytes"
45
"github.com/coroot/coroot-node-agent/cgroup"
56
"os"
67
"path"
@@ -23,7 +24,7 @@ func GetCmdline(pid uint32) []byte {
2324
if err != nil {
2425
return nil
2526
}
26-
return cmdline
27+
return bytes.TrimSuffix(cmdline, []byte{0})
2728
}
2829

2930
func GetNsPid(pid uint32) uint32 {

0 commit comments

Comments
 (0)