diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..769e3a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/kubernetes/config/ diff --git a/README.md b/README.md index f9bc1dc..8f5e678 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,34 @@ Feel free to [open issues] for questions, suggestions, bugs, to-do items, and whatever else you want to discuss or resolve. [open issues]: https://gitea.kosmos.org/kosmos/gitea.kosmos.org/issues + +## Kubernetes + +### Apply changes to resources + +``` +kubectl apply -f gitea-db.yaml +kubectl apply -f gitea-server.yaml +``` + +### Write the secrets to the local filesystem + +``` +./script/get_secrets +``` + +It writes the secrets (currently the app.ini file, as well as auto-generated +TLS certificates that are only used when no Let's Encrypt cert is available) +to the `kubernetes/config/` folder. These files are not in Git because they +contain credentials. + +Once you have edited them locally, you need to delete the secrets stored on +Kubernetes before uploading them again. This is done by this script: + +``` +./script/replace_secrets +``` + +### Reuse a released persistent volume: + +https://github.com/kubernetes/kubernetes/issues/48609#issuecomment-314066616 diff --git a/kubernetes/config/.gitkeep b/kubernetes/config/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/kubernetes/gitea-db.yaml b/kubernetes/gitea-db.yaml new file mode 100644 index 0000000..629c017 --- /dev/null +++ b/kubernetes/gitea-db.yaml @@ -0,0 +1,69 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: gitea-db +spec: + replicas: 1 + strategy: + type: Recreate + template: + metadata: + labels: + name: gitea-db + spec: + containers: + - env: + - name: MYSQL_DATABASE + value: gitea + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: mysql-pass + key: password + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: gitea-mysql-pass + key: password + - name: MYSQL_USER + value: gitea + image: mariadb:10.3.10 + name: gitea-db + resources: {} + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - mountPath: /var/lib/mysql + name: gitea-db-data + restartPolicy: Always + volumes: + - name: gitea-db-data + persistentVolumeClaim: + claimName: gitea-db-data +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: gitea-db-data + labels: + name: gitea-db-data +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +apiVersion: v1 +kind: Service +metadata: + name: gitea-db + labels: + service: gitea-db +spec: + selector: + name: gitea-db + type: ClusterIP + ports: + - port: 3306 diff --git a/kubernetes/gitea-server.yaml b/kubernetes/gitea-server.yaml new file mode 100644 index 0000000..029ee71 --- /dev/null +++ b/kubernetes/gitea-server.yaml @@ -0,0 +1,111 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: gitea-server +spec: + replicas: 1 + template: + metadata: + labels: + name: gitea-server + spec: + initContainers: + - name: init-config + image: busybox + command: ['sh', '-c', 'mkdir -p /data/gitea/conf && mkdir -p /data/gitea/https && cp /root/conf/app.ini /data/gitea/conf/app.ini && chown 1000:1000 /data/gitea/conf/app.ini && chmod 660 /data/gitea/conf/app.ini && cp /root/conf/*.pem /data/gitea/https && chmod 600 /data/gitea/https/*.pem && chown -R 1000:1000 /data/gitea'] + volumeMounts: + - mountPath: /data + name: gitea-server-data + - mountPath: /root/conf + name: config + containers: + # This is only used for the initial setup, it does nothing once a app.ini + # file exists in the conf/ directory of the data directory + # (/data/gitea/conf in our case) + - env: + - name: DB_HOST + value: gitea-db:3306 + - name: DB_NAME + value: gitea + - name: DB_PASSWD + valueFrom: + secretKeyRef: + name: gitea-mysql-pass + key: password + - name: DB_TYPE + value: mysql + - name: DB_USER + value: gitea + - name: ROOT_URL + value: https://gitea.kosmos.org + - name: RUN_MODE + value: prod + - name: SECRET_KEY + valueFrom: + secretKeyRef: + name: gitea-secret-key + key: password + - name: SSH_DOMAIN + value: gitea.kosmos.org + image: 5apps/gitea:latest + name: gitea-server + ports: + - containerPort: 3000 + - containerPort: 3001 + - containerPort: 22 + resources: {} + volumeMounts: + - mountPath: /data + name: gitea-server-data + restartPolicy: Always + volumes: + - name: gitea-server-data + persistentVolumeClaim: + claimName: gitea-server-data + - name: config + secret: + secretName: gitea-config + items: + - key: app.ini + path: app.ini + mode: 256 + - key: cert.pem + path: cert.pem + mode: 256 + - key: key.pem + path: key.pem + mode: 256 +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: gitea-server-data +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +apiVersion: v1 +kind: Service +metadata: + name: gitea-server + labels: + name: gitea-server +spec: + type: LoadBalancer + # preserves the client source IP + externalTrafficPolicy: Local + ports: + - name: "ssh" + port: 22 + targetPort: 22 + - name: "http" + port: 80 + targetPort: 3001 + - name: "https" + port: 443 + targetPort: 3000 + selector: + name: gitea-server diff --git a/script/get_secrets b/script/get_secrets new file mode 100755 index 0000000..0a7dcc2 --- /dev/null +++ b/script/get_secrets @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby + +require 'yaml' +require 'base64' + +secret = `kubectl get secret gitea-config -o yaml` +yaml = YAML.load(secret) + +yaml['data'].each do |key, data| + filename = File.join('kubernetes', 'config', key) + File.open(filename, "w+") do |f| + puts "Writing #{filename}" + f.write Base64.decode64(data) + end +end diff --git a/script/replace_secrets b/script/replace_secrets new file mode 100755 index 0000000..d7bb190 --- /dev/null +++ b/script/replace_secrets @@ -0,0 +1,7 @@ +#!/usr/bin/env sh + +# Delete the gitea-config secrets +kubectl delete secret gitea-config +# Replace it from the local files in kubernetes/config/* (acquired by running +# ./script/get_secrets) +kubectl create secret generic gitea-config --from-file=cert.pem=kubernetes/config/cert.pem --from-file=key.pem=kubernetes/config/key.pem --from-file=app.ini=kubernetes/config/app.ini