Kubernetes for Beginners - Lab Guide

KNET Solutions (Online Training Centre),

https://knetsolutions.in

knetsolutions2@gmail.com

Phone/WhatsApp: +919445042007

Online Training/One to One Personalized training


Kubernetes


1. Introduction

This tutorial is (Kubernetes for beginners Lab Guide), prepared by KNET Solutions. This Book is used as Course material for UDEMY Kubernetes for Beginners Course.

The Online Course is available in UDEMY. The Course link is UDEMY KUBERNETES BEGINNERS COURSE

This Course covers Kubernetes Introduction, Setting up your own Kubernetes in AWS VM, Kubernetes Resources, Deploying sample applications, HELM, Monitoring the Kubernetes with Prometheus, Grafana, Alert Manager.

Some book contents (IMAGE/Text) are copied from Freely available resources from internet / Opensource materials. Thanks to the original authors.

This Book is free to use.



2. Kubernetes installation (using MiniKube)

VM details

AWS VM (Minimum):

  • 2vCPU/4GB RAM/20GB HDD
  • Ubuntu 18.04

AWS VM (Recommended):

  • 4vCPU/8GB RAM/50GB HDD
  • Ubuntu 18.04

In the security groups allow the incoming traffic for the TCP port 80 and 8080.

Tools Installation

docker

sudo apt-get update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
sudo apt update
sudo apt install -y docker-ce
sudo service docker status
sudo usermod -aG docker $USER && newgrp docker

conntrack & socat

sudo apt-get install -y conntrack socat

kubectl

curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

minikube installation

curl -LO https://storage.googleapis.com/minikube/releases/v1.12.2/minikube_latest_amd64.deb
sudo dpkg -i minikube_latest_amd64.deb

Note: we need to install minikube version 1.12.2 for ingress support in driver=none.

kubernetes installation

The recent kubernetes versions are,

  • v1.18.x
  • v1.17.x
  • v1.16.x

We are running/installing minikube in root user.

sudo -i
minikube start --kubernetes-version=v1.18.1 --driver=none

it may take 5-10 mins, depends on your internet speed.

minikube start --help

verification

minikube status

verify the basic kubernetes cli commands

kubectl get nodes
kubectl get pods

kubeconfig & kubectl

The Kubernetes Cluster Access credentials are stored in kubeconfig file. A file that is used to configure access to clusters is called a kubeconfig file. This is a generic way of referring to configuration files.

The file contains Kubernetes API Server address, certificates.

Kubectl is a command line tool to control your kubernetes cluster.

kubectl looks for a file named config in the $HOME/.kube directory. You can specify other kubeconfig files by setting the KUBECONFIG environment variable .

As part of our minikube installing, minikube creates $HOME/.kube file.

export KUBECONFIG=dev-cluster.yaml
kubectl get pods

kubectl command overview

kubectl [command] [TYPE] [NAME] [flags]

command (operations) :

  • get
  • delete
  • create
  • edit
  • apply
  • describe
  • ..... etc

TYPE (Resource Types)

  • pods
  • deployments
  • namespaces
  • services
  • ingress
  • configmaps
  • .........etc

NAME means, Name of the resource

Flags : Specifies optional flag

Example Commands:

kubectl get pods
kubectl get nodes
kubectl describe nodes ip-172-31-17-157

Reference:



3. Basic Minikube commands

Operational Commands

Status

Gets the status of a local Kubernetes cluster.

minikube status

Pause/UnPause

pause and unpause only kubernetes control plane services. User plane(deployments) will continue to run, user can access.

minikube pause
minikube unpause

Stop/Start

Stop your local cluster & Start a cluster(Running)

minikube stop
minikube start

delete

minikube delete --all

Upgrade to the specific version

minikube start --kubernetes-version=v1.18.2 --driver=none

Addons

minikube provides handy addon command, to install the necessary/basic important system deloyments required by the user .

Example:

  • kubernetes dashboard
  • ingress controller
  • storage driver etc

