Thursday, 29 April 2021

Move Existing data to Glacier

 #!/bin/bash

> filelist

aws sts get-caller-identity

TARGETBUCKET=$1

echo ''

echo $TARGETBUCKET

echo ''

aws s3 ls $TARGETBUCKET --recursive | awk '{ print $4 }' >> filelist

while read objname

do

 aws s3api copy-object --copy-source $TARGETBUCKET/${objname} --bucket $TARGETBUCKET --storage-class GLACIER --key ${objname}

done < filelist

aws s3api list-objects --bucket $TARGETBUCKET --query 'Contents[].{Key: Key, SC: StorageClass}' --output table

Thursday, 11 February 2021

LVM Shorthand

 LVM Creation


sudo pvcreate /dev/sda /dev/sdb

sudo vgcreate LVMVolGroup /dev/sda /dev/sdb

sudo lvcreate -L 10G -n test1 LVMVolGroup

sudo lvcreate -l 100%FREE -n test2 LVMVolGroup

sudo mkfs -t ext4 /dev/LVMVolGroup/test1

sudo mkfs -t ext4 /dev/LVMVolGroup/test2

sudo mkdir /vol1

sudo mkdir /vol2

sudo mount /dev/LVMVolGroup/test1 /vol1

sudo mount /dev/LVMVolGroup/test2 /vol2

echo "/dev/LVMVolGroup/test1 /vol1 auto noatime 0 0" | sudo tee -a /etc/fstab

echo "/dev/LVMVolGroup/test2 /vol2 auto noatime 0 0" | sudo tee -a /etc/fstab

sudo mount -a

sudo reboot


Useful Commands:

pvdisplay

vgdiaplay

lvdisplay

Saturday, 26 December 2020

Single Node K8S Cluster

- hosts: localhost
  become: yes
  tasks:
   - name: install gpg
     apt:
       name: gpg
       state: present
       update_cache: true

   - name: install Docker
     apt:
       name: docker.io
       state: present
       update_cache: true

   - name: Enable service
     service:
       name: docker
       enabled: yes

   - name: start service
     service:
       name: docker
       state: started

   - name: install APT Transport HTTPS
     apt:
       name: apt-transport-https
       state: present

   - name: add Kubernetes apt-key
     apt_key:
       url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
       state: present

   - name: add Kubernetes' APT repository
     apt_repository:
      repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
      state: present
      filename: 'kubernetes'

   - name: install kubelet
     apt:
       name: kubelet
       state: present
       update_cache: true

   - name: install kubeadm
     apt:
       name: kubeadm
       state: present

   - name: install kubectl
     apt:
       name: kubectl
       state: present
       force: yes

   - name: Disable SWAP since kubernetes can't work with swap enabled (1/2)
     shell: |
       swapoff -a
     when: ansible_swaptotal_mb > 0

   - name: Disable SWAP in fstab since kubernetes can't work with swap enabled (2/2)
     replace:
       path: /etc/fstab
       regexp: '^(.+?\sswap\s+sw\s+.*)$'
       replace: '# \1'

   - name: initialize the cluster
     shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
     args:
       chdir: $HOME
       creates: cluster_initialized.txt

   - name: create .kube directory
     file:
       path: $HOME/.kube
       state: directory
       mode: 0755

   - name: copy admin.conf to user's kube config
     copy:
       src: /etc/kubernetes/admin.conf
       dest: $HOME/.kube/config
       remote_src: yes

   - name: install Pod network
     become: yes
     shell: kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
     args:
       chdir: $HOME
       creates: pod_network_setup.txt

   - name: Single Node Cluster
     shell: kubectl taint nodes --all node-role.kubernetes.io/master-


Tuesday, 10 March 2020

Full Automated Jenkins Pipeline

Main App:

