Tuesday, 24 July 2018

Using MetalLB in Kubernetes for the external connectivity

MetalLB for External Connectivity

   This post explains how we can use MetalLB to attract traffic from a gateway router to kubernetes cluster. 

Prerequisites

  • kubernetes cluster ( I have 1 master + 2 node cluster)
  • Installed pod networking. Calico is used as CNI in my setup
  • Gateway router with BGP. 

Installation and configuration 

  1. Install Metallb using below yaml file. 
kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.6.2/manifests/metallb.yaml

This will create one controller and two speaker pods. Controller will be responsible for assigning external IP address from the address pool defined in the config file (step 3).
Speaker nodes will announce the IP address to the gateway router

      2.  You can view the pods running successfully in namespace metallb-system

    







      3. Create a config map with BGP configuration details and address pool from which externalIP for the services will be picked automatically as shown below

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    peers:
    - peer-address: 172.16.0.11
      peer-asn: 65001
      my-asn: 64512
    address-pools:
    - name: default
      protocol: bgp
      addresses:
      - 80.11.12.0/30
In the above configuration peer-address and peer-asn are the IP address and asn of my gateway router.

    4. After creating config map file check whether BGP peer is established with the gateway router in the speaker logs.

root@master1:~/metalLB# kubectl logs -n metallb-system speaker-fx4d9
......
{"caller":"bgp.go:62","event":"sessionUp","localASN":64512,"msg":"BGP session established","peer":"172.16.0.11:179","peerASN":65001,"ts":"2018-07-06T00:19:51.282711062Z"}

Create a service and test


  •      Create a service to check whether metalLB assigns externalIP. If you dont want to assign a fixed externalIP to your service you can use loadBalancerIP. Note that the address must be in the range defined in the config map in step 3.

apiVersion: v1
kind: Service
metadata:
  name: metalservice
  namespace: default
spec:
  ports:
  - port: 5001
    protocol: TCP
    targetPort: 80
  selector:
    run: my-nginx
  loadBalancerIP: 80.11.12.1
  type: LoadBalancer

  •     Check whether the service got external-ip

root@master1:~/metalLB# kubectl get svc
NAME           TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes     ClusterIP      10.96.0.1                 <none>        443/TCP          17h
metalservice   LoadBalancer   10.111.117.248   80.11.12.1    5001:30879/TCP   2h


In the speaker logs you can see the external IP is advertised 

{"caller":"bgp_controller.go:162","event":"updatedAdvertisements","ip":"80.11.12.1","msg":"making advertisements using BGP","numAds":1,"pool":"default","protocol":"bgp","service":"default/metalservice","ts":"2018-07-06T00:22:18.896880181Z"}


  • Verification from router

In the router you can see the externalIP address and next hop as the worker nodes

vm-011 ~ # gobgp global rib
   Network              Next Hop             AS_PATH              Age        Attrs
*> 80.11.12.1/32    172.16.0.10          64512                02:11:07   [{Origin: ?} {Med: 0} {LocalPref: }]
80.11.12.1/32      172.16.0.9           64512                02:11:07   [{Origin: ?} {Med: 0} {LocalPref:}]
*> 172.16.0.0/16        0.0.0.0                                   00:21:31   [{Origin: i} {Med: 0}]

Check whether you can access the service from the router

vm-011 ~ # wget http://80.11.12.1:5001
Connecting to 80.11.12.1:5001 (80.11.12.1:5001)
index.html           100% |**************************************************************************************************************************************************************|   612   0:00:00 ETA
vm-011 ~ #


References




Thursday, 21 June 2018

How to clean up Kubernetes

Steps to clean up kubernetes 

Follow below steps to clean

kubeadm reset
sudo apt-get -y purge kubeadm kubectl kubelet kube*
sudo apt-get -y autoremove
sudo rm -rf ~/.kube

How to setup Kubernetes cluster in windows using Ubuntu VMs

Setting up Kubernetes cluster in Windows using Ubuntu VMs

Below lists simple steps that can be followed to set up a cluster using ubuntu VMs. You can set it up in any OS. I have windows machine.

1 master+ 2 node deployment

 Prerequisites

  • Oracle VM Virtual Box : Download from https://www.virtualbox.org/
  • Turn on hardware virtualization support in BIOS Settings. (Hyper V in windows 10 )

Create VMs

Create 2 VMs for 1 master with 1 worker node cluster with below requirements
  • Version: Ubuntu (64-bit)
  • Processor: 2 CPU
  • 4 GB RAM
  • Network : Select NAT as adapter 1 and Host only adapter as adapter 2

Initial setup on all nodes

  1. Turn off swap  using  sudo swapoff -a
             Comment the line with swap in /etc/fstab
              nano /etc/fstab  
  2. Add IP address of all nodes in etc/hosts with details of ip address and hostname as below. 
                        

     Note! Above IP addresses are selected by adding a new virtual host adapter as explained in Add new Adapter Interface . It is also possible to use default IP address selected by Virtual Box as below and no need to create a new adapter interface. 



      3. Install docker
                     apt-get update && apt-get install -y docker.io
       4. Install Kubernetes

          apt-get update && apt-get install -y apt-transport-https curl
          curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
          cat << EOF >/etc/apt/sources.list.d/kubernetes.list
             deb http://apt.kubernetes.io/ kubernetes-xenial main
           EOF

          apt-get update && apt-get install -y kubelet kubeadm kubectl
      5. Update cgroup-driver 
            nano /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    Edit kubeadm.conf file and add below variable after the last Environment
           Environment="cgroup-driver=systemd/cgroup-driver=cgroupfs" 


On Master Node

1. kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=<IP_Address_of_MasterNode>

eg: kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=172.16.0.3

The above command will generate below comments as part of the output
"
To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube  
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config 
 sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each nodeas root:
kubeadm join 172.16.0.3:6443 --token 1yy5o4.qokxr4wu5t58kxe1 --discovery-token-ca-cert-hash sha256:ca16640bf7de68d2e036dbe08e5097f6246379ffd87c0d08ef8f4e1d83f08fcc "

Save this join command and can be used to add any number of nodes to your cluster.

2. Start the cluster as mentioned in the result of step1

     mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

3. Join other nodes using the command after logging to worker nodes

kubeadm join 172.16.0.3:6443 --token 1yy5o4.qokxr4wu5t58kxe1 --discovery-token-ca-cert-hash sha256:ca16640bf7de68d2e036dbe08e5097f6246379ffd87c0d08ef8f4e1d83f08fcc

3. Check whether the nodes are running

kubectl get nodes -o wide

Note! The nodes status will be 'NotReady'  as CNI is not yet installed. Proceed to step 4 for that.

4. Install CNI plugin. I have used calico. If your node has multiple interfaces make sure your /etc/hosts has the IP address of all nodes updated as mentioned in the category Initial setup on all nodes. Otherwise calico will pickup IP address of the first interface

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

5. Check whether all pods are running 

watch kubectl get pods --all-namespaces




Recreate Token

If token has expired and want to join new nodes use below command on master node

kubectl create token

kubeadm list token

Use the token listed using the above command to join the new node