Kubernetes (for development)
****************************

.. highlight:: bash


Install ``k3d``::

  wget -q -O - https://raw.githubusercontent.com/rancher/k3d/master/install.sh | TAG=v1.3.4 bash

Install ``kubectl``::

  curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.16.3/bin/linux/amd64/kubectl
  mv kubectl ~/bin/
  chmod +x ~/bin/kubectl

Create a cluster::

  k3d create

Set the ``KUBECONFIG`` environment variable::

  # bash
  export KUBECONFIG=$(k3d get-kubeconfig)
  # fish
  set -x KUBECONFIG (k3d get-kubeconfig)

Helm
----

From `Initialize Helm (Install Tiller)`_
(and `GitHub issue, tiller won't install #489`_)

Download ``helm`` from https://github.com/helm/helm/releases/tag/v2.16.1

.. note:: These instructions work for ``helm`` version 2.x.x, but not 3.x.x.

For example:

- Download ``helm-v2.16.1-linux-amd64.tar.gz``.
- Extract ``helm`` and move it to your ``~/bin/`` folder.

::

  helm version

::

  kubectl -n kube-system create serviceaccount tiller
  kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
  helm init --service-account tiller

  # test
  kubectl -n kube-system  rollout status deploy/tiller-deploy

Postgres
========

::

  helm install --name kb-dev-db stable/postgresql --set service.nodePort=30432 --set service.type=NodePort --set postgresqlPassword=postgres

Connect using the ``service``::

  # bash
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services kb-dev-db-postgresql)
  PGPASSWORD="postgres" psql --host $NODE_IP --port $NODE_PORT -U postgres -d postgres

  # fish
  set -x NODE_IP (kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  set -x NODE_PORT (kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services kb-dev-db-postgresql)
  export PGPASSWORD="postgres"; psql --host $NODE_IP --port $NODE_PORT -U postgres -d postgres

Flowable
--------

.. note:: Install Postgres_ first...

Log into ``psql`` and create the ``flowable`` table::

  CREATE DATABASE flowable TEMPLATE=template0 ENCODING='utf-8';

Then run :download:`misc/k3s/init_flowable.sh`

redis
=====

Install::

  helm install stable/redis --name kb-redis --set master.service.nodePort=30379 --set master.service.type=NodePort --set usePassword=false --cluster.enabled=false

.. note:: ``cluster.enabled=false`` is not recognised (for some reason)...
          Just remove it for now...

Connect::

  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services kb-redis-master)
  redis-cli -h $NODE_IP -p $NODE_PORT

Traefik
=======

https://github.com/rancher/k3d/issues/103#issuecomment-528896912

::

  sudo -i service tomcat8 stop
  kubectl -n kube-system edit configmap traefik

Add the ``api`` section below ``metrics`` e.g::

  [metrics]
    [metrics.prometheus]
      entryPoint = "traefik"
  [api]
    entryPoint = "dash"
    dashboard = true

To find the 'EXTERNAL-IP'::

  kubectl get service --all-namespaces

Nothing is happening... I tried::

  http GET http://172.20.0.2:8080/dash/

https://felixwiedmann.de/k3d-manage-k3s-clusters/

https://localhost:6443/ does ask for a user name and password!

.. :)

I think this just worked:

From:
https://github.com/rancher/k3d/blob/master/docs/examples.md

Apply this::

  apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    name: flowable-rest
    annotations:
      ingress.kubernetes.io/ssl-redirect: "false"
  spec:
    rules:
    - http:
        paths:
        - path: /
          backend:
            serviceName: flowable-rest
            servicePort: 8080

::

  ➤ kubectl get ing
  NAME                  HOSTS   ADDRESS      PORTS   AGE
  kb-flowable-ingress   *                    80      132m
  flowable-rest         *       172.20.0.2   80      2m6s

::

  http GET http://172.20.0.2/
  http GET http://rest-admin:test@172.20.0.2/repository/deployments/
  http GET http://admin:test@172.20.0.2/repository/deployments/
  # this one is OK
  http GET http://rest-admin:test@172.20.0.2/actuator/health
  # this one is working!
  http GET http://rest-admin:test@172.20.0.2/service/repository/deployments/


Elastic
=======

https://github.com/helm/charts/tree/master/stable/elasticsearch

::

  helm install --name kb-elastic stable/elasticsearch
  client.serviceType=
  client.httpNodePort

::

  Elasticsearch can be accessed:

  * Within your cluster, at the following DNS name at port 9200:

  kb-elastic-elasticsearch-client.default.svc

  * From outside the cluster, run these commands in the same shell:

  export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services kb-elastic-elasticsearch-client)
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT

To remove::

  ➤ helm delete kb-elastic
  # list pvc and delete
  ➤ kubectl get pvc
  ➤ kubectl delete pvc data-kb-elastic-elasticsearch-data-0

.. -----------------------------------------------------------------------------
.. Old Docs Below Here
.. -----------------------------------------------------------------------------

Install
=======

::

  # you will need your sudo password here...
  ➤ curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644

  ➤ kubectl get nodes
  NAME                    STATUS   ROLES    AGE    VERSION
  patrick-inspiron        Ready    master   105s   v1.16.3-k3s.2

  ➤ kubectl get po -n kube-system
  ➤ kubectl get pods --all-namespaces
  ➤ kubectl version

