Skip to content

Commit

Permalink
feat(helm): added Helm chart to allow installation of the driver (#12)
Browse files Browse the repository at this point in the history
* feat(helm): added functional helm chart

Signed-off-by: Mateusz Urbanek <[email protected]>

* feat(helm): add support for user provided secret

Signed-off-by: Mateusz Urbanek <[email protected]>

* docs(installation): added installation command

Signed-off-by: Mateusz Urbanek <[email protected]>

* chore: added new labels for marking PRs

Signed-off-by: Mateusz Urbanek <[email protected]>

---------

Signed-off-by: Mateusz Urbanek <[email protected]>
  • Loading branch information
shanduur-akamai authored Dec 15, 2023
1 parent 65ddd5f commit c9853f4
Show file tree
Hide file tree
Showing 15 changed files with 378 additions and 160 deletions.
8 changes: 7 additions & 1 deletion .github/labels.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@
- name: help wanted
color: 006b75
description: Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.
- name: do-not-merge
color: e11d21
description: Indicates that a PR should not merge.

- name: area/api
color: 0052cc
description: Indicates an issue on api area.
- name: area/dependency
color: 0052cc
description: Issues or PRs related to dependency changes
description: Issues or PRs related to dependency changes.
- name: area/example
color: 0052cc
- name: area/helm
color: 0052cc
description: Issues or PRs related to Helm chart.

- name: kind/bug
color: e11d21
Expand Down
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ repos:
rev: v1.11.3
hooks:
- id: helm-docs
args:
- '--badge-style=flat'
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,27 @@ Follow these steps to get started with Linode COSI Driver:

1. **Prerequisites:**
1. Install COSI Custom Resource Definitions.
```
```sh
kubectl create -k github.com/kubernetes-sigs/container-object-storage-interface-api
```

2. Install COSI Controller.
```
```sh
kubectl create -k github.com/kubernetes-sigs/container-object-storage-interface-controller
```

2. **Installation:**
<!-- TODO: write install instructions -->
1. Create new API token in [Akamai Cloud Manager](https://cloud.linode.com/profile/tokens). The token must be configured with the following permissions:
- **Object Storage** - Read/Write

2. Install Linode COSI Driver using Helm.
```sh
helm install linode-cosi-driver \
./helm/linode-cosi-driver/ \
--set=apiToken=<YOUR_LINODE_API_TOKEN> \
--namespace=linode-cosi-driver \
--create-namespace
```

3. **Usage:**
<!-- TODO: write usage examples -->
Expand Down
3 changes: 2 additions & 1 deletion githooks/.tools.brew
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
checkmake
helm
golangci-lint
helm
kube-linter
norwoodj/tap/helm-docs
8 changes: 8 additions & 0 deletions githooks/install-hooks.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
#!/bin/bash -aex

if [[ "$(uname -s)" == "Darwin" ]]; then
if command -v brew &> /dev/null; then
xargs brew install < ./githooks/.tools.brew
else
echo "Homebrew not installed. Please install required tools manually."
fi
fi

pre-commit install --hook-type pre-commit
pre-commit install --hook-type commit-msg
16 changes: 7 additions & 9 deletions helm/.kube-linter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ checks:
# - "no-node-affinity"
- "no-read-only-root-fs"
# - "no-readiness-probe"
# - "no-rolling-update-strategy"
- "no-rolling-update-strategy"
- "non-existent-service-account"
# - "non-isolated-pod"
- "privilege-escalation-container"
Expand All @@ -50,21 +50,19 @@ checks:
- "wildcard-in-rules"
- "writable-host-mount"

# NOTE: manually exclude failing for documentation, fix them in future or
# comment why are they disabled.
# NOTE: manually exclude failing for documentation, fix them in future or comment why are they disabled.
exclude:
- "access-to-secrets" # NOTE: COSI Provisioner Sidecar requires access to secrets
- "access-to-secrets" # NOTE: COSI Provisioner Sidecar requires access to secrets.
- "dnsconfig-options"
- "minimum-three-replicas"
- "no-liveness-probe"
- "no-node-affinity"
- "no-readiness-probe"
- "no-rolling-update-strategy"
- "non-isolated-pod"
- "pdb-max-unavailable"
- "pdb-min-available"
- "required-annotation-email"
- "required-label-owner"
- "required-annotation-email" # NOTE: annotations are on the customer side, as we do not annotate by default.
- "required-label-owner" # NOTE: owner label is on the customer side, as we do not add additional annotations by default.
- "unset-cpu-requirements"
- "unset-memory-requirements"
- "use-namespace"
- "unset-memory-requirements" # NOTE: resources should be set during installation time IF it is required.
- "use-namespace" # NOTE: namespace is handled by helm.
62 changes: 27 additions & 35 deletions helm/linode-cosi-driver/README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,39 @@
# linode-cosi-driver

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.16.0](https://img.shields.io/badge/AppVersion-1.16.0-informational?style=flat-square)
![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat) ![AppVersion: v0.1.0](https://img.shields.io/badge/AppVersion-v0.1.0-informational?style=flat)

A Helm chart for Kubernetes

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | |
| autoscaling.enabled | bool | `false` | |
| autoscaling.maxReplicas | int | `100` | |
| autoscaling.minReplicas | int | `1` | |
| autoscaling.targetCPUUtilizationPercentage | int | `80` | |
| fullnameOverride | string | `""` | |
| image.pullPolicy | string | `"IfNotPresent"` | |
| image.repository | string | `"nginx"` | |
| image.tag | string | `""` | |
| imagePullSecrets | list | `[]` | |
| ingress.annotations | object | `{}` | |
| ingress.className | string | `""` | |
| ingress.enabled | bool | `false` | |
| ingress.hosts[0].host | string | `"chart-example.local"` | |
| ingress.hosts[0].paths[0].path | string | `"/"` | |
| ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | |
| ingress.tls | list | `[]` | |
| nameOverride | string | `""` | |
| nodeSelector | object | `{}` | |
| podAnnotations | object | `{}` | |
| podLabels | object | `{}` | |
| podSecurityContext | object | `{}` | |
| replicaCount | int | `1` | |
| resources | object | `{}` | |
| securityContext | object | `{}` | |
| service.port | int | `80` | |
| service.type | string | `"ClusterIP"` | |
| serviceAccount.annotations | object | `{}` | |
| serviceAccount.automount | bool | `true` | |
| serviceAccount.create | bool | `true` | |
| serviceAccount.name | string | `""` | |
| tolerations | list | `[]` | |
| volumeMounts | list | `[]` | |
| volumes | list | `[]` | |
| affinity | object | `{}` | Node affinity rules for pod assignment. |
| apiToken | string | `""` | Linode API token. This field is **required** unless secret is created before deployment (see `secret.ref` value). |
| driver.image.pullPolicy | string | `"IfNotPresent"` | Driver container image pull policy. |
| driver.image.repository | string | `"docker.io/linode/linode-cosi-driver"` | Driver container image repository. |
| driver.image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. |
| fullnameOverride | string | `""` | Overrides the full chart name. |
| imagePullSecrets | list | `[]` | List of Docker registry secret names to pull images. |
| linodeApiUrl | string | `""` | Linode API URL, leave empty for default. |
| linodeApiVersion | string | `""` | Linode API version, leave empty for default. |
| nameOverride | string | `""` | Overrides the chart name. |
| nodeSelector | object | `{}` | Node labels for pod assignment. |
| podAnnotations | object | `{}` | Annotations to add to the pod. |
| podSecurityContext.runAsNonRoot | bool | `true` | Run the pod as a non-root user. |
| podSecurityContext.runAsUser | int | `65532` | User ID to run the pod as. |
| rbac.annotations | object | `{}` | Annotations to add to the service account, cluster role, and cluster role binding. |
| rbac.name | string | `""` | The name of the service account, cluster role, and cluster role binding to use. If not set, a name is generated using the fullname template. |
| replicaCount | int | `1` | Number of pod replicas. |
| resources | object | `{}` | Specify CPU and memory resource limits if needed. |
| secret.annotations | object | `{}` | Annotations to add to the secret. |
| secret.ref | string | `""` | Name of existing secret. If not set, a new secret is created. |
| securityContext.readOnlyRootFilesystem | bool | `true` | Container runs with a read-only root filesystem. |
| sidecar.image.pullPolicy | string | `"IfNotPresent"` | Sidecar container image pull policy. |
| sidecar.image.repository | string | `"gcr.io/k8s-staging-sig-storage/objectstorage-sidecar/objectstorage-sidecar"` | Sidecar container image repository. |
| sidecar.image.tag | string | `"v20221117-v0.1.0-22-g0e67387"` | Overrides the image tag whose default is the chart appVersion. |
| sidecar.logVerbosity | int | `4` | Log verbosity level for the sidecar container. |
| tolerations | list | `[]` | Tolerations for pod assignment. |

----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.11.3](https://github.com/norwoodj/helm-docs/releases/v1.11.3)
90 changes: 90 additions & 0 deletions helm/linode-cosi-driver/templates/Deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "linode-cosi-driver.fullname" . }}
labels:
{{- include "linode-cosi-driver.labels" . | trim | nindent 4 }}
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
replicas: {{ .Values.replicaCount }}
minReadySeconds: 30
progressDeadlineSeconds: 600
revisionHistoryLimit: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
{{- include "linode-cosi-driver.selectorLabels" . | trim | nindent 6 }}
template:
metadata:
labels:
{{- include "linode-cosi-driver.labels" . | trim | nindent 8 }}
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "linode-cosi-driver.rbacName" . }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: driver
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
image: {{ include "linode-cosi-driver.driverImageName" . }}
imagePullPolicy: {{ .Values.driver.image.pullPolicy }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
envFrom:
- secretRef:
name: {{ include "linode-cosi-driver.secretName" . }}
volumeMounts:
- name: cosi-socket-dir
mountPath: /var/lib/cosi
- name: objectstorage-provisioner-sidecar
image: {{ include "linode-cosi-driver.provisionerSidecarImageName" . }}
imagePullPolicy: {{ .Values.sidecar.image.pullPolicy }}
args:
- "-v={{ include "linode-cosi-driver.provisionerSidecarVerbosity" . }}"
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: cosi-socket-dir
mountPath: /var/lib/cosi
{{- 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: cosi-socket-dir
emptyDir: {}
22 changes: 0 additions & 22 deletions helm/linode-cosi-driver/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,22 +0,0 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- 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 "linode-cosi-driver.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 --namespace {{ .Release.Namespace }} svc -w {{ include "linode-cosi-driver.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "linode-cosi-driver.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
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 "linode-cosi-driver.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
50 changes: 50 additions & 0 deletions helm/linode-cosi-driver/templates/Role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ include "linode-cosi-driver.rbacName" . }}
labels:
{{- include "linode-cosi-driver.labels" . | trim | nindent 4 }}
{{- with .Values.rbac.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
rules:
- apiGroups:
- objectstorage.k8s.io # COSI resources are grouped here
resources: # we do not add bucketclasses here, as those are managed by COSI Controller
- buckets
- bucketclaims
- bucketaccesses
- bucketaccessclasses
- buckets/status
- bucketaccesses/status
- bucketclaims/status
- bucketaccessclasses/status
verbs:
- create
- get
- update
- delete
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases # lease is created during leader election process by COSI Provisioner Sidecar
verbs:
- create
- get
- update
- delete
- list
- watch
- apiGroups:
- "" # default API group
resources:
- events # events are emmited from COSI Provisioner Sidecar
- secrets # secrets are created by COSI Provisioner Sidecar as a part of access granting
verbs: # CRUD
- create
- get
- update
- delete
18 changes: 18 additions & 0 deletions helm/linode-cosi-driver/templates/RoleBinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ include "linode-cosi-driver.rbacName" . }}
labels:
{{- include "linode-cosi-driver.labels" . | trim | nindent 4 }}
{{- with .Values.rbac.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
subjects:
- kind: ServiceAccount
name: {{ include "linode-cosi-driver.rbacName" . }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: {{ include "linode-cosi-driver.rbacName" . }}
apiGroup: rbac.authorization.k8s.io
22 changes: 22 additions & 0 deletions helm/linode-cosi-driver/templates/Secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{- if not .Values.secret.ref }}
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: {{ include "linode-cosi-driver.name" . }}
labels:
{{- include "linode-cosi-driver.labels" . | trim | nindent 4 }}
{{- with .Values.secret.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
type: Opaque
data:
LINODE_TOKEN: {{ required ".Values.apiToken required" .Values.apiToken | b64enc }}
{{- if .Values.linodeApiUrl -}}
LINODE_API_URL: {{ .Values.linodeApiUrl | b64enc }}
{{- end }}
{{- if .Values.linodeApiVersion -}}
LINODE_API_VERSION: {{ .Values.linodeApiVersion | b64enc }}
{{- end }}
{{- end }}
Loading

0 comments on commit c9853f4

Please sign in to comment.