Skip to content

Commit

Permalink
kubernetes runtime support for the debug command
Browse files Browse the repository at this point in the history
Signed-off-by: Kyle Quest <kcq.public@gmail.com>
  • Loading branch information
kcq committed Jul 13, 2023
1 parent 2a03ea8 commit 739ddec
Show file tree
Hide file tree
Showing 53 changed files with 5,895 additions and 156 deletions.
11 changes: 6 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ require (
github.com/urfave/cli/v2 v2.3.0
golang.org/x/net v0.12.0
golang.org/x/sys v0.10.0
k8s.io/api v0.27.1
k8s.io/apimachinery v0.27.1
k8s.io/cli-runtime v0.27.1
k8s.io/client-go v0.27.1
k8s.io/api v0.27.3
k8s.io/apimachinery v0.27.3
k8s.io/cli-runtime v0.27.3
k8s.io/client-go v0.27.3
)

require (
Expand Down Expand Up @@ -72,6 +72,7 @@ require (
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
Expand Down Expand Up @@ -136,7 +137,7 @@ require (
github.com/stretchr/testify v1.8.1
github.com/ulikunitz/xz v0.5.7 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a // indirect
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
)

Expand Down
23 changes: 13 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwq
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
Expand Down Expand Up @@ -584,6 +585,8 @@ github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQ
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM=
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
Expand Down Expand Up @@ -1210,23 +1213,23 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
k8s.io/api v0.27.1 h1:Z6zUGQ1Vd10tJ+gHcNNNgkV5emCyW+v2XTmn+CLjSd0=
k8s.io/api v0.27.1/go.mod h1:z5g/BpAiD+f6AArpqNjkY+cji8ueZDU/WV1jcj5Jk4E=
k8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y=
k8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg=
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
k8s.io/apimachinery v0.27.1 h1:EGuZiLI95UQQcClhanryclaQE6xjg1Bts6/L3cD7zyc=
k8s.io/apimachinery v0.27.1/go.mod h1:5ikh59fK3AJ287GUvpUsryoMFtH9zj/ARfWCo3AyXTM=
k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM=
k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
k8s.io/cli-runtime v0.27.1 h1:MMzp5Q/Xmr5L1Lrowuc+Y/r95XINC6c6/fE3aN7JDRM=
k8s.io/cli-runtime v0.27.1/go.mod h1:tEbTB1XP/nTH3wujsi52bw91gWpErtWiS15R6CwYsAI=
k8s.io/cli-runtime v0.27.3 h1:h592I+2eJfXj/4jVYM+tu9Rv8FEc/dyCoD80UJlMW2Y=
k8s.io/cli-runtime v0.27.3/go.mod h1:LzXud3vFFuDFXn2LIrWnscPgUiEj7gQQcYZE2UPn9Kw=
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
k8s.io/client-go v0.27.1 h1:oXsfhW/qncM1wDmWBIuDzRHNS2tLhK3BZv512Nc59W8=
k8s.io/client-go v0.27.1/go.mod h1:f8LHMUkVb3b9N8bWturc+EDtVVVwZ7ueTVquFAJb2vA=
k8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8=
k8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48=
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
Expand All @@ -1240,8 +1243,8 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a h1:gmovKNur38vgoWfGtP5QOGNOA7ki4n6qNYoFAgMlNvg=
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY=
Expand Down
33 changes: 30 additions & 3 deletions pkg/app/master/commands/debug/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,20 @@ const (
Alias = "dbg"
)

const (
DockerRuntime = "docker"
KubernetesRuntime = "k8s"
)

type CommandParams struct {
/// the runtime environment type
Runtime string
/// the running container which we want to attach to
TargetRef string
/// the target namespace (k8s runtime)
TargetNamespace string
/// the target pod (k8s runtime)
TargetPod string
/// the name/id of the container image used for debugging
DebugContainerImage string
/// ENTRYPOINT used for launching the debugging image
Expand All @@ -26,6 +37,8 @@ type CommandParams struct {
Cmd []string
/// launch the debug container with an interactive terminal attached (like '--it' in docker)
DoTerminal bool
/// Kubeconfig file path (k8s runtime)
Kubeconfig string
}

var debugImages = map[string]string{
Expand All @@ -36,19 +49,24 @@ var debugImages = map[string]string{
KoolkitsJVMImage: "JVM KoolKit - https://github.com/lightrun-platform/koolkits/blob/main/jvm/README.md",
DigitaloceanDoksImage: "Kubernetes manifests for investigation and troubleshooting - https://github.com/digitalocean/doks-debug",
ZinclabsUbuntuImage: "Common utilities for debugging your cluster - https://github.com/openobserve/debug-container",
BusyboxImage: "A lightweight image with common unix utilities - https://busybox.net/about.html",
}

var CLI = &cli.Command{
Name: Name,
Aliases: []string{Alias},
Usage: Usage,
Flags: []cli.Flag{
cflag(FlagRuntime),
cflag(FlagTarget),
cflag(FlagNamespace),
cflag(FlagPod),
cflag(FlagDebugImage),
cflag(FlagEntrypoint),
cflag(FlagCmd),
cflag(FlagTerminal),
cflag(FlagListDebugImage),
cflag(FlagKubeconfig),
},
Action: func(ctx *cli.Context) error {
xc := app.NewExecutionContext(Name, ctx.String(commands.FlagConsoleFormat))
Expand All @@ -67,9 +85,13 @@ var CLI = &cli.Command{
}

commandParams := &CommandParams{
Runtime: ctx.String(FlagRuntime),
TargetRef: ctx.String(FlagTarget),
TargetNamespace: ctx.String(FlagNamespace),
TargetPod: ctx.String(FlagPod),
DebugContainerImage: ctx.String(FlagDebugImage),
DoTerminal: ctx.Bool(FlagTerminal),
Kubeconfig: ctx.String(FlagKubeconfig),
}

if rawEntrypoint := ctx.String(FlagEntrypoint); rawEntrypoint != "" {
Expand All @@ -88,9 +110,14 @@ var CLI = &cli.Command{

if commandParams.TargetRef == "" {
if ctx.Args().Len() < 1 {
xc.Out.Error("param.target", "missing target")
cli.ShowCommandHelp(ctx, Name)
return nil
if commandParams.Runtime != KubernetesRuntime {
xc.Out.Error("param.target", "missing target")
cli.ShowCommandHelp(ctx, Name)
return nil
}
//NOTE:
//It's ok to not specify the target container for k8s
//We'll pick the default or first container in the target pod
} else {
commandParams.TargetRef = ctx.Args().First()
if ctx.Args().Len() > 1 && ctx.Args().Slice()[1] == "--" {
Expand Down
37 changes: 37 additions & 0 deletions pkg/app/master/commands/debug/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@ import (

// Debug command flag names and usage descriptions
const (
FlagRuntime = "runtime"
FlagRuntimeUsage = "Runtime environment type"

FlagTarget = "target"
FlagTargetUsage = "Target container (name or ID)"

FlagNamespace = "namespace"
FlagNamespaceUsage = "Namespace to target (k8s runtime)"

FlagPod = "pod"
FlagPodUsage = "Pod to target (k8s runtime)"

FlagDebugImage = "debug-image"
FlagDebugImageUsage = "Debug image to use for the debug side-car container"

Expand All @@ -24,6 +33,9 @@ const (

FlagListDebugImage = "list-debug-images"
FlagListDebugImageUsage = "List possible debug images to use for the debug side-car container"

FlagKubeconfig = "kubeconfig"
FlagKubeconfigUsage = "Kubeconfig file location (k8s runtime)"
)

const (
Expand All @@ -34,15 +46,34 @@ const (
KoolkitsJVMImage = "lightruncom/koolkits:jvm"
DigitaloceanDoksImage = "digitalocean/doks-debug:latest"
ZinclabsUbuntuImage = "public.ecr.aws/zinclabs/debug-ubuntu-base:latest"
BusyboxImage = "busybox:latest"
)

var Flags = map[string]cli.Flag{
FlagRuntime: &cli.StringFlag{
Name: FlagRuntime,
Value: DockerRuntime,
Usage: FlagRuntimeUsage,
EnvVars: []string{"DSLIM_DBG_RT"},
},
FlagTarget: &cli.StringFlag{
Name: FlagTarget,
Value: "",
Usage: FlagTargetUsage,
EnvVars: []string{"DSLIM_DBG_TARGET"},
},
FlagNamespace: &cli.StringFlag{
Name: FlagNamespace,
Value: "default",
Usage: FlagNamespaceUsage,
EnvVars: []string{"DSLIM_DBG_TARGET_NS"},
},
FlagPod: &cli.StringFlag{
Name: FlagPod,
Value: "",
Usage: FlagPodUsage,
EnvVars: []string{"DSLIM_DBG_TARGET_POD"},
},
FlagDebugImage: &cli.StringFlag{
Name: FlagDebugImage,
Value: NicolakaNetshootImage,
Expand Down Expand Up @@ -73,6 +104,12 @@ var Flags = map[string]cli.Flag{
Usage: FlagListDebugImageUsage,
EnvVars: []string{"DSLIM_DBG_LIST_IMAGES"},
},
FlagKubeconfig: &cli.StringFlag{
Name: FlagKubeconfig,
Value: "${HOME}/.kube/config",
Usage: FlagKubeconfigUsage,
EnvVars: []string{"DSLIM_DBG_KUBECONFIG"},
},
}

func cflag(name string) cli.Flag {
Expand Down
81 changes: 81 additions & 0 deletions pkg/app/master/commands/debug/handle_docker_runtime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package debug

import (
"fmt"

dockerapi "github.com/fsouza/go-dockerclient"
log "github.com/sirupsen/logrus"

"github.com/docker-slim/docker-slim/pkg/app"
"github.com/docker-slim/docker-slim/pkg/app/master/commands"
"github.com/docker-slim/docker-slim/pkg/app/master/container"
"github.com/docker-slim/docker-slim/pkg/app/master/inspectors/image"
"github.com/docker-slim/docker-slim/pkg/util/errutil"
)

// HandleDockerRuntime implements support for the docker runtime
func HandleDockerRuntime(
logger *log.Entry,
xc *app.ExecutionContext,
gparams *commands.GenericParams,
commandParams *CommandParams,
client *dockerapi.Client) {
imageInspector, err := image.NewInspector(client, commandParams.DebugContainerImage)
if imageInspector.NoImage() {
err := imageInspector.Pull(true, "", "", "")
xc.FailOn(err)
}

targetContainerInfo, err := client.InspectContainer(commandParams.TargetRef)
if err != nil {
xc.Out.Error("target.container.inspect", err.Error())
xc.Out.State("exited",
ovars{
"exit.code": -1,
})
xc.Exit(-1)
}

options := container.ExecutionOptions{
Entrypoint: commandParams.Entrypoint,
Cmd: commandParams.Cmd,
Terminal: commandParams.DoTerminal,
}

exe, err := container.NewExecution(
xc,
logger,
client,
commandParams.DebugContainerImage,
&options,
nil,
true,
true)

// attach network, IPC & PIDs, essentially this is run --network container:golang_service --pid container:golang_service --ipc container:golang_service
mode := fmt.Sprintf("container:%s", commandParams.TargetRef)

if targetContainerInfo.HostConfig.IpcMode == "shareable" {
exe.IpcMode = mode
}

exe.NetworkMode = mode
exe.PidMode = mode

xc.FailOn(err)

err = exe.Start()
xc.FailOn(err)

_, err = exe.Wait()
xc.FailOn(err)

defer func() {
err = exe.Cleanup()
errutil.WarnOn(err)
}()

if !commandParams.DoTerminal {
exe.ShowContainerLogs()
}
}
Loading

0 comments on commit 739ddec

Please sign in to comment.