Docker by doing 5 - Kubernetes

Setting up a Kubernetes cluster with docker

Configure the Kubernetes cluster

1 master, 3 worker nodes

  1. In Node 1, add the Kubernetes repo to /etc/yum.repos.d.
    1
    cat << EOF > /etc/yum.repos.d/kubernetes.repo
  2. Install the repo
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [kubernetes]
    name=Kubernetes
    baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
    https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
    exclude=kube*
    EOF
  3. Disable SELinux
    1
    setenforce 0
  4. Install Kubernetes, enable and start kubelet
    1
    2
    3
    # use a version to be more stable
    yum install -y kubelet-1.11.3 kubeadm-1.11.3 kubectl-1.11.3 --disableexcludes=kubernetes
    systemctl enable kubelet && systemctl start kubelet
  5. Set up the bridge network
    1
    2
    3
    4
    5
    6
    cat <<EOF > /etc/sysctl.d/k8s.conf
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    EOF
    # reload so changes take effect
    sysctl --system
  6. Initialize the master node, and set the code network CIDR and start using cluster
    1
    2
    3
    4
    5
    kubeadm init --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.11.3
    # start using the cluster
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g)$HOME/.kube/config
  7. Install Flannel (for networking settings) on the master node
    1
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
  8. Repeat Steps 1-5 in your Node 2 and Node 3 terminals
  9. In your Node 1 terminal window, run the following command
    1
    2
    kubeadmin token create --print-join-command
    # copy the command to join
  10. Paste the previous result command and run it in your Node 2 and Node 3 terminal, and then check everything went ok
    1
    2
    3
    4
    kubectl get nodes
    # 3 nodes
    # 2 with role "none"
    # 1 with role "master"

Create a Pod

  1. Create the pod.yml file and edit it
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    apiVersion: v1
    kind: Pod
    metadata:
    name: nginx-pod-demo
    labels:
    app: nginx-demo
    spec:
    containers:
    - image: nginx:latest
    name: nginx-demo
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  2. Create the pod
    1
    2
    3
    kubectl create -f pod.yml
    # check them
    kubectl get pods

Create the service

  1. Create the service.yml file and edit it
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    kind: Service
    apiVersion: v1
    metadata:
    name: service-demo
    spec:
    selector:
    app: nginx-demo
    ports:
    - protocol: TCP
    port: 80
    targetPort: 80
    type: NodePort
  2. Create the service
    1
    2
    3
    kubectl create -f service.yml
    # check it
    kubectl get services
  3. Browse to PUBLIC_IP_ADDRESS:SERVICE_PORT_NUMBER, check the Nginx welcome screen

Scaling pods in Kubernetes

Deploy

  1. Initialize Kubernetes cluster and install Flannel (see “Configure the Kubernetes cluster, steps 6,7”)
  2. Deploy (deployment.yml)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    kind: Deployment
    apiVersion: v1
    metadata:
    name: httpd-deployment
    labels:
    app: httpd
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: httpd
    template:
    metadata:
    labels:
    app: httpd
    spec:
    containers:
    -name: httpd
    image: httpd:latest
    ports:
    - containerPort: 80
    1
    2
    3
    4
    # deploy
    kubectl create -f deployment.yml
    # check it
    kubectl get pods
  3. Create the service.yml file and edit it
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    kind: Service
    apiVersion: v1
    metadata:
    name: service-deployment
    spec:
    selector:
    app: httpd
    ports:
    - protocol: TCP
    port: 80
    targetPort: 80
    type: NodePort
    1
    2
    3
    4
    # launch
    kubectl create -f service.yml
    # check it
    kubectl get pods

Scale the deployment

  1. Scale up to 5 replicas (deployment.yml)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    kind: Deployment
    apiVersion: v1
    metadata:
    name: httpd-deployment
    labels:
    app: httpd
    spec:
    replicas: 5
    selector:
    matchLabels:
    app: httpd
    template:
    metadata:
    labels:
    app: httpd
    spec:
    containers:
    -name: httpd
    image: httpd:latest
    ports:
    - containerPort: 80
    1
    2
    3
    kubectl apply -f deployment.yml
    # check it
    kubectl get pods
  2. Scale down to 2 replicas (edit deployment.yml)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    kind: Deployment
    apiVersion: v1
    metadata:
    name: httpd-deployment
    labels:
    app: httpd
    spec:
    replicas: 2
    selector:
    matchLabels:
    app: httpd
    template:
    metadata:
    labels:
    app: httpd
    spec:
    containers:
    -name: httpd
    image: httpd:latest
    ports:
    - containerPort: 80
    1
    2
    3
    kubectl apply -f deployment.yml
    # check it
    kubectl get pods

Creating a Helm chart

Creating an application using Helm

  1. Install Helm
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # get the install script
    curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > /tmp/get_helm.sh
    # verify the download
    cat /tmp/get_helm.sh
    # modify the access permissions
    chmod 700 /tmp/get_helm.sh
    # Set the version to v2.8.2
    DESIRED_VERSION=v2.8.2 /tmp/get_helm.sh
    # init Helm
    helm init --wait
  2. Give Helm permission to work with Kubernetes
    1
    2
    3
    kubectl --namespace=kube-system create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
    # check it
    helm ls

Create a Helm chart

  1. Create charts directory and create one chart
    1
    2
    3
    4
    5
    6
    7
    8
    mkdir charts
    cd charts
    # chart for httpd
    helm create httpd
    # check content
    cd httpd/
    ls
    # chart.yaml and values.yaml should exist
  2. Edit the values.yaml file:
    • Under image: change the repository to httpd. Change the tag to latest
    • Under service: change type to NodePort
    • httpd/values.yaml should look like this:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      replicaCount: 1

      image:
      repository: httpd
      tag: latest
      pullPolicy: IfNotPresent

      service:
      type: NodePort
      port: 80

      ingress:
      enabled: false
      annotations: {}
      path: /
      hosts:
      - chart-example.local
      tls: []

      resources: {}
      nodeSelector: {}

      tolerations: []

      affinity: {}

Create the application

  1. From the charts directory, install our application
    1
    2
    3
    helm install --name my-httpd ./httpd/
    # copy the commands listed under the NOTES section of the output and paste them to run them
    # it should return the private IP address and port number of our application
  2. Check the pods
    1
    2
    3
    # check pods
    kubectl get pods
    # you should see the pod that was created by Helm
  3. Check services
    kubectl get services
    # locate the port number of my-httpd displayed in the output
    
  4. Browser to PUBLIC_IP_ADDRESS:SERVICE_PORT to check it works