blob: 4e0d0c6c52bc5ce93c5d4b0b2a0965239a88ad3e [file] [log] [blame]
Nathan Skrzypczak9ad39c02021-08-19 11:38:06 +02001Manual Installation
2===================
3
4This document describes how to clone the Contiv repository and then use
5`kubeadm <https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/>`__
6to manually install Kubernetes with Contiv-VPP networking on one or more
7bare metal or VM hosts.
8
9Clone the Contiv Repository
10---------------------------
11
12To clone the Contiv repository enter the following command:
13
14::
15
16 git clone https://github.com/contiv/vpp/<repository-name>
17
18**Note:** Replace ** with the name you want assigned to your cloned
19contiv repository.
20
21The cloned repository has important folders that contain content that
22are referenced in this Contiv documentation; those folders are noted
23below:
24
25::
26
27 vpp-contiv2$ ls
28 build build-root doxygen gmod LICENSE Makefile RELEASE.md src
29 build-data docs extras INFO.yaml MAINTAINERS README.md sphinx_venv test
30
31Preparing Your Hosts
32--------------------
33
34Host-specific Configurations
35~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36
37- **VmWare VMs**: the vmxnet3 driver is required on each interface that
38 will be used by VPP. Please see
39 `here <https://github.com/contiv/vpp/tree/master/docs/VMWARE_FUSION_HOST.md>`__
40 for instructions how to install the vmxnet3 driver on VmWare Fusion.
41
42Setting up Network Adapter(s)
43~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44
45Setting up DPDK
46^^^^^^^^^^^^^^^
47
48DPDK setup must be completed **on each node** as follows:
49
50- Load the PCI UIO driver:
51
52 ::
53
54 $ sudo modprobe uio_pci_generic
55
56- Verify that the PCI UIO driver has loaded successfully:
57
58 ::
59
60 $ lsmod | grep uio
61 uio_pci_generic 16384 0
62 uio 20480 1 uio_pci_generic
63
64 Please note that this driver needs to be loaded upon each server
65 bootup, so you may want to add ``uio_pci_generic`` into the
66 ``/etc/modules`` file, or a file in the ``/etc/modules-load.d/``
67 directory. For example, the ``/etc/modules`` file could look as
68 follows:
69
70 ::
71
72 # /etc/modules: kernel modules to load at boot time.
73 #
74 # This file contains the names of kernel modules that should be loaded
75 # at boot time, one per line. Lines beginning with "#" are ignored.
76 uio_pci_generic
77
78 .. rubric:: Determining Network Adapter PCI Addresses
79 :name: determining-network-adapter-pci-addresses
80
81 You need the PCI address of the network interface that VPP will use
82 for the multi-node pod interconnect. On Debian-based distributions,
83 you can use ``lshw``\ (*):
84
85::
86
87 $ sudo lshw -class network -businfo
88 Bus info Device Class Description
89 ====================================================
90 pci@0000:00:03.0 ens3 network Virtio network device
91 pci@0000:00:04.0 ens4 network Virtio network device
92
93**Note:** On CentOS/RedHat/Fedora distributions, ``lshw`` may not be
94available by default, install it by issuing the following command:
95``yum -y install lshw``
96
97Configuring vswitch to Use Network Adapters
98^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
99
100Finally, you need to set up the vswitch to use the network adapters:
101
102- `Setup on a node with a single
103 NIC <https://github.com/contiv/vpp/tree/master/docs/SINGLE_NIC_SETUP.md>`__
104- `Setup a node with multiple
105 NICs <https://github.com/contiv/vpp/tree/master/docs/MULTI_NIC_SETUP.md>`__
106
107Using a Node Setup Script
108~~~~~~~~~~~~~~~~~~~~~~~~~
109
110You can perform the above steps using the `node setup
111script <https://github.com/contiv/vpp/tree/master/k8s/README.md#setup-node-sh>`__.
112
113Installing Kubernetes with Contiv-VPP CNI plugin
114------------------------------------------------
115
116After the nodes you will be using in your K8s cluster are prepared, you
117can install the cluster using
118`kubeadm <https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/>`__.
119
120(1/4) Installing Kubeadm on Your Hosts
121~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
122
123For first-time installation, see `Installing
124kubeadm <https://kubernetes.io/docs/setup/independent/install-kubeadm/>`__.
125To update an existing installation, you should do a
126``apt-get update && apt-get upgrade`` or ``yum update`` to get the
127latest version of kubeadm.
128
129On each host with multiple NICs where the NIC that will be used for
130Kubernetes management traffic is not the one pointed to by the default
131route out of the host, a `custom management
132network <https://github.com/contiv/vpp/tree/master/docs/CUSTOM_MGMT_NETWORK.md>`__
133for Kubernetes must be configured.
134
135Using Kubernetes 1.10 and Above
136^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
137
138In K8s 1.10, support for huge pages in a pod has been introduced. For
139now, this feature must be either disabled or memory limit must be
140defined for vswitch container.
141
142To disable huge pages, perform the following steps as root: \* Using
143your favorite editor, disable huge pages in the kubelet configuration
144file (``/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`` or
145``/etc/default/kubelet`` for version 1.11+):
146
147::
148
149 Environment="KUBELET_EXTRA_ARGS=--feature-gates HugePages=false"
150
151- Restart the kubelet daemon:
152
153::
154
155 systemctl daemon-reload
156 systemctl restart kubelet
157
158To define memory limit, append the following snippet to vswitch
159container in deployment yaml file:
160
161::
162
163 resources:
164 limits:
165 hugepages-2Mi: 1024Mi
166 memory: 1024Mi
167
168or set ``contiv.vswitch.defineMemoryLimits`` to ``true`` in `helm
169values <https://github.com/contiv/vpp/blob/master/k8s/contiv-vpp/README.md>`__.
170
171(2/4) Initializing Your Master
172~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173
174Before initializing the master, you may want to
175`remove <#tearing-down-kubernetes>`__ any previously installed K8s
176components. Then, proceed with master initialization as described in the
177`kubeadm
178manual <https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#initializing-your-master>`__.
179Execute the following command as root:
180
181::
182
183 kubeadm init --token-ttl 0 --pod-network-cidr=10.1.0.0/16
184
185**Note:** ``kubeadm init`` will autodetect the network interface to
186advertise the master on as the interface with the default gateway. If
187you want to use a different interface (i.e. a custom management network
188setup), specify the ``--apiserver-advertise-address=<ip-address>``
189argument to kubeadm init. For example:
190
191::
192
193 kubeadm init --token-ttl 0 --pod-network-cidr=10.1.0.0/16 --apiserver-advertise-address=192.168.56.106
194
195**Note:** The CIDR specified with the flag ``--pod-network-cidr`` is
196used by kube-proxy, and it **must include** the ``PodSubnetCIDR`` from
197the ``IPAMConfig`` section in the Contiv-vpp config map in Contiv-vpp’s
198deployment file
199`contiv-vpp.yaml <https://github.com/contiv/vpp/blob/master/k8s/contiv-vpp/values.yaml>`__.
200Pods in the host network namespace are a special case; they share their
201respective interfaces and IP addresses with the host. For proxying to
202work properly it is therefore required for services with backends
203running on the host to also **include the node management IP** within
204the ``--pod-network-cidr`` subnet. For example, with the default
205``PodSubnetCIDR=10.1.0.0/16`` and ``PodIfIPCIDR=10.2.1.0/24``, the
206subnet ``10.3.0.0/16`` could be allocated for the management network and
207``--pod-network-cidr`` could be defined as ``10.0.0.0/8``, so as to
208include IP addresses of all pods in all network namespaces:
209
210::
211
212 kubeadm init --token-ttl 0 --pod-network-cidr=10.0.0.0/8 --apiserver-advertise-address=10.3.1.1
213
214If Kubernetes was initialized successfully, it prints out this message:
215
216::
217
218 Your Kubernetes master has initialized successfully!
219
220After successful initialization, don’t forget to set up your .kube
221directory as a regular user (as instructed by ``kubeadm``):
222
223.. code:: bash
224
225 mkdir -p $HOME/.kube
226 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
227 sudo chown $(id -u):$(id -g) $HOME/.kube/config
228
229(3/4) Installing the Contiv-VPP Pod Network
230~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231
232If you have already used the Contiv-VPP plugin before, you may need to
233pull the most recent Docker images on each node:
234
235::
236
237 bash <(curl -s https://raw.githubusercontent.com/contiv/vpp/master/k8s/pull-images.sh)
238
239Install the Contiv-VPP network for your cluster as follows:
240
241- If you do not use the STN feature, install Contiv-vpp as follows:
242
243 ::
244
245 kubectl apply -f https://raw.githubusercontent.com/contiv/vpp/master/k8s/contiv-vpp.yaml
246
247- If you use the STN feature, download the ``contiv-vpp.yaml`` file:
248
249 ::
250
251 wget https://raw.githubusercontent.com/contiv/vpp/master/k8s/contiv-vpp.yaml
252
253 Then edit the STN configuration as described
254 `here <https://github.com/contiv/vpp/tree/master/docs/SINGLE_NIC_SETUP.md#configuring-stn-in-contiv-vpp-k8s-deployment-files>`__.
255 Finally, create the Contiv-vpp deployment from the edited file:
256
257 ::
258
259 kubectl apply -f ./contiv-vpp.yaml
260
261Beware contiv-etcd data is persisted in ``/var/etcd`` by default. It has
262to be cleaned up manually after ``kubeadm reset``. Otherwise outdated
263data will be loaded by a subsequent deployment.
264
265You can also generate random subfolder, alternatively:
266
267::
268
269 curl --silent https://raw.githubusercontent.com/contiv/vpp/master/k8s/contiv-vpp.yaml | sed "s/\/var\/etcd\/contiv-data/\/var\/etcd\/contiv-data\/$RANDOM/g" | kubectl apply -f -
270
271Deployment Verification
272^^^^^^^^^^^^^^^^^^^^^^^
273
274After some time, all contiv containers should enter the running state:
275
276::
277
278 root@cvpp:/home/jan# kubectl get pods -n kube-system -o wide | grep contiv
279 NAME READY STATUS RESTARTS AGE IP NODE
280 ...
281 contiv-etcd-gwc84 1/1 Running 0 14h 192.168.56.106 cvpp
282 contiv-ksr-5c2vk 1/1 Running 2 14h 192.168.56.106 cvpp
283 contiv-vswitch-l59nv 2/2 Running 0 14h 192.168.56.106 cvpp
284
285In particular, make sure that the Contiv-VPP pod IP addresses are the
286same as the IP address specified in the
287``--apiserver-advertise-address=<ip-address>`` argument to kubeadm init.
288
289Verify that the VPP successfully grabbed the network interface specified
290in the VPP startup config (``GigabitEthernet0/4/0`` in our case):
291
292::
293
294 $ sudo vppctl
295 vpp# sh inter
296 Name Idx State Counter Count
297 GigabitEthernet0/4/0 1 up rx packets 1294
298 rx bytes 153850
299 tx packets 512
300 tx bytes 21896
301 drops 962
302 ip4 1032
303 host-40df9b44c3d42f4 3 up rx packets 126601
304 rx bytes 44628849
305 tx packets 132155
306 tx bytes 27205450
307 drops 24
308 ip4 126585
309 ip6 16
310 host-vppv2 2 up rx packets 132162
311 rx bytes 27205824
312 tx packets 126658
313 tx bytes 44634963
314 drops 15
315 ip4 132147
316 ip6 14
317 local0 0 down
318
319You should also see the interface to kube-dns (``host-40df9b44c3d42f4``)
320and to the node’s IP stack (``host-vppv2``).
321
322Master Isolation (Optional)
323^^^^^^^^^^^^^^^^^^^^^^^^^^^
324
325By default, your cluster will not schedule pods on the master for
326security reasons. If you want to be able to schedule pods on the master,
327(e.g., for a single-machine Kubernetes cluster for development), then
328run:
329
330::
331
332 kubectl taint nodes --all node-role.kubernetes.io/master-
333
334More details about installing the pod network can be found in the
335`kubeadm
336manual <https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network>`__.
337
338(4/4) Joining Your Nodes
339~~~~~~~~~~~~~~~~~~~~~~~~
340
341To add a new node to your cluster, run as root the command that was
342output by kubeadm init. For example:
343
344::
345
346 kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>
347
348More details can be found int the `kubeadm
349manual <https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#joining-your-nodes>`__.
350
351.. _deployment-verification-1:
352
353Deployment Verification
354^^^^^^^^^^^^^^^^^^^^^^^
355
356After some time, all contiv containers should enter the running state:
357
358::
359
360 root@cvpp:/home/jan# kubectl get pods -n kube-system -o wide | grep contiv
361 NAME READY STATUS RESTARTS AGE IP NODE
362 contiv-etcd-gwc84 1/1 Running 0 14h 192.168.56.106 cvpp
363 contiv-ksr-5c2vk 1/1 Running 2 14h 192.168.56.106 cvpp
364 contiv-vswitch-h6759 2/2 Running 0 14h 192.168.56.105 cvpp-slave2
365 contiv-vswitch-l59nv 2/2 Running 0 14h 192.168.56.106 cvpp
366 etcd-cvpp 1/1 Running 0 14h 192.168.56.106 cvpp
367 kube-apiserver-cvpp 1/1 Running 0 14h 192.168.56.106 cvpp
368 kube-controller-manager-cvpp 1/1 Running 0 14h 192.168.56.106 cvpp
369 kube-dns-545bc4bfd4-fr6j9 3/3 Running 0 14h 10.1.134.2 cvpp
370 kube-proxy-q8sv2 1/1 Running 0 14h 192.168.56.106 cvpp
371 kube-proxy-s8kv9 1/1 Running 0 14h 192.168.56.105 cvpp-slave2
372 kube-scheduler-cvpp 1/1 Running 0 14h 192.168.56.106 cvpp
373
374In particular, verify that a vswitch pod and a kube-proxy pod is running
375on each joined node, as shown above.
376
377On each joined node, verify that the VPP successfully grabbed the
378network interface specified in the VPP startup config
379(``GigabitEthernet0/4/0`` in our case):
380
381::
382
383 $ sudo vppctl
384 vpp# sh inter
385 Name Idx State Counter Count
386 GigabitEthernet0/4/0 1 up
387 ...
388
389From the vpp CLI on a joined node you can also ping kube-dns to verify
390node-to-node connectivity. For example:
391
392::
393
394 vpp# ping 10.1.134.2
395 64 bytes from 10.1.134.2: icmp_seq=1 ttl=64 time=.1557 ms
396 64 bytes from 10.1.134.2: icmp_seq=2 ttl=64 time=.1339 ms
397 64 bytes from 10.1.134.2: icmp_seq=3 ttl=64 time=.1295 ms
398 64 bytes from 10.1.134.2: icmp_seq=4 ttl=64 time=.1714 ms
399 64 bytes from 10.1.134.2: icmp_seq=5 ttl=64 time=.1317 ms
400
401 Statistics: 5 sent, 5 received, 0% packet loss
402
403Deploying Example Applications
404~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
405
406Simple Deployment
407^^^^^^^^^^^^^^^^^
408
409You can go ahead and create a simple deployment:
410
411::
412
413 $ kubectl run nginx --image=nginx --replicas=2
414
415Use ``kubectl describe pod`` to get the IP address of a pod, e.g.:
416
417::
418
419 $ kubectl describe pod nginx | grep IP
420
421You should see two ip addresses, for example:
422
423::
424
425 IP: 10.1.1.3
426 IP: 10.1.1.4
427
428You can check the pods’ connectivity in one of the following ways: \*
429Connect to the VPP debug CLI and ping any pod:
430
431::
432
433 sudo vppctl
434 vpp# ping 10.1.1.3
435
436- Start busybox and ping any pod:
437
438::
439
440 kubectl run busybox --rm -ti --image=busybox /bin/sh
441 If you don't see a command prompt, try pressing enter.
442 / #
443 / # ping 10.1.1.3
444
445- You should be able to ping any pod from the host:
446
447::
448
449 ping 10.1.1.3
450
451Deploying Pods on Different Nodes
452^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
453
454to enable pod deployment on the master, untaint the master first:
455
456::
457
458 kubectl taint nodes --all node-role.kubernetes.io/master-
459
460In order to verify inter-node pod connectivity, we need to tell
461Kubernetes to deploy one pod on the master node and one POD on the
462worker. For this, we can use node selectors.
463
464In your deployment YAMLs, add the ``nodeSelector`` sections that refer
465to preferred node hostnames, e.g.:
466
467::
468
469 nodeSelector:
470 kubernetes.io/hostname: vm5
471
472Example of whole JSONs:
473
474::
475
476 apiVersion: v1
477 kind: Pod
478 metadata:
479 name: nginx1
480 spec:
481 nodeSelector:
482 kubernetes.io/hostname: vm5
483 containers:
484 - name: nginx
485
486 : nginx
487
488::
489
490 apiVersion: v1
491 kind: Pod
492 metadata:
493 name: nginx2
494 spec:
495 nodeSelector:
496 kubernetes.io/hostname: vm6
497 containers:
498 - name: nginx
499 image: nginx
500
501After deploying the JSONs, verify they were deployed on different hosts:
502
503::
504
505 $ kubectl get pods -o wide
506 NAME READY STATUS RESTARTS AGE IP NODE
507 nginx1 1/1 Running 0 13m 10.1.36.2 vm5
508 nginx2 1/1 Running 0 13m 10.1.219.3 vm6
509
510Now you can verify the connectivity to both nginx PODs from a busybox
511POD:
512
513::
514
515 kubectl run busybox --rm -it --image=busybox /bin/sh
516
517 / # wget 10.1.36.2
518 Connecting to 10.1.36.2 (10.1.36.2:80)
519 index.html 100% |*******************************************************************************************************************************************************************| 612 0:00:00 ETA
520
521 / # rm index.html
522
523 / # wget 10.1.219.3
524 Connecting to 10.1.219.3 (10.1.219.3:80)
525 index.html 100% |*******************************************************************************************************************************************************************| 612 0:00:00 ETA
526
527Uninstalling Contiv-VPP
528~~~~~~~~~~~~~~~~~~~~~~~
529
530To uninstall the network plugin itself, use ``kubectl``:
531
532::
533
534 kubectl delete -f https://raw.githubusercontent.com/contiv/vpp/master/k8s/contiv-vpp.yaml
535
536Tearing down Kubernetes
537~~~~~~~~~~~~~~~~~~~~~~~
538
539- First, drain the node and make sure that the node is empty before
540 shutting it down:
541
542::
543
544 kubectl drain <node name> --delete-local-data --force --ignore-daemonsets
545 kubectl delete node <node name>
546
547- Next, on the node being removed, reset all kubeadm installed state:
548
549::
550
551 rm -rf $HOME/.kube
552 sudo su
553 kubeadm reset
554
555- If you added environment variable definitions into
556 ``/etc/systemd/system/kubelet.service.d/10-kubeadm.conf``, this would
557 have been a process from the `Custom Management Network
558 file <https://github.com/contiv/vpp/blob/master/docs/CUSTOM_MGMT_NETWORK.md#setting-up-a-custom-management-network-on-multi-homed-nodes>`__,
559 then remove the definitions now.
560
561Troubleshooting
562~~~~~~~~~~~~~~~
563
564Some of the issues that can occur during the installation are:
565
566- Forgetting to create and initialize the ``.kube`` directory in your
567 home directory (As instructed by ``kubeadm init --token-ttl 0``).
568 This can manifest itself as the following error:
569
570 ::
571
572 W1017 09:25:43.403159 2233 factory_object_mapping.go:423] Failed to download OpenAPI (Get https://192.168.209.128:6443/swagger-2.0.0.pb-v1: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")), falling back to swagger
573 Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
574
575- Previous installation lingering on the file system.
576 ``'kubeadm init --token-ttl 0`` fails to initialize kubelet with one
577 or more of the following error messages:
578
579 ::
580
581 ...
582 [kubelet-check] It seems like the kubelet isn't running or healthy.
583 [kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10255/healthz' failed with error: Get http://localhost:10255/healthz: dial tcp [::1]:10255: getsockopt: connection refused.
584 ...
585
586If you run into any of the above issues, try to clean up and reinstall
587as root:
588
589::
590
591 sudo su
592 rm -rf $HOME/.kube
593 kubeadm reset
594 kubeadm init --token-ttl 0
595 rm -rf /var/etcd/contiv-data
596 rm -rf /var/bolt/bolt.db
597
598Contiv-specific kubeadm installation on Aarch64
599-----------------------------------------------
600
601Supplemental instructions apply when using Contiv-VPP for Aarch64. Most
602installation steps for Aarch64 are the same as that described earlier in
603this chapter, so you should firstly read it before you start the
604installation on Aarch64 platform.
605
606Use the `Aarch64-specific kubeadm install
607instructions <https://github.com/contiv/vpp/blob/master/docs/arm64/MANUAL_INSTALL_ARM64.md>`__
608to manually install Kubernetes with Contiv-VPP networking on one or more
609bare-metals of Aarch64 platform.