Tạo nguyên mẫu hạ tầng Network tại chỗ cho Workloads chạy trên Kubernetes Clusters: Phần 3

cloudFun

Bài đăng trước trong loạt bài đã đi sâu vào việc thiết lập IP Fabric trên Cumulus VX và tạo Kubernetes cluster được kết nối với nó. Bài viết này sẽ tập trung vào một trong những scenarios có sẵn để triển khai Calico và Kubernetes.(Bài viết tiếp theo sẽ xét đến scenario thứ 2; phần đầu của loạt bài này đã đề cập đến lịch sử của data centre networking và Calico cho Kubernetes.)

Theo như bài đăng trước, bây giờ cần triển khai Calico networking plugin để vận hành cluster. Bài viết này sẽ mô tả cách triển khai Calico với VXLAN overlay network. Nếu quan tâm đến việc triển khai bằng BGP mà không cần đóng gói, hãy đọc bài viết tiếp theo.

Hy vọng rằng loạt bài này sẽ hữu ích nếu người dùng đang ở giai đoạn thứ 3 của chuyển đổi Cloud Native, được gọi là Build, các hệ thống được tạo ra để giúp tổ chức cạnh tranh và phát triển.

Trong trường hợp muốn đưa toàn bộ môi trường lên workstation, thì tất cả scripts và playbook được sử dụng trong bài này có thể tìm trong kho lưu trữ GitLab

Kubernetes Inter-Workload giao tiếp với Overlay Network
Trong trường hợp này, các thành phần Calico networking đóng gói inter-workload traffic vào VXLAN. Cung cấp công cụ để di chuyển traffic qua network mà không làm nó nhận biết được workload hoặc service IP addresses. Không bắt buộc phải chạy BGP networking trên Kubernetes nodes, vì vậy nó có thể bị vô hiệu hóa để loại bỏ layer bổ sung phức tạp.

Như được trình bày ở sơ đồ dưới, giao thức định tuyến IP (eBGP) chạy độc lập với Kubernetes networking và không tương tác với định tuyến IP Kubernetes. Giao thức eBGP chịu trách nhiệm báo IP addresses của các networks được kết nối trực tiếp với leaf1 và leaf2 switches tương ứng. Mục đích là đạt được khả năng tiếp cận IP node-to-node trên IP Fabric, theo như Calico yêu cầu để xây dựng VXLAN overlay network cho Kubernetes.
PS19_10_21_Prototyping_on_premises_architecture_blogpost_Part3-diagram_1 copy.png

Vì IP Fabric chỉ cung cấp khả năng tiếp cận node-to-node, nên không thể biết IP addressing nào được dùng cho Kubernetes workloads. Do đó, trong trường hợp này, bất kỳ inter-workload traffic nào cũng phải được gói gọn trong VXLAN. Như được trình bày ở sơ đồ dưới, đối với bất kỳ inter-pod traffic nào, một overlay tunnel động giữa 2 nodes được xây dựng để mang workload traffic.
PS19_10_21_Prototyping_on_premises_architecture_blogpost_Part3-diagram_2 copy.png

Để hỗ trợ cho scenario này, cần đặt VXLAN làm calico_backend trong calico.yaml file. Lưu ý là điều này sẽ vô hiệu hóa chức năng BGP trong Calico, vì nó không phải là thành phần bắt buộc để scenario này hoạt động.

Calico.yaml file hoàn chỉnh có thể tìm thấy trong kho lưu trữ GitLab. Điều đáng nói là tệp này cũng cho Calico biết CIDRs nào nên được sử dụng cho pod và service addressing trên Kubernetes nodes. Kiểm tra các tham số CALICO_IPV4POOL_CIDR và CALICO_ADVERTISE_CLUSTER_IPS trong tệp đó. Trong scenario này, 10.64.0.0/12 và 10.80.0.0/12 prefixes sẽ được sử dụng cho pods và services tương ứng.