list

minikube addons list

install

minikube addons enable dashboard

remove

minikube addons disable dashboard

Metrics Server

  1. Install kubernetes metrics server
minikube addons enable metrics-server
  1. Check the pods & services of dashboard
kubectl get pods -A
kubectl get svc -A
  1. verify the metrics
kubectl top nodes
kubectl top pods

Dashboard Demo

  1. Install the kubernetes dashboard (UI)
minikube addons enable dashboard
  1. Check the pods & services of dashboard
kubectl get pods -A
kubectl get svc -A
  1. port forwarding
kubectl port-forward --address 0.0.0.0 --namespace kubernetes-dashboard svc/kubernetes-dashboard 8080:80

Here 80 is a service port, 8080 is a forward port.

Open the browser and access it from your laptop. http://x.x.x.x:8080

Thats all.

Reference



4. Kuberenetes Resources

Sample Deployment

  1. create nginx-web.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: nginx
---
  1. Apply this yaml file
kubectl apply -f nginx-web.yaml
  1. verify the resources
kubectl get deployments
kubectl get services
  1. open the service nodeport assigned for this service in AWS Security Group
  1. Now access the NGINX Webserver default page from your Laptop
http://aws-ip:3xxxx

Pod

  1. create a nginx-pod.yaml file
kind: Pod
apiVersion: v1
metadata:
name: nginxpod
labels:
foo: bar
spec:
containers:
- name: nginxpod
image: nginx:1.14.2
ports:
- containerPort: 80
  1. create a resource
kubectl apply -f nginx-pod.yaml
  1. verify the operations
kubectl get pods
kubectl describe pods nginxpod
  1. verify the logs
kubectl logs -f nginxpod
  1. login to the nginx pod shell, and execute some commands.
kubectl exec -it nginxpod -- /bin/sh
ls -lrt
  1. port forwarding to access from outside(not Recommended - only for debugging)
kubectl port-forward --address 0.0.0.0 pod/nginxpod 8080:80
  1. Delete the pod
kubectl delete -f nginx-pod.yaml
#or
kubectl delete pod nginxpod

Deployment

  1. create a nginx deploy yaml(nginx-deploy.yaml) file
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
  1. create a resource
kubectl apply -f nginx-deploy.yaml
  1. verify the operations
kubectl get deployment
kubectl describe deployment nginx-deployment
kubectl get pods
kubectl describe pods nginxpod
  1. verify the pod logs

  2. login to the each nginx pod shell, and execute some commands.

  3. Now delete some pod...

kubectl delete pod nginx-pod

Now the pods will be created automatically and keep the replication number as specified in the deployment.

  1. delete the deployment
kubectl delete deployment nginx-deployment
#or
kubectl delete -f nginx-deploy.yaml

Services

There are 3 types of services.

Reference: https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/

expose a Service onto an external IP address. Kubernetes supports two ways of doing this: NodePorts and LoadBalancers


NodePort

  1. Deploy the nginix-deploy.yaml file (previous step)

  2. Create a service for nginx-svc.yaml

apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: nginx

targetPort: is the port the container accepts traffic on, port: is the abstracted Service port, which can be any port other pods use to access the Service

The default Nodeport ports range are 30000-32767

  1. apply this Resource
kubectl apply -f nginx-deploy.yaml
  1. verify it
kubectl get services

Note down the exposed port. open that port from your security group of the VM.

open a browser from your laptop and access it.

http://54.255.208.88:3xxxx/
  1. delete the Resources
kubectl delete -f nginx-deploy.yaml
kubectl delete -f nginx-svc.yaml

ClusterIP

ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.

  1. Deploy the nginix-deploy.yaml file (previous step)

  2. Create a service for nginx-svc.yaml

apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx-svc
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: nginx
  1. Apply this Resources
