Wednesday 7 August 2019

Grafana / Infludb K8s deployment via piepline

Grafana


1. Dockerfile


FROM grafana/grafana:latest
LABEL description="Grafana docker image with custom setup"
ENV GF_SMTP_ENABLED true
ENV GF_SMTP_HOST mxrelay.ara.ac.nz:25
ENV GF_SMTP_FROM_ADDRESS admin@grafana.ara.ac.nz

USER root

RUN apt-get -q update &&\
    DEBIAN_FRONTEND="noninteractive" apt-get -q upgrade -y -o Dpkg::Options::="--force-confnew" --no-install-recommends &&\
    DEBIAN_FRONTEND="noninteractive" apt-get -q install -y -o Dpkg::Options::="--force-confnew" --no-install-recommends curl gosu &&\
    apt-get -q autoremove &&\
    apt-get -q clean -y && rm -rf /var/lib/apt/lists/* && rm -f /var/cache/apt/*.bin

ADD run.sh /run.sh
RUN chmod +x /run.sh
RUN mkdir -p /opt/grafana/dashboards
ADD ["*.json", "/opt/grafana/dashboards/"]
ADD ["default-dashboard.yaml", "/etc/grafana/provisioning/dashboards/"]
ADD ["notification.yaml", "/etc/grafana/provisioning/notifiers/"]
ENTRYPOINT ["/run.sh", "GF_SMTP_ENABLED", "GF_SMTP_HOST", "GF_SMTP_FROM_ADDRESS"]

2. run.sh


#!/bin/bash -e

: "${GF_PATHS_DATA:=/var/lib/grafana}"
: "${GF_PATHS_LOGS:=/var/log/grafana}"
: "${GF_PATHS_PLUGINS:=/var/lib/grafana/plugins}"
: "${GF_PATHS_PROVISIONING:=/etc/grafana/provisioning}"
: "${GF_SMTP_FROM_ADDRESS:=admin@grafana.ara.ac.nz}"
: "${GF_SMTP_ENABLED:=true}"
: "${GF_SMTP_HOST:=mxrelay.ara.ac.nz:25}"

chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_LOGS"
chown -R grafana:grafana /etc/grafana

# Start grafana with gosu
exec gosu grafana /usr/share/grafana/bin/grafana-server  \
  --homepath=/usr/share/grafana             \
  --config=/etc/grafana/grafana.ini         \
  cfg:default.paths.data="$GF_PATHS_DATA"   \
  cfg:default.paths.logs="$GF_PATHS_LOGS"   \
  cfg:default.paths.plugins="$GF_PATHS_PLUGINS" \
  cfg:default.smtp.enabled="$GF_SMTP_ENABLED" \
  cfg:default.smtp.host="$GF_SMTP_HOST" \
  cfg:default.smtp.from_address="$GF_SMTP_FROM_ADDRESS" &

sleep 5

###############################################################
# Creating Default Data Source

# Set new Data Source name
INFLUXDB_DATA_SOURCE="InfluxDB"
INFLUXDB_DATA_SOURCE_WEB=`echo ${INFLUXDB_DATA_SOURCE} | sed 's/ /%20/g'`

# Set information about grafana host
GRAFANA_URL=`hostname -i`
GRAFANA_PORT="3000"
GRAFANA_USER="admin"
GRAFANA_PASSWORD="admin"

# Check $INFLUXDB_DATA_SOURCE status
INFLUXDB_DATA_SOURCE_STATUS=`curl -s -L -i \
 -H "Accept: application/json" \
 -H "Content-Type: application/json" \
 -X GET http://${GRAFANA_USER}:${GRAFANA_PASSWORD}@${GRAFANA_URL}:${GRAFANA_PORT}/api/datasources/name/${INFLUXDB_DATA_SOURCE_WEB} | head -1 | awk '{print $2}'`

#Debug Time!
curl -s -L -i \
 -H "Accept: application/json" \
 -H "Content-Type: application/json" \
 -X GET http://${GRAFANA_USER}:${GRAFANA_PASSWORD}@${GRAFANA_URL}:${GRAFANA_PORT}/api/datasources/name/${INFLUXDB_DATA_SOURCE_WEB} >>$GF_PATHS_LOGS/grafana.log 2>>$GF_PATHS_LOGS/grafana.log 
echo "http://${GRAFANA_USER}:${GRAFANA_PASSWORD}@${GRAFANA_URL}:${GRAFANA_PORT}/api/datasources/name/${INFLUXDB_DATA_SOURCE_WEB}" >> $GF_PATHS_LOGS/grafana.log
echo "INFLUXDB_DATA_SOURCE_STATUS: "$INFLUXDB_DATA_SOURCE_STATUS >> $GF_PATHS_LOGS/grafana.log
echo "GRAFANA_URL: "$GRAFANA_URL >> $GF_PATHS_LOGS/grafana.log
echo "GRAFANA_PORT: "$GRAFANA_PORT >> $GF_PATHS_LOGS/grafana.log
echo "GRAFANA_USER: "$GRAFANA_USER >> $GF_PATHS_LOGS/grafana.log
echo "GRAFANA_PASSWORD: "$GRAFANA_PASSWORD >> $GF_PATHS_LOGS/grafana.log

# Check if $INFLUXDB_DATA_SOURCE exists
if [ ${INFLUXDB_DATA_SOURCE_STATUS} != 200 ]
then
  # If not exists, create one 
  echo "Data Source: '"${INFLUXDB_DATA_SOURCE}"' not found in Grafana configuration"
  echo "Creating Data Source: '"$INFLUXDB_DATA_SOURCE"'"
  curl -L -i \
   -H "Accept: application/json" \
   -H "Content-Type: application/json" \
   -X POST -d '{
    "name":"'"${INFLUXDB_DATA_SOURCE}"'",
    "type":"influxdb",
    "url":"http://influxdb:8086",
    "access":"proxy",
    "basicAuth":false,
    "database":"telegraf",
    "user":"grafana",
    "password":"grafana"}
  ' \
  http://${GRAFANA_USER}:${GRAFANA_PASSWORD}@${GRAFANA_URL}:${GRAFANA_PORT}/api/datasources
else
  #Continue if it doesn't exists
  echo "Data Source '"${INFLUXDB_DATA_SOURCE}"' already exists."
fi

tail -f $GF_PATHS_LOGS/grafana.log

3. graf-serv-deploy.yml


---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: grafana
  namespace: default
  labels:
    app: grafana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - image: araregistry.azurecr.io/ara/nashgrafana:latest
        imagePullPolicy: Always
        name: nashgrafana
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: azurecr
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: grafana
  name: grafana
  namespace: default
spec:
  type: NodePort
  ports:
  - nodePort: 30030
    port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    app: grafana

4. notification.yml


notifiers:
  - name: notification-channel
    type: email
    uid: notifier1
    org_name: Main Org.
    is_default: true
    disable_resolve_message: false
    settings:
      addresses: naveed.sheikh@ara.ac.nz

5. default-dashboard.yml


# # config file version
apiVersion: 1

providers:
 - name: 'default'
   orgId: 1
   folder: ''
   type: file
   options:
     path: /opt/grafana/dashboards

6. Jenkinsfile


pipeline {
  agent any
  stages {
    stage('Build') {
      environment {
        KUBECONFIG = '/home/isadmin/.kube/config-mon1'
      }
      steps {
        sh '''sudo docker build -t araregistry.azurecr.io/ara/nashgrafana:latest -f Dockerfile .

sudo docker push araregistry.azurecr.io/ara/nashgrafana:latest'''
      }
    }
    stage('Pull Changes') {
      steps {
        sh '''sudo ssh -T root@logmon1.ara.ac.nz docker login araregistry.azurecr.io -u AraRegistry -p xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

sudo ssh -T root@logmon1.ara.ac.nz docker pull araregistry.azurecr.io/ara/nashgrafana:latest'''
      }
    }
    stage('Deploy') {
      steps {
        sh '''# Deploy service
kubectl apply -f ${WORKSPACE}/fullgrafana.yml'''
      }
    }
  }
  environment {
    KUBECONFIG = '/home/isadmin/.kube/config-mon1'
  }
}

--------------------------------------------------------------------------------------------------------------------------

InfluxdB



1. Dockerfile


FROM influxdb:latest
LABEL description="InfluxDB docker image with custom setup"

USER root

ADD influxdb.template.conf /influxdb.template.conf

ADD run.sh /run.sh
RUN chmod +x /run.sh

CMD ["/run.sh"]


2. Jenkinsfile


pipeline {
  agent any
  stages {
    stage('Build') {
      environment {
        KUBECONFIG = '/home/isadmin/.kube/config-mon1'
      }
      steps {
        sh '''sudo docker build -t araregistry.azurecr.io/ara/nashflux:latest -f Dockerfile .

sudo docker push araregistry.azurecr.io/ara/nashflux:latest'''
      }
    }
    stage('Pull Changes') {
      steps {
        sh '''sudo ssh -T root@logmon1.ara.ac.nz docker login araregistry.azurecr.io -u AraRegistry -p xxxxxxxxxxxxxxxxxxx

sudo ssh -T root@logmon1.ara.ac.nz docker pull araregistry.azurecr.io/ara/nashflux:latest'''
      }
    }
    stage('Deploy') {
      steps {
        sh '''# Deploy service
kubectl apply -f ${WORKSPACE}/fulldeploymentinflux.yml'''
      }
    }
  }
  environment {
    KUBECONFIG = '/home/isadmin/.kube/config-mon1'
  }
}

3. run.sh


#!/bin/bash

set -m
CONFIG_TEMPLATE="/influxdb.template.conf"
CONFIG_FILE="/etc/influxdb/influxdb.conf"
CURR_TIMESTAMP=`date +%s`

INFLUX_HOST="localhost"
INFLUX_API_PORT="8086"
[ "${INFLUX_ADMIN_USER}" = "" ] &&
        INFLUX_ADMIN_USER="grafana"
[ "${INFLUX_ADMIN_PASS}" = "" ] &&
        INFLUX_ADMIN_PASS="grafana"
[ "${INFLUX_DATABASE}" = "" ] &&
        INFLUX_DATABASE="telegraf"

mv -v $CONFIG_FILE $CONFIG_FILE.$CURR_TIMESTAMP
cp -v $CONFIG_TEMPLATE $CONFIG_FILE

exec influxd -config=$CONFIG_FILE 1>>/var/log/influxdb/influxdb.log 2>&1 &
sleep 5

USER_EXISTS=`influx -host=${INFLUX_HOST} -port=${INFLUX_API_PORT} -execute="SHOW USERS" | awk '{print $1}' | grep "${INFLUX_ADMIN_USER}" | wc -l`

if [ -n ${USER_EXISTS} ]
then
  influx -host=${INFLUX_HOST} -port=${INFLUX_API_PORT} -execute="CREATE USER ${INFLUX_ADMIN_USER} WITH PASSWORD '${INFLUX_ADMIN_PASS}' WITH ALL PRIVILEGES"
  influx -host=${INFLUX_HOST} -port=${INFLUX_API_PORT} -username=${INFLUX_ADMIN_USER} -password="${INFLUX_ADMIN_PASS}" -execute="create database ${INFLUX_DATABASE} WITH DURATION 180d NAME biannual"
fi

tail -f /var/log/influxdb/influxdb.log

4. influx-serv-full.yml


---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  namespace: default
  name: standard
provisioner: kubernetes.io/host-path
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: influxvol
  namespace: default
spec:
  storageClassName: 'standard'
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/var/k8sdata"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: influxvol
  namespace: default
spec:
  storageClassName: 'standard'
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: influxdb
  namespace: default
  labels:
    app: influxdb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: influxdb
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: influxdb
    spec:
      containers:
      - image: araregistry.azurecr.io/ara/nashflux:latest
        imagePullPolicy: Always
        name: nashflux
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        ports:
        - containerPort: 8086
        volumeMounts:
        - name: influxstorage
          mountPath: /var/lib/influxdb
      volumes:
      - name: influxstorage
        persistentVolumeClaim:
          claimName: influxvol
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: azurecr
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: influxdb
  name: influxdb
  namespace: default
spec:
  type: NodePort
  ports:
  - nodePort: 31050
    port: 8086
    protocol: TCP
    targetPort: 8086
  selector:
    app: influxdb

--------------------------------------------------------------------------------------------------------------------------

Dont forget to add secret and if 1 node master then untaint the master node for this to work.

Thanks

No comments:

Post a Comment