kubernetes-diffwatcher

command module
v0.0.0-...-8a41695 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 15, 2023 License: Apache-2.0 Imports: 3 Imported by: 0

README

DiffWatcher is a state Monitor for k8s

DiffWatcher started as fork from kubewatch Diffwatcher is state Monitor for k8s. It monitors changes to various resources and notifies the user what was changed It can be used standalone or deployed in Kubernetes.

Image you have a cluster with many namespaces, with different shareholders. You want to track any changes made to the watched items, without using CI/CD pipelines (using kubectl, lens, k9s etc.). You want to get notified about such changes,you also want to see what exactly was changed. This is what diffwatcher is for.

Build Status Go Report Card codecov Docker Pulls GitHub release

There are basically two kind of notifications:

  • notifications for UPDATED items The whole idea behind is to track the usefull differences made on the items we watch, ignoring things like metadata changes, status changes, etc. Not only a simple msg that something was changed.
  • notifications for ADDED/DELETED items this is the original idea behind kubewatch, to track the added/deleted items and notify about them.

The usecase we are mainly intrested is the first one. We want to track the changes made on the items we watch (mainly deployments,rs,hpa,configmaps), and get notified about any changes made on them.

TL;DR

#Latest Release: 1.0.1- [Release Notes]

  • Add support for ignoring specific namespaces and watching more than one namespace
  • Add metrics
  • Deeper Diff for configmaps (currently it drops the new configmap as a whole). its Work for me atm. It needs more work to be more generic.

Latest image

docmarr/kubernetes-diffwatcher:1.0.1

Install

$ helm repo add diffwatcher https://marvasgit.github.io/kubernetes-diffwatcher/
$ helm install my-release diffwatcher

Introduction

This chart bootstraps a diffwatcher deployment on a Kubernetes cluster using the Helm package manager.

Prerequisites

  • Kubernetes 1.19+
  • Helm 3.2.0+

Installing the Chart

To install the chart with the release name my-release:

$ helm repo add diffwatcher https://marvasgit.github.io/kubernetes-diffwatcher/
$ helm install my-release diffwatcher

The command deploys diffwatcher on the Kubernetes cluster in the default configuration. The Parameters section lists the parameters that can be configured during installation.

Uninstalling the Chart

To uninstall/delete the my-release deployment:

$ helm delete my-release

The command removes all the Kubernetes components associated with the chart and deletes the release.

Parameters

