diff --git a/docker/imageflow_server_unsecured/helm_chart/.helmignore b/docker/imageflow_server_unsecured/helm_chart/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/docker/imageflow_server_unsecured/helm_chart/Chart.yaml b/docker/imageflow_server_unsecured/helm_chart/Chart.yaml new file mode 100644 index 000000000..157a07922 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v2 +name: imageflow +description: A Helm chart for imageflow deployments + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.16 + +# This is the version number of the application being deployed. it must correspond with the docker container version. This version number should be +# incremented each time you want to upgrade the container itself. This version is not expected to be symantic. +appVersion: v1.5.4-rc58 diff --git a/docker/imageflow_server_unsecured/helm_chart/README.MD b/docker/imageflow_server_unsecured/helm_chart/README.MD new file mode 100644 index 000000000..5b1b20369 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/README.MD @@ -0,0 +1,78 @@ +# Imageflow Helm Chart + +This is a heml deployment chart for kubernetes. +The chart pulls and deploys the image with the configuration options in Values.yaml + +## container version + +If you need to upgrade or use a different version of the container please use the appVersion: setting in Chart.yaml Everytime you upgrade or change the chart values or other files you are expected to update the chartversion as well. these updates are symantic. More information can be found here https://helm.sh/docs/topics/charts/ + +## File structure + +``` +. +├── charts +│ └── [...] // Additional charts for dependencies could be deployed here +├── templates // In normal circumstances these should not be edited, Use the values.yml file instead +│ ├── Tests // Optional +│ | └── [...] // Testcontainers and deployscripts +│ |── _helpers.tpl // Helper fuctions to create and maintain variables +│ |── deployment.yaml // Deployment of the mail app. +│ |── hpa.yaml // Template for pod auto scaling +│ |── ingress.yaml // Template for ingress creation +│ |── notes.txt // Generates message after template deployment +│ |── persistent-volume-claim.yaml // Template for PVC creation +│ |── service.yaml // Template for service creation +│ └── serviceaccount.yaml // Template for Service Account creation +├── .helmignore +│── Chart.yaml // Appversion and container version live here +│── README.MD +│── values.yaml + +``` + +## deployment + +Cd into this directory and run + +```bash +helm install $deploymentname ./ --namespace $namespacename +``` + +### Test deployment + +Generate a readable output without deploying + +```bash +helm install $deploymentname ./ --namespace $namespacename --dry-run +``` + +### Upgrade deployment + +Upgrade existing deployment + +```bash +helm upgrade --install $deploymentname ./ --namespace $namespacename --dry-run +``` + +## Container Startup arguments. + +The Values.yaml file supports an array of startup arguments. When you are ready to mount containers you can add the settings to the "startupArgs:" in the values file. + +``` +startupArgs: [ + "sudo chown -R imageflow /home/imageflow/; /home/imageflow/imageflow_server start \ + --bind-address 0.0.0.0 \ + --port 3000 \ + --demo \ + --data-dir /home/imageflow/data/", + ] +``` + +## Ingress + +This chart comes with ingress support out of the box. For ingress to work you do need to have an ingress controller installed on your cluster. The example uses an Nginx ingress with TLS, but by changing the annotations you can change this to another installed ingress controller. Ingress settings are located in Values.yaml + +## live and readyness probes. + +Inside of the values.yaml you are able to switch on or off the monitoring of the container, these settings are used to avoid stuck containers from traffic being routed to them. When disabled, the container will always keep running. diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/NOTES.txt b/docker/imageflow_server_unsecured/helm_chart/templates/NOTES.txt new file mode 100644 index 000000000..c690f55a7 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/NOTES.txt @@ -0,0 +1,28 @@ +Thank you for installing ImageFlow! + + +{{- if .Values.ingress.enabled }} +1. Your applicatonURL is: +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} +1. Get the application URL by running these commands: + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "imageflow.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} +1. Get the application URL by running these commands: + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "imageflow.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "imageflow.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} +1. Get the application URL by running these commands: + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "imageflow.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/_helpers.tpl b/docker/imageflow_server_unsecured/helm_chart/templates/_helpers.tpl new file mode 100644 index 000000000..a47d129d6 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "imageflow.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "imageflow.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "imageflow.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "imageflow.labels" -}} +helm.sh/chart: {{ include "imageflow.chart" . }} +{{ include "imageflow.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "imageflow.selectorLabels" -}} +app.kubernetes.io/name: {{ include "imageflow.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "imageflow.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "imageflow.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/deployment.yaml b/docker/imageflow_server_unsecured/helm_chart/templates/deployment.yaml new file mode 100644 index 000000000..9ef634954 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/deployment.yaml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "imageflow.fullname" . }} + labels: + {{- include "imageflow.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "imageflow.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "imageflow.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "imageflow.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + command: ["/bin/sh", "-c"] + args: {{ .Values.startupArgs }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.persistentVolume.enabled }} + volumeMounts: + - mountPath: /home/imageflow/data + name: {{ include "imageflow.fullname" . }} + {{- end }} + ports: + - name: http + containerPort: 3000 + protocol: TCP + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.livenessProbe.path }} + port: http + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.readinessProbe.path }} + port: http + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: {{ include "imageflow.fullname" . }} + persistentVolumeClaim: + claimName: {{ include "imageflow.fullname" . }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/hpa.yaml b/docker/imageflow_server_unsecured/helm_chart/templates/hpa.yaml new file mode 100644 index 000000000..a52c4eab1 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "imageflow.fullname" . }} + labels: + {{- include "imageflow.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "imageflow.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/ingress.yaml b/docker/imageflow_server_unsecured/helm_chart/templates/ingress.yaml new file mode 100644 index 000000000..c1093c104 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/ingress.yaml @@ -0,0 +1,41 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "imageflow.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "imageflow.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/persistent-volume-claim.yaml b/docker/imageflow_server_unsecured/helm_chart/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..d180ed6ed --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/persistent-volume-claim.yaml @@ -0,0 +1,15 @@ +{{- if .Values.persistentVolume.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "imageflow.fullname" . }} + labels: + {{- include "imageflow.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.persistentVolume.accessModes | quote }} + storageClassName: {{ .Values.persistentVolume.storageClassName | quote }} + resources: + requests: + storage: {{ .Values.persistentVolume.size | quote }} +{{- end }} \ No newline at end of file diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/service.yaml b/docker/imageflow_server_unsecured/helm_chart/templates/service.yaml new file mode 100644 index 000000000..33c4e4f4d --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "imageflow.fullname" . }} + labels: + {{- include "imageflow.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "imageflow.selectorLabels" . | nindent 4 }} diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/serviceaccount.yaml b/docker/imageflow_server_unsecured/helm_chart/templates/serviceaccount.yaml new file mode 100644 index 000000000..1ac863c03 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "imageflow.serviceAccountName" . }} + labels: + {{- include "imageflow.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/docker/imageflow_server_unsecured/helm_chart/templates/tests/test-connection.yaml b/docker/imageflow_server_unsecured/helm_chart/templates/tests/test-connection.yaml new file mode 100644 index 000000000..363c75523 --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "imageflow.fullname" . }}-test-connection" + labels: + {{- include "imageflow.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "imageflow.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/docker/imageflow_server_unsecured/helm_chart/values.yaml b/docker/imageflow_server_unsecured/helm_chart/values.yaml new file mode 100644 index 000000000..52650ca5b --- /dev/null +++ b/docker/imageflow_server_unsecured/helm_chart/values.yaml @@ -0,0 +1,114 @@ +# Default values for imageflow. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +#Sets the number of replicas that need to run +replicaCount: 1 + +image: + repository: imazen/imageflow_server_unsecured + pullPolicy: IfNotPresent + +imagePullSecrets: [] +nameOverride: "imageflow" +fullnameOverride: "imageflow" + +# Startupargs for imageflow server, Here you can specify the mounts and other options. +# see https://github.com/imazen/imageflow#beyond-the-demo for more information on this. +startupArgs: [ + "sudo chown -R imageflow /home/imageflow/; /home/imageflow/imageflow_server start \ + --bind-address 0.0.0.0 \ + --port 3000 \ + --demo \ + --data-dir /home/imageflow/data/", + ] +livenessProbe: + # Enables a livenessprobe to a path to check health of the container + enabled: false + # Path to an asset on server that will answer with a 200 ok + path: /path/to/image.jpg + +readinessProbe: + # enables a readyness probe to see if container has finished starting + enabled: false + # Path to an asset on server that will answer with a 200 ok + path: /path/to/image.jpg + +persistentVolume: + # Enabled creates a PV for the container with fullname as name + enabled: true + # Sets accessmode https://kubernetes.io/docs/concepts/storage/persistent-volumes/ + accessModes: ReadWriteMany #ReadWriteOnce, ReadOnlyMany or ReadWriteMany + # Sets storageclass can be azurefile || azurefile-premium for readWriteMany and shared between containers. + # OR default || managed-premium for disk type claims that are only accessable to one container + storageClassName: azurefile + #Size in Mi || Gi etc + size: 500Mi + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: + {} + # fsGroup: 2000 + +securityContext: + {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 3000 + +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: nginx + cert-manager.io/cluster-issuer: tif-letsencrypt-cluster-issuer + hosts: + - host: domain.ext + paths: + - path: / + tls: + - secretName: secretname-tls + hosts: + - domain.ext + +resources: + {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {}