Kubernetes_Monitoring

Kubernetes_Monitoring

Kubernetes_Monitoring


Prerequisites must be installed and configured.

  • Kubernetes

All action done on kubernetes master server.

Clone or copy YAML script from below git repo.

git clone https://github.com/bibinwilson/kubernetes-prometheus

Create a monitoring Namespace

[root@kmaster ~]# kubectl create namespace monitoring

You need to assign cluster reader permission to this namespace so that Prometheus can fetch the metrics from kubernetes API’s.

[root@kmaster ~]# kubectl create -f clusterRole.yaml

Create a Config Map
We should create a config map with all the prometheus scrape config and alerting rules,
which will be mounted to the Prometheus container in /etc/prometheus as prometheus.yaml and prometheus.rules files.
The prometheus.yaml contains all the configuration to dynamically discover pods and services running in the kubernetes cluster.
prometheus.rules will contain all the alert rules for sending alerts to alert manager.

[root@kmaster ~]# kubectl create -f config-map.yaml -n monitoring

Create a Prometheus Deployment

[root@kmaster ~]# kubectl create  -f prometheus-deployment.yaml --namespace=monitoring
[root@kmaster ~]# kubectl get deployments --namespace=monitoring
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
prometheus-deployment   1/1     1            1           16m

Get the Prometheus pod name.

[root@kmaster ~]# kubectl get pods --namespace=monitoring
NAME                                    READY   STATUS    RESTARTS   AGE
prometheus-deployment-fd6676489-wmn6w   1/1     Running   0          18m

Exposing Prometheus as a Service so we can connect prometheus with Grafana.

To access the Prometheus dashboard over a IP or a DNS name, you need to expose it as kubernetes service.
Note: If you are on AWS or Google Cloud, You can use Loadbalancer type, which will create a load balancer and points it to the service.

[root@kmaster ~]# kubectl create -f prometheus-service.yaml --namespace=monitoring
[root@kmaster ~]# kubectl get services  --namespace=monitoring
NAME                 TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
prometheus-service   NodePort   10.103.247.50   <none>        8080:30000/TCP   24s

Once created, you can access the Prometheus dashboard using any Kubernetes node IP on port 30000. If you are on the cloud, make sure you have the right firewall rules for accessing the apps.

In my example "Grafana" deploy on separate server.

Add repo to install "Grafana"

