Skip to content

Commit

Permalink
enhancement: add the agentpod resource config in agentless mode (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
calmkart authored and aylei committed Oct 19, 2019
1 parent d62a8d9 commit 489450b
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 3 deletions.
9 changes: 9 additions & 0 deletions README.md
Expand Up @@ -95,6 +95,9 @@ kubectl-debug POD_NAME
# the default registry-secret-name is kubectl-debug-registry-secret, the default namespace is default
# please set the secret data source as {Username: <username>, Password: <password>}
kubectl-debug POD_NAME --image calmkart/netshoot:latest --registry-secret-name <k8s_secret_name> --registry-secret-namespace <namespace>
# in agentless mode, you can set the agent pod's resource limits/requests, for example:
# default is not set
kubectl-debug POD_NAME --agentless --agent-pod-cpu-requests=250m --agent-pod-cpu-limits=500m --agent-pod-memory-requests=200Mi --agent-pod-memory-limits=500Mi
```

Example:
Expand Down Expand Up @@ -177,6 +180,12 @@ command:
# default namspace is default
RegistrySecretName: my-debug-secret
RegistrySecretNamespace: debug
# in agentless mode, you can set the agent pod's resource limits/requests:
# default is not set
agentCpuRequests: ""
agentCpuLimits: ""
agentMemoryRequests: ""
agentMemoryLimits: ""
```

If the debug-agent is not accessible from host port, it is recommended to set `portForward: true` to using port-forawrd mode.
Expand Down
10 changes: 10 additions & 0 deletions docs/zh-cn.md
Expand Up @@ -89,6 +89,10 @@ kubectl-debug POD_NAME
# secret data原文请设置为 {Username: <username>, Password: <password>}
# 默认secret_name为kubectl-debug-registry-secret,默认namspace为default
kubectl-debug POD_NAME --image calmkart/netshoot:latest --registry-secret-name <k8s_secret_name> --registry-secret-namespace <namespace>

# 在agentless模式中,你可以设置agent pod的resource资源限制,如下示例
# 若不设置,默认为空
kubectl-debug POD_NAME --agentless --agent-pod-cpu-requests=250m --agent-pod-cpu-limits=500m --agent-pod-memory-requests=200Mi --agent-pod-memory-limits=500Mi
```

举例:
Expand Down Expand Up @@ -168,6 +172,12 @@ command:
# 默认RegistrySecretName为kubectl-debug-registry-secret,默认RegistrySecretNamespace为default
RegistrySecretName: my-debug-secret
RegistrySecretNamespace: debug
# 在agentless模式下可以设置agent pod的resource资源限制
# 若不设置,默认为空
agentCpuRequests: ""
agentCpuLimits: ""
agentMemoryRequests: ""
agentMemoryLimits: ""
```

> `kubectl-debug` 会将容器的 entrypoint 直接覆盖掉, 这是为了避免在 debug 时不小心启动非 shell 进程.
Expand Down
89 changes: 86 additions & 3 deletions pkg/plugin/cmd.go
Expand Up @@ -21,6 +21,7 @@ import (
authorizationv1 "k8s.io/api/authorization/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -71,9 +72,13 @@ You may set default configuration such as image and command in the config file,

usageError = "expects 'debug POD_NAME' for debug command"

defaultAgentImage = "aylei/debug-agent:latest"
defaultAgentPodNamePrefix = "debug-agent-pod"
defaultAgentPodNamespace = "default"
defaultAgentImage = "aylei/debug-agent:latest"
defaultAgentPodNamePrefix = "debug-agent-pod"
defaultAgentPodNamespace = "default"
defaultAgentPodCpuRequests = ""
defaultAgentPodCpuLimits = ""
defaultAgentPodMemoryRequests = ""
defaultAgentPodMemoryLimits = ""

defaultRegistrySecretName = "kubectl-debug-registry-secret"
defaultRegistrySecretNamespace = "default"
Expand Down Expand Up @@ -104,6 +109,7 @@ type DebugOptions struct {
AgentPodName string
AgentPodNamespace string
AgentPodNode string
AgentPodResource agentPodResources

Flags *genericclioptions.ConfigFlags
CoreClient coreclient.CoreV1Interface
Expand All @@ -127,6 +133,13 @@ type DebugOptions struct {
wait sync.WaitGroup
}

type agentPodResources struct {
CpuRequests string
CpuLimits string
MemoryRequests string
MemoryLimits string
}

// NewDebugOptions new debug options
func NewDebugOptions(streams genericclioptions.IOStreams) *DebugOptions {
return &DebugOptions{
Expand Down Expand Up @@ -186,6 +199,14 @@ func NewDebugCmd(streams genericclioptions.IOStreams) *cobra.Command {
fmt.Sprintf("Agentless mode, pod name prefix , default to %s", defaultAgentPodNamePrefix))
cmd.Flags().StringVar(&opts.AgentPodNamespace, "agent-pod-namespace", "",
fmt.Sprintf("Agentless mode, agent pod namespace, default to %s", defaultAgentPodNamespace))
cmd.Flags().StringVar(&opts.AgentPodResource.CpuRequests, "agent-pod-cpu-requests", "",
fmt.Sprintf("Agentless mode, agent pod cpu requests, default is not set"))
cmd.Flags().StringVar(&opts.AgentPodResource.MemoryRequests, "agent-pod-memory-requests", "",
fmt.Sprintf("Agentless mode, agent pod memory requests, default is not set"))
cmd.Flags().StringVar(&opts.AgentPodResource.CpuLimits, "agent-pod-cpu-limits", "",
fmt.Sprintf("Agentless mode, agent pod cpu limits, default is not set"))
cmd.Flags().StringVar(&opts.AgentPodResource.MemoryLimits, "agent-pod-memory-limits", "",
fmt.Sprintf("Agentless mode, agent pod memory limits, default is not set"))
opts.Flags.AddFlags(cmd.Flags())

return cmd
Expand Down Expand Up @@ -307,6 +328,38 @@ func (o *DebugOptions) Complete(cmd *cobra.Command, args []string, argsLenAtDash
}
}

if len(o.AgentPodResource.CpuRequests) < 1 {
if len(config.AgentPodCpuRequests) > 0 {
o.AgentPodResource.CpuRequests = config.AgentPodCpuRequests
} else {
o.AgentPodResource.CpuRequests = defaultAgentPodCpuRequests
}
}

if len(o.AgentPodResource.MemoryRequests) < 1 {
if len(config.AgentPodMemoryRequests) > 0 {
o.AgentPodResource.MemoryRequests = config.AgentPodMemoryRequests
} else {
o.AgentPodResource.MemoryRequests = defaultAgentPodMemoryRequests
}
}

if len(o.AgentPodResource.CpuLimits) < 1 {
if len(config.AgentPodCpuLimits) > 0 {
o.AgentPodResource.CpuLimits = config.AgentPodCpuLimits
} else {
o.AgentPodResource.CpuLimits = defaultAgentPodCpuLimits
}
}

if len(o.AgentPodResource.MemoryLimits) < 1 {
if len(config.AgentPodMemoryLimits) > 0 {
o.AgentPodResource.MemoryLimits = config.AgentPodMemoryLimits
} else {
o.AgentPodResource.MemoryLimits = defaultAgentPodMemoryLimits
}
}

if config.PortForward {
o.PortForward = true
}
Expand Down Expand Up @@ -674,6 +727,7 @@ func (o *DebugOptions) getAgentPod() *corev1.Pod {
TimeoutSeconds: 1,
FailureThreshold: 3,
},
Resources: o.buildAgentResourceRequirements(),
VolumeMounts: []corev1.VolumeMount{
{
Name: "docker",
Expand Down Expand Up @@ -790,3 +844,32 @@ func (o *DebugOptions) deleteAgent(agentPod *corev1.Pod) {
fmt.Fprintf(o.ErrOut, "failed to delete agent pod[Name:%s, Namespace: %s], consider manual deletion.\nerror msg: %v", agentPod.Name, agentPod.Namespace, err)
}
}

// build the agent pod Resource Requirements
func (o *DebugOptions) buildAgentResourceRequirements() corev1.ResourceRequirements {
return getResourceRequirements(getResourceList(o.AgentPodResource.CpuRequests, o.AgentPodResource.MemoryRequests), getResourceList(o.AgentPodResource.CpuLimits, o.AgentPodResource.MemoryLimits))
}

func getResourceList(cpu, memory string) corev1.ResourceList {
// catch error in resource.MustParse
defer func() {
if err := recover(); err != nil {
fmt.Printf("Parse Resource list error: %v\n", err)
}
}()
res := corev1.ResourceList{}
if cpu != "" {
res[corev1.ResourceCPU] = resource.MustParse(cpu)
}
if memory != "" {
res[corev1.ResourceMemory] = resource.MustParse(memory)
}
return res
}

func getResourceRequirements(requests, limits corev1.ResourceList) corev1.ResourceRequirements {
res := corev1.ResourceRequirements{}
res.Requests = requests
res.Limits = limits
return res
}
4 changes: 4 additions & 0 deletions pkg/plugin/config.go
Expand Up @@ -23,6 +23,10 @@ type Config struct {
AgentPodNamePrefix string `yaml:"agentPodNamePrefix,omitempty"`
AgentPodNamespace string `yaml:"agentPodNamespace,omitempty"`
AgentImage string `yaml:"agentImage,omitempty"`
AgentPodCpuRequests string `yaml:"agentCpuRequests,omitempty"`
AgentPodMemoryRequests string `yaml:"agentMemoryRequests,omitempty"`
AgentPodCpuLimits string `yaml:"agentCpuLimits,omitempty"`
AgentPodMemoryLimits string `yaml:"agentMemoryLimits,omitempty"`

// deprecated
AgentPortOld int `yaml:"agent_port,omitempty"`
Expand Down

0 comments on commit 489450b

Please sign in to comment.