pipeline {

  agent any

  stages {

    stage('Docker Build') {

      steps {

        sh '''sed -i "s/appname/${APPNAME}/g; s/relver/v1.${BUILD_NUMBER}/g" ${WORKSPACE}/docker-compose.yml

#sed -i "s/substitute/${JENENV}/g; s/initial/${APPNAME}/g" ${WORKSPACE}/filebeat.yml

sudo docker-compose build

'''

      }

    }

    stage('Docker Push/Pull') {

      steps {

        sh '''sudo docker-compose push

previous="$((${BUILD_NUMBER}-1))"

sudo docker pull ${REG}/${APPNAME}:v1.$previous || true

if [[ "$(sudo docker images -q ${REG}/${APPNAME}:v1.$previous 2> /dev/null)" != "" ]]; then

   sudo docker tag ${REG}/${APPNAME}:v1.$previous ${REG}/${APPNAME}:${RELEASE}

   sudo docker push ${REG}/${APPNAME}:${RELEASE}

   exit 0

else

   :

   exit 0

fi

#sudo ssh -T root@${SLAVE} docker login ${REG} -u AraRegistry -p ${ARA_CRED_PSW}

#sudo docker pull ${REG}/${APPNAME}:${RELEASE}

'''

      }

    }

    stage('Anchore Call') {

      steps {

        build job: 'anchore/Web', parameters: [

                    string(name: 'IMAGE_NAME', value: String.valueOf(REG) + '/' + String.valueOf(APPNAME) + ':v1.' + String.valueOf(BUILD_NUMBER)),

                    string(name: 'PARENT_WS', value: String.valueOf(WORKSPACE))

                    ], propagate: false, wait: false

        }

      }

        stage('Secret') {

          steps {

            sh '''check=$(kubectl get secret -n ${JENENV} | grep ${APPNAME} | awk \'{print $1}\')

if [ -z "$check" ]

then

 kubectl apply -f ${MY_CREDENTIAL} -n ${JENENV}

else

 kubectl delete secret -n ${JENENV} ${APPNAME}-secret

 kubectl apply -f ${MY_CREDENTIAL} -n ${JENENV}

fi

'''

          }

        }

        stage('Deploy') {
          steps {

            sh '''sed -i "s/JenEnv/${JENENV}/g; s/appname/${APPNAME}/g; s/relver/v1.${BUILD_NUMBER}/g" ${WORKSPACE}/config/deploy.yml

sed -i "s/JenEnv/${JENENV}/g; s/appname/${APPNAME}/g" ${WORKSPACE}/config/service.yml

# Deploy service

 kubectl apply -f ${WORKSPACE}/config/service.yml

 # Deploy

 kubectl apply -f ${WORKSPACE}/config/deploy.yml

 sleep 20

 # Get rollout status

 rolloutStatus=`kubectl rollout status deployment/${APPNAME} -n ${JENENV}`

 if [[ $rolloutStatus != *"successfully rolled out"* ]]; then

   echo "rollout of ${APPNAME} failed"

   exit 1

 fi

 # Now get the running pods

 failingPods=`kubectl get pods --field-selector=status.phase=Running -n ${JENENV} --selector=app=microgateway| wc -l`

 if (( $failingPods <= 1 )); then

   echo "${APPNAME} pods not running"

   exit 1

 fi

 '''

          }

        }

    stage('Push Version No') {

          steps {

            sh '''cd /var/lib/jenkins/workspace/${APPNAME}_develop/

echo "${APPNAME}:v1.${BUILD_ID} deployed on $(date)" > last-build-rel-ver.txt

git add last-build-rel-ver.txt

git commit -m "automated version"

git config credential.helper store

git push

'''

      }

    }

        stage('Azure Repo') {

          steps {

            build job: 'AzureClean/master', parameters: [

                    string(name: 'PARENT_APPNAME', value: String.valueOf(APPNAME))

                    ], propagate: true, wait: true

          }

        }

        stage('Cleanup') {

          steps {

            build(job: 'cleanupprod', propagate: true, wait: true)

          }

        }

      }

      environment {

        MY_CREDENTIAL = credentials('adservice_test')

        ARA_CRED = credentials('ara_secret')

        KUBECONFIG = '/home/isadmin/.kube/config'

        REG = 'araregistry.azurecr.io/ara'

        APPNAME = 'adhoc-room-availability'

        RELEASE = 'stable'

        JENENV = 'prod'

        SLAVE = 'box21.ara.ac.nz'

      }

    }



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

Scanner Call:

pipeline {
  agent any
  stages {
    stage('Analyze') {
      steps {
        sh 'echo "${IMAGE_NAME} ${PARENT_WS}/Dockerfile" > anchore_images'
        anchore(name: 'anchore_images', engineRetries: '5000' )
      }
      post {
        failure {
          script {            
              sh '''job=$(echo ${PARENT_WS} | cut -c 28-)

echo "https://kubeops1.ara.ac.nz:8443/job/anchore/job/${BRANCH_NAME}/${BUILD_NUMBER}/anchore-results/" | mail -s "Build: $job has failed to pass security scan" InfoSystems@ara.ac.nz

'''
          }
        }
        always {
          script {            
              sh '''

for i in `cat anchore_images | awk \'{print $1}\'`;do sudo docker rmi $i; done

'''
          }
        }
      }
    }
  }
  parameters {
    string(defaultValue: '', description: 'param1', name: 'IMAGE_NAME')
    string(defaultValue: '', description: 'param2', name: 'PARENT_WS')
  }
}

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

Repo Call:

pipeline {
  agent any
  stages {
    stage('Clean-Up') {
      steps {
        sh '''cd ${WORKSPACE}/
taglist=$(sudo ./docker_reg_tool https://${REPO} list ara/${PARENT_APPNAME} | grep 'latest')
for tags in $taglist
do
echo $tags
sudo ./docker_reg_tool https://${REPO} delete ara/${PARENT_APPNAME} $tags
done'''
      }
    }

  }
  parameters {
    string(defaultValue: '', description: 'param1', name: 'PARENT_APPNAME')
  }
  environment {
    REPO = 'araregistry.azurecr.io'
  }
}

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

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

Tuesday, 6 August 2019

Telegraf for K8s Cluster monitering

RBAC

kubectl create clusterrolebinding default-admin --clusterrole cluster-admin --serviceaccount=default:default

Secret

kubectl create secret -n monitoring generic telegraf --from-literal=env=prod --from-literal=monitor_username=youruser --from-literal=monitor_password=yourpassword --from-literal=monitor_host=https://your.influxdb.local --from-literal=monitor_database=yourdb

Daemon apply

apiVersion: v1
kind: ConfigMap
metadata:
  name: telegraf
  namespace: monitoring
  labels:
    k8s-app: telegraf
data:
  telegraf.conf: |+
    [global_tags]
      env = "$ENV"
    [agent]
      hostname = "$HOSTNAME"
    [[outputs.influxdb]]
      urls = ["$MONITOR_HOST"] # required
      database = "$MONITOR_DATABASE" # required
      timeout = "5s"
      username = "$MONITOR_USERNAME"
      password = "$MONITOR_PASSWORD"
   
    [[inputs.cpu]]
      percpu = true
      totalcpu = true
      collect_cpu_time = false
      report_active = false
    [[inputs.disk]]
      ignore_fs = ["tmpfs", "devtmpfs", "devfs"]
    [[inputs.diskio]]
    [[inputs.kernel]]
    [[inputs.mem]]
    [[inputs.processes]]
    [[inputs.swap]]
    [[inputs.system]]
    [[inputs.net]]
    [[inputs.docker]]
      endpoint = "unix:///var/run/docker/libcontainerd/docker-containerd.sock"
    [[inputs.kubernetes]]
      url = "https://$HOSTNAME:10250"
      #bearer_token = "/var/run/secrets/kubernetes.io/serviceaccount/token"
      bearer_token_string = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      insecure_skip_verify = true

---
# Section: Daemonset
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: telegraf
  namespace: monitoring
  labels:
    k8s-app: telegraf
