#4483 WIP - Add Helm Chart for deploying on Kubernetes
Opened a year ago by dminca. Modified 6 months ago
dminca/pagure feature/helm-chart  into  master

file modified
+5
@@ -20,6 +20,7 @@ 

        - GL_USER=root

        - PYTHONPATH=/code

        - PAGURE_CONFIG=/code/dev/openshift.cfg

+ 

    worker:

      build:

        context: ./containers
@@ -35,6 +36,7 @@ 

      environment:

        - PYTHONPATH=/code

        - PAGURE_CONFIG=/code/dev/openshift.cfg

+ 

    logcom:

      build:

        context: ./containers
@@ -50,6 +52,7 @@ 

      environment:

        - PYTHONPATH=.

        - PAGURE_CONFIG=/code/dev/openshift.cfg

+ 

    ev:

      build:

        context: ./containers
@@ -64,8 +67,10 @@ 

      environment:

        - PYTHONPATH=.

        - PAGURE_CONFIG=/code/dev/openshift.cfg

+ 

    redis:

      image: redis

+ 

    postgresql:

      image: postgres

      environment:

file added
+43
@@ -0,0 +1,43 @@ 

+ # Developing with the Helm Chart

+ > This docu provides you detailed instructions for easily developing

+ > this Helm Chart (ie. testing, deploying the app et. al.)

+ 

+ ## Prerequisites

+ 

+ In order to start hacking locally without hassle, you're gonna need to install

+ * [k3d][1] - installation instructions in readme

+ * [kubectl][2] - for running commands in the Kubernetes cluster

+ 

+ ## Spinning up a mini Kubernetes cluster locally

+ Helm Charts run on Kubernetes, therefore a Kubernetes cluster is a requirement, this is

+ how you can spin up your tiny Kubernetes cluster locally with [k3d][1]

+ 

+ ```bash

+ # create the cluster

+ k3d create

+ 

+ # authenticate to execute commands in cluster

+ export KUBECONFIG="$(k3d get-kubeconfig --name='k3s-default')"

+ 

+ # check if you have the cluster ready

+ kubectl get nodes -owide

+ ```

+ 

+ ## Start hacking

+ 

+ Install the helm chart in your local Kubernetes cluster now

+ 

+ ```bash

+ helm install --name pagure helm/pagure

+ ```

+ 

+ ## Teardown

+ 

+ If you decide to call it a day, just destroy the local Kubernetes cluster

+ 

+ ```bash

+ k3d delete

+ ```

+ 

+ [1]: https://github.com/rancher/k3d

+ [2]: https://kubernetes.io/docs/tasks/tools/install-kubectl/ 

\ No newline at end of file

@@ -0,0 +1,22 @@ 

+ # 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

+ *~

+ # Various IDEs

+ .project

+ .idea/

+ *.tmproj

+ .vscode/

@@ -0,0 +1,5 @@ 

+ apiVersion: v1

+ appVersion: "1.0"

+ description: A Helm chart for Kubernetes

+ name: pagure

+ version: 0.1.0

@@ -0,0 +1,19 @@ 

+ # pagure Helm Chart

+ > Deploys fully-fledged pagure.io on your Kubernetes cluster

+ 

+ ## TL;DR;

+ 

+ ```sh

+ helm install --name pagure helm/pagure

+ ```

+ 

+ ## Configuration

+ 

+ The table lists the configurable parameters of the pagure chart and their default values.

+ 

+ <!-- # TODO: describe values.yaml by adding more rows to this table -->

+ 

+ Parameter | Description | Default

+ --- | --- | ---

+ `foo.bar` | name of the foobar component | `foobar`

+ 

@@ -0,0 +1,21 @@ 

+ 1. Get the application URL by running these commands:

+ {{- if .Values.ingress.enabled }}

+ {{- range $host := .Values.ingress.hosts }}

+   {{- range $.Values.ingress.paths }}

+   http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}{{ . }}

+   {{- end }}

+ {{- end }}

+ {{- else if contains "NodePort" .Values.service.type }}

+   export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "pagure.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 }}

+      NOTE: It may take a few minutes for the LoadBalancer IP to be available.

+            You can watch the status of by running 'kubectl get svc -w {{ include "pagure.fullname" . }}'

+   export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "pagure.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

+   echo http://$SERVICE_IP:{{ .Values.service.port }}

+ {{- else if contains "ClusterIP" .Values.service.type }}

+   export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "pagure.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")

+   echo "Visit http://127.0.0.1:8080 to use your application"