kubectl apply -f nginx-svc.yaml
  1. create one more client deployment(client.yaml)
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-client
spec:
replicas: 1
selector:
matchLabels:
app: sample-client
template:
metadata:
labels:
app: sample-client
spec:
containers:
- image: sureshkvl/nginx-test:1.0
name: sample-client
---
kubectl apply -f client.yaml
  1. Now from client pod, request the nginx service
kubectl exec -it sample-client-xxxxxx -- /bin/sh
curl http://nginix-svc

This service is not exposed outside


LoadBalancer

On cloud providers which support external load balancers (such as amazon elb), setting the type field to LoadBalancer provisions a load balancer for your Service.


Ingress Controller deployment

  1. Install ingress controller
minikube addons list
minikube addons enable ingress
  1. verify the pods,svc,ingress
kubectl get pods -A
kubectl get svc -A

Now ingress controller is setup, we can consume through ingress resource.

Ingress Resource

Ingress manages external access to the services in a cluster ( HTTP & HTTPS).

Ingress may provide load balancing, SSL termination and name-based virtual hosting.

An Ingress does not expose arbitrary ports or protocols (only HTTP or HTTPS)

Prerequisites: Ingress Controller must be deployed.

References: https://kubernetes.io/docs/concepts/services-networking/ingress/

Example resource

Example1

  1. deploy the nginx-deploy.yaml

  2. deploy the nginx-service.yaml(ClusterIP)

  3. Create the nginx-ingress.yaml file (ingress resource for nginx service)

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: web.54.255.208.88.xip.io
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: http
---
  1. verify the resources.
kubectl get ingress
kubectl describe ingress nginx-ingress
  1. Now access the URL from your laptop
http://web.54.255.208.88.xip.io

Namespace

Namespaces are a way to divide cluster resources between multiple users.

Namespaces are intended for use in environments with many users spread across multiple teams, or projects.

Kuberenetes control plane components are deployed in kube-system namespace.

The default namespace name is default.

To display , all namespaces available in the cluster

kubectl get namespaces
#or
kubectl get ns

To create a namespace

kubectl create namespace test

Create a deployment(nginx-deployment) in a test namespace

kubectl apply -f nginx-deployment.yaml -n test

To display the resources(pods, deployements) in the namespaces, use "-n namespace-name"

kubectl get pods
kubectl get pods -n kube-system
kubectl get pods -n test
kubectl get deployments -n test

References



5. DNS Setup

DNS

Option1:

  1. If you haved valid internet domain name (purchased from domain name vendor such as godaddy), point the domain DNS Record to this public of this VM.

Example: mydomain.com

  1. we can create all deployments with this domain name. Example:
  • wordpress.mydomain.com
  • db.mydomain.com
  • jenkins.mydomain.com

etc.

Option2:

  1. if you dont have valid domain name, still we can use the public ip address(18.221.195.181) as domain name, using special testing method http://54.255.208.88.xip.io
  1. we can create all deployments with this domain name. Example:
  • wordpress.54.255.208.88.xip.io
  • db.54.255.208.88.xip.io
  • jenkins.54.255.208.88.xip.io

etc.



6. Deployments with Manifests file

Example1 - Simple WebServer (blue)

Minimum Resources - deployment, service, ingress

  1. create the webblue.yaml file
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-blue
labels:
app: web-blue
spec:
replicas: 2
selector:
matchLabels:
app: web-blue
template:
metadata:
labels:
app: web-blue
spec:
containers:
- name: color
image: knet/color:3
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-blue-svc
labels:
app: web-blue-svc
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: web-blue
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: blue-ingress
spec:
rules:
- host: blue.knetsks.com
http:
paths:
- path: /
backend:
serviceName: web-blue-svc
servicePort: http
---

Note : CHANGE your sub domain name - host: blue.knetsks.com according to your domain name or public IP (blue.54.255.208.88.xip.io)

apply it

kubectl apply -f webblue.yaml
  1. verify the deployments, service, ingress
kubectl get deploy
kubectl get pods
kubectl get ingress
  1. Open the URL in your Laptop browser
http://blue.knetsks.com

Example2 - Simple WebServer (Red background)