Global parameters
Name Description Value
global.imageRegistry Global Docker image registry ""
global.imagePullSecrets Global Docker registry secret names as an array []
Common parameters
Name Description Value
kubeVersion Force target Kubernetes version (using Helm capabilities if not set) ""
nameOverride String to partially override common.names.fullname template ""
fullnameOverride String to fully override common.names.fullname template ""
commonLabels Labels to add to all deployed objects {}
commonAnnotations Annotations to add to all deployed objects {}
diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) false
diagnosticMode.command Command to override all containers in the the deployment(s)/statefulset(s) ["sleep"]
diagnosticMode.args Args to override all containers in the the deployment(s)/statefulset(s) ["infinity"]
extraDeploy Array of extra objects to deploy with the release []
diffwatcher parameters
Name Description Value
image.registry diffwatcher image registry docker.io
image.repository diffwatcher image repository bitnami/diffwatcher
image.tag diffwatcher image tag (immutable tags are recommended) 0.1.0-debian-10-r513
image.pullPolicy diffwatcher image pull policy IfNotPresent
image.pullSecrets Specify docker-registry secret names as an array []
hostAliases Add deployment host aliases []
message.title Message Title used for MsTeams and others "XXXX"
diff.ignore List of Json path to ignore during compare process ""
slack.enabled Enable Slack notifications true
slack.channel Slack channel to notify XXXX
slack.token Slack API token XXXX
hipchat.enabled Enable HipChat notifications false
hipchat.room HipChat room to notify ""
hipchat.token HipChat token ""
hipchat.url HipChat URL ""
mattermost.enabled Enable Mattermost notifications false
mattermost.channel Mattermost channel to notify ""
mattermost.url Mattermost URL ""
mattermost.username Mattermost user to notify ""
flock.enabled Enable Flock notifications false
flock.url Flock URL ""
msteams.enabled Enable Microsoft Teams notifications false
msteams.webhookurl Microsoft Teams webhook URL ""
webhook.enabled Enable Webhook notifications false
webhook.url Webhook URL ""
smtp.enabled Enable SMTP (email) notifications false
smtp.to Destination email address (required) ""
smtp.from Source email address (required) ""
smtp.hello SMTP hello field (optional) ""
smtp.smarthost SMTP server address (name:port) (required) ""
smtp.subject Source email subject ""
smtp.auth.username Username for LOGIN and PLAIN auth mech ""
smtp.auth.password Password for LOGIN and PLAIN auth mech ""
smtp.auth.secret Secret for CRAM-MD5 auth mech ""
smtp.auth.identity Identity for PLAIN auth mech ""
smtp.requireTLS Force STARTTLS. Set to true or false ""
namespaceToWatch Namespace to watch, leave it empty for watching all ""
resourcesToWatch.deployment Watch changes to Deployments true
resourcesToWatch.replicationcontroller Watch changes to ReplicationControllers false
resourcesToWatch.replicaset Watch changes to ReplicaSets false
resourcesToWatch.daemonset Watch changes to DaemonSets false
resourcesToWatch.services Watch changes to Services false
resourcesToWatch.pod Watch changes to Pods true
resourcesToWatch.job Watch changes to Jobs false
resourcesToWatch.persistentvolume Watch changes to PersistentVolumes false
command Override default container command (useful when using custom images) []
args Override default container args (useful when using custom images) []
lifecycleHooks for the diffwatcher container(s) to automate configuration before or after startup {}
extraEnvVars Extra environment variables to be set on diffwatcher container []
extraEnvVarsCM Name of existing ConfigMap containing extra env vars ""
extraEnvVarsSecret Name of existing Secret containing extra env vars ""
diffwatcher deployment parameters
Name Description Value
replicaCount Number of diffwatcher replicas to deploy 1
podSecurityContext.enabled Enable diffwatcher containers' SecurityContext false
podSecurityContext.fsGroup Set diffwatcher containers' SecurityContext fsGroup ""
containerSecurityContext.enabled Enable diffwatcher pods' Security Context false
containerSecurityContext.runAsUser Set diffwatcher pods' SecurityContext runAsUser ""
containerSecurityContext.runAsNonRoot Set diffwatcher pods' SecurityContext runAsNonRoot ""
resources.limits The resources limits for the diffwatcher container {}
resources.requests The requested resources for the diffwatcher container {}
startupProbe.enabled Enable startupProbe false
startupProbe.initialDelaySeconds Initial delay seconds for startupProbe 10
startupProbe.periodSeconds Period seconds for startupProbe 10
startupProbe.timeoutSeconds Timeout seconds for startupProbe 1
startupProbe.failureThreshold Failure threshold for startupProbe 3
startupProbe.successThreshold Success threshold for startupProbe 1
livenessProbe.enabled Enable livenessProbe false
livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe 10
livenessProbe.periodSeconds Period seconds for livenessProbe 10
livenessProbe.timeoutSeconds Timeout seconds for livenessProbe 1
livenessProbe.failureThreshold Failure threshold for livenessProbe 3
livenessProbe.successThreshold Success threshold for livenessProbe 1
readinessProbe.enabled Enable readinessProbe false
readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe 10
readinessProbe.periodSeconds Period seconds for readinessProbe 10
readinessProbe.timeoutSeconds Timeout seconds for readinessProbe 1
readinessProbe.failureThreshold Failure threshold for readinessProbe 3
readinessProbe.successThreshold Success threshold for readinessProbe 1
customStartupProbe Override default startup probe {}
customLivenessProbe Override default liveness probe {}
customReadinessProbe Override default readiness probe {}
podAffinityPreset Pod affinity preset. Ignored if affinity is set. Allowed values: soft or hard ""
podAntiAffinityPreset Pod anti-affinity preset. Ignored if affinity is set. Allowed values: soft or hard soft
nodeAffinityPreset.type Node affinity preset type. Ignored if affinity is set. Allowed values: soft or hard ""
nodeAffinityPreset.key Node label key to match. Ignored if affinity is set. ""
nodeAffinityPreset.values Node label values to match. Ignored if affinity is set. []
affinity Affinity for pod assignment {}
nodeSelector Node labels for pod assignment {}
tolerations Tolerations for pod assignment []
priorityClassName Controller priorityClassName ""
schedulerName Name of the k8s scheduler (other than default) ""
topologySpreadConstraints Topology Spread Constraints for pod assignment []
podLabels Extra labels for diffwatcher pods {}
podAnnotations Annotations for diffwatcher pods {}
extraVolumes Optionally specify extra list of additional volumes for diffwatcher pods []
extraVolumeMounts Optionally specify extra list of additional volumeMounts for diffwatcher container(s) []
updateStrategy.type Deployment strategy type. RollingUpdate
initContainers Add additional init containers to the diffwatcher pods []
sidecars Add additional sidecar containers to the diffwatcher pods []
RBAC parameters
Name Description Value
rbac.create Whether to create & use RBAC resources or not false
serviceAccount.create Specifies whether a ServiceAccount should be created true
serviceAccount.name Name of the service account to use. If not set and create is true, a name is generated using the fullname template. ""
serviceAccount.automountServiceAccountToken Automount service account token for the server service account true
serviceAccount.annotations Annotations for service account. Evaluated as a template. Only used if create is true. {}