spec:
  selector:
    matchLabels:
      name: telegraf
  template:
    metadata:
      labels:
        name: telegraf
    spec:
      containers:
      - name: telegraf
        image: docker.io/telegraf:latest
        resources:
          limits:
            memory: 500Mi
          requests:
            cpu: 500m
            memory: 500Mi
        env:
        - name: HOSTNAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: "HOST_PROC"
          value: "/rootfs/proc"
        - name: "HOST_SYS"
          value: "/rootfs/sys"
        - name: ENV
          valueFrom:
            secretKeyRef:
              name: telegraf
              key: env
        - name: MONITOR_USERNAME
          valueFrom:
            secretKeyRef:
              name: telegraf
              key: monitor_username
        - name: MONITOR_PASSWORD
          valueFrom:
            secretKeyRef:
              name: telegraf
              key: monitor_password
        - name: MONITOR_HOST
          valueFrom:
            secretKeyRef:
              name: telegraf
              key: monitor_host
        - name: MONITOR_DATABASE
          valueFrom:
            secretKeyRef:
              name: telegraf
              key: monitor_database
        volumeMounts:
        - name: sys
          mountPath: /rootfs/sys
          readOnly: true
        - name: proc
          mountPath: /rootfs/proc
          readOnly: true
        - name: docker-socket
          mountPath: /var/run/docker/libcontainerd/docker-containerd.sock
          readOnly: true
        - name: utmp
          mountPath: /var/run/utmp
          readOnly: true
        - name: config
          mountPath: /etc/telegraf
      terminationGracePeriodSeconds: 30
      volumes:
      - name: sys
        hostPath:
          path: /sys
      - name: docker-socket
        hostPath:
          path: /var/run/docker/libcontainerd/docker-containerd.sock
      - name: proc
        hostPath:
          path: /proc
      - name: utmp
        hostPath:
          path: /var/run/utmp
      - name: config
        configMap:
          name: telegraf

Wednesday, 31 July 2019

Kubernetes Deployment Via Ansible

/etc/ansible/playbook/kube-dependencies.yaml

- hosts: all
  become: yes
  tasks:
   - name: install gpg
     apt:
       name: gpg
       state: present
       update_cache: true

   - name: install Docker
     apt:
       name: docker.io
       state: present
       update_cache: true

   - name: Enable service
     service:
       name: docker
       enabled: yes

   - name: start service
     service:
       name: docker
       state: started

   - name: install APT Transport HTTPS
     apt:
       name: apt-transport-https
       state: present

   - name: add Kubernetes apt-key
     apt_key:
       url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
       state: present

   - name: add Kubernetes' APT repository
     apt_repository:
      repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
      state: present
      filename: 'kubernetes'

   - name: install kubelet
     apt:
       name: kubelet
       state: present
       update_cache: true

   - name: install kubeadm
     apt:
       name: kubeadm
       state: present

- hosts: master
  become: yes
  tasks:
   - name: install kubectl
     apt:
       name: kubectl
       state: present
       force: yes

/etc/ansible/playbook/master.yaml

- hosts: master
  become: yes
  tasks:
    - name: Disable SWAP since kubernetes can't work with swap enabled (1/2)
      shell: |
        swapoff -a
      when: ansible_swaptotal_mb > 0

    - name: Disable SWAP in fstab since kubernetes can't work with swap enabled (2/2)
      replace:
        path: /etc/fstab
        regexp: '^(.+?\sswap\s+sw\s+.*)$'
        replace: '# \1'

    - name: initialize the cluster
      shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
      args:
        chdir: $HOME
        creates: cluster_initialized.txt

    - name: create .kube directory
      become: yes
      file:
        path: $HOME/.kube
        state: directory
        mode: 0755

    - name: copy admin.conf to user's kube config
      copy:
        src: /etc/kubernetes/admin.conf
        dest: $HOME/.kube/config
        remote_src: yes

    - name: install Pod network
      become: yes
      shell: kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
      args:
        chdir: $HOME
        creates: pod_network_setup.txt

/etc/ansible/playbook/workers.yaml

- hosts: master
  become: yes
  gather_facts: false
  tasks:
    - name: get join command
      shell: kubeadm token create --print-join-command
      register: join_command_raw

    - name: set join command
      set_fact:
        join_command: "{{ join_command_raw.stdout_lines[0] }}"

- hosts: workers
  become: yes
  tasks:
    - name: Remove swapfile from /etc/fstab
      mount:
        name: swap
        fstype: swap
        state: absent

    - name: Disable swap
      command: swapoff -a
      when: ansible_swaptotal_mb > 0
    
    - name: join cluster
      shell: "{{ hostvars[groups['master'][0]].join_command }} >> node_joined.txt"
      args:
        chdir: $HOME
        creates: node_joined.txt

/etc/ansible/hosts

[master]
192.168.109.150

[workers]
192.168.109.151

[all:vars]
ansible_python_interpreter=/usr/bin/python3