Skip to content

Commit a6d3a32

Browse files
authored
Merge pull request #2 from ethpandaops/skylenet/add-cloudflare-tunnel
add cloudflare-tunnel
2 parents f8903a8 + ca77646 commit a6d3a32

File tree

11 files changed

+348
-3
lines changed

11 files changed

+348
-3
lines changed

.github/workflows/lint-test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ jobs:
4444
- name: Run chart-testing (install)
4545
run: >
4646
ct install --config ct.yaml
47+
--excluded-charts cloudflare-tunnel

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@ the latest versions of the packages. You can then run the following command to
2323
helm search repo ethpandaops-general-helm-charts
2424
```
2525

26-
**TODO** install/uninstall example once we have a chart published
27-
2826
## List of charts
2927

30-
**TODO**
28+
- [`cloudflare-tunnel`](charts/cloudflare-tunnel)
3129

3230
## Development
3331

charts/cloudflare-tunnel/Chart.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: v2
2+
name: cloudflare-tunnel
3+
description: Creation of a cloudflared deployment - a reverse tunnel for an environment
4+
type: application
5+
version: 0.1.2
6+
icon: https://developers.cloudflare.com/cloudflare-one/favicon-32x32.png
7+
maintainers:
8+
- name: barnabasbusa
9+
email: busa.barnabas@gmail.com

charts/cloudflare-tunnel/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# cloudflare-tunnel
2+
3+
![Version: 0.1.2](https://img.shields.io/badge/Version-0.1.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
4+
5+
Creation of a cloudflared deployment - a reverse tunnel for an environment
6+
7+
## Values
8+
9+
| Key | Type | Default | Description |
10+
|-----|------|---------|-------------|
11+
| affinity | object | `{}` | |
12+
| cloudflare.account | string | `""` | |
13+
| cloudflare.enableWarp | bool | `false` | |
14+
| cloudflare.ingress | list | `[]` | |
15+
| cloudflare.secret | string | `""` | |
16+
| cloudflare.tunnelId | string | `""` | |
17+
| cloudflare.tunnelName | string | `""` | |
18+
| fullnameOverride | string | `""` | |
19+
| image.pullPolicy | string | `"IfNotPresent"` | |
20+
| image.repository | string | `"cloudflare/cloudflared"` | |
21+
| image.tag | string | `"latest"` | |
22+
| imagePullSecrets | list | `[]` | |
23+
| nameOverride | string | `""` | |
24+
| nodeSelector | object | `{}` | |
25+
| podAnnotations | object | `{}` | |
26+
| podSecurityContext.runAsNonRoot | bool | `true` | |
27+
| podSecurityContext.runAsUser | int | `65532` | |
28+
| replicaCount | int | `2` | |
29+
| resources | object | `{}` | |
30+
| securityContext.allowPrivilegeEscalation | bool | `false` | |
31+
| securityContext.capabilities.drop[0] | string | `"ALL"` | |
32+
| securityContext.readOnlyRootFilesystem | bool | `true` | |
33+
| serviceAccount.annotations | object | `{}` | |
34+
| serviceAccount.name | string | `""` | |
35+
| tolerations | list | `[]` | |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{{ template "chart.header" . }}
2+
{{ template "chart.deprecationWarning" . }}
3+
4+
{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}
5+
6+
{{ template "chart.description" . }}
7+
8+
{{ template "chart.homepageLine" . }}
9+
10+
{{ template "chart.sourcesSection" . }}
11+
12+
{{ template "chart.requirementsSection" . }}
13+
14+
{{ template "chart.valuesSection" . }}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "cloudflare-tunnel.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11+
If release name contains chart name it will be used as a full name.
12+
*/}}
13+
{{- define "cloudflare-tunnel.fullname" -}}
14+
{{- if .Values.fullnameOverride }}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- $name := default .Chart.Name .Values.nameOverride }}
18+
{{- if contains $name .Release.Name }}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
20+
{{- else }}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22+
{{- end }}
23+
{{- end }}
24+
{{- end }}
25+
26+
{{/*
27+
Create chart name and version as used by the chart label.
28+
*/}}
29+
{{- define "cloudflare-tunnel.chart" -}}
30+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31+
{{- end }}
32+
33+
{{/*
34+
Common labels
35+
*/}}
36+
{{- define "cloudflare-tunnel.labels" -}}
37+
helm.sh/chart: {{ include "cloudflare-tunnel.chart" . }}
38+
{{ include "cloudflare-tunnel.selectorLabels" . }}
39+
{{- if .Chart.AppVersion }}
40+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41+
{{- end }}
42+
app.kubernetes.io/managed-by: {{ .Release.Service }}
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "cloudflare-tunnel.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "cloudflare-tunnel.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# This configmap stores the configuration used by cloudflared.
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ include "cloudflare-tunnel.fullname" . }}
6+
data:
7+
config.yaml: |
8+
# Name of the tunnel you want to run
9+
tunnel: {{ .Values.cloudflare.tunnelName }}
10+
# The location of the secret containing the tunnel credentials
11+
credentials-file: /etc/cloudflared/creds/credentials.json
12+
# General purpose TCP routing for the network
13+
warp-routing:
14+
enabled: {{ .Values.cloudflare.enableWarp }}
15+
# Serves the metrics server under /metrics and the readiness server under /ready
16+
metrics: 0.0.0.0:2000
17+
# Autoupdates applied in a k8s pod will be lost when the pod is removed or restarted, so
18+
# autoupdate doesn't make sense in Kubernetes. However, outside of Kubernetes, we strongly
19+
# recommend using autoupdate.
20+
no-autoupdate: true
21+
# The `ingress` block tells cloudflared which local service to route incoming
22+
# requests to. For more about ingress rules, see
23+
# https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/ingress
24+
ingress:
25+
{{- with .Values.cloudflare.ingress }}
26+
{{- toYaml . | nindent 6 }}
27+
{{- end }}
28+
# This rule matches any traffic which didn't match a previous rule, and responds with HTTP 404.
29+
- service: http_status:404
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Here we deploy cloudflared images. The tunnel credentials are stored in
2+
# a k8s secret, and the configuration is stored in a k8s configmap.
3+
apiVersion: apps/v1
4+
kind: Deployment
5+
metadata:
6+
name: {{ include "cloudflare-tunnel.fullname" . }}
7+
labels:
8+
{{- include "cloudflare-tunnel.labels" . | nindent 4 }}
9+
spec:
10+
replicas: {{ .Values.replicaCount }}
11+
selector:
12+
matchLabels:
13+
{{- include "cloudflare-tunnel.selectorLabels" . | nindent 6 }}
14+
template:
15+
metadata:
16+
annotations:
17+
# These are here so the deployment rolls when the config or secret change.
18+
checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
19+
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
20+
{{- with .Values.podAnnotations }}
21+
{{- toYaml . | nindent 8 }}
22+
{{- end }}
23+
labels:
24+
{{- include "cloudflare-tunnel.selectorLabels" . | nindent 8 }}
25+
spec:
26+
{{- with .Values.imagePullSecrets }}
27+
imagePullSecrets:
28+
{{- toYaml . | nindent 8 }}
29+
{{- end }}
30+
serviceAccountName: {{ include "cloudflare-tunnel.fullname" . }}
31+
securityContext:
32+
{{- toYaml .Values.podSecurityContext | nindent 8 }}
33+
containers:
34+
- name: {{ .Chart.Name }}
35+
securityContext:
36+
{{- toYaml .Values.securityContext | nindent 12 }}
37+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
38+
imagePullPolicy: {{ .Values.image.pullPolicy }}
39+
args:
40+
- tunnel
41+
# Points cloudflared to the config file, which configures what
42+
# cloudflared will actually do. This file is created by a ConfigMap.
43+
- --config
44+
- /etc/cloudflared/config/config.yaml
45+
- run
46+
livenessProbe:
47+
httpGet:
48+
# Cloudflared has a /ready endpoint which returns 200 if and only if
49+
# it has an active connection to the edge.
50+
path: /ready
51+
port: 2000
52+
failureThreshold: 1
53+
initialDelaySeconds: 10
54+
periodSeconds: 10
55+
volumeMounts:
56+
- name: config
57+
mountPath: /etc/cloudflared/config
58+
readOnly: true
59+
# Each tunnel has an associated "credentials file" which authorizes machines
60+
# to run the tunnel. cloudflared will read this file from its local filesystem,
61+
# and it'll be stored in a k8s secret.
62+
- name: creds
63+
mountPath: /etc/cloudflared/creds
64+
readOnly: true
65+
resources:
66+
{{- toYaml .Values.resources | nindent 12 }}
67+
volumes:
68+
- name: creds
69+
secret:
70+
secretName: {{ include "cloudflare-tunnel.fullname" . }}
71+
- name: config
72+
configMap:
73+
name: {{ include "cloudflare-tunnel.fullname" . }}
74+
items:
75+
- key: config.yaml
76+
path: config.yaml
77+
{{- with .Values.nodeSelector }}
78+
nodeSelector:
79+
{{- toYaml . | nindent 8 }}
80+
{{- end }}
81+
affinity:
82+
{{- with .Values.affinity }}
83+
{{- toYaml . | nindent 8 }}
84+
{{- else }}
85+
podAntiAffinity:
86+
preferredDuringSchedulingIgnoredDuringExecution:
87+
- weight: 10
88+
podAffinityTerm:
89+
topologyKey: kubernetes.io/hostname
90+
labelSelector:
91+
matchExpressions:
92+
{{- range $k, $v := include "cloudflare-tunnel.selectorLabels" . | fromYaml }}
93+
- key: {{ $k }}
94+
operator: In
95+
values:
96+
- {{ $v }}
97+
{{- end }}
98+
{{- end }}
99+
{{- with .Values.tolerations }}
100+
tolerations:
101+
{{- toYaml . | nindent 8 }}
102+
{{- end }}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# This credentials secret allows cloudflared to authenticate itself
2+
# to the Cloudflare infrastructure.
3+
apiVersion: v1
4+
kind: Secret
5+
metadata:
6+
name: {{ include "cloudflare-tunnel.fullname" . }}
7+
labels:
8+
{{- include "cloudflare-tunnel.labels" . | nindent 4 }}
9+
stringData:
10+
credentials.json: |-
11+
{
12+
"AccountTag": {{ .Values.cloudflare.account | quote }},
13+
"TunnelID": {{ .Values.cloudflare.tunnelId | quote }},
14+
"TunnelName": {{ .Values.cloudflare.tunnelName | quote }},
15+
"TunnelSecret": {{ .Values.cloudflare.secret | quote }}
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Here we create a service account with no privileges to run the
2+
# deployment - just in case the default service account is different.
3+
apiVersion: v1
4+
kind: ServiceAccount
5+
metadata:
6+
name: {{ include "cloudflare-tunnel.fullname" . }}
7+
labels:
8+
{{- include "cloudflare-tunnel.labels" . | nindent 4 }}
9+
{{- with .Values.serviceAccount.annotations }}
10+
annotations:
11+
{{- toYaml . | nindent 4 }}
12+
{{- end }}

charts/cloudflare-tunnel/values.yaml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Default values for cloudflare-tunnel.
2+
3+
# Cloudflare parameters.
4+
cloudflare:
5+
# Your Cloudflare account number.
6+
account: ""
7+
# The name of the tunnel this instance will serve
8+
tunnelName: ""
9+
# The ID of the above tunnel.
10+
tunnelId: ""
11+
# The secret for the tunnel.
12+
secret: ""
13+
# If true, turn on WARP routing for TCP
14+
enableWarp: false
15+
# Define ingress rules for the tunnel. See
16+
# https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/configuration-file/ingress
17+
ingress: []
18+
# The first rule proxies traffic to the httpbin sample service named web-server at port 80
19+
# - hostname: tunnel.example.com
20+
# service: http://web-service:80
21+
# This rule sends traffic to the built-in hello-world HTTP server. This can help debug connectivity
22+
# issues. If hello.example.com resolves and tunnel.example.com does not, then the problem is
23+
# in the connection from cloudflared to your local service, not from the internet to cloudflared.
24+
# - hostname: hello.example.com
25+
# service: hello_world
26+
27+
image:
28+
repository: cloudflare/cloudflared
29+
pullPolicy: IfNotPresent
30+
tag: "latest"
31+
32+
replicaCount: 2
33+
34+
imagePullSecrets: []
35+
nameOverride: ""
36+
fullnameOverride: ""
37+
38+
serviceAccount:
39+
# Annotations to add to the service account
40+
annotations: {}
41+
# The name of the service account to use.
42+
# If not set and create is true, a name is generated using the fullname template
43+
name: ""
44+
45+
podAnnotations: {}
46+
47+
# Security items common to everything in the pod. Here we require that it
48+
# does not run as the user defined in the image, literally named "nonroot".
49+
podSecurityContext:
50+
runAsNonRoot: true
51+
runAsUser: 65532
52+
53+
# Security items for one container. We lock it down.
54+
securityContext:
55+
allowPrivilegeEscalation: false
56+
capabilities:
57+
drop:
58+
- ALL
59+
readOnlyRootFilesystem: true
60+
61+
resources: {}
62+
# We usually recommend not to specify default resources and to leave this as a conscious
63+
# choice for the user. This also increases chances charts run on environments with little
64+
# resources, such as Minikube. If you do want to specify resources, uncomment the following
65+
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
66+
# limits:
67+
# cpu: 100m
68+
# memory: 128Mi
69+
# requests:
70+
# cpu: 100m
71+
# memory: 128Mi
72+
73+
nodeSelector: {}
74+
75+
tolerations: []
76+
77+
# Default affinity is to spread out over nodes; use this to override.
78+
affinity: {}

0 commit comments

Comments
 (0)