Specify each parameter using the --set key=value[,key=value] argument to helm install. For example,

$ helm install my-release bitnami/diffwatcher \
  --set=slack.channel="#bots",slack.token="XXXX-XXXX-XXXX"

Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example,

$ helm install my-release -f values.yaml bitnami/diffwatcher

Tip: You can use the default values.yaml

Configuration and installation details

Rolling VS Immutable tags

It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image.

Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist.

Create a Slack bot

Open https://my.slack.com/services/new/bot to create a new Slack bot. The API token can be found on the edit page (it starts with xoxb-).

Invite the Bot to your channel by typing /join @name_of_your_bot in the Slack message area.

Adding extra environment variables

In case you want to add extra environment variables (useful for advanced operations like custom init scripts), you can use the extraEnvVars property.

extraEnvVars:
  - name: LOG_LEVEL
    value: debug

Alternatively, you can use a ConfigMap or a Secret with the environment variables. To do so, use the extraEnvVarsCM or the extraEnvVarsSecret values.

Sidecars and Init Containers

If you have a need for additional containers to run within the same pod as the diffwatcher app (e.g. an additional metrics or logging exporter), you can do so via the sidecars config parameter. Simply define your container according to the Kubernetes container spec.

sidecars:
  - name: your-image-name
    image: your-image
    imagePullPolicy: Always
    ports:
      - name: portname
       containerPort: 1234

Similarly, you can add extra init containers using the initContainers parameter.

initContainers:
  - name: your-image-name
    image: your-image
    imagePullPolicy: Always
    ports:
      - name: portname
        containerPort: 1234
Deploying extra resources

There are cases where you may want to deploy extra objects, such a ConfigMap containing your app's configuration or some extra deployment with a micro service used by your app. For covering this case, the chart allows adding the full specification of other objects using the extraDeploy parameter.

Setting Pod's affinity

This chart allows you to set your custom affinity using the affinity parameter. Find more information about Pod's affinity in the kubernetes documentation.

As an alternative, you can use of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the bitnami/common chart. To do so, set the podAffinityPreset, podAntiAffinityPreset, or nodeAffinityPreset parameters.

Local Installation
Using go package installer:
# Download and install diffwatcher
$ go get -u github.com/marvasgit/kubernetes-diffwatcher

# Configure the notification channel
$ diffwatcher config add slack --channel <slack_channel> --token <slack_token>

# Add resources to be watched
$ diffwatcher resource add --po --svc
INFO[0000] resource svc configured
INFO[0000] resource po configured

# start diffwatcher server
$ diffwatcher
INFO[0000] Starting diffwatcher controller                 pkg=diffwatcher-service
INFO[0000] Starting diffwatcher controller                 pkg=diffwatcher-pod
INFO[0000] Processing add to service: default/kubernetes  pkg=diffwatcher-service
INFO[0000] Processing add to service: kube-system/tiller-deploy  pkg=diffwatcher-service
INFO[0000] Processing add to pod: kube-system/tiller-deploy-69ffbf64bc-h8zxm  pkg=diffwatcher-pod
INFO[0000] diffwatcher controller synced and ready         pkg=diffwatcher-service
INFO[0000] diffwatcher controller synced and ready         pkg=diffwatcher-pod

Using Docker:

To Run diffwatcher Container interactively, place the config file in $HOME/.diffwatcher.yaml location and use the following command.

docker run --rm -it --network host -v $HOME/.diffwatcher.yaml:/root/.diffwatcher.yaml -v $HOME/.kube/config:/opt/bitnami/diffwatcher/.kube/config --name <container-name> us-central1-docker.pkg.dev/genuine-flight-317411/devel/diffwatcher

Example:

$ docker run --rm -it --network host -v $HOME/.diffwatcher.yaml:/root/.diffwatcher.yaml -v $HOME/.kube/config:/opt/bitnami/diffwatcher/.kube/config --name diffwatcher-app us-central1-docker.pkg.dev/genuine-flight-317411/devel/diffwatcher

==> Writing config file...
INFO[0000] Starting diffwatcher controller                 pkg=diffwatcher-service
INFO[0000] Starting diffwatcher controller                 pkg=diffwatcher-pod
INFO[0000] Starting diffwatcher controller                 pkg=diffwatcher-deployment
INFO[0000] Starting diffwatcher controller                 pkg=diffwatcher-namespace
INFO[0000] Processing add to namespace: kube-node-lease  pkg=diffwatcher-namespace
INFO[0000] Processing add to namespace: kube-public      pkg=diffwatcher-namespace
INFO[0000] Processing add to namespace: kube-system      pkg=diffwatcher-namespace
INFO[0000] Processing add to namespace: default          pkg=diffwatcher-namespace
....

To Demonise diffwatcher container use

$ docker run --rm -d --network host -v $HOME/.diffwatcher.yaml:/root/.diffwatcher.yaml -v $HOME/.kube/config:/opt/bitnami/diffwatcher/.kube/config --name diffwatcher-app us-central1-docker.pkg.dev/genuine-flight-317411/devel/diffwatcher

Configure

diffwatcher supports config command for configuration. Config file will be saved at $HOME/.diffwatcher.yaml

$ diffwatcher config -h

config command allows admin setup his own configuration for running diffwatcher

Usage:
  diffwatcher config [flags]
  diffwatcher config [command]

Available Commands:
  add         add webhook config to .diffwatcher.yaml
  test        test handler config present in .diffwatcher.yaml
  view        view .diffwatcher.yaml

Flags:
  -h, --help   help for config

Use "diffwatcher config [command] --help" for more information about a command.
Example:
slack:
  • Create a slack Bot

  • Edit the Bot to customize its name, icon and retrieve the API token (it starts with xoxb-).

  • Invite the Bot into your channel by typing: /invite @name_of_your_bot in the Slack message area.

  • Add Api token to diffwatcher config using the following steps

    $ diffwatcher config add slack --channel <slack_channel> --token <slack_token>
    

    You have an altenative choice to set your SLACK token, channel via environment variables:

    $ export KW_SLACK_TOKEN='XXXXXXXXXXXXXXXX'
    $ export KW_SLACK_CHANNEL='#channel_name'
    
slackwebhookurl:
  • Create a slack app

  • Enable Incoming Webhooks. (On "Settings" page.)

  • Create an incoming webhook URL (Add New Webhook to Workspace on "Settings" page.)

  • Pick a channel that the app will post to, and then click to Authorize your app. You will get back your webhook URL.
    The Slack Webhook URL will look like: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

  • Add slack webhook url to diffwatcher config using the following steps

    $ diffwatcher config add slackwebhookurl --username <slack_username> --emoji <slack_emoji> --channel <slack_channel> --slackwebhookurl <slack_webhook_url>
    

    Or, you have an altenative choice to set your SLACK channel, username, emoji and webhook URL via environment variables:

    $ export KW_SLACK_CHANNEL=slack_channel
    $ export KW_SLACK_USERNAME=slack_username
    $ export KW_SLACK_EMOJI=slack_emoji
    $ export KW_SLACK_WEBHOOK_URL=slack_webhook_url
    
  • Example apply done in a bash script:

$ cat diffwatcher-configmap-slackwebhook.yaml | sed "s|<slackchannel>|"\"$SlackChannel"\"|g;s|<slackusername>|"\"$SlackUsesrName"\"|g;s|<slackemoji>|"\"$SlackEmoji"\"|g;s|<SlackWebhookUrl>|"\"$WebhookUrl"\"|g" | kubectl create -f -
  • An example diffwatcher-configmap-slackwebhook.yaml YAML File:
apiVersion: v1
kind: ConfigMap
metadata:
 name: diffwatcher
