From 04d0d6c931c541ead098a4171763cc0051cf7fdd Mon Sep 17 00:00:00 2001 From: Julien Dubois Date: Mon, 14 Jan 2019 16:28:02 +0100 Subject: [PATCH] Add Kubernetes support --- k8s/README.md | 66 ++++++++++++++++++++++++++++++++++ k8s/jhonline-deployment.yml | 71 +++++++++++++++++++++++++++++++++++++ k8s/jhonline-mysql.yml | 46 ++++++++++++++++++++++++ k8s/jhonline-service.yml | 14 ++++++++ k8s/jwt-secret.yml | 8 +++++ kubectl-apply.sh | 5 +++ 6 files changed, 210 insertions(+) create mode 100644 k8s/README.md create mode 100644 k8s/jhonline-deployment.yml create mode 100644 k8s/jhonline-mysql.yml create mode 100644 k8s/jhonline-service.yml create mode 100644 k8s/jwt-secret.yml create mode 100755 kubectl-apply.sh diff --git a/k8s/README.md b/k8s/README.md new file mode 100644 index 00000000..a8b8c17f --- /dev/null +++ b/k8s/README.md @@ -0,0 +1,66 @@ +# JHipster generated kubernetes configuration + +## Preparation + +You will need to push your image to a registry. If you have not done so, use the following commands to tag and push the images: + +``` +$ docker image tag jhonline jhipster-c4/jhonline +$ docker push jhipster-c4/jhonline +``` + +## Deployment + +You can deploy all your apps by running the below bash command: + +``` +./kubectl-apply.sh +``` + +## Exploring your services + + +Use these commands to find your application's IP addresses: + +``` +$ kubectl get svc jhonline +``` + +## Scaling your deployments + +You can scale your apps using + +``` +$ kubectl scale deployment --replicas +``` + +## zero-downtime deployments + +The default way to update a running app in kubernetes, is to deploy a new image tag to your docker registry and then deploy it using + +``` +$ kubectl set image deployment/-app = +``` + +Using livenessProbes and readinessProbe allows you to tell kubernetes about the state of your apps, in order to ensure availablity of your services. You will need minimum 2 replicas for every app deployment, you want to have zero-downtime deployed. This is because the rolling upgrade strategy first kills a running replica in order to place a new. Running only one replica, will cause a short downtime during upgrades. + + + +## Troubleshooting + +> my apps doesn't get pulled, because of 'imagePullBackof' + +check the registry your kubernetes cluster is accessing. If you are using a private registry, you should add it to your namespace by `kubectl create secret docker-registry` (check the [docs](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) for more info) + +> my apps get killed, before they can boot up + +This can occur, if your cluster has low resource (e.g. Minikube). Increase the `initialDelySeconds` value of livenessProbe of your deployments + +> my apps are starting very slow, despite I have a cluster with many resources + +The default setting are optimized for middle scale clusters. You are free to increase the JAVA_OPTS environment variable, and resource requests and limits to improve the performance. Be careful! + + +> my SQL based microservice stuck during liquibase initialization when running multiple replicas + +Sometimes the database changelog lock gets corrupted. You will need to connect to the database using `kubectl exec -it` and remove all lines of liquibases `databasechangeloglock` table. diff --git a/k8s/jhonline-deployment.yml b/k8s/jhonline-deployment.yml new file mode 100644 index 00000000..bba08180 --- /dev/null +++ b/k8s/jhonline-deployment.yml @@ -0,0 +1,71 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: jhonline + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: jhonline + version: "v1" + template: + metadata: + labels: + app: jhonline + version: "v1" + spec: + initContainers: + - name: init-ds + image: busybox + command: + - '/bin/sh' + - '-c' + - | + while true + do + rt=$(nc -z -w 1 jhonline-mysql 3306) + if [ $? -eq 0 ]; then + echo "DB is UP" + break + fi + echo "DB is not yet reachable;sleep for 10s before retry" + sleep 10 + done + containers: + - name: jhonline-app + image: jhipster/jhipster-online + env: + - name: SPRING_PROFILES_ACTIVE + value: prod + - name: JHIPSTER_SECURITY_AUTHENTICATION_JWT_BASE64_SECRET + valueFrom: + secretKeyRef: + name: jwt-secret + key: secret + - name: SPRING_DATASOURCE_URL + value: jdbc:mysql://jhonline-mysql.default.svc.cluster.local:3306/jhonline?useUnicode=true&characterEncoding=utf8&useSSL=false + - name: JAVA_OPTS + value: " -Xmx256m -Xms256m" + resources: + requests: + memory: "256Mi" + cpu: "500m" + limits: + memory: "512Mi" + cpu: "1" + ports: + - name: http + containerPort: 8080 + readinessProbe: + httpGet: + path: /management/health + port: http + initialDelaySeconds: 20 + periodSeconds: 15 + failureThreshold: 6 + livenessProbe: + httpGet: + path: /management/health + port: http + initialDelaySeconds: 120 diff --git a/k8s/jhonline-mysql.yml b/k8s/jhonline-mysql.yml new file mode 100644 index 00000000..7959fa1a --- /dev/null +++ b/k8s/jhonline-mysql.yml @@ -0,0 +1,46 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: jhonline-mysql + namespace: default +spec: + replicas: 1 + template: + metadata: + labels: + app: jhonline-mysql + spec: + volumes: + - name: data + emptyDir: {} + containers: + - name: mysql + image: mysql:8.0.13 + env: + - name: MYSQL_USER + value: root + - name: MYSQL_ALLOW_EMPTY_PASSWORD + value: 'yes' + - name: MYSQL_DATABASE + value: jhonline + args: + - --lower_case_table_names=1 + - --skip-ssl + - --character_set_server=utf8mb4 + - --explicit_defaults_for_timestamp + ports: + - containerPort: 3306 + volumeMounts: + - name: data + mountPath: /var/lib/mysql/ +--- +apiVersion: v1 +kind: Service +metadata: + name: jhonline-mysql + namespace: default +spec: + selector: + app: jhonline-mysql + ports: + - port: 3306 diff --git a/k8s/jhonline-service.yml b/k8s/jhonline-service.yml new file mode 100644 index 00000000..f25e52ae --- /dev/null +++ b/k8s/jhonline-service.yml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: jhonline + namespace: default + labels: + app: jhonline +spec: + selector: + app: jhonline + type: LoadBalancer + ports: + - name: http + port: 8080 diff --git a/k8s/jwt-secret.yml b/k8s/jwt-secret.yml new file mode 100644 index 00000000..846f2000 --- /dev/null +++ b/k8s/jwt-secret.yml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: jwt-secret + namespace: default +type: Opaque +data: + secret: eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA== diff --git a/kubectl-apply.sh b/kubectl-apply.sh new file mode 100755 index 00000000..5f42e958 --- /dev/null +++ b/kubectl-apply.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# Files are ordered in proper order with needed wait for the dependent custom resource definitions to get initialized. +# Usage: bash kubectl-apply.sh + +kubectl apply -f k8s/