diff --git a/docs/pages/kubernetes-access/helm/reference.mdx b/docs/pages/kubernetes-access/helm/reference.mdx index d0a76b3b4ef14..ec5a03ea8c816 100644 --- a/docs/pages/kubernetes-access/helm/reference.mdx +++ b/docs/pages/kubernetes-access/helm/reference.mdx @@ -1326,6 +1326,79 @@ These labels can then be used with Teleport's RBAC policies to define access rul +## `storage` + +### `storage.enabled` + +| Type | Default value | +| - | - | +| `bool` | `false` | + +Enables the creation of a Kubernetes persistent volume to hold Teleport agent state. + +[Kubernetes reference](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) + + + + ```yaml + storage: + enabled: true + ``` + + + ```bash + --set storage.enabled=true + ``` + + + +### `storage.storageClassName` + +| Type | Default value | +| - | - | +| `string` | `nil` | + +The storage class name the persistent volume should use when creating persistent volume claims. The provided storage class +name needs to exist on the Kubernetes cluster for Teleport to use. + +[Kubernetes reference](https://kubernetes.io/docs/concepts/storage/storage-classes/) + + + + ```yaml + storage: + storageClassName: teleport-storage-class + ``` + + + ```bash + --set storage.storageClassName=teleport-storage-class + ``` + + + +### `storage.requests` + +| Type | Default value | +| - | - | +| `string` | `128Mi` | + +The size of persistent volume to create. + + + + ```yaml + storage: + requests: 128Mi + ``` + + + ```bash + --set storage.requests=128Mi + ``` + + + ## `image` | Type | Default value | @@ -1554,6 +1627,32 @@ Kubernetes affinity to set for pod assignments. +## `nodeSelector` + +| Type | Default value | +| - | - | +| `object` | `{}` | + +`nodeSelector` can be used to add a map of key-value pairs to constrain the nodes the agent pods will run on. + +[Kubernetes reference](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) + + + + ```yaml + nodeSelector: + role: node + region: us-east + ``` + + + ```bash + --set nodeSelector.role=node \ + --set nodeSelector.region=us-east + ``` + + + ## `annotations.config` | Type | Default value | Can be used in `custom` mode? | `teleport.yaml` equivalent | diff --git a/examples/chart/teleport-kube-agent/.lint/node-selector.yaml b/examples/chart/teleport-kube-agent/.lint/node-selector.yaml new file mode 100644 index 0000000000000..a9f3d5c4a9652 --- /dev/null +++ b/examples/chart/teleport-kube-agent/.lint/node-selector.yaml @@ -0,0 +1,5 @@ +authToken: auth-token +proxyAddr: proxy.example.com:3080 +kubeClusterName: test-kube-cluster-name +nodeSelector: + gravitational.io/k8s-role: node diff --git a/examples/chart/teleport-kube-agent/.lint/stateful.yaml b/examples/chart/teleport-kube-agent/.lint/stateful.yaml new file mode 100644 index 0000000000000..5424307ed38b8 --- /dev/null +++ b/examples/chart/teleport-kube-agent/.lint/stateful.yaml @@ -0,0 +1,6 @@ +authToken: auth-token +proxyAddr: proxy.example.com:3080 +kubeClusterName: test-kube-cluster-name +storage: + enabled: true + storageClassName: "aws-gp2" diff --git a/examples/chart/teleport-kube-agent/README.md b/examples/chart/teleport-kube-agent/README.md index 9f68582acf36a..d77dd51fc8846 100644 --- a/examples/chart/teleport-kube-agent/README.md +++ b/examples/chart/teleport-kube-agent/README.md @@ -9,13 +9,16 @@ with an existing Teleport cluster: To use it, you will need: - an existing Teleport cluster (at least proxy and auth services) - a reachable proxy endpoint (`$PROXY_ENDPOINT` e.g. `teleport.example.com:3080` or `teleport.example.com:443`) -- a reachable reverse tunnel port on the proxy (e.g. `teleport.example.com:3024`). The address is automatically retrieved from the Teleport proxy configuration. -- a [static join - token](https://goteleport.com/teleport/docs/admin-guide/#adding-nodes-to-the-cluster) - for this Teleport cluster (`$JOIN_TOKEN`) - - this chart does not currently support dynamic join tokens; please [file an - issue](https://github.com/gravitational/teleport/issues/new?labels=type%3A+feature+request&template=feature_request.md) - if you require support for dynamic tokens +- a reachable reverse tunnel port on the proxy (e.g. `teleport.example.com:3024`). The address is automatically + retrieved from the Teleport proxy configuration. +- either a static or dynamic join token for the Teleport Cluster + - a [static join token](https://goteleport.com/teleport/docs/admin-guide/#adding-nodes-to-the-cluster) + for this Teleport cluster (`$JOIN_TOKEN`) is used by default. + - optionally a [dynamic join token](https://goteleport.com/teleport/docs/admin-guide/#adding-nodes-to-the-cluster) can + be used on Kubernetes clusters that support persistent volumes. Set `storage.enabled=true` and + `storage.storageClassName=` in the helm configuration to use persistent + volumes. + ## Combining roles diff --git a/examples/chart/teleport-kube-agent/templates/deployment.yaml b/examples/chart/teleport-kube-agent/templates/deployment.yaml index dc975359019b0..efc24ef8077ed 100644 --- a/examples/chart/teleport-kube-agent/templates/deployment.yaml +++ b/examples/chart/teleport-kube-agent/templates/deployment.yaml @@ -1,3 +1,8 @@ +# +# Warning to maintainers, any changes to this file that are not specific to the Deployment need to also be duplicated +# in the statefulset.yaml file. +# +{{- if not .Values.storage.enabled }} {{- if .Values.teleportVersionOverride }} {{- $_ := set . "teleportVersion" .Values.teleportVersionOverride }} {{- else }} @@ -65,6 +70,10 @@ spec: {{- toYaml .Values.extraVolumeMounts | nindent 8 }} {{- end }} {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} containers: - name: "teleport" image: "{{ if .Values.enterprise }}{{ .Values.enterpriseImage }}{{ else }}{{ .Values.image }}{{ end }}:{{ .teleportVersion }}" @@ -128,3 +137,4 @@ spec: {{- toYaml .Values.extraVolumes | nindent 6 }} {{- end }} serviceAccountName: {{ .Values.serviceAccountName | default .Release.Name }} +{{- end }} \ No newline at end of file diff --git a/examples/chart/teleport-kube-agent/templates/statefulset.yaml b/examples/chart/teleport-kube-agent/templates/statefulset.yaml new file mode 100644 index 0000000000000..1fcc4f008e599 --- /dev/null +++ b/examples/chart/teleport-kube-agent/templates/statefulset.yaml @@ -0,0 +1,144 @@ +# +# Warning to maintainers, any changes to this file that are not specific to the StatefulSet need to also be duplicated +# in the deployment.yaml file. +# +{{- if .Values.storage.enabled }} +{{- if .Values.teleportVersionOverride }} + {{- $_ := set . "teleportVersion" .Values.teleportVersionOverride }} +{{- else }} + {{- $_ := set . "teleportVersion" .Chart.Version }} +{{- end }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Release.Name }} +spec: + serviceName: {{ .Release.Name }} + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ .Release.Name }} + template: + metadata: + annotations: + # ConfigMap checksum, to recreate the pod on config changes. + checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} +{{- if .Values.annotations.pod }} + {{- toYaml .Values.annotations.pod | nindent 8 }} +{{- end }} + labels: + app: {{ .Release.Name }} + spec: + {{- if .Values.affinity }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: + {{- toYaml .Values.tolerations | nindent 6 }} + {{- end }} +{{- if .Values.initContainers }} + initContainers: {{- toYaml .Values.initContainers | nindent 6 }} + {{- if .Values.resources }} + resources: + {{- toYaml .Values.resources | nindent 10 }} + {{- end }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - all + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 9807 + volumeMounts: + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /etc/teleport-secrets + name: "auth-token" + readOnly: true + - mountPath: /var/lib/teleport + name: "data" + {{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 8 }} + {{- end }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccountName | default .Release.Name }} + {{- if .Values.nodeSelector }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + containers: + - name: "teleport" + image: "{{ if .Values.enterprise }}{{ .Values.enterpriseImage }}{{ else }}{{ .Values.image }}{{ end }}:{{ .teleportVersion }}" + args: + - "--diag-addr=0.0.0.0:3000" + {{- if .Values.insecureSkipProxyTLSVerify }} + - "--insecure" + {{- end }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - all + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 9807 + ports: + - name: diag + containerPort: 3000 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 # wait 5s for agent to start + periodSeconds: 5 # poll health every 5s + failureThreshold: 6 # consider agent unhealthy after 30s (6 * 5s) + readinessProbe: + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 # wait 5s for agent to register + periodSeconds: 5 # poll health every 5s + failureThreshold: 12 # consider agent unhealthy after 60s (12 * 5s) +{{- if .Values.resources }} + resources: + {{- toYaml .Values.resources | nindent 10 }} +{{- end }} + volumeMounts: + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /etc/teleport-secrets + name: "auth-token" + readOnly: true + - mountPath: /var/lib/teleport + name: "{{ .Release.Name }}-teleport-data" +{{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 8 }} +{{- end }} + volumes: + - name: "config" + configMap: + name: {{ .Release.Name }} + - name: "auth-token" + secret: + secretName: {{ .Values.secretName }} +{{- if .Values.extraVolumes }} + {{- toYaml .Values.extraVolumes | nindent 6 }} +{{- end }} + volumeClaimTemplates: + - metadata: + name: "{{ .Release.Name }}-teleport-data" + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.storage.storageClassName }} + resources: + requests: + storage: {{ .Values.storage.requests }} +{{- end }} \ No newline at end of file diff --git a/examples/chart/teleport-kube-agent/values.yaml b/examples/chart/teleport-kube-agent/values.yaml index 8addda419c9df..0f2ce05aa1a34 100644 --- a/examples/chart/teleport-kube-agent/values.yaml +++ b/examples/chart/teleport-kube-agent/values.yaml @@ -57,6 +57,26 @@ podSecurityPolicy: # Labels is a map of key values pairs about this cluster labels: {} +################################################################ +# Values that must be provided if using persistent storage for Teleport state. +# +# Assigning a persistent volume to Teleport agent allows the agent to store its security association with the Teleport +# cluster for re-use when the pod is restarted. Without a persistent storage for this state, every time Teleport agent +# starts it must use the authToken to create a new registration with the cluster. By using the persistent volume the +# authToken can be routinely rotated without breaking agents' ability to restart, as the token is only used on the first +# startup. When persistent volumes are enabled, the agent will be deployed as a StatefulSet instead of a Deployment to +# Kubernetes. +# +# Fields: +# enabled: Set to true to enable the use of StatefulSets and Persistent volumes. +# storageClassName: The name of the kubernetes storage class to use when creating volumes. See https://kubernetes.io/docs/concepts/storage/storage-classes/ +# requests: The size of the volume to request from the persistent storage system +################################################################ +storage: + enabled: false + storageClassName: "" + requests: 128Mi + ################################################################ # Values that you shouldn't need to change. ################################################################ @@ -88,6 +108,10 @@ logLevel: INFO # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity affinity: {} +# nodeSelector to apply for pod assignment +# https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ +nodeSelector: {} + # Kubernetes annotations to apply # https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ annotations: