Helm3 chart (#44)

* add helm3 chart

* add reference to a helm3 chart to docs

Co-authored-by: Aleksei Sizov <a.sizov@typeable.io>
This commit is contained in:
Alex-Sizov 2021-05-12 17:02:40 +03:00 committed by iko
parent 92ee8d3df4
commit 291c3c4c4e
21 changed files with 1041 additions and 0 deletions

View File

@ -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/

View File

@ -0,0 +1,6 @@
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 10.4.2
digest: sha256:616138842fd07e138b0e8d6b7dac7989942b01a94967c37ca41c94e3fe93e9e4
generated: "2021-05-07T21:02:01.403373727+03:00"

View File

@ -0,0 +1,20 @@
apiVersion: v2
name: octopod
description: An opensource self-hosted solution for managing multiple deployments in a Kubernetes cluster.
type: application
version: 0.0.1
appVersion: 1.1
keywords:
- kubernetes
- octopod
home: https://octopod.site
sources:
- https://github.com/typeable/octopod
maintainers:
- name: Alex Sizov
email: a.sizov@typeable.io
dependencies:
- name: postgresql
version: 10.4.2
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled

View File

@ -0,0 +1,158 @@
# Octopod
### This is beta version of a chart!
[Octopod](https://octopod.site/) is a fully open-source self-hosted solution for managing multiple deployments in a Kubernetes cluster with a user-friendly web interface. Managing deployments does not require any technical expertise.
## TL;DR
TBD (install chart from typeable's chart repository)
## Introduction
This chart bootstraps an Octopod deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
## Prerequisites
- Kubernetes 1.12+
- Helm 3.1.0
- PV support (for postgresql persistense)
- nginx-ingress controller
## Installing the Chart
This chart will not create or delete any namespaces for you.
You'll need to create 2 namespaces before installing:
First in which octopod will be installed
```console
$ kubectl create namespace octopod
```
Second in which Octopod will deploy all it's deployments (configured in octopod.deploymentNamespace)
```console
$ kubectl create namespace octopod-deployments
```
Also you need to generate certificates for octo client<->octopod server communication.
Generate certificates
```bash
mkdir certs
cd certs && \
openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -nodes -subj "/CN=localhost/O=Server" && \
openssl req -newkey rsa:4096 -keyout client_key.pem -out client_csr.pem -nodes -subj "/CN=Client" && \
openssl x509 -req -in client_csr.pem -CA server_cert.pem -CAkey server_key.pem -out client_cert.pem -set_serial 01 -days 3650
```
Create configmap from generated certificates
```console
kubectl create configmap octopod-certs -n octopod --from-file=./certs
```
Name for configmap is cofigured in octopod.certsConfigMapName
To install the chart with the release name `my-release` from current directory execute:
```console
$ helm dependency build
$ helm -n octopod install my-release .
```
The command deploys Octopod on the Kubernetes cluster in the default configuration inside octopod namespace. The [Parameters](#parameters) section lists the parameters that can be configured during installation.
## Uninstalling the Chart
To uninstall/delete the `my-release` deployment:
```console
$ helm -n octopod delete my-release
```
The command removes all the Kubernetes components but PVC's associated with the postgres chart and deletes the release.
## Parameters
The following tables lists the configurable parameters of the Octopod chart and their default values.
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | Octopod deployment affinity |
| controlScripts.image.pullPolicy | string | `"IfNotPresent"` | control scripts image pull policy |
| controlScripts.image.repository | string | `"typeable/octopod-helm-example"` | Control scripts image repository (you probably want to use your own control scripts) |
| controlScripts.image.tag | float | `1.1` | Control scitpts image tag |
| fullnameOverride | string | `""` | Override chart full name |
| image.pullPolicy | string | `"IfNotPresent"` | Octopod image pull policy |
| image.repository | string | `"typeable/octopod"` | Octopod image repository |
| image.tag | string | `""` | Octopod image tag (default values is taken from chart metadata) |
| imagePullSecrets | list | `[]` | Pull secrets if you want to use private registry |
| ingress.app.annotations | object | `{}` | Additional ingress annotations for app service |
| ingress.app.host | string | `"octopod-app.example.com"` | Hostname for app service |
| ingress.enabled | bool | `true` | Create ingress objects or not |
| ingress.ingressClass | string | `"nginx"` | Ingress class |
| ingress.powerApp.annotations | object | `{}` | Additional ingress annotations for power-app service |
| ingress.powerApp.host | string | `"octopod-powerapp.example.com"` | Hostname for power-app |
| ingress.tls.clusterIssuer | string | `"letsencrypt"` | Name of cluster issuer you want to use |
| ingress.tls.enabled | bool | `true` | Use https for all services |
| ingress.ui.annotations | object | `{}` | Additional ingress annotations for ui service |
| ingress.ui.host | string | `"octopod.example.com"` | Hostname for main UI |
| ingress.ws.annotations | object | `{}` | Additional ingress annotations for ws service |
| ingress.ws.host | string | `"octopod-ws.example.com"` | Hostname for websockets ingress |
| nameOverride | string | `""` | Name ovveride (default is Release.Name) |
| nodeSelector | object | `{}` | Node selector if you want octopod to use specific nodes onn your cluster |
| octopod.archiveRetention | int | `1209600` | |
| octopod.baseDomain | string | `""` | Domain that will be used as a ase for Octopod deploymets |
| octopod.certsConfigMapName | string | `"octopod-certs"` | Config map with self-signed certificates |
| octopod.deploymentNamespace | string | `"octopod-deployment"` | Name of a namespace which will be used for all Octopod deployments (you need to create it yourself) |
| octopod.migrations.enabled | bool | `true` | Enable or not automatic DB schema migrations |
| octopod.projectName | string | `"Octopod"` | Project name |
| octopod.statusUpdateTimeout | int | `600` | Time to wait before deployment is marked as failed |
| podAnnotations | object | `{}` | Additional pod annotations |
| podSecurityContext | object | `{}` | Additional security context |
| postgresql.enabled | bool | `true` | Use bitnami postgres chart |
| postgresql.postgresqlDatabase | string | `"octopod"` | Database name for octopod |
| postgresql.postgresqlUsername | string | `"octopod"` | Octopod DB username |
| rbac.create | bool | `true` | Creates ClusterRoles and Bindings for Octopod service account |
| replicaCount | int | `1` | Number of Octopod replicas |
| resources.limits.cpu | string | `"200m"` | CPU limits |
| resources.limits.memory | string | `"512Mi"` | Memory limits |
| resources.requests.cpu | string | `"200m"` | CPU requests |
| resources.requests.memory | string | `"256Mi"` | Memory requests |
| securityContext.runAsGroup | int | `1000` | Use non-root GID |
| securityContext.runAsUser | int | `1000` | Use non-root UID |
| service.ports.app | int | `4000` | App service port |
| service.ports.powerApp | int | `4443` | Power app service port |
| service.ports.ui | int | `80` | UI service port |
| service.ports.ws | int | `4020` | WebSockets service port |
| service.type | string | `"ClusterIP"` | Octopod service type |
| serviceAccount.annotations | object | `{}` | Additional anotations for Octopod's SA |
| serviceAccount.create | bool | `true` | Create ServiceAccount |
| serviceAccount.name | string | `""` | ServiceAccount name override |
| sqitch.image.pullPolicy | string | `"IfNotPresent"` | squitch image pull policy |
| sqitch.image.repository | string | `"typeable/sqitch"` | squitch image repository |
| sqitch.image.tag | string | `"v2.0.0"` | squitch image tag |
| tolerations | list | `[]` | Octpod deploymet tolerations |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
```console
$ helm -n octopod install my-release \
--set controlScripts.image.repository=registry.example.com/control,controlScripts.image.tag=0.0.1 \
.
```
The above command sets control scripts image to your custom repository
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```console
$ helm install my-release -f values.yaml .
```
> **Tip**: You can use the default [values.yaml](values.yaml)
## Configuration and installation details
If you want to have authentication for Octopod UI you can use project like [Oauth2-Proxy](https://github.com/oauth2-proxy/oauth2-proxy) or directly use your oauth provider.
After that you can add following annotations to UI ingress (considering that your oauth provider installed on oath.example.com):
```yaml
ingress:
ui:
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://oauth.example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://oauth.example.com/oauth2/start?rd=/redirect/$http_host$request_uri"
```

View File

@ -0,0 +1,98 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "octopod.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 "octopod.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 "octopod.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "octopod.labels" -}}
helm.sh/chart: {{ include "octopod.chart" . }}
{{ include "octopod.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "octopod.selectorLabels" -}}
app.kubernetes.io/name: {{ include "octopod.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "octopod.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "octopod.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{- define "controlScriptsPath" -}}
/utils
{{- end }}
{{- define "octopodAppAuthSecretName" -}}
{{- printf "%s-app-auth-secret" (include "octopod.fullname" .) }}
{{- end }}
{{- define "octopodAppAuthPassword" -}}
{{- randAlphaNum 32 }}
{{- end }}
{{- define "httpScheme" -}}
{{- if .Values.ingress.tls.enabled -}}
https
{{- else -}}
http
{{- end }}
{{- end }}
{{- define "wsScheme" -}}
{{- if .Values.ingress.tls.enabled -}}
wss
{{- else -}}
ws
{{- end }}
{{- end }}
{{- define "postgresqlHost" -}}
{{ .Release.Name }}-postgresql
{{- end }}
{{- define "postgresqlSecretName" -}}
{{ .Release.Name }}-postgresql
{{- end }}

View File

@ -0,0 +1,163 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "octopod.fullname" . }}
labels:
{{- include "octopod.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "octopod.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "octopod.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "octopod.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
initContainers:
- name: copy-control-scripts
image: "{{ .Values.controlScripts.image.repository }}:{{ .Values.controlScripts.image.tag }}"
imagePullPolicy: {{ .Values.controlScripts.image.pullPolicy }}
command:
- sh
- -c
- 'cp /utils/* /copy/'
volumeMounts:
- name: control-scripts
mountPath: /copy
- name: run-init
image: typeable/octopod:1.1
command:
- sh
- -c
- '/utils/init'
volumeMounts:
- name: home
mountPath: /home/octopod
- name: control-scripts
mountPath: {{ include "controlScriptsPath" . }}
- name: copy-www
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
command:
- sh
- -c
- |
set -ex
cp -a /www/* /copy/
find /www -type f -exec touch {} +
volumeMounts:
- name: www
mountPath: /copy
containers:
- name: octopod
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 4443
protocol: TCP
- containerPort: 4000
protocol: TCP
args:
- --port
- {{ .Values.service.ports.powerApp | quote }}
- --ui-port
- {{ .Values.service.ports.app | quote }}
- --ws-port
- {{ .Values.service.ports.ws | quote }}
- --db
- host='{{ include "postgresqlHost" . }}' port=5432 user='{{ .Values.postgresql.postgresqlUsername }}' password=$(PG_PASS)
- --db-pool-size
- "10"
- --tls-cert-path
- /tls/server_cert.pem
- --tls-key-path
- /tls/server_key.pem
- --tls-store-path
- /tls_store
envFrom:
- configMapRef:
name: {{ include "octopod.fullname" . }}
env:
- name: PG_PASS
valueFrom:
secretKeyRef:
name: {{ include "postgresqlSecretName" . }}
key: postgresql-password
volumeMounts:
- name: home
mountPath: /home/octopod
- name: control-scripts
mountPath: {{ include "controlScriptsPath" . }}
- name: certs
mountPath: /tls/server_cert.pem
subPath: server_cert.pem
- name: certs
mountPath: /tls/server_key.pem
subPath: server_key.pem
- name: certs
mountPath: /tls_store/server_cert.pem
subPath: server_cert.pem
readinessProbe:
httpGet:
port: {{ .Values.service.ports.app }}
path: /api/v1/ping
periodSeconds: 20
livenessProbe:
httpGet:
port: {{ .Values.service.ports.app }}
path: /api/v1/ping
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
- name: nginx
image: nginx:1.17.5
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/app.conf
subPath: app.conf
- name: nginx-config
mountPath: /www/config.json
subPath: config.json
- name: www
mountPath: /www
ports:
- containerPort: {{ .Values.service.ports.ui }}
protocol: TCP
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: home
emptyDir: {}
- name: control-scripts
emptyDir: {}
- name: www
emptyDir: {}
- name: nginx-config
configMap:
name: {{ include "octopod.fullname" . }}-nginx-config
- name: certs
configMap:
name: {{ .Values.octopod.certsConfigMapName }}

View File

@ -0,0 +1,47 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "octopod.fullname" . -}}
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}-app
labels:
{{- include "octopod.labels" . | nindent 4 }}
annotations:
{{- if .Values.ingress.tls.enabled }}
kubernetes.io/tls-acme: "true"
cert-manager.io/cluster-issuer: {{ .Values.ingress.tls.clusterIssuer | quote }}
{{- end }}
kubernetes.io/ingress.class: {{ .Values.ingress.ingressClass | quote }}
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-next-upstream: "http_502 error timeout"
nginx.ingress.kubernetes.io/auth-secret: {{ include "octopodAppAuthSecretName" . }}
nginx.ingress.kubernetes.io/auth-secret-type: auth-file
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: {{ printf "%s://%s" (include "httpScheme" .) .Values.ingress.ui.host | quote }}
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, PATCH, OPTIONS"
{{- with .Values.ingress.app.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls.enabled }}
tls:
- hosts:
- {{ .Values.ingress.app.host }}
secretName: {{ $fullName }}-app-tls
{{- end }}
rules:
- host: {{ .Values.ingress.app.host | quote }}
http:
paths:
- path: /
backend:
serviceName: {{ $fullName }}
servicePort: {{ .Values.service.ports.app }}
{{- end }}

View File

@ -0,0 +1,40 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "octopod.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 }}-powerapp
labels:
{{- include "octopod.labels" . | nindent 4 }}
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.ingressClass | quote }}
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-next-upstream: "http_502 error timeout"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
{{- with .Values.ingress.powerApp.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
- hosts:
- {{ .Values.ingress.powerApp.host }}
secretName: {{ $fullName }}-powerapp-tls
{{- end }}
rules:
- host: {{ .Values.ingress.powerApp.host | quote }}
http:
paths:
- path: /
backend:
serviceName: {{ $fullName }}
servicePort: {{ .Values.service.ports.powerApp }}
{{- end }}

View File

@ -0,0 +1,41 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "octopod.fullname" . -}}
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}-ui
labels:
{{- include "octopod.labels" . | nindent 4 }}
annotations:
{{- if .Values.ingress.tls.enabled }}
kubernetes.io/tls-acme: "true"
cert-manager.io/cluster-issuer: {{ .Values.ingress.tls.clusterIssuer | quote }}
{{- end }}
kubernetes.io/ingress.class: {{ .Values.ingress.ingressClass | quote }}
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-next-upstream: "http_502 error timeout"
{{- with .Values.ingress.ui.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls.enabled }}
tls:
- hosts:
- {{ .Values.ingress.ui.host }}
secretName: {{ $fullName }}-ui-tls
{{- end }}
rules:
- host: {{ .Values.ingress.ui.host | quote }}
http:
paths:
- path: /
backend:
serviceName: {{ $fullName }}
servicePort: {{ .Values.service.ports.ui }}
{{- end }}

View File

@ -0,0 +1,41 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "octopod.fullname" . -}}
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}-ws
labels:
{{- include "octopod.labels" . | nindent 4 }}
annotations:
{{- if .Values.ingress.tls.enabled }}
kubernetes.io/tls-acme: "true"
cert-manager.io/cluster-issuer: {{ .Values.ingress.tls.clusterIssuer | quote }}
{{- end }}
kubernetes.io/ingress.class: {{ .Values.ingress.ingressClass | quote }}
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-next-upstream: "http_502 error timeout"
{{- with .Values.ingress.ws.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls.enabled }}
tls:
- hosts:
- {{ .Values.ingress.ws.host }}
secretName: {{ $fullName }}-ws-tls
{{- end }}
rules:
- host: {{ .Values.ingress.ws.host | quote }}
http:
paths:
- path: /
backend:
serviceName: {{ $fullName }}
servicePort: {{ .Values.service.ports.ws }}
{{- end }}

View File

@ -0,0 +1,77 @@
{{- if .Values.octopod.migrations.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "octopod.fullname" . }}-migrations
labels:
{{- include "octopod.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-delete-policy": hook-succeeded
spec:
activeDeadlineSeconds: 600
template:
spec:
initContainers:
- name: copy
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
command:
- "bash"
- "-ec"
- |
set -ex
# copy migrations
cp -av /migrations/* /mymigrations
# create sqitch.conf
echo '[core]' > /mymigrations/sqitch.conf
echo 'engine = pg' >> /mymigrations/sqitch.conf
echo 'plan_file = sqitch.plan' >> /mymigrations/sqitch.conf
echo 'top_dir = .' >> /mymigrations/sqitch.conf
echo '[engine "pg"]' >> /mymigrations/sqitch.conf
echo ' registry = sqitch' >> /mymigrations/sqitch.conf
echo '[deploy]' >> /mymigrations/sqitch.conf
echo ' verify = true' >> /mymigrations/sqitch.conf
echo '[rebase]' >> /mymigrations/sqitch.conf
echo ' verify = true' >> /mymigrations/sqitch.conf
echo '[target "octopod"]' >> /mymigrations/sqitch.conf
echo 'uri = db:pg://{{ .Values.postgresql.postgresqlUsername }}:$(PG_PASS)@{{ include "postgresqlHost" . }}/{{ .Values.postgresql.postgresqlDatabase }}' >> /mymigrations/sqitch.conf
env:
- name: PG_PASS
valueFrom:
secretKeyRef:
name: {{ include "postgresqlSecretName" . }}
key: postgresql-password
volumeMounts:
- name: migrations
mountPath: /mymigrations
containers:
- name: migrations
image: "{{ .Values.sqitch.image.repository }}:{{ .Values.sqitch.image.tag }}"
command:
- "bash"
- "-c"
- |
set -x
echo 'checking connection to postgresql...'
for i in $(seq 1 6); do psql "postgres://{{ .Values.postgresql.postgresqlUsername }}:$(PG_PASS)@{{ include "postgresqlHost" . }}/{{ .Values.postgresql.postgresqlDatabase }}" -c ''; if [ $? -eq 0 ]; then break; fi; sleep 10; done
set -e
echo 'run migrations...'
cd /migrations && /usr/local/bin/sqitch deploy octopod
env:
- name: PG_PASS
valueFrom:
secretKeyRef:
name: {{ include "postgresqlSecretName" . }}
key: postgresql-password
volumeMounts:
- name: migrations
mountPath: /migrations
volumes:
- name: migrations
emptyDir: {}
restartPolicy: Never
backoffLimit: 3
{{- end }}

View File

@ -0,0 +1,24 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "octopod.fullname" . }}-nginx-config
labels:
{{- include "octopod.labels" . | nindent 4 }}
data:
app.conf: |
server {
listen 80 default_server;
server_name _;
root /www;
index index.html;
error_page 404 =200 /index.html;
}
config.json: |
{
"app_url": "{{ printf "%s://%s" (include "httpScheme" .) .Values.ingress.app.host}}",
"ws_url": "{{ printf "%s://%s" (include "wsScheme" .) .Values.ingress.ws.host}}",
"app_auth": "Basic {{ printf "octopod:%s" (include "octopodAppAuthPassword" .) | b64enc }}",
"kubernetes_dashboard_url_template": null
}

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: {{ include "octopodAppAuthSecretName" . }}
labels:
{{- include "octopod.labels" . | nindent 4 }}
data:
auth: {{ htpasswd "octopod" (include "octopodAppAuthPassword" . ) | b64enc }}

View File

@ -0,0 +1,20 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "octopod.fullname" . }}
labels:
{{- include "octopod.labels" . | nindent 4 }}
data:
PROJECT_NAME: {{ .Values.octopod.projectName | quote }}
BASE_DOMAIN: {{ .Values.octopod.baseDomain | quote }}
NAMESPACE: {{ .Values.octopod.deploymentNamespace | quote }}
STATUS_UPDATE_TIMEOUT: {{ .Values.octopod.statusUpdateTimeout | quote }}
ARCHIVE_RETENTION: {{ .Values.octopod.archiveRetention | quote }}
CREATION_COMMAND: {{ printf "%s/create" (include "controlScriptsPath" .) | quote }}
UPDATE_COMMAND: {{ printf "%s/update" (include "controlScriptsPath" .) | quote }}
ARCHIVE_COMMAND: {{ printf "%s/archive" (include "controlScriptsPath" .) | quote }}
CHECKING_COMMAND: {{ printf "%s/check" (include "controlScriptsPath" .) | quote }}
CLEANUP_COMMAND: {{ printf "%s/cleanup" (include "controlScriptsPath" .) | quote }}
ARCHIVE_CHECKING_COMMAND: {{ printf "%s/archive_check" (include "controlScriptsPath" .) | quote }}
TAG_CHECKING_COMMAND: {{ printf "%s/tag_check" (include "controlScriptsPath" .) | quote }}
INFO_COMMAND: {{ printf "%s/info" (include "controlScriptsPath" .) | quote }}

View File

@ -0,0 +1,30 @@
{{- if and .Values.rbac.create (eq .Values.serviceAccount.create true) -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "octopod.fullname" . }}
labels:
{{- include "octopod.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["pods/portforward"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "octopod.fullname" . }}
labels:
{{- include "octopod.labels" . | nindent 4 }}
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: {{ include "octopod.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ include "octopod.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end -}}

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "octopod.fullname" . }}
labels:
{{- include "octopod.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
{{- range $portName, $portNumber := .Values.service.ports }}
- name: octopod-{{ $portName | lower }}
port: {{ $portNumber }}
targetPort: {{ $portNumber }}
{{- end }}
selector:
{{- include "octopod.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "octopod.serviceAccountName" . }}
labels:
{{- include "octopod.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,104 @@
# Default values for octopod.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: typeable/octopod
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# 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: ""
rbac:
create: true
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext:
runAsUser: 1000
runAsGroup: 1000
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
service:
type: ClusterIP
ports:
powerApp: 4443
ui: 80
app: 4000
ws: 4020
ingress:
enabled: true
ingressClass: nginx
tls:
enabled: true
clusterIssuer: letsencrypt
powerApp:
host: octopod-powerapp.sizov-test.thebestagent.pro
annotations: {}
ui:
host: octopod.sizov-test.thebestagent.pro
annotations: {}
app:
host: octopod-app.sizov-test.thebestagent.pro
annotations: {}
ws:
host: octopod-ws.sizov-test.thebestagent.pro
annotations: {}
resources:
limits:
cpu: 200m
memory: 512Mi
requests:
cpu: 200m
memory: 256Mi
nodeSelector: {}
tolerations: []
affinity: {}
octopod:
certsConfigMapName: octopod-certs
projectName: Octopod
deploymentNamespace: octopod-deployment
baseDomain: "sizov-test.thebestagent.pro"
statusUpdateTimeout: 600
archiveRetention: 1209600
migrations:
enabled: true
controlScripts:
image:
repository: typeable/octopod-helm-example
pullPolicy: IfNotPresent
tag: 1.1
sqitch:
image:
repository: typeable/sqitch
pullPolicy: IfNotPresent
tag: v2.0.0
postgresql:
enabled: true
postgresqlUsername: octopod
postgresqlDatabase: octopod

View File

@ -0,0 +1,104 @@
# Default values for octopod.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: typeable/octopod
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# 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: ""
rbac:
create: true
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext:
runAsUser: 1000
runAsGroup: 1000
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
service:
type: ClusterIP
ports:
powerApp: 4443
ui: 80
app: 4000
ws: 4020
ingress:
enabled: true
ingressClass: nginx
tls:
enabled: true
clusterIssuer: letsencrypt
powerApp:
host: octopod-powerapp.example.com
annotations: {}
ui:
host: octopod.example.com
annotations: {}
app:
host: octopod-app.example.com
annotations: {}
ws:
host: octopod-ws.example.com
annotations: {}
resources:
limits:
cpu: 200m
memory: 512Mi
requests:
cpu: 200m
memory: 256Mi
nodeSelector: {}
tolerations: []
affinity: {}
octopod:
certsConfigMapName: octopod-certs
projectName: Octopod
deploymentNamespace: octopod-deployment
baseDomain: ""
statusUpdateTimeout: 600
archiveRetention: 1209600
migrations:
enabled: true
controlScripts:
image:
repository: typeable/octopod-helm-example
pullPolicy: IfNotPresent
tag: 1.1
sqitch:
image:
repository: typeable/sqitch
pullPolicy: IfNotPresent
tag: v2.0.0
postgresql:
enabled: true
postgresqlUsername: octopod
postgresqlDatabase: octopod

View File

@ -422,3 +422,7 @@ helm upgrade --install octopod ./octopod \
[kubedog]: https://github.com/werf/kubedog
[lets-encrypt]: https://letsencrypt.org
[lets-encrypt-rate-limits]: https://letsencrypt.org/docs/rate-limits
## Helm 3 chart
You can use a [Helm 3](../../charts/helm3/octopod) chart (beta!) to install octopod.

View File

@ -280,3 +280,6 @@
[minikube]: https://kubernetes.io/ru/docs/tasks/tools/install-minikube
[tiller]: https://v2.helm.sh/docs/install
[kubedog]: https://github.com/werf/kubedog
## Helm 3
Для установки Octopod вы также можете использовать чарт [Helm 3](../../charts/helm3/octopod) (бета версия!).