Minimum Resources - deployment, service, ingress

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-red
labels:
app: web-red
spec:
replicas: 1
selector:
matchLabels:
app: web-red
template:
metadata:
labels:
app: web-red
spec:
containers:
- name: color
image: knet/color:1
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-red-svc
labels:
app: web-red-svc
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: web-red
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: red-ingress
spec:
rules:
- host: red.knetsks.com
http:
paths:
- path: /
backend:
serviceName: web-red-svc
servicePort: http
---

Same as example1

Example3 - Simple WebServer (green background)

Minimum Resources - deployment, service, ingress

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-green
labels:
app: web-green
spec:
replicas: 3
selector:
matchLabels:
app: web-green
template:
metadata:
labels:
app: web-green
spec:
containers:
- name: color
image: knet/color:2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-green-svc
labels:
app: web-green-svc
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: web-green
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: green-ingress
spec:
rules:
- host: green.knetsks.com
http:
paths:
- path: /
backend:
serviceName: web-green-svc
servicePort: http
---

same as example1



7. HELM

Installation

For helm 3.0, we do not required any server side installation in kubernetes.

  1. Install helm client (3.x) & Update the helm repo
wget https://get.helm.sh/helm-v3.2.1-linux-amd64.tar.gz
tar xvzf helm-v3.2.1-linux-amd64.tar.gz
cp linux-amd64/helm /usr/bin/.
helm version

helm version : https://github.com/helm/helm/releases

  1. Repo Update
helm repo list
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

Helm Commands

Search Charts/Applications from the repo

helm repo list
helm search repo stable
helm search repo stable | grep mysql
helm search repo stable/my

Get details of specific chart

helm show chart stable/mysql
helm show readme stable/mysql
helm show values stable/mysql
helm show all stable/mysql

dry-run to see the resources for this chart.

helm install --dry-run db1 stable/mysql

Install & Uninstall

helm install db1 stable/mysql
helm history db1
helm uninstall db1
helm list

Customize the chart values

  • Every chart has comes with default config values. which can be customized by the user.

  • User can override this default values by providing the explicit values, during installation.

Identify the customization values

helm show values bitnami/wordpress
  • create a customization values in yaml format. pass this file as input during installation

Wordpress Deployment

  1. create a wordpress namespace
kubectl create ns wordpress
  1. Read the configuration parameter for wordpress from bitname/wordpress chart.
  1. Create a values.yaml file
  • install the Chart with this values.yaml file
wordpressUsername: admin
wordpressPassword: admin123
service:
type: ClusterIP
persistence:
enabled: false
mariadb:
master:
persistence:
enabled: false
ingress:
enabled: true
hostname: wordpress.knetsks.com
  1. install it
helm install -n wordpress -f values.yaml wp1 bitnami/wordpress
  1. verify the deployments
kubectl get pods -n wordpress
kubectl get svc -n wordpress
kubectl get ingress -n wordpress
  1. open the browser and access the below url
http://wordpress.knetsks.com
  1. delete
helm delete -n wordpress wp1

Jenkins deployment

  1. create a cicd namespace
kubectl create ns cicd
  1. Read the configuration parameter for wordpress from bitnami/jenkins chart.
  1. Create a values.yaml file
  • install the Chart with this values.yaml file
service:
type: ClusterIP
persistence:
enabled: false
ingress:
enabled: true
hostname: jenkins.knetsks.com
  1. install it
helm install -n cicd -f values.yaml jenkins1 bitnami/jenkins
  1. The output shows username & password for this jenkins deployment.
  1. verify the deployments
kubectl get pods -n cicd
kubectl get svc -n cicd
kubectl get ingress -n cicd
  1. open the browser and access the below url
http://jenkins.knetsks.com
  1. Use username/password to login

Redmine deployment

  1. Read the configuration parameter for wordpress from bitnami/redmine.
  1. Create a values.yaml file
  • install the Chart with this values.yaml file