Thực thi vagrant.calico-vxlan-overlay.sh script để triển khai networking cho scenario này:
Mã:
$ sh vagrant.calico-vxlan-overlay.sh
serviceaccount/calicoctl created
pod/calicoctl created
clusterrole.rbac.authorization.k8s.io/calicoctl created
clusterrolebinding.rbac.authorization.k8s.io/calicoctl created
Connection to 127.0.0.1 closed.
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
Để xác minh rằng các phiên BGP được thiết lập giữa các IP Fabric switches và không có phiên nào khác, hãy sử dụng các lệnh trong snippet dưới đây:
Mã:
$ vagrant ssh leaf1 -c "sudo net show bgp sum"
show bgp ipv4 unicast summary
=============================
BGP router identifier 172.16.255.101, local AS number 65101 vrf-id 0
BGP table version 6
RIB entries 11, using 1672 bytes of memory
Peers 2, using 39 KiB of memory
Peer groups 1, using 64 bytes of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
spine-sw1.lab.local(172.16.0.0) 4 65001 2564 2566 0 0 0 02:07:56 3
spine-sw2.lab.local(172.16.0.4) 4 65002 2565 2566 0 0 0 02:07:56 3
Total number of neighbors 2
$ vagrant ssh leaf2 -c "sudo net show bgp sum"
show bgp ipv4 unicast summary
=============================
BGP router identifier 172.16.255.102, local AS number 65102 vrf-id 0
BGP table version 6
RIB entries 11, using 1672 bytes of memory
Peers 2, using 39 KiB of memory
Peer groups 1, using 64 bytes of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
spine-sw1.lab.local(172.16.0.2) 4 65001 2560 2562 0 0 0 02:07:43 4
spine-sw2.lab.local(172.16.0.6) 4 65002 2561 2562 0 0 0 02:07:43 4
Total number of neighbors 2
Trong output ở trên, có thể thấy rằng mỗi 2 leaf switches có 2 phiên BGP cho cả 2 spines. Không có phiên nào khác được thiết lập.