+   kubectl port-forward $POD_NAME 8080:80

+ {{- end }}

@@ -0,0 +1,32 @@ 

+ {{/* vim: set filetype=mustache: */}}

+ {{/*

+ Expand the name of the chart.

+ */}}

+ {{- define "pagure.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 "pagure.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 "pagure.chart" -}}

+ {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}

+ {{- end -}}

@@ -0,0 +1,51 @@ 

+ apiVersion: apps/v1

+ kind: Deployment

+ metadata:

+   name: {{ include "pagure.fullname" . }}

+   labels:

+     app.kubernetes.io/name: {{ include "pagure.name" . }}

+     helm.sh/chart: {{ include "pagure.chart" . }}

+     app.kubernetes.io/instance: {{ .Release.Name }}

+     app.kubernetes.io/managed-by: {{ .Release.Service }}

+ spec:

+   replicas: {{ .Values.replicaCount }}

+   selector:

+     matchLabels:

+       app.kubernetes.io/name: {{ include "pagure.name" . }}

+       app.kubernetes.io/instance: {{ .Release.Name }}

+   template:

+     metadata:

+       labels:

+         app.kubernetes.io/name: {{ include "pagure.name" . }}

+         app.kubernetes.io/instance: {{ .Release.Name }}

+     spec:

+       containers:

+         - name: {{ .Chart.Name }}

+           image: "{{ .Values.image }}"

+           imagePullPolicy: {{ .Values.pullPolicy }}

+           ports:

+             - name: http

+               containerPort: 80

+               protocol: TCP

+           livenessProbe:

+             httpGet:

+               path: /

+               port: http

+           readinessProbe:

+             httpGet:

+               path: /

+               port: http

+           resources:

+             {{- toYaml .Values.resources | nindent 12 }}

+ {{- with .Values.nodeSelector }}

+       nodeSelector:

+         {{- toYaml . | nindent 8 }}

+ {{- end }}

+ {{- with .Values.affinity }}

+       affinity:

+         {{- toYaml . | nindent 8 }}

+ {{- end }}

+ {{- with .Values.tolerations }}

+       tolerations:

+         {{- toYaml . | nindent 8 }}

+ {{- end }}

@@ -0,0 +1,44 @@ 

+ {{- if .Values.ingress.enabled -}}

+ {{- $fullName := include "pagure.fullname" . -}}

+ {{- $ingressPaths := .Values.ingress.paths -}}

+ {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}

+ apiVersion: networking.k8s.io/v1beta1

+ {{- else -}}

+ apiVersion: extensions/v1beta1

+ {{- end }}

+ kind: Ingress

+ metadata:

+   name: {{ $fullName }}

+   labels:

+     app.kubernetes.io/name: {{ include "pagure.name" . }}

+     helm.sh/chart: {{ include "pagure.chart" . }}

+     app.kubernetes.io/instance: {{ .Release.Name }}

+     app.kubernetes.io/managed-by: {{ .Release.Service }}