replicas: 2
service:
type: ClusterIP
persistence:
enabled: false
mariadb:
master:
persistence:
enabled: false
ingress:
enabled: true
hostname: redmine.knetsks.com
  1. install it
helm install -f values.yaml redmine bitnami/redmine


8. Monitoring

Deploy the Monitoring Stack

  1. create a monitoring namespace
kubectl create ns monitoring
  1. create values.yaml file
prometheus:
prometheusSpec:
retention: 1h
ingress:
enabled: true
hosts: [prometheus.knetsks.com]
alertmanager:
ingress:
enabled: true
hosts: [alerts.knetsks.com]
grafana:
ingress:
enabled: true
hosts: [grafana.knetsks.com]

To know, More details about configuration parameters, https://github.com/helm/charts/tree/master/stable/prometheus-operator

  1. Install it
helm install -n monitoring -f values.yaml mon stable/prometheus-operator
  1. Verify the Pods, Services, Ingress
kubectl get pods -n monitoring
kubectl get svc -n monitoring
kubectl get ingress -n monitoring

Wait, till Pods are Active

  1. Prometheus portal http://prometheus.knetsks.com
  1. Alertmanager portal http://alerts.knetsks.com
  1. Grafana portal http://grafana.knetsks.com

    default username: admin password: prom-operator


Verify the Cluster Metrics in Grafana Dashboard

The default prometheus operator installation have Kubernetes cluster metrics dashboard(infrastructure).

Todo


Monitor your Application (POD) Metrics

In the earlier chapter, we have seen the metrics of kubernetes cluster components (Infrastructure).

Now, we would like to monitor the user deployment applications such as wordpress, or other components.

Steps

  1. metrics exporter (a.k.a node exporter) for the application to be deployed as side car container. Usually this is supported/provided by the HELM Charts for all generic applications. If not available, we have to make it.
  1. Create the Prometheus Service Monitor Resource (This resource links/routes the metrics to our Promethus Monitoring Solution)
  1. Verify the Metrics are visible in Prometheus & Grafana UI..
  1. Make a Dashboard for this metrics in Grafana.

Example1: Wordpress deployment

I have deleted our existing wordpress deployment. and creating new one with metrics enabled.

1. create values.yaml file

wordpressUsername: admin
wordpressPassword: admin123
service:
type: ClusterIP
persistence:
enabled: false
mariadb:
master:
persistence:
enabled: false
ingress:
enabled: true
hostname: wordpress.knetsks.com
metrics:
enabled: true

2. install it

helm install -n wordpress -f values.yaml wp1 bitnami/wordpress

3. verify the metrics are exposed from the pods

helm list -n wordpress
kubectl get pods -n wordpress
kubectl describe pod/wp1-wordpress-fc86478f9-jx9kg -n wordpress

verify the side-car (apacher exporter) container also running in the wordpress pods, this expose /metrics on port 9117/TCP

Do, kubectl port forwarding and verify it.

kubectl port-forward -n wordpress pod/wp1-wordpress-fc86478f9-jx9kg 9117:9117

From the VM,

curl localhost:9117/metrics
......
# TYPE apache_accesses_total counter
apache_accesses_total 289
...... skipped

4. verify the metrics are exposed from the service

kubectl get svc -n wordpress

we should see the service expose the 9117/TCP Port also. Now we should port forward the service and check this.

kubectl port-forward -n wordpress svc/wp1-wordpress 9117:9117

Do query the metrics endpoint

curl localhost:9117/metrics
......
# TYPE apache_accesses_total counter
apache_accesses_total 289
...... skipped

So metrics are exposed from service also..

5. Now Create the service Monitor

Service monitor resource requires 2 important parameters

a) ServiceMonitorSelector, ServiceMonitorNameSpaceSelector parameters to be noted from prometheus resource.

kubectl -n monitoring get prometheus -o yaml
Example:
....
....skipped
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector:
matchLabels:
release: mon;

Here "release:mon" is ServiceMonitorSelector Lablel, serviceMonitorNamespaceSelector is {}, which means default namespace. This means, prometheus can query the metrics only from default name space.

b) wordpress service label name, and metrics port name to be noted from wordpress service resource

kubectl describe svc/wp1-wordpress -n wordpress

c) Create service monitor(sm.yaml) yaml file.

---
kind: ServiceMonitor
apiVersion: monitoring.coreos.com/v1
metadata:
name: wordpress-sm
labels:
app: wordpress-sm
release: mon
spec:
selector:
matchLabels:
app.kubernetes.io/instance: wp1
app.kubernetes.io/name: wordpress
namespaceSelector:
matchNames:
- wordpress
endpoints:
- port: metrics
interval: 10s
---

Note:

  • lables - "release:mon", we have refereed from prometheus resource
  • matchLabels - we have referred from the kubernetes service resource
  • matchNames - wordpress. we run our service in wordpress namespace.
kubectl apply -f sm.yaml -n wordpress

6. Now verify the Service Monitor

kubectl get servicemonitor -n wordpress
kubectl describe servicemonitor wordpress-sm -n wordpress

7. verify it in the prometheus UI

  • open prometheus UI
  • type any parameter which you seen in /metrics endpoint ex: apache_accesses_total
  • click "Execute", you will see the metric.

8. verify it grafana


Logging

Centralized log management and analyzing is important requirements for Containerzied environment.

Logs from Kubernetes control plane components(api,scheduler,controller, etc) and user application deployments(such as wordpress, jenkins, other applications.) to be collected and visualized in centralized User Interface (dashboard).

LOKI is log aggregation system inspired by prometheus . So it works out of the box.

It requires 3 components

  • loki
  • promtail
  • grafana

We already deployed grafana as part of monitoring stack.

loki-stack helm chart deploys loki and promtail.

1. repo update

helm repo add loki https://grafana.github.io/loki/charts
helm repo update

2. install loki-stacl

loki-stack is included with loki and promtail.

kubectl create ns monitoring
helm install loki loki/loki-stack -n monitoring

3. How to verify

k get pods -n monitoring
k get svc -n monitoring

4. Integreate Loki with grafana

  • open grafana UI (grafana.knetsks.com)
  • click Configuration -> Datasources
  • Add Datasource
  • Select loki
  • In the name specify "loki",and in URL "http://loki.monitoring:3100". Note this is service name of the loki "k get svc -n monitoring"
  • Save and Test.. It should work.

5. How to view the Logs.

  • open grafana UI (grafana.knetsks.com)
  • click Explore , and select Loki Datasource
  • click LogLabels, you can see the query filter based on "namespace", "pod", "job", "container" etc....

References



9. Certificate Manager Integreation

So far we used HTTP for our sevices , such as (http://grafana.knetsks.com, http://wordpress.knetsks.com) etc. Because we dont have valid certificate management system for our services.

we can deploy cert-manager and lets-encrypt , for certifiate management system. This components will take care of HTTPS(Certificates) for our services automatically.

Prerequisties:

  • ingress controller (we have alredy deployed ingress-controller)

Deploy cert-manager

  1. create a namespace
kubectl create ns cert-manager
  1. install custom resources
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.14.1/cert-manager.crds.yaml
  1. Update the helm repo for certmanager
helm repo add jetstack https://charts.jetstack.io
helm repo update
  1. create values.yaml
ingressShim:
defaultIssuerName: letsencrypt-prod
defaultIssuerKind: ClusterIssuer

Note: letsencrypt-staging or letsencrypt-prod can be used as defaultIssuerName. If it is prod, certificate will be valid(no security risk in browser)

  1. install
helm install cert-manager jetstack/cert-manager --version v0.14.1 --namespace cert-manager -f values.yaml
  1. verification
kubectl get pods --namespace cert-manager

Cert manager can be configured with variety of certificate issuers, such as

  • SelfSigned
  • CA
  • Vault
  • Venafi
  • External
  • ACME

We are going to see Automated Certificate Management Environment (ACME) method.

Lets-encrypt is Free, Opencertificate Authority (ACME). we are going to use lets-encrypt.

Integreate cert-manager with Lets-encrypt certissuer

There are two standard methods for validation(RFC 8555) of Domain name by ACME (To make sure, client is requesting the certificate for his own domain)

  • http1
  • dns1

HTTP01

  1. create a cluster issuer(cissuer.yaml) yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: knetsolutions2@gmail.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx

Note: Here your ingress class name is nginx. (This is default class name)

  1. Apply and verify it
k apply -f cissuer.yaml -n cert-manager
k get clusterissuer -n cert-manager

Thats all its ready, how we can consume.

  1. Lets do the sample color deployment(color.yaml).

In the ingress resource, add the annotations as below,

annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
cert-manager.io/acme-challenge-type: http01

The complete manifests file is below,

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-blue
labels:
app: web-blue
spec:
replicas: 2
selector:
matchLabels:
app: web-blue
template:
metadata:
labels:
app: web-blue
spec:
containers:
- name: color
image: knet/color:3
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-blue-svc
labels:
app: web-blue-svc
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: web-blue
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: blue-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
cert-manager.io/acme-challenge-type: http01
spec:
tls:
- hosts: ["blue.knetsks.com"]
secretName: blue-secret-name
rules:
- host: blue.knetsks.com
http:
paths:
- path: /
backend:
serviceName: web-blue-svc
servicePort: http
kubectl apply -f color.yaml

thats all.

  1. wordpress deployment
wordpressUsername: admin
wordpressPassword: admin123
service:
type: ClusterIP
persistence:
enabled: false
mariadb:
master:
persistence:
enabled: false
ingress:
enabled: true
hostname: wordpress.knetsks.com
certManager: true
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
cert-manager.io/acme-challenge-type: http01
tls: true

DNS01

There are only few DNS providers are supported by cert-manager (route53, clourflare, akami, etc) https://cert-manager.io/docs/configuration/acme/dns01/

We demonstrate with aws route53 DNS.

Note: we use aws access-key/secret key for domain name validation.

Prerequisties: you should specify the aws_access, aws_secret_key, hostedZoneID(for domain name)

  1. create secret (aws secret jet)
kubectl create secret generic route53-secret --from-literal=secret-access-key=xxx -n cert-manager
  1. create staging.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: knetsolutions2@gmail.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- selector:
dnsZones:
- "knetsks.com"
dns01:
route53:
region: eu-east-2
hostedZoneID: xxxxxxxx
accessKeyID: xxxxxxx
secretAccessKeySecretRef:
name: route53-secret
key: secret-access-key
  1. apply staging.yml
kubectl apply -f staging.yml -n cert-manager

Thats all its ready.

How to consume

  1. In the ingress resource , use this annotations
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
  1. Example with wordpress helm chart values
wordpressUsername: admin
wordpressPassword: admin123
service:
type: ClusterIP
persistence:
enabled: false
mariadb:
master:
persistence:
enabled: false
ingress:
enabled: true
hostname: wordpress.knetsks.com
certManager: true
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
tls: true
  1. verification
kubectl get certificate -A
kubectl get Issuers,ClusterIssuers -A
kubectl get Certificates,CertificateRequests,Orders,Challenges -A
kubectl describe clusterissuer.cert-manager.io/letsencrypt-staging -A

References



10. Other topics

Installing Minikube in Laptop

The prefered option is install it in the VM.

  1. Create a ubuntu 18.04 VM
  2. Login to the VM,
  3. install minikube with driver None .

As mentioned in section2.

Other options are , 1. From your linux laptop, 2. Install minikube with driver=kvm2

minikube start --kubernetes-version=v1.18.1 --driver=kvm2

default username/password for the minikube vm is docker & tcuser

command to delete the exited docker containers

sudo docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs sudo docker rm

11. References

Docker Installation

Minikube

Dashboard

Kubernetes

jenkins chart

prometheus-operator