Remove
------

::

  /usr/local/bin/k3s-uninstall.sh

Commands
========

``ConfigMap``::

  kubectl get configmaps -o yaml

``Pod``::

  kubectl get pod
  kubectl get pods --all-namespaces
  kubectl describe pod
  # a specific pod (get the name from the 'get pod' command)
  kubectl describe pod postgres-78b64dc858-d8ktt
  # logs for a pod (get the name from the 'get pod' command)
  kubectl logs postgres-78b64dc858-d8ktt -f
  kubectl get ing
  kubectl get endpoints

Test
====

To deploy a simple pod
----------------------

From `Intro to Kubernetes and Rancher Online Training: August 1, 2019`_

Download :download:`misc/k3s/pod.yaml`

::

  kubectl apply -f pod.yaml
  # check progress
  kubectl get pods -w

  # check logs
  kubectl describe pod

.. note:: ``CrashLoopBackOff`` is an *expected* response because the bash script
          in the pod is completing.  Kubernetes doesn't expect this, so the
          backoff is a delay before re-starting.

Delete the pod::

  kubectl delete po/myapp-pod

Local Storage
=============

::

  kubectl apply -f ~/dev/module/docs/source/misc/k3s/flowable/rancher-local-path-storage.yaml
  # check
  kubectl get storageclass

Flowable
========

The GIT repository is here:
https://github.com/flowable/flowable-engine/tree/master/k8s

::

  kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
  kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml

  # try without local storage
  # kubectl apply -f ~/dev/module/docs/source/misc/k3s/flowable/flowable-local-storageclass.yaml
  helm repo add flowable https://flowable.org/helm/
  # helm install flowable/flowable --name=flowable
  helm install flowable/flowable --name=kb-flowable --set postgres.enabled=false --set rest.enabled=true --set database.username=postgres --set database.password=postgres --set database.datasourceDriverClassName=org.postgresql.Driver --set database.datasourceUrl=jdbc:postgresql://postgres-service-name:5432/flowable

WIP
---

This gets an Nginx response:
http://flowable-idm-default.localhost.nip.io/
You can see the ingress using this command::

  kubectl get ing

So try:
http://kb-flowable.localhost.nip.io/flowable-rest/

Old Postgres Notes
==================

Version 3 (``helm``)
--------------------

::

  helm install --name kb-dev-db stable/postgresql --set service.nodePort=30432 --set service.type=NodePort --set postgresqlPassword=postgres

.. tip:: If you change the password and need to re-install, then you will need
         to delete the persistent volume...
         For more information, search for
         ``kubectl get pvc``
         and
         ``kubectl delete pvc data-some-lingering-pvc``
         in
         https://github.com/helm/charts/issues/12836

Connect using the ``service``::

  # password 'postgres'
  psql -h 127.0.0.1 -U postgres -d postgres -p 30432

Uninstall::

  helm del --purge kb-dev-db
  kubectl delete pvc data-kb-dev-db-postgresql-0

Version 2 (I am hoping this may be persistent)
----------------------------------------------

From:
https://severalnines.com/database-blog/using-kubernetes-deploy-postgresql

Using these ``yaml`` files:

- :download:`misc/k3s/severalnines/postgres-configmap.yaml`
- :download:`misc/k3s/severalnines/postgres-storage.yaml`
- :download:`misc/k3s/severalnines/postgres-deployment.yaml`
- :download:`misc/k3s/severalnines/postgres-service.yaml`

::

  kubectl create -f postgres-configmap.yaml
  kubectl create -f postgres-storage.yaml
  kubectl create -f postgres-deployment.yaml
  kubectl create -f postgres-service.yaml

Find the IP address::

  kubectl get service

Connect to Postgres using the port number:::

  psql -h localhost -U postgresadmin --password -p 31053 postgresdb

Version 1 (is not persistent)
-----------------------------

::

  kubectl apply -f ~/dev/module/docs/source/misc/k3s/postgres.yaml
  # check progress
  kubectl get pods -w

  kubectl apply -f ~/dev/module/docs/source/misc/k3s/postgres-service.yaml
  # check progress
  kubectl get service
  # output
  NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
  kubernetes   ClusterIP   10.43.0.1      <none>        443/TCP          55m
  postgres     NodePort    10.43.51.112   <none>        5432:30432/TCP   15m

To connect Postgres to the port listed above::

  psql -h localhost -U postgres -d postgres -p 30432

redis (with ``helm``)
---------------------

Install::

  helm install stable/redis --name kb-redis --set master.service.nodePort=30379 --set master.service.type=NodePort --set usePassword=false --cluster.enabled=false

Connect::

  redis-cli -h 127.0.0.1 -p 30379 ping

Uninstall::

  helm del --purge kb-redis


.. _`Intro to Kubernetes and Rancher Online Training: August 1, 2019`: https://youtu.be/wVlCbPtH41I?t=1736
.. _`Initialize Helm (Install Tiller)`: https://rancher.com/docs/rancher/v2.x/en/installation/ha/helm-init/
.. _`GitHub issue, tiller won't install #489`: https://github.com/rancher/k3s/issues/489