+ {{- 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: {{ . | quote }}

+       http:

+         paths:

+ {{- range $ingressPaths }}

+           - path: {{ . }}

+             backend:

+               serviceName: {{ $fullName }}

+               servicePort: http

+ {{- end }}

+ {{- end }}

+ {{- end }}

@@ -0,0 +1,19 @@ 

+ apiVersion: v1

+ kind: Service

+ metadata:

+   name: {{ include "pagure.fullname" . }}

+   labels:

+     app.kubernetes.io/name: {{ include "pagure.name" . }}

+     helm.sh/chart: {{ include "pagure.chart" . }}

+     app.kubernetes.io/instance: {{ .Release.Name }}

+     app.kubernetes.io/managed-by: {{ .Release.Service }}

+ spec:

+   type: {{ .Values.service.type }}

+   ports:

+     - port: {{ .Values.service.port }}

+       targetPort: http

+       protocol: TCP

+       name: http

+   selector:

+     app.kubernetes.io/name: {{ include "pagure.name" . }}

+     app.kubernetes.io/instance: {{ .Release.Name }}

@@ -0,0 +1,18 @@ 

+ apiVersion: v1

+ kind: Pod

+ metadata:

+   name: "{{ include "pagure.fullname" . }}-test-connection"

+   labels:

+     app.kubernetes.io/name: {{ include "pagure.name" . }}

+     helm.sh/chart: {{ include "pagure.chart" . }}

+     app.kubernetes.io/instance: {{ .Release.Name }}

+     app.kubernetes.io/managed-by: {{ .Release.Service }}

+   annotations:

+     "helm.sh/hook": test-success

+ spec:

+   containers:

+     - name: wget

+       image: busybox

+       command: ['wget']

+       args:  ['{{ include "pagure.fullname" . }}:{{ .Values.service.port }}']

+   restartPolicy: Never

@@ -0,0 +1,46 @@ 

+ # Default values for pagure.

+ # This is a YAML-formatted file.

+ # Declare variables to be passed into your templates.

+ 

+ replicaCount: 1

+ 

+ image: "dminca/pagure-web:latest" # TODO: replace with official image

just pushed it to https://hub.docker.com/repository/docker/dminca/pagure-web for now, to catch some speed; will update the image later on

+ pullPolicy: IfNotPresent

+ 

+ nameOverride: ""

+ fullnameOverride: ""

+ 

+ service:

+   type: ClusterIP

+   port: 80

+ 

+ ingress:

+   enabled: false

+   annotations: {}

+     # kubernetes.io/ingress.class: nginx

+     # kubernetes.io/tls-acme: "true"

+   paths: []

+   hosts:

+     - chart-example.local

+   tls: []

+   #  - secretName: chart-example-tls

+   #    hosts:

+   #      - chart-example.local

+ 

+ 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

+ 

+ nodeSelector: {}

+ 

+ tolerations: []

+ 

+ affinity: {}

Hi there,

Just saw your presentation from openSuse Conference '19 from Nürnberg, thrown a few questions after the presentation and now I want to contribute to this cool project, therefore:

  • Create Helm Chart for easily deploying pagure on K8s
  • clean-up some stuff in here to make it more readable
  • refactor

Resolves:
Related:
Signed-off-by: Daniel Andrei Minca

1 new commit added

  • generate the scaffold code for the Helm Chart
a year ago

1 new commit added

  • add README for describing what we're doing here
a year ago

1 new commit added

  • fix markdown table
a year ago

@dminca Thanks for writing this!

Question: doesn't a Helm chart require a container image with Pagure in it to work from?

@ngompa yes that's a prerequisite.

And from the looks of it, it has the web and worker Docker images https://pagure.io/pagure/blob/master/f/dev/containers

I am unfortunately not able to test this, is this PR still valid? If so then we should get it in (with all my apologies for the lag)

hi there,

yes it's valid. Unfortunately I also didn't have much time to work on it, but now since we're isolated in our houses will try to make this thing work.

One question tho: where do you push Docker images, do you have some Container Registry? I'm gonna need that for the Kubernetes Deployment - ideally it should run official Fedora images

This is something that @pingou and I should probably figure out ASAP. I think we do have a way of making these, but we need to confirm that...

One question tho: where do you push Docker images, do you have some Container Registry? I'm gonna need that for the Kubernetes Deployment - ideally it should run official Fedora images

Fedora has its own registry and otherwise people use quay.io

rebased onto 730958c

6 months ago

2 new commits added

  • make it compatible with k8s version >=1.14
  • replace old syntax
6 months ago

going through this https://pagure.io/docs/pagure/ need to understand what components I need to glue together

in the mean-time, this remains an open question; where exactly is this pagure image pushed right now? From what I saw in the code there's a registry available at registry.fedoraproject.org

Is the pagure image pushed there also?

Right now, the image isn't pushed anywhere yet...

1 new commit added

  • add instructions for hacking on kubernetes
6 months ago

mah lawd - it's amazing how this markdown gets formatted 🤦‍♂️

Do I need to turn this into *.rst? We use only *.rst docs in the repo I guess

1 new commit added

  • add instructions for hacking on kubernetes
6 months ago

1 new commit added

  • try a first spin
6 months ago

just pushed it to https://hub.docker.com/repository/docker/dminca/pagure-web for now, to catch some speed; will update the image later on

1 new commit added

  • fix indentation
6 months ago

hey, I think having a helm chart is great, but it pretty much requires having an automaticly built and updated container image generated by the project. Wanna open an issue requesting that?

@jberkus Do you have any suggestions on how to do that? I would love to get something set up for that...

Ideally it would get built by Fedora automation and published to registry.fedoraproject.org. I understand that can take a while to make happen, though.

Are there RPMs for Pagure?

@dminca I see the postgres and redis instances in the docker-compose you have here, but not in the Helm chart. Where are they?

Ideally it would get built by Fedora automation and published to registry.fedoraproject.org. I understand that can take a while to make happen, though.
Are there RPMs for Pagure?

Yes. RPMs exist for all supported releases of Fedora and both EPEL 7 and EPEL 8.