[root@feenixdv yum.repos.d]# cat grafana.repo
[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt

[root@feenixdv yum.repos.d]# yum install grafana
[root@feenixdv yum.repos.d]# yum list installed grafana
Loaded plugins: langpacks, product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Installed Packages
grafana.x86_64                                                    6.0.1-1                                                     @grafana
[root@feenixdv yum.repos.d]# systemctl restart grafana-server.service
[root@feenixdv yum.repos.d]# systemctl status grafana-server
? grafana-server.service - Grafana instance
   Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2019-03-14 20:54:34 PDT; 5h 35min ago

Now Grafana access on http://IP:3000. Default login is "admin/admin".
Now create connection with Prometheus and create graph.

Now craete graph.

Example:-

Variables:-

Name:- Node Query:- label_values(kubernetes_io_hostname)
Name:- Deployment Query:- label_values(deployment)
Name:- Statefulset Query:- label_values(statefulset)
Name:- Daemonset Query:- label_values(daemonset)
 
some Graph query example:-
Name:- 10 CPU hungry pods
Visualization:- Graph
Query:- sort_desc(topk(10, sum by (pod_name)( rate(container_cpu_usage_seconds_total{pod_name!=""}[1m] ) )))


Name:-10 memory hungry pods
Visualization:-Graph
Query:-sort_desc(topk(10, sum(container_memory_usage_bytes{pod_name!=""}) by (pod_name)))

Name:-Deployment CPU usage
Visualization:-Singlestat
Query:-sum (rate (container_cpu_usage_seconds_total{pod_name=~"^$Deployment$Statefulset$Daemonset.*$", kubernetes_io_hostname=~"^$Node$"}[2m])) / sum (machine_cpu_cores{kubernetes_io_hostname=~"^$Node$"}) * 100

Name:-CPU usage
Visualization:-Graph
Query:-sum (rate (container_cpu_usage_seconds_total{image!="",name=~"^k8s_.*",io_kubernetes_container_name!="POD",pod_name=~"^$Deployment$Statefulset$Daemonset.*$",kubernetes_io_hostname=~"^$Node$"}[1m])) by (pod_name,kubernetes_io_hostname)
sum (kube_pod_container_resource_requests_cpu_cores{pod=~"^$Deployment$Statefulset$Daemonset.*$",node=~"^$Node$"}) by (pod,node)
sum ((kube_node_status_allocatable_cpu_cores{node=~"^$Node$"})) by (node)

Name:-Memory usage
Visualization:-Graph
Query:-sum (container_memory_working_set_bytes{id!="/",pod_name=~"^$Deployment$Statefulset$Daemonset.*$",kubernetes_io_hostname=~"^$Node$"}) by (pod_name,kubernetes_io_hostname)
sum ((kube_pod_container_resource_requests_memory_bytes{pod=~"^$Deployment$Statefulset$Daemonset.*$",node=~"^$Node$"})) by (pod,node)
sum ((kube_node_status_allocatable_memory_bytes{node=~"^$Node$"})) by (node)

Name:-All processes network I/O
Visualization:-Graph
Query:-sum (rate (container_network_receive_bytes_total{id!="/",pod_name=~"^$Deployment$Statefulset$Daemonset.*$",kubernetes_io_hostname=~"^$Node$"}[1m])) by (pod_name, kubernetes_io_hostname)
– sum( rate (container_network_transmit_bytes_total{id!="/",pod_name=~"^$Deployment$Statefulset$Daemonset.*$",kubernetes_io_hostname=~"^$Node$"}[1m])) by (pod_name, kubernetes_io_hostname)

Kubernetes_Dashboard

Kubernetes_Dashboard

Kubernetes_Dashboard_Setup

 

After "kubernetes-on-VMware-workstation-or-VirtualBox" install web UI to access Kubernetes_Dashboard

Install dashboard on Master only

[root@kmaster ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
secret/kubernetes-dashboard-certs created
serviceaccount/kubernetes-dashboard created
role.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
deployment.apps/kubernetes-dashboard created
service/kubernetes-dashboard created

Check "kubernetes-dashboard" is running or not

[root@kmaster ~]# kubectl get pod -o wide --all-namespaces
kube-system   kubernetes-dashboard-57df4db6b-5zm4k   1/1     Running       0          92s   10.244.0.13      kmaster   <none>           <none>

Add Admin-role

[root@kmaster ~]# kubectl apply -f https://gist.githubusercontent.com/chukaofili/9e94d966e73566eba5abdca7ccb067e6/raw/0f17cd37d2932fb4c3a2e7f4434d08bc64432090/k8s-dashboard-admin-user.yaml
serviceaccount/admin-user created
clusterrolebinding.rbac.authorization.k8s.io/admin-user created
[root@kmaster ~]# kubectl get sa admin-user -n kube-system
NAME         SECRETS   AGE
admin-user   1         11s

Get admin-user-token

[root@kmaster ~]# kubectl describe sa admin-user -n kube-system
Name:                admin-user
Namespace:           kube-system
Labels:              <none>
Annotations:         kubectl.kubernetes.io/last-applied-configuration:
                       {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"admin-user","namespace":"kube-system"}}
Image pull secrets:  <none>
Mountable secrets:   admin-user-token-gt42f
Tokens:              admin-user-token-gt42f
Events:              <none>
[root@kmaster ~]# kubectl describe secret admin-user-token-gt42f -n kube-system
Name:         admin-user-token-gt42f
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
              kubernetes.io/service-account.uid: 7ba5f30a-2c69-11e9-9e6d-000c29a96cf0

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLWd0NDJmIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI3YmE1ZjMwYS0yYzY5LTExZTktOWU2ZC0wMDBjMjlhOTZjZjAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.Z2AKuy4q2X9GaqnsotH5PdXLF7I55qv5XWKmPmAbVqzPYzpWAQpr603YNiHsYMoVriQl5X_0m6wxCK7AFB3xTZfBXECtvmmxJQ17wRZIRbnVV-FRsYHBMdn6CEwSb-u1uf4upNpeBnr0gC1vCq4Rwj4jMBc6Gr-4VJfrgXWMCQirwvfxgUhTun3Bv_vNDAn4Wu93ga1cnBfgZXJg9FTsKkJM9R9SHN4oz7q6FfvujGkhxysz14HLXW6Z5ezN1TO8JVYpURtJ60lWdtWLfi2KCRVIoGcJ-VvOfNs_lrGt2dIReDOBUHrC4DGcThy3Ce8ZJ_QMp_8-3HHAZ-obii9AtA

Use this token to access kubernetes dashboard. Before that you need to start kubectl proxy.

[root@kmaster ~]# kubectl proxy
Starting to serve on 127.0.0.1:8001

To access "kubernetes dashboard" on our local browser we need to set tunnel in putty.

Now we can access "kubernetes dashboard" on the local browser using token ID.

 

kubernetes On “VMware Workstation” or “vitrualBox”

kubernetes On “VMware Workstation” or “vitrualBox”

kubernetes deployment on "VMware Workstation Pro" or "VirtualBox"


In my lab setup:-

192.168.40.191 kmaster RHEL7.3 CPU_CORE:- 2
192.168.40.192 knode1 RHEL7.3 CPU_CORE:- 1
192.168.40.193 knode2 RHEL7.3 CPU_CORE:- 1



On both (Master and Node)
—————————–
In this example, I am going to disable SELinux on master and node both.

#sed -i -e s/enforcing/disabled/g /etc/sysconfig/selinux;
#sed -i -e s/permissive/disabled/g /etc/sysconfig/selinux
#setenforce 0
#sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

Also, disable the firewall.

#systemctl disable firewalld
#systemctl stop firewalld

Enable network bridge.

#modprobe br_netfilter
#echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

Make swap off for installation.

#swapoff -a && sed -i '/swap/d' /etc/fstab

Install requisitory(Docker)

#yum install -y yum-utils device-mapper-persistent-data lvm2
#yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#yum install -y docker-ce

Add kubernetes repo to install kubernetes

#cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[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
EOF

#yum install -y kubelet kubeadm kubectl

#systemctl start docker && systemctl enable docker
#systemctl start kubelet && systemctl enable kubelet
#sed -i 's/cgroup-driver=systemd/cgroup-driver=cgroupfs/g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
#systemctl daemon-reload

On master only
——————-
Add network bridge configuration in a file and reload values.

[root@kmaster ~]# cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
[root@kmaster ~]# sysctl --system

Put "admin.conf" in ".bash_profile" to load at login time.

[root@kmaster ~]# echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> ~/.bash_profile
[root@kmaster ~]# source ~/.bash_profile

Note:- If you are using any type of proxy on any node, disable before kubernetes initialization.

[root@kmaster ~]# unset http_proxy
[root@kmaster ~]# unset https_proxy

Now launch the initialization script.

[root@kmaster ~]# kubeadm init --ignore-preflight-errors all --pod-network-cidr=10.244.0.0/16 --token-ttl 0
I0209 04:38:11.240261    4481 version.go:94] could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable-1.txt": Get https://storage.googleapis.com/kubernetes-release/release/stable-1.txt: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
I0209 04:38:11.240748    4481 version.go:95] falling back to the local client version: v1.13.3
[init] Using Kubernetes version: v1.13.3
[preflight] Running pre-flight checks