Tiếp theo, đăng nhập vào Kubernetes master node ( k8s-master-l1-1 ) và kiểm tra trạng thái của Kubernetes nodes bằng lệnh kubectl get nodes -o widel. Ngay bây giờ, tất cả các nodes nên chuyển sang trạng thái Ready vì networking component đã được triển khai. Cũng nên kiểm tra xem tất cả Calico pods cần thiết đã được triển khai thành công trên tất cả các nodes chưa:
Mã:
$ vagrant ssh k8s-master-l1-1
[vagrant@k8s-master-l1-1 ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-l1-1 Ready master 20h v1.15.2
k8s-node-l1-1 Ready <none> 20h v1.15.2
k8s-node-l1-2 Ready <none> 20h v1.15.2
k8s-node-l2-1 Ready <none> 20h v1.15.2
k8s-node-l2-2 Ready <none> 20h v1.15.2
[vagrant@k8s-master-l1-1 ~]$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-59f54d6bbc-xpn6z 1/1 Running 0 24m
calico-node-8wdhx 1/1 Running 0 24m
calico-node-hwkkx 1/1 Running 0 24m
calico-node-mm4lw 1/1 Running 0 24m
calico-node-qwzml 1/1 Running 0 24m
calico-node-txjvc 1/1 Running 0 24m
calicoctl 1/1 Running 0 24m
coredns-5c98db65d4-27f97 1/1 Running 0 20h
coredns-5c98db65d4-hbzts 1/1 Running 0 20h
etcd-k8s-master-l1-1 1/1 Running 1 20h
kube-apiserver-k8s-master-l1-1 1/1 Running 1 20h
kube-controller-manager-k8s-master-l1-1 1/1 Running 1 20h
kube-proxy-49db5 1/1 Running 1 20h
kube-proxy-nczf7 1/1 Running 1 20h
kube-proxy-tw7sm 1/1 Running 1 20h
kube-proxy-x76j7 1/1 Running 1 20h
kube-proxy-zdvql 1/1 Running 1 20h
kube-scheduler-k8s-master-l1-1 1/1 Running 1 20h
Nếu tất cả nodes ở trạng thái Ready và Calico pods ở trạng thái Running, điều đó có nghĩa là control plane của Calico đã hoạt động. Để kiểm tra data plane với VXLAN encapsulation, một triển khai mẫu với service có thể được triển khai đến cluster. Triển khai Nginx đơn giản có thể tìm thấy trong thư mục demo và được áp dụng như sau:
Mã:
[vagrant@k8s-master-l1-1 ~]$ kubectl apply -f demo/namespace.yaml
namespace/space1 created
[vagrant@k8s-master-l1-1 ~]$ kubectl apply -f demo/deployment.yaml
deployment.extensions/nginx-deployment created
[vagrant@k8s-master-l1-1 ~]$ kubectl apply -f demo/service.yaml
service/nginx-service created
[vagrant@k8s-master-l1-1 ~]$ kubectl get pods -n space1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-55457b9d87-nnzz5 1/1 Running 0 56s 10.65.76.193 k8s-node-l1-2 <none> <none>
Việc triển khai Nginx phải được chia thành 4 pods để triển khai pods trên các pods khác, vì vậy khả năng tiếp cận inter-pod IP có thể kiểm tra bằng scale command:
Mã:
[vagrant@k8s-master-l1-1 ~]$ kubectl scale deployment/nginx-deployment --replicas=4 -n space1
deployment.extensions/nginx-deployment scaled
Theo output được hiển thị ở đây, 4 pods được triển khai trên 4 pods riêng biệt:
Mã:
[vagrant@k8s-master-l1-1 ~]$ kubectl get pods -n space1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-55457b9d87-nnzz5 1/1 Running 0 4m3s 10.65.76.193 k8s-node-l1-2 <none> <none>
nginx-deployment-55457b9d87-x9llj 1/1 Running 0 13s 10.67.209.2 k8s-node-l1-1 <none> <none>
nginx-deployment-55457b9d87-xhhwl 1/1 Running 0 13s 10.76.172.132 k8s-node-l2-2 <none> <none>
nginx-deployment-55457b9d87-z9pl9 1/1 Running 0 13s 10.68.86.129 k8s-node-l2-1 <none> <none>
Tiếp theo, kiểm tra xem có path qua network giữa các pods hay không bằng ping utility.

Đăng nhập vào nginx-deployment-55457b9d87-z9pl9 pod chạy trên k8s-node-l2-1 bằng lệnh kubectl exec và cài đặt ping utility. Triển khai ping hướng tới Nginx pod nginx-deployment-55457b9d87-nnzz5 chạy trên k8s-node-l1-2 (10,65.76.193), được kết nối với leaf1 switch. (Output bên dưới được lược bỏ)
Mã:
[vagrant@k8s-master-l1-1 ~]$ kubectl exec -it nginx-deployment-55457b9d87-z9pl9 -n space1 -- bash
root@nginx-deployment-55457b9d87-z9pl9:/# apt update && apt install iputils-ping
debconf: falling back to frontend: Teletype
Setting up iputils-ping (3:20180629-2) ...
Processing triggers for libc-bin (2.28-10) ...
root@nginx-deployment-55457b9d87-z9pl9:/# ping 10.65.76.193
PING 10.65.76.193 (10.65.76.193) 56(84) bytes of data.
64 bytes from 10.65.76.193: icmp_seq=1 ttl=62 time=1.57 ms
64 bytes from 10.65.76.193: icmp_seq=2 ttl=62 time=1.86 ms
64 bytes from 10.65.76.193: icmp_seq=3 ttl=62 time=1.60 ms
64 bytes from 10.65.76.193: icmp_seq=4 ttl=62 time=1.56 ms
Như output ở trên, pod từ xa đã phản hồi thành công các yêu cầu ping, có nghĩa là có một path qua network giữa 2 pods chạy trên các nodes riêng biệt.

Bây giờ nên kiểm tra traffic ở một trong các nodes, để xác minh xem traffic có được gói gọn trong VXLAN theo kế hoạch hay không. Mở tab mới trong terminal và ssh vào k8s-node-l2-1. Để kiểm tra traffic, tcpdump utility sẽ được sử dụng. Đầu tiên nó cần được cài đặt trên node. Vì VXLAN encapsulation đang sử dụng giao thức UDP trên cổng 4789, nên có thể thu nạp bất kỳ UDP traffic nào trên cổng đó với tcpdump. Việc thu nạp Traffic cần phải được thực hiện trên giao diện eth0, được kết nối với IP Fabric network. (Một số output được lược bỏ)
Mã:
piotrszlenk@mbpro13 ~/Documents/Dev/calico-cumulus (master) $ vagrant ssh k8s-node-l2-1
[vagrant@k8s-node-l2-1 ~]$ sudo yum install -y tcpdump
[vagrant@k8s-node-l2-1 ~]$ sudo tcpdump -i eth0 -ne udp port 4789
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
08:57:12.688881 08:00:27:53:73:c7 > 08:00:27:91:d4:66, ethertype IPv4 (0x0800), length 148: 10.0.102.101.41553 > 10.0.101.102.4789: VXLAN, flags [I] (0x08), vni 4096
66:92:0a:fb:a9:be > 66:81:2e:61:22:8a, ethertype IPv4 (0x0800), length 98: 10.68.86.129 > 10.65.76.193: ICMP echo request, id 592, seq 1, length 64
08:57:12.690316 08:00:27:91:d4:66 > 08:00:27:53:73:c7, ethertype IPv4 (0x0800), length 148: 10.0.101.102.32779 > 10.0.102.101.4789: VXLAN, flags [I] (0x08), vni 4096
66:81:2e:61:22:8a > 66:92:0a:fb:a9:be, ethertype IPv4 (0x0800), length 98: 10.65.76.193 > 10.68.86.129: ICMP echo reply, id 592, seq 1, length 64
08:57:13.690925 08:00:27:53:73:c7 > 08:00:27:91:d4:66, ethertype IPv4 (0x0800), length 148: 10.0.102.101.41553 > 10.0.101.102.4789: VXLAN, flags [I] (0x08), vni 4096
66:92:0a:fb:a9:be > 66:81:2e:61:22:8a, ethertype IPv4 (0x0800), length 98: 10.68.86.129 > 10.65.76.193: ICMP echo request, id 592, seq 2, length 64
>08:57:13.692672 08:00:27:91:d4:66 > 08:00:27:53:73:c7, ethertype IPv4 (0x0800), length 148: 10.0.101.102.32779 > 10.0.102.101.4789: VXLAN, flags [I] (0x08), vni 4096
66:81:2e:61:22:8a > 66:92:0a:fb:a9:be, ethertype IPv4 (0x0800), length 98: 10.65.76.193 > 10.68.86.129: ICMP echo reply, id 592, seq 2, length 64
08:57:14.691941 08:00:27:53:73:c7 > 08:00:27:91:d4:66, ethertype IPv4 (0x0800), length 148: 10.0.102.101.41553 > 10.0.101.102.4789: VXLAN, flags [I] (0x08), vni 4096
66:92:0a:fb:a9:be > 66:81:2e:61:22:8a, ethertype IPv4 (0x0800), length 98: 10.68.86.129 > 10.65.76.193: ICMP echo request, id 592, seq 3, length 64
08:57:14.693449 08:00:27:91:d4:66 > 08:00:27:53:73:c7, ethertype IPv4 (0x0800), length 148: 10.0.101.102.32779 > 10.0.102.101.4789: VXLAN, flags [I] (0x08), vni 4096
66:81:2e:61:22:8a > 66:92:0a:fb:a9:be, ethertype IPv4 (0x0800), length 98: 10.65.76.193 > 10.68.86.129: ICMP echo reply, id 592, seq 3, length 64
08:57:15.693151 08:00:27:53:73:c7 > 08:00:27:91:d4:66, ethertype IPv4 (0x0800), length 148: 10.0.102.101.41553 > 10.0.101.102.4789: VXLAN, flags [I] (0x08), vni 4096
66:92:0a:fb:a9:be > 66:81:2e:61:22:8a, ethertype IPv4 (0x0800), length 98: 10.68.86.129 > 10.65.76.193: ICMP echo request, id 592, seq 4, length 64
08:57:15.694624 08:00:27:91:d4:66 > 08:00:27:53:73:c7, ethertype IPv4 (0x0800), length 148: 10.0.101.102.32779 > 10.0.102.101.4789: VXLAN, flags [I] (0x08), vni 4096
66:81:2e:61:22:8a > 66:92:0a:fb:a9:be, ethertype IPv4 (0x0800), length 98: 10.65.76.193 > 10.68.86.129: ICMP echo reply, id 592, seq 4, length 64
Như có thể quan sát được trong quá trình thu nạp packet, ethernet frame từ k8s-node-l2-1 (IP 10.0.102.101) đến k8s-node-l1-2 (IP 10.0.101.102) chứa ICMP echo request có nguồn gốc từ container có IP là 10,68,86.129 và được nhắm mục tiêu đến container có IP là 10,65.76.193. ICMP packet đó được gói gọn trong VXLAN với VNI là 4096, là giá trị mặc định cho Calico. Nó trông như sau:
Mã:
08:57:12.688881 08:00:27:53:73:c7 > 08:00:27:91:d4:66, ethertype IPv4 (0x0800), length 148: 10.0.102.101.41553 > 10.0.101.102.4789: VXLAN, flags [I] (0x08), vni 4096
66:92:0a:fb:a9:be > 66:81:2e:61:22:8a, ethertype IPv4 (0x0800), length 98: 10.68.86.129 > 10.65.76.193: ICMP echo request, id 592, seq 1, length 64
Dòng tiếp theo hiển thị ethernet frame bị thu nạp có chứa thông báo ICMP echo reply từ container từ xa được gói gọn trong VXLAN.
Mã:
08:57:12.690316 08:00:27:91:d4:66 > 08:00:27:53:73:c7, ethertype IPv4 (0x0800), length 148: 10.0.101.102.32779 > 10.0.102.101.4789: VXLAN, flags [I] (0x08), vni 409666:81:2e:61:22:8a > 66:92:0a:fb:a9:be, ethertype IPv4 (0x0800), length 98: 10.65.76.193 > 10.68.86.129: ICMP echo reply, id 592, seq 1, length 64
Phản hồi thành công tới lệnh ping xác nhận rằng khả năng tiếp cận IP đã đạt được giữa các pods chạy trên 2 nodes riêng biệt, có thể quan sát trong output ở trên. Một overlay network với VXLAN encapsulation đã được sử dụng để di chuyển traffic.

Tại thời điểm này, Kubernetes cluster sẽ hoạt động hoàn toàn với Calico là network component. Inter-Pod traffic được gói gọn trong VXLAN do đó mạng IP Fabric network cơ sở không nhận biết được IP addressing được sử dụng cho Pods hoặc Services. Không có BGP peering nào được tham gia giữa IP Fabric network và các Kubernetes nodes.

Bây giờ hãy xem một scenario có sẵn khác để triển khai Calico và Kubernetes, trong đó Calico được định cấu hình để ngang hàng với BGP với IP Fabric và không đóng gói inter-pod traffic vào VXLAN

Nguồn: https://blog.container-solutions.com/
 
Top