github.com/zhyoulun/cilium@v1.6.12/test/k8sT/DatapathConfiguration.go (about)

     1  // Copyright 2017-2019 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package k8sTest
    16  
    17  import (
    18  	"fmt"
    19  
    20  	. "github.com/cilium/cilium/test/ginkgo-ext"
    21  	"github.com/cilium/cilium/test/helpers"
    22  
    23  	. "github.com/onsi/gomega"
    24  )
    25  
    26  var _ = Describe("K8sDatapathConfig", func() {
    27  
    28  	var kubectl *helpers.Kubectl
    29  	var demoDSPath string
    30  	var ipsecDSPath string
    31  
    32  	BeforeAll(func() {
    33  		kubectl = helpers.CreateKubectl(helpers.K8s1VMName(), logger)
    34  		demoDSPath = helpers.ManifestGet("demo_ds.yaml")
    35  		ipsecDSPath = helpers.ManifestGet("ipsec_ds.yaml")
    36  
    37  		deleteCiliumDS(kubectl)
    38  	})
    39  
    40  	BeforeEach(func() {
    41  		kubectl.ApplyDefault(demoDSPath).ExpectSuccess("cannot install Demo application")
    42  		kubectl.ApplyDefault(ipsecDSPath).ExpectSuccess("cannot install IPsec keys")
    43  		kubectl.NodeCleanMetadata()
    44  	})
    45  
    46  	AfterEach(func() {
    47  		kubectl.Delete(demoDSPath)
    48  		kubectl.Delete(ipsecDSPath)
    49  		ExpectAllPodsTerminated(kubectl)
    50  
    51  		deleteCiliumDS(kubectl)
    52  	})
    53  
    54  	AfterFailed(func() {
    55  		kubectl.CiliumReport(helpers.KubeSystemNamespace,
    56  			"cilium bpf tunnel list",
    57  			"cilium endpoint list")
    58  	})
    59  
    60  	AfterAll(func() {
    61  		kubectl.CloseSSHClient()
    62  	})
    63  
    64  	JustAfterEach(func() {
    65  		kubectl.ValidateNoErrorsInLogs(CurrentGinkgoTestDescription().Duration)
    66  	})
    67  
    68  	cleanService := func() {
    69  		// To avoid hit GH-4384
    70  		kubectl.DeleteResource("service", "test-nodeport testds-service").ExpectSuccess(
    71  			"Service is deleted")
    72  	}
    73  
    74  	deployCilium := func(options []string) {
    75  		DeployCiliumOptionsAndDNS(kubectl, options)
    76  
    77  		err := kubectl.WaitforPods(helpers.DefaultNamespace, "", helpers.HelperTimeout)
    78  		ExpectWithOffset(1, err).Should(BeNil(), "Pods are not ready after timeout")
    79  
    80  		_, err = kubectl.CiliumNodesWait()
    81  		ExpectWithOffset(1, err).Should(BeNil(), "Failure while waiting for k8s nodes to be annotated by Cilium")
    82  
    83  		By("Making sure all endpoints are in ready state")
    84  		err = kubectl.CiliumEndpointWaitReady()
    85  		ExpectWithOffset(1, err).To(BeNil(), "Failure while waiting for all cilium endpoints to reach ready state")
    86  	}
    87  
    88  	Context("Encapsulation", func() {
    89  		BeforeEach(func() {
    90  			SkipIfFlannel()
    91  		})
    92  
    93  		validateBPFTunnelMap := func() {
    94  			By("Checking that BPF tunnels are in place")
    95  			ciliumPod, err := kubectl.GetCiliumPodOnNode(helpers.KubeSystemNamespace, helpers.K8s1)
    96  			ExpectWithOffset(1, err).Should(BeNil(), "Unable to determine cilium pod on node %s", helpers.K8s1)
    97  			status := kubectl.CiliumExec(ciliumPod, "cilium bpf tunnel list | wc -l")
    98  			status.ExpectSuccess()
    99  			Expect(status.IntOutput()).Should(Equal(3), "Did not find expected number of entries in BPF tunnel map")
   100  		}
   101  
   102  		It("Check connectivity with transparent encryption and VXLAN encapsulation", func() {
   103  			if !helpers.RunsOnNetNext() {
   104  				Skip("Skipping test because it is not running with the net-next kernel")
   105  				return
   106  			}
   107  
   108  			deployCilium([]string{
   109  				"--set global.encryption.enabled=true",
   110  			})
   111  			validateBPFTunnelMap()
   112  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test with IPsec between nodes failed")
   113  			cleanService()
   114  		}, 600)
   115  
   116  		It("Check connectivity with sockops and VXLAN encapsulation", func() {
   117  			// Note if run on kernel without sockops feature is ignored
   118  			deployCilium([]string{
   119  				"--set global.sockops.enabled=true",
   120  			})
   121  			validateBPFTunnelMap()
   122  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   123  			cleanService()
   124  		}, 600)
   125  
   126  		It("Check connectivity with VXLAN encapsulation", func() {
   127  			deployCilium([]string{
   128  				"--set global.tunnel=vxlan",
   129  			})
   130  			validateBPFTunnelMap()
   131  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   132  			cleanService()
   133  		}, 600)
   134  
   135  		It("Check connectivity with Geneve encapsulation", func() {
   136  			deployCilium([]string{
   137  				"--set global.tunnel=geneve",
   138  			})
   139  			validateBPFTunnelMap()
   140  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   141  			cleanService()
   142  		})
   143  
   144  		It("Check vxlan connectivity with per endpoint routes", func() {
   145  			Skip("Encapsulation mode is not supported with per-endpoint routes")
   146  
   147  			deployCilium([]string{
   148  				"--set global.autoDirectNodeRoutes=true",
   149  			})
   150  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   151  			cleanService()
   152  		})
   153  
   154  	})
   155  
   156  	Context("DirectRouting", func() {
   157  		It("Check connectivity with automatic direct nodes routes", func() {
   158  			SkipIfFlannel()
   159  
   160  			deployCilium([]string{
   161  				"--set global.tunnel=disabled",
   162  				"--set global.autoDirectNodeRoutes=true",
   163  			})
   164  
   165  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   166  			cleanService()
   167  		})
   168  
   169  		It("Check direct connectivity with per endpoint routes", func() {
   170  			SkipIfFlannel()
   171  
   172  			deployCilium([]string{
   173  				"--set global.tunnel=disabled",
   174  				"--set global.autoDirectNodeRoutes=true",
   175  				"--set global.endpointRoutes.enabled=true",
   176  			})
   177  
   178  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   179  			cleanService()
   180  		})
   181  	})
   182  
   183  	Context("Transparent encryption DirectRouting", func() {
   184  		It("Check connectivity with transparent encryption and direct routing", func() {
   185  			SkipIfFlannel()
   186  
   187  			deployCilium([]string{
   188  				"--set global.tunnel=disabled",
   189  				"--set global.autoDirectNodeRoutes=true",
   190  				"--set global.encryption.enabled=true",
   191  				"--set global.encryption.interface=enp0s8",
   192  			})
   193  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   194  			cleanService()
   195  		})
   196  	})
   197  
   198  	Context("IPv4Only", func() {
   199  		It("Check connectivity with IPv6 disabled", func() {
   200  			// Flannel always disables IPv6, this test is a no-op in that case.
   201  			SkipIfFlannel()
   202  
   203  			deployCilium([]string{
   204  				"--set global.ipv4.enabled=true",
   205  				"--set global.ipv6.enabled=false",
   206  			})
   207  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   208  			cleanService()
   209  		})
   210  	})
   211  
   212  	Context("ManagedEtcd", func() {
   213  		AfterAll(func() {
   214  			deleteETCDOperator(kubectl)
   215  		})
   216  		It("Check connectivity with managed etcd", func() {
   217  			deployCilium([]string{
   218  				"--set global.etcd.enabled=true",
   219  				"--set global.etcd.managed=true",
   220  			})
   221  			Expect(testPodConnectivityAcrossNodes(kubectl)).Should(BeTrue(), "Connectivity test between nodes failed")
   222  			cleanService()
   223  		})
   224  	})
   225  })
   226  
   227  func testPodConnectivityAcrossNodes(kubectl *helpers.Kubectl) bool {
   228  	By("Checking pod connectivity between nodes")
   229  
   230  	filter := "zgroup=testDS"
   231  
   232  	err := kubectl.WaitforPods(helpers.DefaultNamespace, fmt.Sprintf("-l %s", filter), helpers.HelperTimeout)
   233  	ExpectWithOffset(1, err).Should(BeNil(), "Failure while waiting for connectivity test pods to start")
   234  	pods, err := kubectl.GetPodNames(helpers.DefaultNamespace, filter)
   235  	Expect(err).Should(BeNil(), "Failure while retrieving pod name for %s", filter)
   236  	podIP, err := kubectl.Get(
   237  		helpers.DefaultNamespace,
   238  		fmt.Sprintf("pod %s -o json", pods[1])).Filter("{.status.podIP}")
   239  	Expect(err).Should(BeNil(), "Failure to retrieve IP of pod %s", pods[1])
   240  	res := kubectl.ExecPodCmd(helpers.DefaultNamespace, pods[0], helpers.Ping(podIP.String()))
   241  	return res.WasSuccessful()
   242  }