data:
 .diffwatcher.yaml: |
   namespace: ""
   handler:
     slackwebhook:
       enabled: true
       channel: <slackchannel>
       username: <slackusername>
       emoji: <slackemoji>
       slackwebhookurl: <SlackWebhookUrl>
   resource:
     clusterrole: false
     configmap: false
     daemonset: false
     deployment: true
     ingress: false
     job: false
     namespace: false
     node: false
     persistentvolume: false
     pod: true
     replicaset: false
     replicationcontroller: false
     secret: false
     serviceaccount: false
     services: true
     event: true
     coreevent: false
   ```
flock:
  • Create a flock bot.

  • Add flock webhook url to config using the following command.

    $ diffwatcher config add flock --url <flock_webhook_url>
    

    You have an altenative choice to set your FLOCK URL

    $ export KW_FLOCK_URL='https://api.flock.com/hooks/sendMessage/XXXXXXXX'
    

Testing Config

To test the handler config by send test messages use the following command.

$ diffwatcher config test -h

Tests handler configs present in .diffwatcher.yaml by sending test messages

Usage:
  diffwatcher config test [flags]

Flags:
  -h, --help   help for test
Example:
$ diffwatcher config test

Testing Handler configs from .diffwatcher.yaml
2019/06/03 12:29:23 Message successfully sent to channel ABCD at 1559545162.000100

Viewing config

To view the entire config file $HOME/.diffwatcher.yaml use the following command.

$ diffwatcher config view
Contents of .diffwatcher.yaml

handler:
  slack:
    token: xoxb-xxxxx-yyyy-zzz
    channel: kube-watch
  hipchat:
    token: ""
    room: ""
    url: ""
  mattermost:
    channel: ""
    url: ""
    username: ""
  flock:
    url: ""
  webhook:
    url: ""
  cloudevent:
    url: ""
resource:
  deployment: false
  replicationcontroller: false
  replicaset: false
  daemonset: false
  services: false
  pod: true
  job: false
  node: false
  clusterrole: false
  clusterrolebinding: false
  serviceaccount: false
  persistentvolume: false
  namespace: false
  secret: false
  configmap: false
  ingress: false
  event: true
  coreevent: false
namespace: ""
message:
  title: "XXXX"
diff:
  ignore:
  - "metadata.creationTimestamp"
  - "metadata.resourceVersion"
  - "metadata.selfLink"
  - "metadata.uid"
  - "status"
  - "metadata.managedFields"
  - "metadata.generation"
  - "metadata.annotations.kubectl.kubernetes.io/last-applied-configuration"
  - "metadata.annotations.deployment.kubernetes.io/revision"
  - "metadata.annotations.kubernetes.io/change-cause"
  - "metadata.annotations.kubernetes.io/psp"
  - "metadata.annotations.kubernetes.io/psp-spec"
  - "metadata.annotations.kubernetes.io/psp-status"

Resources

To manage the resources being watched, use the following command, changes will be saved to $HOME/.diffwatcher.yaml.

$ diffwatcher resource -h

manage resources to be watched

Usage:
  diffwatcher resource [flags]
  diffwatcher resource [command]

Available Commands:
  add         adds specific resources to be watched
  remove      remove specific resources being watched

Flags:
      
      --clusterrolebinding      watch for cluster role bindings
      --clusterrole             watch for cluster roles
      --cm                      watch for plain configmaps
      --deploy                  watch for deployments
      --ds                      watch for daemonsets
  -h, --help                    help for resource
      --ing                     watch for ingresses
      --job                     watch for jobs
      --node                    watch for Nodes
      --ns                      watch for namespaces
      --po                      watch for pods
      --pv                      watch for persistent volumes
      --rc                      watch for replication controllers
      --rs                      watch for replicasets
      --sa                      watch for service accounts
      --secret                  watch for plain secrets
      --svc                     watch for services
      --coreevent               watch for events from the kubernetes core api. (Old events api, replaced in kubernetes 1.19)

Use "diffwatcher resource [command] --help" for more information about a command.

Add/Remove resource:
$ diffwatcher resource add -h

adds specific resources to be watched

Usage:
  diffwatcher resource add [flags]

Flags:
  -h, --help   help for add

Global Flags:
      --clusterrole             watch for cluster roles
      --clusterrolebinding      watch for cluster role bindings
      --cm                      watch for plain configmaps
      --deploy                  watch for deployments
      --ds                      watch for daemonsets
      --ing                     watch for ingresses
      --job                     watch for jobs
      --node                    watch for Nodes
      --ns                      watch for namespaces
      --po                      watch for pods
      --pv                      watch for persistent volumes
      --rc                      watch for replication controllers
      --rs                      watch for replicasets
      --sa                      watch for service accounts
      --secret                  watch for plain secrets
      --svc                     watch for services
      --coreevent               watch for events from the kubernetes core api. (Old events api, replaced in kubernetes 1.19)

Example:
# rc, po and svc will be watched
$ diffwatcher resource add --rc --po --svc

# rc, po and svc will be stopped from being watched
$ diffwatcher resource remove --rc --po --svc
Changing log level

In case you want to change the default log level, add an environment variable named LOG_LEVEL with value from trace/debug/info/warning/error

env:
- name: LOG_LEVEL
  value: debug
Changing log format

In case you want to change the log format to json, add an environment variable named LOG_FORMATTER with value json

env:
- name: LOG_FORMATTER
  value: json

Build

Using go

Clone the repository anywhere:

$ git clone https://github.com/marvasgit/kubernetes-diffwatcher.git
$ cd diffwatcher
$ go build

or

You can also use the Makefile directly:

$ make build
Prerequisites
  • You need to have Go (v1.5 or later) installed. Make sure to set $GOPATH
Using Docker
$ make docker-image
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
diffwatcher           latest              919896d3cd90        3 minutes ago       27.9MB
Prerequisites
  • you need to have docker installed.

Things for future version

  • Add support for ignoring specific namespaces and watching more than one namespace (1.0.1)

  • Add metrics (1.0.1)

  • Deeper Diff for configmaps (currently it drops the new configmap as a whole)(1.0.1)

  • Add regex support for path ignorance in diff

  • Change config source file from yaml to json

  • Dissable processing during deployment

Contribution

Refer to the contribution guidelines to get started.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
pkg
handlers/smtp
Package smtp implements an email notification handler for diffwatcher.
Package smtp implements an email notification handler for diffwatcher.
tools
yannotated
Yannotated generates an annotated yaml config boilerplate from a Go structure tree.
Yannotated generates an annotated yaml config boilerplate from a Go structure tree.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL