diff --git a/k8s/argocd-farm.yaml b/k8s/argocd-farm.yaml new file mode 100644 index 0000000..56992cf --- /dev/null +++ b/k8s/argocd-farm.yaml @@ -0,0 +1,20 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: farm-platform + namespace: argocd +spec: + project: default + source: + repoURL: http://gitea.geocrop.svc.cluster.local:3000/fchinembiri/geocrop-platform..git + targetRevision: HEAD + path: k8s/farm + destination: + server: https://kubernetes.default.svc + namespace: farm + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s/farm/01-namespace-secrets.yaml b/k8s/farm/01-namespace-secrets.yaml new file mode 100644 index 0000000..e5e003f --- /dev/null +++ b/k8s/farm/01-namespace-secrets.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: farm +--- +apiVersion: v1 +kind: Secret +metadata: + name: farm-db-credentials + namespace: farm +type: Opaque +data: + # Base64 encoded: farmos + POSTGRES_USER: ZmFybW9z + # Base64 encoded: f4rm0s_db_p4ssw0rd + POSTGRES_PASSWORD: ZjRybTBzX2RiX3A0c3N3MHJk + # Base64 encoded: farmos + POSTGRES_DB: ZmFybW9z + # Base64 encoded: timescale + TIMESCALE_USER: dGltZXNjYWxl + # Base64 encoded: t1m3sc4l3_db_p4ssw0rd + TIMESCALE_PASSWORD: dDFtM3NjNGwzX2RiX3A0c3N3MHJk + # Base64 encoded: sensors + TIMESCALE_DB: c2Vuc29ycw== diff --git a/k8s/farm/02-storage.yaml b/k8s/farm/02-storage.yaml new file mode 100644 index 0000000..184f9d8 --- /dev/null +++ b/k8s/farm/02-storage.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: farmos-sites-pvc + namespace: farm +spec: + accessModes: [ReadWriteOnce] + resources: + requests: + storage: 2Gi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgis-data-pvc + namespace: farm +spec: + accessModes: [ReadWriteOnce] + resources: + requests: + storage: 5Gi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: timescaledb-data-pvc + namespace: farm +spec: + accessModes: [ReadWriteOnce] + resources: + requests: + storage: 10Gi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: nodered-data-pvc + namespace: farm +spec: + accessModes: [ReadWriteOnce] + resources: + requests: + storage: 1Gi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: grafana-data-pvc + namespace: farm +spec: + accessModes: [ReadWriteOnce] + resources: + requests: + storage: 1Gi diff --git a/k8s/farm/03-databases.yaml b/k8s/farm/03-databases.yaml new file mode 100644 index 0000000..c068bfa --- /dev/null +++ b/k8s/farm/03-databases.yaml @@ -0,0 +1,141 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: postgis + namespace: farm +spec: + serviceName: "postgis" + replicas: 1 + selector: + matchLabels: + app: postgis + template: + metadata: + labels: + app: postgis + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - vmi3045103.contaboserver.net + containers: + - name: postgis + image: postgis/postgis:14-3.3 + ports: + - containerPort: 5432 + env: + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: POSTGRES_PASSWORD + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: POSTGRES_DB + resources: + requests: + memory: "256Mi" + cpu: "100m" + limits: + memory: "1Gi" + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data + volumes: + - name: data + persistentVolumeClaim: + claimName: postgis-data-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: postgis + namespace: farm +spec: + ports: + - port: 5432 + selector: + app: postgis +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: timescaledb + namespace: farm +spec: + serviceName: "timescaledb" + replicas: 1 + selector: + matchLabels: + app: timescaledb + template: + metadata: + labels: + app: timescaledb + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - vmi3045103.contaboserver.net + containers: + - name: timescaledb + image: timescale/timescaledb:latest-pg14 + ports: + - containerPort: 5432 + env: + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: TIMESCALE_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: TIMESCALE_PASSWORD + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: TIMESCALE_DB + resources: + requests: + memory: "256Mi" + cpu: "100m" + limits: + memory: "1Gi" + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data + volumes: + - name: data + persistentVolumeClaim: + claimName: timescaledb-data-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: timescaledb + namespace: farm +spec: + ports: + - port: 5432 + selector: + app: timescaledb diff --git a/k8s/farm/04-apps.yaml b/k8s/farm/04-apps.yaml new file mode 100644 index 0000000..f3e20cf --- /dev/null +++ b/k8s/farm/04-apps.yaml @@ -0,0 +1,185 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: farmos + namespace: farm +spec: + replicas: 1 + selector: + matchLabels: + app: farmos + template: + metadata: + labels: + app: farmos + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - vmi3045103.contaboserver.net + containers: + - name: farmos + image: farmos/farmos:3.x + env: + - name: FARMOS_DB_TYPE + value: "pgsql" + - name: FARMOS_DB_HOST + value: "postgis" + - name: FARMOS_DB_PORT + value: "5432" + - name: FARMOS_DB_NAME + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: POSTGRES_DB + - name: FARMOS_DB_USER + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: POSTGRES_USER + - name: FARMOS_DB_PASS + valueFrom: + secretKeyRef: + name: farm-db-credentials + key: POSTGRES_PASSWORD + resources: + requests: + memory: "512Mi" + cpu: "200m" + limits: + memory: "1Gi" + volumeMounts: + - name: sites + mountPath: /opt/drupal/web/sites + volumes: + - name: sites + persistentVolumeClaim: + claimName: farmos-sites-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: farmos + namespace: farm +spec: + ports: + - port: 80 + targetPort: 80 + selector: + app: farmos +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nodered + namespace: farm +spec: + replicas: 1 + selector: + matchLabels: + app: nodered + template: + metadata: + labels: + app: nodered + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - vmi3045103.contaboserver.net + containers: + - name: nodered + image: nodered/node-red:latest + ports: + - containerPort: 1880 + resources: + requests: + memory: "256Mi" + cpu: "100m" + limits: + memory: "512Mi" + volumeMounts: + - name: data + mountPath: /data + volumes: + - name: data + persistentVolumeClaim: + claimName: nodered-data-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: nodered + namespace: farm +spec: + ports: + - port: 1880 + selector: + app: nodered +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: grafana + namespace: farm +spec: + replicas: 1 + selector: + matchLabels: + app: grafana + template: + metadata: + labels: + app: grafana + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - vmi3045103.contaboserver.net + containers: + - name: grafana + image: grafana/grafana:latest + env: + - name: GF_SECURITY_ALLOW_EMBEDDING + value: "true" + ports: + - containerPort: 3000 + resources: + requests: + memory: "256Mi" + cpu: "100m" + limits: + memory: "512Mi" + volumeMounts: + - name: data + mountPath: /var/lib/grafana + volumes: + - name: data + persistentVolumeClaim: + claimName: grafana-data-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: grafana + namespace: farm +spec: + ports: + - port: 3000 + selector: + app: grafana diff --git a/k8s/farm/05-ingress.yaml b/k8s/farm/05-ingress.yaml new file mode 100644 index 0000000..f9fb2f4 --- /dev/null +++ b/k8s/farm/05-ingress.yaml @@ -0,0 +1,51 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: farm-ingress + namespace: farm + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/proxy-body-size: "100m" +spec: + ingressClassName: nginx + tls: + - hosts: + - farm.techarvest.co.zw + secretName: farmos-tls + - hosts: + - nodered.farm.techarvest.co.zw + secretName: nodered-tls + - hosts: + - grafana.farm.techarvest.co.zw + secretName: grafana-tls + rules: + - host: farm.techarvest.co.zw + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: farmos + port: + number: 80 + - host: nodered.farm.techarvest.co.zw + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nodered + port: + number: 1880 + - host: grafana.farm.techarvest.co.zw + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: grafana + port: + number: 3000 diff --git a/k8s/farm/kustomization.yaml b/k8s/farm/kustomization.yaml new file mode 100644 index 0000000..8d1817f --- /dev/null +++ b/k8s/farm/kustomization.yaml @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - 01-namespace-secrets.yaml + - 02-storage.yaml + - 03-databases.yaml + - 04-apps.yaml + - 05-ingress.yaml