[WARNING SystemVerification]: this Docker version is not on the list of validated versions: 18.09.0. Latest validated version: 18.06
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"

.

.

.

[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes master has initialized successfully!

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 node
as root:

  kubeadm join 192.168.40.184:6443 --token yz06cb.3mtnv1swalusctr1 --discovery-token-ca-cert-hash sha256:ea180f65eb0b8b3e6d0122300fa02d49592d08283c8f9f5091787ff080692c93


Run below command as suggested in the last installation screen.

[root@kmaster ~]# mkdir -p $HOME/.kube
[root@kmaster ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@kmaster ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config

Check name-spaces

[root@kmaster ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                            READY   STATUS    RESTARTS   AGE
kube-system   coredns-86c58d9df4-2ftxf        0/1     Pending   0          2m52s
kube-system   coredns-86c58d9df4-plxft        0/1     Pending   0          2m52s
kube-system   etcd-kmaster                      1/1     Running   0          2m20s
kube-system   kube-apiserver-kmaster            1/1     Running   0          2m13s
kube-system   kube-controller-manager-kmaster   1/1     Running   0          2m19s
kube-system   kube-proxy-fpr6w                1/1     Running   0          2m52s
kube-system   kube-scheduler-kmaster            1/1     Running   0          2m8s

Install POD network (only one pod network per cluster) to change "coredns" pending to running state.

[root@kmaster ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.extensions/kube-flannel-ds-amd64 created
daemonset.extensions/kube-flannel-ds-arm64 created
daemonset.extensions/kube-flannel-ds-arm created
daemonset.extensions/kube-flannel-ds-ppc64le created
daemonset.extensions/kube-flannel-ds-s390x created

Now all are in running state.

[root@kmaster ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                            READY   STATUS    RESTARTS   AGE
kube-system   coredns-86c58d9df4-2ftxf        1/1     Running   0          7m2s
kube-system   coredns-86c58d9df4-plxft        1/1     Running   0          7m2s
kube-system   etcd-kmaster                      1/1     Running   0          6m30s
kube-system   kube-apiserver-kmaster            1/1     Running   0          6m23s
kube-system   kube-controller-manager-kmaster   1/1     Running   0          6m29s
kube-system   kube-flannel-ds-amd64-v59nj     1/1     Running   0          3m2s
kube-system   kube-proxy-fpr6w                1/1     Running   0          7m2s
kube-system   kube-scheduler-kmaster            1/1     Running   0          6m18s


To join any node with master cluster

[root@knode1 ~]# kubeadm join 192.168.40.184:6443 --token gfjzba.ci5gvqt09lqpspzm --discovery-token-ca-cert-hash sha256:0dfb374c6cc87683c0ff5e8e04e149738934c25ab2bcfb1ca72f501847f06301

To check available joined node on master

[root@kmaster ~]# kubectl get nodes
NAME      STATUS   ROLES    AGE   VERSION
kmaster   Ready    master   26h   v1.13.3
knode1    Ready    <none>   26h   v1.13.3
knode2    Ready    <none>   26h   v1.13.3