diff --git a/pkg/command/check.go b/pkg/command/check.go index 98e81196..5695f31d 100644 --- a/pkg/command/check.go +++ b/pkg/command/check.go @@ -58,6 +58,9 @@ func NewCheckCmd() *cobra.Command { func (o *CheckOptions) LoadConfig() { fromConfig := &share.DoOptions{} if err := utils.ReadOpt(fromConfig); err == nil { + if len(fromConfig.Mode) == 0 { + fromConfig.Mode = share.Pod + } once.Do(func() { klog.Infof("use config from file!!!!!!") }) @@ -79,7 +82,7 @@ func (o *CheckOptions) Complete() error { Version: o.DoOption.Version, PodWaitTime: o.DoOption.PodWaitTime, Port: o.DoOption.Port, - EnableHostNetwork: false, + EnableHostNetwork: o.DoOption.GetEnableHostNetwork(true), EnableAnalysis: false, } if err := srcfloater.CompleteFromKubeConfigPath(o.DoOption.SrcKubeConfig, ""); err != nil { @@ -97,7 +100,7 @@ func (o *CheckOptions) Complete() error { Version: o.DoOption.Version, PodWaitTime: o.DoOption.PodWaitTime, Port: o.DoOption.Port, - EnableHostNetwork: false, + EnableHostNetwork: o.DoOption.GetEnableHostNetwork(false), EnableAnalysis: false, } if err := dstfloater.CompleteFromKubeConfigPath(o.DoOption.DstKubeConfig, ""); err != nil { diff --git a/pkg/command/clean.go b/pkg/command/clean.go index 321485c7..4a04e888 100644 --- a/pkg/command/clean.go +++ b/pkg/command/clean.go @@ -51,6 +51,9 @@ func NewCleanCmd() *cobra.Command { func (o *CleanOptions) LoadConfig() { fromConfig := &share.DoOptions{} if err := utils.ReadOpt(fromConfig); err == nil { + if len(fromConfig.Mode) == 0 { + fromConfig.Mode = share.Pod + } once.Do(func() { klog.Infof("use config from file!!!!!!") }) @@ -68,7 +71,7 @@ func (o *CleanOptions) Complete() error { Version: o.DoOption.Version, PodWaitTime: o.DoOption.PodWaitTime, Port: o.DoOption.Port, - EnableHostNetwork: false, + EnableHostNetwork: o.DoOption.GetEnableHostNetwork(true), EnableAnalysis: false, } if err := srcfloater.CompleteFromKubeConfigPath(o.DoOption.SrcKubeConfig, ""); err != nil { @@ -86,7 +89,7 @@ func (o *CleanOptions) Complete() error { Version: o.DoOption.Version, PodWaitTime: o.DoOption.PodWaitTime, Port: o.DoOption.Port, - EnableHostNetwork: false, + EnableHostNetwork: o.DoOption.GetEnableHostNetwork(false), EnableAnalysis: false, } if err := dstfloater.CompleteFromKubeConfigPath(o.DoOption.DstKubeConfig, ""); err != nil { diff --git a/pkg/command/init.go b/pkg/command/init.go index 149f56cd..87b49159 100644 --- a/pkg/command/init.go +++ b/pkg/command/init.go @@ -65,6 +65,7 @@ func (o *InitOptions) Run() error { // dst DstImageRepository: "", DstKubeConfig: "", + Mode: share.Pod, } if err := utils.WriteOpt(doOptions); err != nil { diff --git a/pkg/command/resume.go b/pkg/command/resume.go index 93702cd5..9c5b8350 100644 --- a/pkg/command/resume.go +++ b/pkg/command/resume.go @@ -52,6 +52,9 @@ func NewResumeCmd() *cobra.Command { func (o *ResumeOptions) LoadConfig() { fromConfig := &share.DoOptions{} if err := utils.ReadOpt(fromConfig); err == nil { + if len(fromConfig.Mode) == 0 { + fromConfig.Mode = share.Pod + } once.Do(func() { klog.Infof("use config from file!!!!!!") }) @@ -72,7 +75,7 @@ func (o *ResumeOptions) Complete() error { Version: o.DoOption.Version, PodWaitTime: o.DoOption.PodWaitTime, Port: o.DoOption.Port, - EnableHostNetwork: false, + EnableHostNetwork: o.DoOption.GetEnableHostNetwork(true), EnableAnalysis: false, } if err := srcfloater.CompleteFromKubeConfigPath(o.DoOption.SrcKubeConfig, ""); err != nil { @@ -90,7 +93,7 @@ func (o *ResumeOptions) Complete() error { Version: o.DoOption.Version, PodWaitTime: o.DoOption.PodWaitTime, Port: o.DoOption.Port, - EnableHostNetwork: false, + EnableHostNetwork: o.DoOption.GetEnableHostNetwork(false), EnableAnalysis: false, } if err := dstfloater.CompleteFromKubeConfigPath(o.DoOption.DstKubeConfig, ""); err != nil { diff --git a/pkg/command/share/do.go b/pkg/command/share/do.go index 7053d300..1e721d99 100644 --- a/pkg/command/share/do.go +++ b/pkg/command/share/do.go @@ -11,9 +11,19 @@ import ( "k8s.io/klog/v2" ) +type ModeType string + +const ( + Node ModeType = "node" + Pod ModeType = "pod" + NodeToPod ModeType = "node-to-pod" + PodToNode ModeType = "pod-to-node" +) + type DoOptions struct { - Namespace string `json:"namespace,omitempty"` - Version string `json:"version,omitempty"` + Namespace string `json:"namespace,omitempty"` + Version string `json:"version,omitempty"` + Mode ModeType `json:"mode,omitempty"` Protocol string `json:"protocol,omitempty"` PodWaitTime int `json:"podWaitTime,omitempty"` @@ -38,13 +48,51 @@ type DoOptions struct { ResumeRecord []*PrintCheckData `json:"-"` } +func (o *DoOptions) GetEnableHostNetwork(isSrc bool) bool { + if isSrc { + switch o.Mode { + case Node, NodeToPod: + return true + case Pod, PodToNode: + return false + } + } else { + switch o.Mode { + case Node, PodToNode: + return true + case NodeToPod, Pod: + return false + } + } + return false +} + +func (o *DoOptions) GetInfo(floater *Floater, isSrc bool) ([]*FloatInfo, error) { + if isSrc { + switch o.Mode { + case Node, NodeToPod: + return floater.GetNodesInfo() + case Pod, PodToNode: + return floater.GetPodInfo() + } + } else { + switch o.Mode { + case Node, PodToNode: + return floater.GetNodesInfo() + case NodeToPod, Pod: + return floater.GetPodInfo() + } + } + return floater.GetPodInfo() +} + func (o *DoOptions) Run() error { if err := o.SrcFloater.CreateFloater(); err != nil { return err } if o.DstKubeConfig != "" { - srcPodInfos, err := o.SrcFloater.GetPodInfo() + srcInfos, err := o.GetInfo(o.SrcFloater, true) if err != nil { return fmt.Errorf("get src cluster podInfos failed: %s", err) } @@ -52,19 +100,26 @@ func (o *DoOptions) Run() error { if err = o.DstFloater.CreateFloater(); err != nil { return err } - var dstPodInfos []*FloatInfo - dstPodInfos, err = o.DstFloater.GetPodInfo() + var dstInfos []*FloatInfo + dstInfos, err = o.GetInfo(o.DstFloater, false) if err != nil { return fmt.Errorf("get dist cluster podInfos failed: %s", err) } - PrintResult(o.RunRange(srcPodInfos, dstPodInfos)) + PrintResult(o.RunRange(srcInfos, dstInfos)) } else { - srcPodInfos, err := o.SrcFloater.GetPodInfo() + srcInfos, err := o.GetInfo(o.SrcFloater, true) if err != nil { return fmt.Errorf("get src cluster podInfos failed: %s", err) } - PrintResult(o.RunRange(srcPodInfos, srcPodInfos)) + + var dstInfos []*FloatInfo + dstInfos, err = o.GetInfo(o.SrcFloater, false) + if err != nil { + return fmt.Errorf("get dist cluster podInfos failed: %s", err) + } + + PrintResult(o.RunRange(srcInfos, dstInfos)) } if o.AutoClean { @@ -149,7 +204,13 @@ func (o *DoOptions) RunRange(iPodInfos []*FloatInfo, jPodInfos []*FloatInfo) []* cmdObj = command.NewCmd(o.Protocol, o.TargetHostToLookup, o.TargetDNSServer) } else { for _, jPodInfo := range jPodInfos { - for _, ip := range jPodInfo.PodIPs { + targetIPs := jPodInfo.PodIPs + needWrapper := false + if len(jPodInfo.NodeIPs) != 0 { + targetIPs = jPodInfo.NodeIPs + needWrapper = true + } + for _, ip := range targetIPs { var targetIP string var err error var cmdResult *command.Result @@ -163,6 +224,11 @@ func (o *DoOptions) RunRange(iPodInfos []*FloatInfo, jPodInfos []*FloatInfo) []* } // ToDo RunRange && RunNative func support multiple commands, and the code needs to be optimized cmdObj := command.NewCmd(o.Protocol, targetIP, o.Port) + if needWrapper { + cmdObj = command.Wrapper{ + Cmd: cmdObj, + } + } cmdResult = o.SrcFloater.CommandExec(iPodInfo, cmdObj) } mutex.Lock() diff --git a/pkg/command/share/floater.go b/pkg/command/share/floater.go index fa54c8be..a23aab98 100644 --- a/pkg/command/share/floater.go +++ b/pkg/command/share/floater.go @@ -161,7 +161,21 @@ func (f *Floater) applyDaemonSet() error { if err != nil { return err } - _, err = f.Client.AppsV1().DaemonSets(f.Namespace).Create(context.Background(), clusterlinkFloaterDaemonSet, metav1.CreateOptions{}) + + applyFunc := func() error { + _, err = f.Client.AppsV1().DaemonSets(f.Namespace).Create(context.Background(), clusterlinkFloaterDaemonSet, metav1.CreateOptions{}) + return err + } + + _, err = f.Client.AppsV1().DaemonSets(f.Namespace).Get(context.Background(), f.Name, metav1.GetOptions{}) + if err == nil { + applyFunc = func() error { + _, err = f.Client.AppsV1().DaemonSets(f.Namespace).Update(context.Background(), clusterlinkFloaterDaemonSet, metav1.UpdateOptions{}) + return err + } + } + + err = applyFunc() if err != nil { if !apierrors.IsAlreadyExists(err) { return fmt.Errorf("linkctl floater run error, daemonset options failed: %v", err) diff --git a/pkg/command/share/remote-command/ping.go b/pkg/command/share/remote-command/ping.go index b9275c8e..a98719e7 100644 --- a/pkg/command/share/remote-command/ping.go +++ b/pkg/command/share/remote-command/ping.go @@ -3,9 +3,11 @@ package command import ( "fmt" "regexp" + + "github.com/kosmos.io/netdoctor/pkg/utils" ) -var pingReg, _ = regexp.Compile(`PING[\s\S]*1\spackets\stransmitted,\s1\spackets\sreceived,\s0[%]\spacket\sloss[\s\S]*$`) +var pingReg, _ = regexp.Compile(`PING[\s\S]*\s0[%]\spacket\sloss[\s\S]*$`) type Ping struct { TargetIP string @@ -17,7 +19,11 @@ func (c *Ping) GetTargetStr() string { func (c *Ping) GetCommandStr() string { // execute once - return fmt.Sprintf("ping -c 1 %s", c.TargetIP) + if utils.IsIPv6(c.TargetIP) { + return fmt.Sprintf("ping6 -c 1 %s", c.TargetIP) + } else { + return fmt.Sprintf("ping -c 1 %s", c.TargetIP) + } } func (c *Ping) ParseResult(result string) *Result { diff --git a/pkg/command/share/remote-command/wrapper.go b/pkg/command/share/remote-command/wrapper.go new file mode 100644 index 00000000..c5b64739 --- /dev/null +++ b/pkg/command/share/remote-command/wrapper.go @@ -0,0 +1,19 @@ +package command + +import "fmt" + +type Wrapper struct { + Cmd Command +} + +func (w Wrapper) GetCommandStr() string { + return fmt.Sprintf(`nsenter --target "1" --mount --uts --ipc --net --pid -- %s`, w.Cmd.GetCommandStr()) +} + +func (w Wrapper) ParseResult(str string) *Result { + return w.Cmd.ParseResult(str) +} + +func (w Wrapper) GetTargetStr() string { + return w.Cmd.GetTargetStr() +} diff --git a/pkg/manifest/manifest_daemonsets.go b/pkg/manifest/manifest_daemonsets.go index 1162fef8..713105da 100644 --- a/pkg/manifest/manifest_daemonsets.go +++ b/pkg/manifest/manifest_daemonsets.go @@ -41,6 +41,7 @@ spec: value: "{{ .Port }}" - name: "ENABLE_ANALYSIS" value: "{{ .EnableAnalysis }}" + hostPID: true tolerations: - effect: NoSchedule operator: Exists diff --git a/pkg/utils/constants.go b/pkg/utils/constants.go index a2c0d7d5..328039c5 100644 --- a/pkg/utils/constants.go +++ b/pkg/utils/constants.go @@ -11,6 +11,6 @@ type Protocol string const ( TCP Protocol = "tcp" UDP Protocol = "udp" - IPv4 Protocol = "ipv4" + ICMP Protocol = "icmp" DNS Protocol = "dns" )