Skip to content
Snippets Groups Projects
Commit 93256351 authored by Ricardo Rocha's avatar Ricardo Rocha Committed by Ricardo Rocha
Browse files

Add sample application for gitops

parent 81308b61
No related branches found
No related tags found
No related merge requests found
# GitOps Getting Started
This repo acts as an example to manage application deployment and configuration
using GitOps and the tool Flux.
An example of an application deployment and configuration managed using GitOps
and the tool Flux.
The sample application has two parts:
* a frontend based on wordpress
The goal is to have a central git repo hosting all the configuration and
deployments for an application, including its dependencies. Permissions set in
this repo also define who is allowed to update the configuration.
This example has two main components:
* a frontend web application based on wordpress
* a backend MySQL database
It should be enough to give you hints on how to manage your own deployments in
......@@ -32,70 +36,74 @@ see what goes in these resources.
## Structure and Releases
The structure of this repo is as follows:
* **chart**: the umbrella chart, with defaults and any extra setup required
* **chart**: the umbrella chart. These is where all the default configuration
for the dependencies is stored, inside the values.yaml file. You can also add
custom manifests under the templates directory
* **namespaces**: Flux expects all the required namespaces to be defined here.
In this example we have both *prod* and *stg*
* **releases**: the different deployments of the application (staging, production),
each with overrides or complements of the default values. These are defined as
Flux HelmRelease resources
each with overrides for the configuration as required - completing the default
values. These are Flux HelmRelease resources
* **secrets**: this is a special directory that is not part of standard Flux. In
the future it will not be required, but for now it holds the parts of the
values yaml definitions that are sensitive (and require encryption to be
safely committed to git)
## Secrets
Secrets are stored along the release values, but encrypted using the [helm
secrets](https://gitlab.cern.ch/helm/plugins/barbican) plugin - this makes them
also version controlled.
To achieve this it means that for the moment they are not managed by Flux, a
better integration will appear later.
We recommend using the [helm secrets](https://gitlab.cern.ch/helm/plugins/barbican)
plugin to encrypt the files under the *secrets* directory.
You need to do the following once before installing flux:
As Flux does not understand this encryption method, we need to create these
secrets in advance, following something like:
```bash
kubectl -n hub create -f releases/prod/hub-secrets.yaml
kubectl -n hub-stg create -f releases/stg/hub-secrets.yaml
kubectl create namespace prod
kubectl create namespace stg
kubectl create -f secrets/prod/secrets.yaml
kubectl create -f secrets/stg/secrets.yaml
```
Remember that these resources are not managed by Flux. If you need to update
any part of the sensitive values yaml data, you need to update them manually
by doing:
```
kubectl apply -f secrets/prod/secrets.yaml
kubectl apply -f secrets/stg/secrets.yaml
```
and update them manually everytime when you update secrets.
In the near future there will be better integration of this way of handling
sensitive configuration data with Flux.
## Deployment
Next deploy the secrets - see the *secrets* section above.
Finally deploy Flux and point it to this repository (the git.url value below):
You need to deploy both the helm operator and flux itself:
```bash
$ cat flux-values.yaml
git:
path: releases,namespaces
pollInterval: 1m
readonly: true
rbac:
create: true
$ helm install fluxcd/flux --namespace flux --name flux --values flux-values.yaml \
--set git.url=https://gitlab.cern.ch/helm/releases/gitops-getting-started
$ helm install fluxcd/helm-operator --namespace flux --name helm-operator
\ --version 0.4.0 --values helm-operator-values.yaml
$ cat helm-operator-values.yaml
createCRD: true
chartsSyncInterval: 1m
configureRepositories:
enable: true
repositories:
- name: cern
url: https://registry.cern.ch/cern/charts
rbac:
create: true
git:
pollInterval: 1m
$ helm install fluxcd/helm-operator --namespace flux --name helm-operator --values helm-operator-values.yaml
$ helm install fluxcd/flux --namespace flux --name flux --version 1.0.0 \
--values flux-values.yaml \
--set git.url=https://gitlab.cern.ch/helm/releases/gitops-getting-started
```
The files *helm-operator-values.yaml* and *flux-values.yaml* contain the
configuration for each of the component. You can change these as you want.
Check the logs to see the multiple releases are being picked up:
```
$ kubectl -n flux logs -f deployment.apps/flux-helm-operator
$ kubectl -n flux logs -f deployment.apps/helm-operator
$ kubectl -n flux logs -f deployment.apps/flux
```
All going well you should see them in helm:
```bash
$ helm ls
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
flux 1 Mon Jan 20 23:04:34 2020 DEPLOYED flux-1.0.0 1.17.0 flux
gitops-getting-started 1 Mon Jan 20 23:17:48 2020 DEPLOYED gitops-getting-started-0.1.0 prod
gitops-getting-started-stg 1 Mon Jan 20 23:17:48 2020 DEPLOYED gitops-getting-started-0.1.0 stg
helm-operator 1 Mon Jan 20 23:04:32 2020 DEPLOYED helm-operator-0.4.0 1.0.0-rc5 flux
```
## FAQ
......
......
apiVersion: v1
description: A Helm chart for a sample gitops application
name: gitops-getting-started
version: 0.1.0
dependencies:
- name: wordpress
version: 8.1.1
repository: https://kubernetes-charts.storage.googleapis.com
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ .Release.Name }}.restricted
spec:
privileged: false
# Required to prevent escalations to root.
allowPrivilegeEscalation: false
# This is redundant with non-root + disallow privilege escalation,
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
# Allow core volume types.
volumes:
- 'hostPath'
- 'configMap'
- 'emptyDir'
- 'secret'
- 'persistentVolumeClaim'
allowedHostPaths:
- pathPrefix: "/var/eos"
readOnly: true
- pathPrefix: "/opt/nvidia-driver"
readOnly: true
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
# Require the container to run without root privileges.
rule: 'MustRunAsNonRoot'
seLinux:
# This policy assumes the nodes are using AppArmor rather than SELinux.
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
readOnlyRootFilesystem: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ .Release.Name }}.psp.restricted
rules:
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: ['{{ .Release.Name }}.restricted']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ .Release.Name }}.psp.restricted
roleRef:
kind: ClusterRole
name: {{ .Release.Name }}.psp.restricted
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .Release.Name }}.psp.restricted
rules:
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: ['{{ .Release.Name}}.restricted']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .Release.Name }}.psp.restricted
roleRef:
kind: Role
name: {{ .Release.Name }}.psp.restricted
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: default
wordpress:
image:
registry: "docker.io"
repository: "bitnami/wordpress"
persistence:
enabled: false
service:
type: "NodePort"
mariadb:
enabled: true
image:
registry: "docker.io"
repository: "bitnami/mariadb"
db:
name: "wordpress"
user: "wordpress"
master:
persistence:
enabled: false
git:
path: releases,namespaces
pollInterval: 5m
readonly: true
rbac:
create: true
createCRD: true
chartsSyncInterval: 1m
configureRepositories:
enable: true
repositories:
- name: stable
url: https://kubernetes-charts.storage.googleapis.com
- name: cern
url: https://registry.cern.ch/chartrepo/cern
rbac:
create: true
git:
pollInterval: 5m
---
apiVersion: v1
kind: Namespace
metadata:
name: prod
---
apiVersion: v1
kind: Namespace
metadata:
name: stg
---
apiVersion: helm.fluxcd.io/v1
kind: HelmRelease
metadata:
name: gitops-getting-started
namespace: prod
annotations:
flux.weave.works/automated: "false"
spec:
releaseName: gitops-getting-started
chart:
git: https://gitlab.cern.ch/helm/releases/gitops-getting-started.git
path: charts/gitops-getting-started
ref: master
valuesFrom:
- secretKeyRef:
namespace: prod
name: gitops-getting-started-secrets
key: values.yaml
values:
wordpress:
service:
nodePorts:
http: "32700"
mariadb:
image:
tag: "10.3.21"
---
apiVersion: helm.fluxcd.io/v1
kind: HelmRelease
metadata:
name: gitops-getting-started-stg
namespace: stg
annotations:
flux.weave.works/automated: "false"
spec:
releaseName: gitops-getting-started-stg
chart:
git: https://gitlab.cern.ch/helm/releases/gitops-getting-started.git
path: charts/gitops-getting-started
ref: master
valuesFrom:
- secretKeyRef:
namespace: stg
name: gitops-getting-started-secrets
key: values.yaml
values:
wordpress:
service:
nodePorts:
http: "32701"
mariadb:
image:
tag: "10.4.11"
apiVersion: v1
kind: Secret
metadata:
name: gitops-getting-started-secrets
namespace: prod
type: Opaque
stringData:
values.yaml: |-
wordpress:
mariadb:
rootUser:
password: "rootsecret"
db:
password: "supersecret"
apiVersion: v1
kind: Secret
metadata:
name: gitops-getting-started-secrets
namespace: stg
type: Opaque
stringData:
values.yaml: |-
wordpress:
mariadb:
rootUser:
password: "rootsecret"
db:
password: "supersecret"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment