func (d CheckServiceNetwork) checkPodToServiceConnection(fromPod *kapi.Pod, toService *kapi.Service) { if len(fromPod.Status.ContainerStatuses) == 0 { d.res.Error("DSvcNet1008", nil, fmt.Sprintf("ContainerID not found for pod %q", util.PrintPod(fromPod))) return } success := util.ExpectedConnectionStatus(fromPod.Namespace, toService.Namespace, d.vnidMap) kexecer := kexec.New() containerID := kcontainer.ParseContainerID(fromPod.Status.ContainerStatuses[0].ContainerID).ID pid, err := kexecer.Command("docker", "inspect", "-f", "{{.State.Pid}}", containerID).CombinedOutput() if err != nil { d.res.Error("DSvcNet1009", err, fmt.Sprintf("Fetching pid for pod %q failed. Error: %s", util.PrintPod(fromPod), err)) return } // In bash, redirecting to /dev/tcp/HOST/PORT or /dev/udp/HOST/PORT opens a connection // to that HOST:PORT. Use this to test connectivity to the service; we can't use ping // like in the pod connectivity check because only connections to the correct port // get redirected by the iptables rules. srvConCmd := fmt.Sprintf("echo -n '' > /dev/%s/%s/%d", strings.ToLower(string(toService.Spec.Ports[0].Protocol)), toService.Spec.ClusterIP, toService.Spec.Ports[0].Port) out, err := kexecer.Command("nsenter", "-n", "-t", strings.Trim(fmt.Sprintf("%s", pid), "\n"), "--", "timeout", "1", "bash", "-c", srvConCmd).CombinedOutput() if success && err != nil { d.res.Error("DSvcNet1010", err, fmt.Sprintf("Connectivity from pod %q to service %q failed. Error: %s, Out: %s", util.PrintPod(fromPod), printService(toService), err, string(out))) } else if !success && err == nil { msg := fmt.Sprintf("Unexpected connectivity from pod %q to service %q.", util.PrintPod(fromPod), printService(toService)) d.res.Error("DSvcNet1011", fmt.Errorf("%s", msg), msg) } }
// checkPodToPodConnection verifies connection from fromPod to toPod. // Connection check from toPod to fromPod will be done by the node of toPod. func (d CheckPodNetwork) checkPodToPodConnection(fromPod, toPod *kapi.Pod) { if len(fromPod.Status.ContainerStatuses) == 0 { err := fmt.Errorf("ContainerID not found for pod %q", util.PrintPod(fromPod)) d.res.Error("DPodNet1006", err, err.Error()) return } success := util.ExpectedConnectionStatus(fromPod.Namespace, toPod.Namespace, d.vnidMap) kexecer := kexec.New() containerID := kcontainer.ParseContainerID(fromPod.Status.ContainerStatuses[0].ContainerID).ID pid, err := kexecer.Command("docker", "inspect", "-f", "{{.State.Pid}}", containerID).CombinedOutput() if err != nil { d.res.Error("DPodNet1007", err, fmt.Sprintf("Fetching pid for pod %q, container %q failed. Error: %s", util.PrintPod(fromPod), containerID, err)) return } out, err := kexecer.Command("nsenter", "-n", "-t", strings.Trim(fmt.Sprintf("%s", pid), "\n"), "--", "ping", "-c1", "-W2", toPod.Status.PodIP).CombinedOutput() if success && err != nil { d.res.Error("DPodNet1008", err, fmt.Sprintf("Connectivity from pod %q to pod %q failed. Error: %s, Out: %s", util.PrintPod(fromPod), util.PrintPod(toPod), err, string(out))) } else if !success && err == nil { msg := fmt.Sprintf("Unexpected connectivity from pod %q to pod %q.", util.PrintPod(fromPod), util.PrintPod(toPod)) d.res.Error("DPodNet1009", fmt.Errorf("%s", msg), msg) } }