helm consul toegevoegd ma nie als submodule?

This commit is contained in:
2020-03-09 12:27:10 +01:00
parent 31368e50b2
commit 3432492589
157 changed files with 14508 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
Thank you for installing HashiCorp Consul!
Now that you have deployed Consul, you should look over the docs on using
Consul with Kubernetes available here:
https://www.consul.io/docs/platform/k8s/index.html
Your release is named {{ .Release.Name }}. To learn more about the release, try:
$ helm status {{ .Release.Name }}
$ helm get {{ .Release.Name }}
{{- if (and .Values.global.bootstrapACLs (gt (len .Values.server.extraConfig) 3)) }}
Warning: Defining server extraConfig potentially disrupts the automatic ACL
bootstrapping required settings. This may cause future issues if
there are conflicts.
{{- end }}

View File

@@ -0,0 +1,63 @@
{{/*
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). Supports the legacy fullnameOverride setting
as well as the global.name setting.
*/}}
{{- define "consul.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else if .Values.global.name -}}
{{- .Values.global.name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "consul.chart" -}}
{{- printf "%s-helm" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Expand the name of the chart.
*/}}
{{- define "consul.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Compute the maximum number of unavailable replicas for the PodDisruptionBudget.
This defaults to (n/2)-1 where n is the number of members of the server cluster.
Special case of replica equaling 3 and allowing a minor disruption of 1 otherwise
use the integer value
Add a special case for replicas=1, where it should default to 0 as well.
*/}}
{{- define "consul.pdb.maxUnavailable" -}}
{{- if eq (int .Values.server.replicas) 1 -}}
{{ 0 }}
{{- else if .Values.server.disruptionBudget.maxUnavailable -}}
{{ .Values.server.disruptionBudget.maxUnavailable -}}
{{- else -}}
{{- if eq (int .Values.server.replicas) 3 -}}
{{- 1 -}}
{{- else -}}
{{- sub (div (int .Values.server.replicas) 2) 1 -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Inject extra environment vars in the format key:value, if populated
*/}}
{{- define "consul.extraEnvironmentVars" -}}
{{- if .extraEnvironmentVars -}}
{{- range $key, $value := .extraEnvironmentVars }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,33 @@
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-client
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- if (or .Values.global.enablePodSecurityPolicies .Values.global.bootstrapACLs) }}
rules:
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames:
- {{ template "consul.fullname" . }}-client
verbs:
- use
{{- end }}
{{- if .Values.global.bootstrapACLs }}
- apiGroups: [""]
resources:
- secrets
resourceNames:
- {{ template "consul.fullname" . }}-client-acl-token
verbs:
- get
{{- end }}
{{- else}}
rules: []
{{- end }}
{{- end }}

View File

@@ -0,0 +1,19 @@
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-client
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-client
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-client
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,23 @@
# ConfigMap with extra configuration specified directly to the chart
# for client agents only.
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "consul.fullname" . }}-client-config
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
data:
extra-from-values.json: |-
{{ tpl .Values.client.extraConfig . | trimAll "\"" | indent 4 }}
{{- if (and .Values.connectInject.enabled .Values.connectInject.centralConfig.enabled) }}
central-config.json: |-
{
"enable_central_service_config": true
}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,333 @@
# DaemonSet to run the Consul clients on every node.
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ template "consul.fullname" . }}
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
{{- if .Values.client.updateStrategy }}
updateStrategy:
{{ tpl .Values.client.updateStrategy . | nindent 4 | trim }}
{{- end }}
selector:
matchLabels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: client
hasDNS: "true"
template:
metadata:
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: client
hasDNS: "true"
annotations:
"consul.hashicorp.com/connect-inject": "false"
{{- if .Values.client.annotations }}
{{- tpl .Values.client.annotations . | nindent 8 }}
{{- end }}
spec:
{{- if .Values.client.affinity }}
affinity:
{{ tpl .Values.client.affinity . | nindent 8 | trim }}
{{- end }}
{{- if .Values.client.tolerations }}
tolerations:
{{ tpl .Values.client.tolerations . | nindent 8 | trim }}
{{- end }}
terminationGracePeriodSeconds: 10
serviceAccountName: {{ template "consul.fullname" . }}-client
{{- if .Values.client.priorityClassName }}
priorityClassName: {{ .Values.client.priorityClassName | quote }}
{{- end }}
{{- if .Values.client.dnsPolicy }}
dnsPolicy: {{ .Values.client.dnsPolicy }}
{{- end }}
volumes:
- name: data
{{- if .Values.client.dataDirectoryHostPath }}
hostPath:
path: {{ .Values.client.dataDirectoryHostPath }}
type: DirectoryOrCreate
{{- else }}
emptyDir: {}
{{- end }}
- name: config
configMap:
name: {{ template "consul.fullname" . }}-client-config
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
- name: consul-ca-key
secret:
{{- if .Values.global.tls.caKey.secretName }}
secretName: {{ .Values.global.tls.caKey.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-key
{{- end }}
items:
- key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }}
path: tls.key
- name: tls-client-cert
emptyDir:
# We're using tmpfs here so that
# client certs are not written to disk
medium: "Memory"
{{- end }}
{{- range .Values.client.extraVolumes }}
- name: userconfig-{{ .name }}
{{ .type }}:
{{- if (eq .type "configMap") }}
name: {{ .name }}
{{- else if (eq .type "secret") }}
secretName: {{ .name }}
{{- end }}
{{- end }}
{{- if .Values.global.bootstrapACLs }}
- name: aclconfig
emptyDir: {}
{{- end }}
containers:
- name: consul
image: "{{ default .Values.global.image .Values.client.image }}"
env:
- name: ADVERTISE_IP
valueFrom:
fieldRef:
{{- if not .Values.client.exposeGossipPorts }}
fieldPath: status.podIP
{{- else }}
# Clients will be exposed on their node's hostPort for external-to-k8s communication,
# so they need to advertise their host ip instead of their pod ip.
fieldPath: status.hostIP
{{- end }}
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: NODE
valueFrom:
fieldRef:
fieldPath: spec.nodeName
{{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }}
- name: GOSSIP_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.global.gossipEncryption.secretName }}
key: {{ .Values.global.gossipEncryption.secretKey }}
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: CONSUL_HTTP_ADDR
value: https://localhost:8501
- name: CONSUL_CACERT
value: /consul/tls/ca/tls.crt
{{- end }}
{{- include "consul.extraEnvironmentVars" .Values.client | nindent 12 }}
command:
- "/bin/sh"
- "-ec"
- |
CONSUL_FULLNAME="{{template "consul.fullname" . }}"
exec /bin/consul agent \
-node="${NODE}" \
-advertise="${ADVERTISE_IP}" \
-bind=0.0.0.0 \
-client=0.0.0.0 \
-node-meta=pod-name:${HOSTNAME} \
-hcl='leave_on_terminate = true' \
{{- if .Values.global.tls.enabled }}
-hcl='ca_file = "/consul/tls/ca/tls.crt"' \
-hcl='cert_file = "/consul/tls/client/tls.crt"' \
-hcl='key_file = "/consul/tls/client/tls.key"' \
{{- if .Values.global.tls.verify }}
-hcl='verify_incoming_rpc = true' \
-hcl='verify_outgoing = true' \
-hcl='verify_server_hostname = true' \
{{- end }}
-hcl='ports { https = 8501 }' \
{{- if .Values.global.tls.httpsOnly }}
-hcl='ports { http = -1 }' \
{{- end }}
{{- end }}
{{- if .Values.client.grpc }}
-hcl='ports { grpc = 8502 }' \
{{- end }}
-config-dir=/consul/config \
{{- range .Values.client.extraVolumes }}
{{- if .load }}
-config-dir=/consul/userconfig/{{ .name }} \
{{- end }}
{{- end }}
{{- if .Values.global.bootstrapACLs}}
-config-dir=/consul/aclconfig \
{{- end }}
-datacenter={{ .Values.global.datacenter }} \
-data-dir=/consul/data \
{{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }}
-encrypt="${GOSSIP_KEY}" \
{{- end }}
{{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }}
{{- range $value := .Values.client.join }}
-retry-join="{{ $value }}" \
{{- end }}
{{- else }}
{{- if .Values.server.enabled }}
{{- range $index := until (.Values.server.replicas | int) }}
-retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \
{{- end }}
{{- end }}
{{- end }}
-domain={{ .Values.global.domain }}
volumeMounts:
- name: data
mountPath: /consul/data
- name: config
mountPath: /consul/config
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
mountPath: /consul/tls/ca
readOnly: true
- name: tls-client-cert
mountPath: /consul/tls/client
readOnly: true
{{- end }}
{{- range .Values.client.extraVolumes }}
- name: userconfig-{{ .name }}
readOnly: true
mountPath: /consul/userconfig/{{ .name }}
{{- end }}
{{- if .Values.global.bootstrapACLs}}
- name: aclconfig
mountPath: /consul/aclconfig
{{- end }}
ports:
{{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }}
- containerPort: 8500
hostPort: 8500
name: http
{{- end }}
{{- if .Values.global.tls.enabled }}
- containerPort: 8501
hostPort: 8501
name: https
{{- end }}
- containerPort: 8502
hostPort: 8502
name: grpc
- containerPort: 8301
{{- if .Values.client.exposeGossipPorts }}
hostPort: 8301
{{- end }}
protocol: "TCP"
name: serflan-tcp
- containerPort: 8301
{{- if .Values.client.exposeGossipPorts }}
hostPort: 8301
{{- end }}
protocol: "UDP"
name: serflan-udp
- containerPort: 8302
name: serfwan
- containerPort: 8300
name: server
- containerPort: 8600
name: dns-tcp
protocol: "TCP"
- containerPort: 8600
name: dns-udp
protocol: "UDP"
readinessProbe:
# NOTE(mitchellh): when our HTTP status endpoints support the
# proper status codes, we should switch to that. This is temporary.
exec:
command:
- "/bin/sh"
- "-ec"
- |
{{- if .Values.global.tls.enabled }}
curl \
--cacert /consul/tls/ca/tls.crt \
https://127.0.0.1:8501/v1/status/leader \
{{- else }}
curl http://127.0.0.1:8500/v1/status/leader \
{{- end }}
2>/dev/null | grep -E '".+"'
{{- if .Values.client.resources }}
resources:
{{ tpl .Values.client.resources . | nindent 12 | trim }}
{{- end }}
{{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled) }}
initContainers:
{{- if .Values.global.bootstrapACLs }}
- name: client-acl-init
image: {{ .Values.global.imageK8S }}
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s acl-init \
-secret-name="{{ template "consul.fullname" . }}-client-acl-token" \
-k8s-namespace={{ .Release.Namespace }} \
-init-type="client"
volumeMounts:
- name: aclconfig
mountPath: /consul/aclconfig
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: client-tls-init
image: "{{ default .Values.global.image .Values.client.image }}"
env:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
command:
- "/bin/sh"
- "-ec"
- |
cd /consul/tls/client
consul tls cert create -client \
-additional-ipaddress=${HOST_IP} \
-dc={{ .Values.global.datacenter }} \
-domain={{ .Values.global.domain }} \
-ca=/consul/tls/ca/cert/tls.crt \
-key=/consul/tls/ca/key/tls.key
mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0.pem tls.crt
mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0-key.pem tls.key
volumeMounts:
- name: tls-client-cert
mountPath: /consul/tls/client
- name: consul-ca-cert
mountPath: /consul/tls/ca/cert
readOnly: true
- name: consul-ca-key
mountPath: /consul/tls/ca/key
readOnly: true
{{- end }}
{{- end }}
{{- if .Values.client.nodeSelector }}
nodeSelector:
{{ tpl .Values.client.nodeSelector . | indent 8 | trim }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,66 @@
{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled))) }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-client
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
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:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
{{- if .Values.client.dataDirectoryHostPath }}
- 'hostPath'
{{- end }}
hostNetwork: false
hostPorts:
{{- if (not (and .Values.global.tls.enabled .Values.global.tls.httpsOnly)) }}
# HTTP Port
- min: 8500
max: 8500
{{- end }}
{{- if .Values.global.tls.enabled }}
# HTTPS port
- min: 8501
max: 8501
{{- end }}
{{- if .Values.client.grpc }}
# gRPC Port
- min: 8502
max: 8502
{{- end }}
{{- if .Values.client.exposeGossipPorts }}
- min: 8301
max: 8301
{{- end }}
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- if .Values.client.dataDirectoryHostPath }}
allowedHostPaths:
- pathPrefix: {{ .Values.client.dataDirectoryHostPath | quote }}
readOnly: false
{{- end }}
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-client
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}

View File

@@ -0,0 +1,36 @@
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.client.snapshotAgent.enabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-snapshot-agent
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- if not (or .Values.global.enablePodSecurityPolicies .Values.global.bootstrapACLs) }}
rules: []
{{- else }}
rules:
{{- end }}
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames:
- {{ template "consul.fullname" . }}-snapshot-agent
verbs:
- use
{{- end }}
{{- if .Values.global.bootstrapACLs }}
- apiGroups: [""]
resources:
- secrets
resourceNames:
- {{ template "consul.fullname" . }}-client-snapshot-agent-acl-token
verbs:
- get
{{- end }}
{{- else }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,21 @@
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.client.snapshotAgent.enabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-snapshot-agent
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-snapshot-agent
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-snapshot-agent
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,140 @@
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.client.snapshotAgent.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "consul.fullname" . }}-snapshot-agent
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
replicas: {{ .Values.client.snapshotAgent.replicas }}
selector:
matchLabels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: client-snapshot-agent
template:
metadata:
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: client-snapshot-agent
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
{{- if .Values.client.tolerations }}
tolerations:
{{ tpl .Values.client.tolerations . | nindent 8 | trim }}
{{- end }}
terminationGracePeriodSeconds: 10
serviceAccountName: {{ template "consul.fullname" . }}-snapshot-agent
{{- if .Values.client.priorityClassName }}
priorityClassName: {{ .Values.client.priorityClassName | quote }}
{{- end }}
{{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey)) }}
volumes:
{{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }}
- name: snapshot-config
secret:
secretName: {{ .Values.client.snapshotAgent.configSecret.secretName }}
items:
- key: {{ .Values.client.snapshotAgent.configSecret.secretKey }}
path: snapshot-config.json
{{- end }}
{{- if .Values.global.bootstrapACLs }}
- name: aclconfig
emptyDir: {}
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
{{- end }}
{{- end }}
containers:
- name: consul-snapshot-agent
image: "{{ default .Values.global.image .Values.client.image }}"
env:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
{{- if .Values.global.tls.enabled }}
- name: CONSUL_HTTP_ADDR
value: https://$(HOST_IP):8501
- name: CONSUL_CACERT
value: /consul/tls/ca/tls.crt
{{- else }}
- name: CONSUL_HTTP_ADDR
value: http://$(HOST_IP):8500
{{- end }}
{{- if .Values.global.bootstrapACLs }}
- name: CONSUL_HTTP_TOKEN
valueFrom:
secretKeyRef:
name: "{{ template "consul.fullname" . }}-client-snapshot-agent-acl-token"
key: "token"
{{- end}}
command:
- "/bin/sh"
- "-ec"
- |
exec /bin/consul snapshot agent \
{{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }}
-config-dir=/consul/config \
{{- end }}
{{- if .Values.global.bootstrapACLs}}
-config-dir=/consul/aclconfig \
{{- end }}
{{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) ) }}
volumeMounts:
{{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }}
- name: snapshot-config
readOnly: true
mountPath: /consul/config
{{- end }}
{{- if .Values.global.bootstrapACLs}}
- name: aclconfig
mountPath: /consul/aclconfig
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
mountPath: /consul/tls/ca
readOnly: true
{{- end }}
{{- end }}
{{- if .Values.global.bootstrapACLs }}
initContainers:
- name: client-snapshot-agent-acl-init
image: {{ .Values.global.imageK8S }}
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s acl-init \
-secret-name="{{ template "consul.fullname" . }}-client-snapshot-agent-acl-token" \
-k8s-namespace={{ .Release.Namespace }} \
-init-type="sync"
volumeMounts:
- name: aclconfig
mountPath: /consul/aclconfig
{{- end }}
{{- if .Values.client.nodeSelector }}
nodeSelector:
{{ tpl .Values.client.nodeSelector . | indent 8 | trim }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,40 @@
{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled))) }}
{{- if .Values.client.snapshotAgent.enabled }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-snapshot-agent
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
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:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.client.snapshotAgent.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-snapshot-agent
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,19 @@
{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-authmethod-role
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
rules:
- apiGroups: [""]
resources:
- serviceaccounts
verbs:
- get
{{- end }}
{{- end }}

View File

@@ -0,0 +1,39 @@
{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-authmethod-authdelegator-role-binding
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: "system:auth-delegator"
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-connect-injector-authmethod-svc-account
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-authmethod-serviceaccount-role-binding
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-connect-injector-authmethod-role
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-connect-injector-authmethod-svc-account
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-authmethod-svc-account
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,37 @@
# The ClusterRole to enable the Connect injector to get, list, watch and patch MutatingWebhookConfiguration.
{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-webhook
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
rules:
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["mutatingwebhookconfigurations"]
verbs:
- "get"
- "list"
- "watch"
- "patch"
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames:
- {{ template "consul.fullname" . }}-connect-injector-webhook
verbs:
- use
{{- end }}
{{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }}
- apiGroups: [""]
resources:
- secrets
resourceNames:
- {{ template "consul.fullname" . }}-connect-inject-acl-token
verbs:
- get
{{- end }}
{{- end }}

View File

@@ -0,0 +1,19 @@
{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-webhook-admin-role-binding
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-connect-injector-webhook
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,200 @@
# The deployment for running the Connect sidecar injector
{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
{{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled for connect injection" }}{{ end }}
{{- if not .Values.client.grpc }}{{ fail "client.grpc must be true for connect injection" }}{{ end }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-webhook-deployment
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: connect-injector
template:
metadata:
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: connect-injector
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
{{- if not .Values.connectInject.certs.secretName }}
serviceAccountName: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account
{{- end }}
containers:
- name: sidecar-injector
image: "{{ default .Values.global.imageK8S .Values.connectInject.image }}"
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- /* A Consul client and ACL token is only necessary for the connect injector if namespaces are enabled */}}
{{- if .Values.global.enableConsulNamespaces }}
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
{{- if (and .Values.connectInject.aclInjectToken.secretName .Values.connectInject.aclInjectToken.secretKey) }}
- name: CONSUL_HTTP_TOKEN
valueFrom:
secretKeyRef:
name: {{ .Values.connectInject.aclInjectToken.secretName }}
key: {{ .Values.connectInject.aclInjectToken.secretKey }}
{{- else if .Values.global.bootstrapACLs }}
- name: CONSUL_HTTP_TOKEN
valueFrom:
secretKeyRef:
name: "{{ template "consul.fullname" . }}-connect-inject-acl-token"
key: "token"
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: CONSUL_HTTP_ADDR
value: https://$(HOST_IP):8501
- name: CONSUL_CACERT
value: /consul/tls/ca/tls.crt
{{- else }}
- name: CONSUL_HTTP_ADDR
value: http://$(HOST_IP):8500
{{- end }}
{{- end }}
command:
- "/bin/sh"
- "-ec"
- |
CONSUL_FULLNAME="{{template "consul.fullname" . }}"
consul-k8s inject-connect \
-default-inject={{ .Values.connectInject.default }} \
-consul-image="{{ default .Values.global.image .Values.connectInject.imageConsul }}" \
{{ if .Values.connectInject.imageEnvoy -}}
-envoy-image="{{ .Values.connectInject.imageEnvoy }}" \
{{ end -}}
-consul-k8s-image="{{ default .Values.global.imageK8S .Values.connectInject.image }}" \
-listen=:8080 \
{{- if .Values.connectInject.overrideAuthMethodName }}
-acl-auth-method="{{ .Values.connectInject.overrideAuthMethodName }}" \
{{- else if .Values.global.bootstrapACLs }}
-acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \
{{- end }}
{{- if .Values.global.tls.enabled }}
-consul-ca-cert=/consul/tls/ca/tls.crt \
{{- end }}
{{- if .Values.connectInject.centralConfig.enabled }}
-enable-central-config=true \
{{- end }}
{{- if (and .Values.connectInject.centralConfig.enabled .Values.connectInject.centralConfig.defaultProtocol) }}
-default-protocol="{{ .Values.connectInject.centralConfig.defaultProtocol }}" \
{{- end }}
{{- range $value := .Values.connectInject.k8sAllowNamespaces }}
-allow-k8s-namespace="{{ $value }}" \
{{- end }}
{{- range $value := .Values.connectInject.k8sDenyNamespaces }}
-deny-k8s-namespace="{{ $value }}" \
{{- end }}
{{- if .Values.global.enableConsulNamespaces }}
-enable-namespaces=true \
{{- if .Values.connectInject.consulNamespaces.consulDestinationNamespace }}
-consul-destination-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} \
{{- end }}
{{- if .Values.connectInject.consulNamespaces.mirroringK8S }}
-enable-k8s-namespace-mirroring=true \
{{- if .Values.connectInject.consulNamespaces.mirroringK8SPrefix }}
-k8s-namespace-mirroring-prefix={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} \
{{- end }}
{{- end }}
{{- if .Values.global.bootstrapACLs }}
-consul-cross-namespace-acl-policy=cross-namespace-policy \
{{- end }}
{{- end }}
{{- if .Values.connectInject.certs.secretName }}
-tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} \
-tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }}
{{- else }}
-tls-auto=${CONSUL_FULLNAME}-connect-injector-cfg \
-tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc
{{- end }}
livenessProbe:
httpGet:
path: /health/ready
port: 8080
scheme: HTTPS
failureThreshold: 2
initialDelaySeconds: 1
periodSeconds: 2
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health/ready
port: 8080
scheme: HTTPS
failureThreshold: 2
initialDelaySeconds: 2
periodSeconds: 2
successThreshold: 1
timeoutSeconds: 5
{{- if (or .Values.connectInject.certs.secretName .Values.global.tls.enabled) }}
volumeMounts:
{{- if .Values.connectInject.certs.secretName }}
- name: certs
mountPath: /etc/connect-injector/certs
readOnly: true
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
mountPath: /consul/tls/ca
readOnly: true
{{- end }}
{{- end }}
{{- if (or .Values.connectInject.certs.secretName .Values.global.tls.enabled) }}
volumes:
{{- if .Values.connectInject.certs.secretName }}
- name: certs
secret:
secretName: {{ .Values.connectInject.certs.secretName }}
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
{{- end }}
{{- end }}
{{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }}
initContainers:
- name: injector-acl-init
image: {{ .Values.global.imageK8S }}
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s acl-init \
-secret-name="{{ template "consul.fullname" . }}-connect-inject-acl-token" \
-k8s-namespace={{ .Release.Namespace }} \
-init-type="sync"
{{- end }}
{{- if .Values.connectInject.nodeSelector }}
nodeSelector:
{{ tpl .Values.connectInject.nodeSelector . | indent 8 | trim }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,30 @@
# The MutatingWebhookConfiguration to enable the Connect injector.
{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-cfg
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
webhooks:
- name: {{ template "consul.fullname" . }}-connect-injector.consul.hashicorp.com
clientConfig:
service:
name: {{ template "consul.fullname" . }}-connect-injector-svc
namespace: {{ .Release.Namespace }}
path: "/mutate"
caBundle: {{ .Values.connectInject.certs.caBundle | quote }}
rules:
- operations: [ "CREATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
{{- if .Values.connectInject.namespaceSelector }}
namespaceSelector:
{{ tpl .Values.connectInject.namespaceSelector . | indent 6 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,38 @@
{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled))) }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-webhook
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
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:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}

View File

@@ -0,0 +1,22 @@
# The service for the Connect sidecar injector
{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-svc
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
ports:
- port: 443
targetPort: 8080
selector:
app: {{ template "consul.name" . }}
release: "{{ .Release.Name }}"
component: connect-injector
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}

View File

@@ -0,0 +1,34 @@
# Service for Consul DNS.
{{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "consul.fullname" . }}-dns
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- if .Values.dns.annotations }}
annotations:
{{ tpl .Values.dns.annotations . | nindent 4 | trim }}
{{- end }}
spec:
{{- if .Values.dns.clusterIP }}
clusterIP: {{ .Values.dns.clusterIP }}
{{- end }}
ports:
- name: dns-tcp
port: 53
protocol: "TCP"
targetPort: dns-tcp
- name: dns-udp
port: 53
protocol: "UDP"
targetPort: dns-udp
selector:
app: {{ template "consul.name" . }}
release: "{{ .Release.Name }}"
hasDNS: "true"
{{- end }}

View File

@@ -0,0 +1,35 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-enterprise-license
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- if or .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies }}
rules:
{{- if .Values.global.bootstrapACLs }}
- apiGroups: [""]
resources:
- secrets
resourceNames:
- {{ template "consul.fullname" . }}-enterprise-license-acl-token
verbs:
- get
{{- end }}
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames:
- {{ template "consul.fullname" . }}-enterprise-license
verbs:
- use
{{- end }}
{{- else }}
rules: []
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,21 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-enterprise-license
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-enterprise-license
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-enterprise-license
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,116 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "consul.fullname" . }}-license
labels:
app.kubernetes.io/managed-by: {{.Release.Service | quote }}
app.kubernetes.io/instance: {{.Release.Name | quote }}
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": post-install
"helm.sh/hook-weight": "100"
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
metadata:
name: {{ template "consul.fullname" . }}-license
labels:
app.kubernetes.io/managed-by: {{.Release.Service | quote }}
app.kubernetes.io/instance: {{.Release.Name | quote }}
helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: license
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
restartPolicy: Never
serviceAccountName: {{ template "consul.fullname" . }}-enterprise-license
{{- if .Values.global.tls.enabled }}
volumes:
- name: consul-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
{{- end }}
containers:
- name: apply-enterprise-license
image: "{{ default .Values.global.image .Values.server.image }}"
env:
- name: ENTERPRISE_LICENSE
valueFrom:
secretKeyRef:
name: {{ .Values.server.enterpriseLicense.secretName }}
key: {{ .Values.server.enterpriseLicense.secretKey }}
- name: CONSUL_HTTP_ADDR
{{- if .Values.global.tls.enabled }}
value: https://{{ template "consul.fullname" . }}-server:8501
{{- else }}
value: http://{{ template "consul.fullname" . }}-server:8500
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: CONSUL_CACERT
value: /consul/tls/ca/tls.crt
{{- end}}
{{- if .Values.global.bootstrapACLs }}
- name: CONSUL_HTTP_TOKEN
valueFrom:
secretKeyRef:
name: "{{ template "consul.fullname" . }}-enterprise-license-acl-token"
key: "token"
{{- end}}
command:
- "/bin/sh"
- "-c"
- |
# Create a script that we can execute with the timeout command.
cat > apply-license.sh << 'EOF'
#!/bin/sh
while true; do
echo "Applying license..."
if consul license put "${ENTERPRISE_LICENSE}"; then
echo "License applied successfully"
break
fi
echo "Retrying in 2s..."
sleep 2
done
EOF
chmod +x ./apply-license.sh
# Time out after 20 minutes.
timeout -t 1200 ./apply-license.sh
{{- if .Values.global.tls.enabled }}
volumeMounts:
- name: consul-ca-cert
mountPath: /consul/tls/ca
readOnly: true
{{- end }}
{{- if .Values.global.bootstrapACLs }}
initContainers:
- name: ent-license-acl-init
image: {{ .Values.global.imageK8S }}
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s acl-init \
-secret-name="{{ template "consul.fullname" . }}-enterprise-license-acl-token" \
-k8s-namespace={{ .Release.Namespace }} \
-init-type="sync"
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,37 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }}
{{- if .Values.global.enablePodSecurityPolicies }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-enterprise-license
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
privileged: false
# Allow core volume types.
volumes:
- 'secret'
allowPrivilegeEscalation: false
# This is redundant with non-root + disallow privilege escalation,
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-enterprise-license
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,34 @@
{{- if .Values.meshGateway.enabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-mesh-gateway
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: mesh-gateway
{{- if or .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies }}
rules:
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames:
- {{ template "consul.fullname" . }}-mesh-gateway
verbs:
- use
{{- end }}
{{- if .Values.global.bootstrapACLs }}
- apiGroups: [""]
resources:
- secrets
resourceNames:
- {{ template "consul.fullname" . }}-mesh-gateway-acl-token
verbs:
- get
{{- end }}
{{- else }}
rules: []
{{- end }}
{{- end }}

View File

@@ -0,0 +1,20 @@
{{- if .Values.meshGateway.enabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-mesh-gateway
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: mesh-gateway
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-mesh-gateway
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-mesh-gateway
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,204 @@
{{- if .Values.meshGateway.enabled }}
{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}}
{{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}}
{{- /* The below test checks if clients are disabled (and if so, fails). We use the conditional from other client files and prepend 'not' */ -}}
{{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled" }}{{ end -}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "consul.fullname" . }}-mesh-gateway
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: mesh-gateway
spec:
replicas: {{ .Values.meshGateway.replicas }}
selector:
matchLabels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: mesh-gateway
template:
metadata:
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: mesh-gateway
annotations:
"consul.hashicorp.com/connect-inject": "false"
{{- if .Values.meshGateway.annotations }}
{{- tpl .Values.meshGateway.annotations . | nindent 8 }}
{{- end }}
spec:
{{- if .Values.meshGateway.affinity }}
affinity:
{{ tpl .Values.meshGateway.affinity . | nindent 8 | trim }}
{{- end }}
{{- if .Values.meshGateway.tolerations }}
tolerations:
{{ tpl .Values.meshGateway.tolerations . | nindent 8 | trim }}
{{- end }}
terminationGracePeriodSeconds: 10
serviceAccountName: {{ template "consul.fullname" . }}-mesh-gateway
volumes:
- name: consul-bin
emptyDir: {}
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
{{- end }}
{{- if .Values.meshGateway.hostNetwork }}
hostNetwork: {{ .Values.meshGateway.hostNetwork }}
{{- end }}
{{- if .Values.meshGateway.dnsPolicy }}
dnsPolicy: {{ .Values.meshGateway.dnsPolicy }}
{{- end }}
initContainers:
# We use the Envoy image as our base image so we use an init container to
# copy the Consul binary to a shared directory that can be used when
# starting Envoy.
- name: copy-consul-bin
image: {{ .Values.global.image | quote }}
command:
- cp
- /bin/consul
- /consul-bin/consul
volumeMounts:
- name: consul-bin
mountPath: /consul-bin
{{- if .Values.global.bootstrapACLs }}
# Wait for secret containing acl token to be ready.
# Doesn't do anything with it but when the main container starts we
# know that it's been created.
- name: mesh-gateway-acl-init
image: {{ .Values.global.imageK8S }}
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s acl-init \
-secret-name="{{ template "consul.fullname" . }}-mesh-gateway-acl-token" \
-k8s-namespace={{ .Release.Namespace }} \
-init-type="sync"
{{- end }}
containers:
- name: mesh-gateway
image: {{ .Values.meshGateway.imageEnvoy | quote }}
{{- if .Values.meshGateway.resources }}
resources:
{{ tpl .Values.meshGateway.resources . | nindent 12 | trim }}
{{- end }}
volumeMounts:
- name: consul-bin
mountPath: /consul-bin
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
mountPath: /consul/tls/ca
readOnly: true
{{- end }}
env:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
{{- if .Values.meshGateway.wanAddress.useNodeName }}
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
{{- end }}
{{- if .Values.global.bootstrapACLs }}
- name: CONSUL_HTTP_TOKEN
valueFrom:
secretKeyRef:
name: "{{ template "consul.fullname" . }}-mesh-gateway-acl-token"
key: "token"
{{- end}}
{{- if .Values.global.tls.enabled }}
- name: CONSUL_HTTP_ADDR
value: https://$(HOST_IP):8501
- name: CONSUL_GRPC_ADDR
value: https://$(HOST_IP):8502
- name: CONSUL_CACERT
value: /consul/tls/ca/tls.crt
{{- else }}
- name: CONSUL_HTTP_ADDR
value: http://$(HOST_IP):8500
- name: CONSUL_GRPC_ADDR
value: $(HOST_IP):8502
{{- end }}
command:
# /bin/sh -c is needed so we can use the pod-specific environment
# variables.
- "/bin/sh"
- "-ec"
- |
exec /consul-bin/consul connect envoy \
-mesh-gateway \
-register \
-address="${POD_IP}:{{ .Values.meshGateway.containerPort }}" \
{{- if .Values.meshGateway.wanAddress.host }}
-wan-address="{{ .Values.meshGateway.wanAddress.host }}:{{ .Values.meshGateway.wanAddress.port }}" \
{{- else if .Values.meshGateway.wanAddress.useNodeName }}
-wan-address="${NODE_NAME}:{{ .Values.meshGateway.wanAddress.port }}" \
{{- else if .Values.meshGateway.wanAddress.useNodeIP }}
-wan-address="${HOST_IP}:{{ .Values.meshGateway.wanAddress.port }}" \
{{- end }}
{{- if and .Values.meshGateway.consulServiceName }}
{{- if and .Values.global.bootstrapACLs (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end }}
-service={{ .Values.meshGateway.consulServiceName | quote }} \
{{- end }}
{{- if .Values.meshGateway.enableHealthChecks }}
livenessProbe:
tcpSocket:
port: {{ .Values.meshGateway.containerPort }}
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
tcpSocket:
port: {{ .Values.meshGateway.containerPort }}
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
{{- end }}
ports:
- name: gateway
containerPort: {{ .Values.meshGateway.containerPort }}
{{- if .Values.meshGateway.hostPort }}
hostPort: {{ .Values.meshGateway.hostPort }}
{{- end }}
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-ec", "/consul-bin/consul services deregister -id=\"{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}\""]
{{- if .Values.meshGateway.priorityClassName }}
priorityClassName: {{ .Values.meshGateway.priorityClassName | quote }}
{{- end }}
{{- if .Values.meshGateway.nodeSelector }}
nodeSelector:
{{ tpl .Values.meshGateway.nodeSelector . | indent 8 | trim }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,39 @@
{{- if and .Values.global.enablePodSecurityPolicies .Values.meshGateway.enabled }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-mesh-gateway
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: mesh-gateway
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:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}

View File

@@ -0,0 +1,33 @@
{{- if and .Values.meshGateway.enabled .Values.meshGateway.service.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "consul.fullname" . }}-mesh-gateway
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: mesh-gateway
{{- if .Values.meshGateway.service.annotations }}
annotations:
{{ tpl .Values.meshGateway.service.annotations . | nindent 4 | trim }}
{{- end }}
spec:
selector:
app: {{ template "consul.name" . }}
release: "{{ .Release.Name }}"
component: mesh-gateway
ports:
- name: gateway
port: {{ .Values.meshGateway.service.port }}
targetPort: {{ .Values.meshGateway.containerPort }}
{{- if .Values.meshGateway.service.nodePort }}
nodePort: {{ .Values.meshGateway.service.nodePort }}
{{- end}}
type: {{ .Values.meshGateway.service.type }}
{{- if .Values.meshGateway.service.additionalSpec }}
{{ tpl .Values.meshGateway.service.additionalSpec . | nindent 2 | trim }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,13 @@
{{- if .Values.meshGateway.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-mesh-gateway
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: mesh-gateway
{{- end }}

View File

@@ -0,0 +1,25 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init-cleanup
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
rules:
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "delete"]
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames:
- {{ template "consul.fullname" . }}-server-acl-init-cleanup
verbs:
- use
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,21 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init-cleanup
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-server-acl-init-cleanup
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-server-acl-init-cleanup
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,56 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
{{- /* See reason for this in server-acl-init-job.yaml */ -}}
{{- if eq (int .Values.server.updatePartition) 0 }}
# This job deletes the server-acl-init job once it completes successfully.
# It runs as a helm hook because it only needs to run when the server-acl-init
# Job gets recreated which only happens during an install or upgrade.
# We also utilize the helm hook-delete-policy to delete this job itself.
# We want to delete the server-acl-init job because once it runs successfully
# it's not needed and also because if it stays around then when users run
# helm upgrade with values that change the spec of the job, Kubernetes errors
# because the job spec is immutable. If the job is deleted, then a new job
# is created and there's no error.
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init-cleanup
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "0"
# If the hook fails then all that happens is we didn't delete the job.
# There's no reason for *this* job to stay around in that case so delete
# regardless of success.
"helm.sh/hook-delete-policy": hook-succeeded,hook-failed
spec:
template:
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init-cleanup
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: server-acl-init-cleanup
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
restartPolicy: Never
serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init-cleanup
containers:
- name: server-acl-init-cleanup
image: {{ .Values.global.imageK8S }}
command:
- consul-k8s
args:
- delete-completed-job
- -k8s-namespace={{ .Release.Namespace }}
- {{ template "consul.fullname" . }}-server-acl-init
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,37 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
{{- if .Values.global.enablePodSecurityPolicies }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init-cleanup
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
privileged: false
# Allow core volume types.
volumes:
- 'secret'
allowPrivilegeEscalation: false
# This is redundant with non-root + disallow privilege escalation,
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init-cleanup
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,50 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
rules:
- apiGroups: [""]
resources:
- pods
verbs:
- list
- apiGroups: [""]
resources:
- secrets
verbs:
- create
- get
- apiGroups: ["apps"]
resources:
- statefulsets
verbs:
- get
{{- if .Values.connectInject.enabled }}
- apiGroups: [""]
resources:
- serviceaccounts
verbs:
- get
- apiGroups: [""]
resources:
- services
verbs:
- get
{{- end }}
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames:
- {{ template "consul.fullname" . }}-server-acl-init
verbs:
- use
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,21 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-server-acl-init
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-server-acl-init
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,130 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
{{- /* We don't render this job when server.updatePartition > 0 because that
means a server rollout is in progress and this job won't complete unless
the rollout is finished (which won't happen until the partition is 0).
If we ran it in this case, then the job would not complete which would cause
the server-acl-init-cleanup hook to run indefinitely which would cause the
helm upgrade command to hang.
*/ -}}
{{- if eq (int .Values.server.updatePartition) 0 }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
template:
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: server-acl-init
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
restartPolicy: Never
serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init
{{- if .Values.global.tls.enabled }}
volumes:
- name: consul-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
{{- end }}
containers:
- name: post-install-job
image: {{ .Values.global.imageK8S }}
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- if .Values.global.tls.enabled }}
volumeMounts:
- name: consul-ca-cert
mountPath: /consul/tls/ca
readOnly: true
{{- end }}
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s server-acl-init \
-server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \
-resource-prefix={{ template "consul.fullname" . }} \
-k8s-namespace={{ .Release.Namespace }} \
{{- if .Values.global.tls.enabled }}
-use-https \
-consul-ca-cert=/consul/tls/ca/tls.crt \
-consul-tls-server-name=server.{{ .Values.global.datacenter }}.{{ .Values.global.domain }} \
{{- end }}
{{- if .Values.syncCatalog.enabled }}
-create-sync-token=true \
{{- end }}
{{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.global.enabled)) }}
-allow-dns=true \
{{- end }}
{{- if .Values.connectInject.enabled }}
-create-inject-auth-method=true \
{{- end }}
{{- if .Values.meshGateway.enabled }}
-create-mesh-gateway-token=true \
{{- end }}
{{- if .Values.connectInject.aclBindingRuleSelector }}
-acl-binding-rule-selector={{ .Values.connectInject.aclBindingRuleSelector }} \
{{- end }}
{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }}
-create-enterprise-license-token=true \
{{- end }}
{{- if .Values.client.snapshotAgent.enabled }}
-create-snapshot-agent-token=true \
{{- end }}
{{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
-create-client-token=false \
{{- end }}
{{- if .Values.global.enableConsulNamespaces }}
-enable-namespaces=true \
{{- /* syncCatalog must be enabled to set sync flags */}}
{{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }}
-consul-sync-destination-namespace={{ .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} \
{{- end }}
{{- if .Values.syncCatalog.consulNamespaces.mirroringK8S }}
-enable-sync-k8s-namespace-mirroring=true \
{{- if .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }}
-sync-k8s-namespace-mirroring-prefix={{ .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} \
{{- end }}
{{- end }}
{{- end }}
{{- /* connectInject must be enabled to set inject flags */}}
{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }}
-create-inject-namespace-token=true \
{{- if .Values.connectInject.consulNamespaces.consulDestinationNamespace }}
-consul-inject-destination-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} \
{{- end }}
{{- if .Values.connectInject.consulNamespaces.mirroringK8S }}
-enable-inject-k8s-namespace-mirroring=true \
{{- if .Values.connectInject.consulNamespaces.mirroringK8SPrefix }}
-inject-k8s-namespace-mirroring-prefix={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} \
{{- end }}
{{- end }}
{{- end }}
{{- end }}
-expected-replicas={{ .Values.server.replicas }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,37 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
{{- if .Values.global.enablePodSecurityPolicies }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
privileged: false
# Allow core volume types.
volumes:
- 'secret'
allowPrivilegeEscalation: false
# This is redundant with non-root + disallow privilege escalation,
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.bootstrapACLs }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-server-acl-init
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,22 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-server
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- if .Values.global.enablePodSecurityPolicies }}
rules:
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames:
- {{ template "consul.fullname" . }}-server
verbs:
- use
{{- else }}
rules: []
{{- end }}
{{- end }}

View File

@@ -0,0 +1,19 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-server
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-server
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-server
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,68 @@
# StatefulSet to run the actual Consul server cluster.
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "consul.fullname" . }}-server-config
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
data:
extra-from-values.json: |-
{{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }}
{{- if .Values.global.bootstrapACLs }}
acl-config.json: |-
{
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"enable_token_persistence": true
}
}
{{- end }}
{{- if and .Values.connectInject.enabled .Values.connectInject.centralConfig.enabled }}
central-config.json: |-
{
"enable_central_service_config": true
}
{{- if gt (len .Values.connectInject.centralConfig.proxyDefaults) 3 }}
proxy-defaults-config.json: |-
{
"config_entries": {
"bootstrap": [
{
"kind": "proxy-defaults",
"name": "global",
{{- if and .Values.meshGateway.enabled .Values.meshGateway.globalMode }}
"mesh_gateway": {
"mode": {{ .Values.meshGateway.globalMode | quote }}
},
{{- end }}
"config":
{{ tpl .Values.connectInject.centralConfig.proxyDefaults . | trimAll "\"" | indent 14 }}
}
]
}
}
{{- else if and .Values.meshGateway.enabled .Values.meshGateway.globalMode }}
proxy-defaults-config.json: |-
{
"config_entries": {
"bootstrap": [
{
"kind": "proxy-defaults",
"name": "global",
"mesh_gateway": {
"mode": {{ .Values.meshGateway.globalMode | quote }}
}
}
]
}
}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,21 @@
# PodDisruptionBudget to prevent degrading the server cluster through
# voluntary cluster changes.
{{- if (and .Values.server.disruptionBudget.enabled (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }}
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: {{ template "consul.fullname" . }}-server
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
maxUnavailable: {{ template "consul.pdb.maxUnavailable" . }}
selector:
matchLabels:
app: {{ template "consul.name" . }}
release: "{{ .Release.Name }}"
component: server
{{- end }}

View File

@@ -0,0 +1,40 @@
{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-server
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
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:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
# Require the container to run without root privileges.
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}

View File

@@ -0,0 +1,69 @@
# Headless service for Consul server DNS entries. This service should only
# point to Consul servers. For access to an agent, one should assume that
# the agent is installed locally on the node and the NODE_IP should be used.
# If the node can't run a Consul agent, then this service can be used to
# communicate directly to a server agent.
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "consul.fullname" . }}-server
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
# This must be set in addition to publishNotReadyAddresses due
# to an open issue where it may not work:
# https://github.com/kubernetes/kubernetes/issues/58662
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
spec:
clusterIP: None
# We want the servers to become available even if they're not ready
# since this DNS is also used for join operations.
publishNotReadyAddresses: true
ports:
{{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }}
- name: http
port: 8500
targetPort: 8500
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: https
port: 8501
targetPort: 8501
{{- end }}
- name: serflan-tcp
protocol: "TCP"
port: 8301
targetPort: 8301
- name: serflan-udp
protocol: "UDP"
port: 8301
targetPort: 8301
- name: serfwan-tcp
protocol: "TCP"
port: 8302
targetPort: 8302
- name: serfwan-udp
protocol: "UDP"
port: 8302
targetPort: 8302
- name: server
port: 8300
targetPort: 8300
- name: dns-tcp
protocol: "TCP"
port: 8600
targetPort: dns-tcp
- name: dns-udp
protocol: "UDP"
port: 8600
targetPort: dns-udp
selector:
app: {{ template "consul.name" . }}
release: "{{ .Release.Name }}"
component: server
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-server
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}

View File

@@ -0,0 +1,248 @@
# StatefulSet to run the actual Consul server cluster.
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ template "consul.fullname" . }}-server
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: server
spec:
serviceName: {{ template "consul.fullname" . }}-server
podManagementPolicy: Parallel
replicas: {{ .Values.server.replicas }}
{{- if (gt (int .Values.server.updatePartition) 0) }}
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: {{ .Values.server.updatePartition }}
{{- end }}
selector:
matchLabels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: server
hasDNS: "true"
template:
metadata:
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: server
hasDNS: "true"
annotations:
"consul.hashicorp.com/connect-inject": "false"
{{- if .Values.server.annotations }}
{{- tpl .Values.server.annotations . | nindent 8 }}
{{- end }}
spec:
{{- if .Values.server.affinity }}
affinity:
{{ tpl .Values.server.affinity . | nindent 8 | trim }}
{{- end }}
{{- if .Values.server.tolerations }}
tolerations:
{{ tpl .Values.server.tolerations . | nindent 8 | trim }}
{{- end }}
terminationGracePeriodSeconds: 30
serviceAccountName: {{ template "consul.fullname" . }}-server
securityContext:
fsGroup: 1000
volumes:
- name: config
configMap:
name: {{ template "consul.fullname" . }}-server-config
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
- name: tls-server-cert
secret:
secretName: {{ template "consul.fullname" . }}-server-cert
{{- end }}
{{- range .Values.server.extraVolumes }}
- name: userconfig-{{ .name }}
{{ .type }}:
{{- if (eq .type "configMap") }}
name: {{ .name }}
{{- else if (eq .type "secret") }}
secretName: {{ .name }}
{{- end }}
{{- end }}
{{- if .Values.server.priorityClassName }}
priorityClassName: {{ .Values.server.priorityClassName | quote }}
{{- end }}
containers:
- name: consul
image: "{{ default .Values.global.image .Values.server.image }}"
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }}
- name: GOSSIP_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.global.gossipEncryption.secretName }}
key: {{ .Values.global.gossipEncryption.secretKey }}
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: CONSUL_HTTP_ADDR
value: https://localhost:8501
- name: CONSUL_CACERT
value: /consul/tls/ca/tls.crt
{{- end }}
{{- include "consul.extraEnvironmentVars" .Values.server | nindent 12 }}
command:
- "/bin/sh"
- "-ec"
- |
CONSUL_FULLNAME="{{template "consul.fullname" . }}"
exec /bin/consul agent \
-advertise="${POD_IP}" \
-bind=0.0.0.0 \
-bootstrap-expect={{ .Values.server.bootstrapExpect }} \
{{- if .Values.global.tls.enabled }}
-hcl='ca_file = "/consul/tls/ca/tls.crt"' \
-hcl='cert_file = "/consul/tls/server/tls.crt"' \
-hcl='key_file = "/consul/tls/server/tls.key"' \
{{- if .Values.global.tls.verify }}
-hcl='verify_incoming_rpc = true' \
-hcl='verify_outgoing = true' \
-hcl='verify_server_hostname = true' \
{{- end }}
-hcl='ports { https = 8501 }' \
{{- if .Values.global.tls.httpsOnly }}
-hcl='ports { http = -1 }' \
{{- end }}
{{- end }}
-client=0.0.0.0 \
-config-dir=/consul/config \
{{- range .Values.server.extraVolumes }}
{{- if .load }}
-config-dir=/consul/userconfig/{{ .name }} \
{{- end }}
{{- end }}
-datacenter={{ .Values.global.datacenter }} \
-data-dir=/consul/data \
-domain={{ .Values.global.domain }} \
{{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }}
-encrypt="${GOSSIP_KEY}" \
{{- end }}
{{- if .Values.server.connect }}
-hcl="connect { enabled = true }" \
{{- end }}
{{- if .Values.ui.enabled }}
-ui \
{{- end }}
{{- range $index := until (.Values.server.replicas | int) }}
-retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \
{{- end }}
-server
volumeMounts:
- name: data-{{ .Release.Namespace }}
mountPath: /consul/data
- name: config
mountPath: /consul/config
{{- if .Values.global.tls.enabled }}
- name: consul-ca-cert
mountPath: /consul/tls/ca/
readOnly: true
- name: tls-server-cert
mountPath: /consul/tls/server
readOnly: true
{{- end }}
{{- range .Values.server.extraVolumes }}
- name: userconfig-{{ .name }}
readOnly: true
mountPath: /consul/userconfig/{{ .name }}
{{- end }}
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- consul leave
ports:
{{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }}
- containerPort: 8500
name: http
{{- end }}
{{- if .Values.global.tls.enabled }}
- containerPort: 8501
name: https
{{- end }}
- containerPort: 8301
name: serflan
- containerPort: 8302
name: serfwan
- containerPort: 8300
name: server
- containerPort: 8600
name: dns-tcp
protocol: "TCP"
- containerPort: 8600
name: dns-udp
protocol: "UDP"
readinessProbe:
# NOTE(mitchellh): when our HTTP status endpoints support the
# proper status codes, we should switch to that. This is temporary.
exec:
command:
- "/bin/sh"
- "-ec"
- |
{{- if .Values.global.tls.enabled }}
curl \
--cacert /consul/tls/ca/tls.crt \
https://127.0.0.1:8501/v1/status/leader \
{{- else }}
curl http://127.0.0.1:8500/v1/status/leader \
{{- end }}
2>/dev/null | grep -E '".+"'
failureThreshold: 2
initialDelaySeconds: 5
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 5
{{- if .Values.server.resources }}
resources:
{{ tpl .Values.server.resources . | nindent 12 | trim }}
{{- end }}
{{- if .Values.server.nodeSelector }}
nodeSelector:
{{ tpl .Values.server.nodeSelector . | indent 8 | trim }}
{{- end }}
volumeClaimTemplates:
- metadata:
name: data-{{ .Release.Namespace }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.server.storage }}
{{- if .Values.server.storageClass }}
storageClassName: {{ .Values.server.storageClass }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,49 @@
{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }}
{{- if $syncEnabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-sync-catalog
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
rules:
- apiGroups: [""]
resources:
- services
- endpoints
verbs:
- get
- list
- watch
{{- if .Values.syncCatalog.toK8S }}
- update
- patch
- delete
- create
{{- end }}
- apiGroups: [""]
resources:
- nodes
verbs:
- get
{{- if .Values.global.bootstrapACLs }}
- apiGroups: [""]
resources:
- secrets
resourceNames:
- {{ template "consul.fullname" . }}-catalog-sync-acl-token
verbs:
- get
{{- end }}
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
verbs:
- use
resourceNames:
- {{ template "consul.fullname" . }}-sync-catalog
{{- end }}
{{- end }}

View File

@@ -0,0 +1,20 @@
{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }}
{{- if $syncEnabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-sync-catalog
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-sync-catalog
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-sync-catalog
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,185 @@
# The deployment for running the sync-catalog pod
{{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "consul.fullname" . }}-sync-catalog
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: sync-catalog
template:
metadata:
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: sync-catalog
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog
{{- if .Values.global.tls.enabled }}
volumes:
- name: consul-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
{{- end }}
containers:
- name: consul-sync-catalog
image: "{{ default .Values.global.imageK8S .Values.syncCatalog.image }}"
env:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- if (and .Values.syncCatalog.aclSyncToken.secretName .Values.syncCatalog.aclSyncToken.secretKey) }}
- name: CONSUL_HTTP_TOKEN
valueFrom:
secretKeyRef:
name: {{ .Values.syncCatalog.aclSyncToken.secretName }}
key: {{ .Values.syncCatalog.aclSyncToken.secretKey }}
{{- end }}
{{- if .Values.global.bootstrapACLs }}
- name: CONSUL_HTTP_TOKEN
valueFrom:
secretKeyRef:
name: "{{ template "consul.fullname" . }}-catalog-sync-acl-token"
key: "token"
{{- end}}
{{- if .Values.global.tls.enabled }}
- name: CONSUL_HTTP_ADDR
value: https://$(HOST_IP):8501
- name: CONSUL_CACERT
value: /consul/tls/ca/tls.crt
{{- else }}
- name: CONSUL_HTTP_ADDR
value: http://$(HOST_IP):8500
{{- end }}
{{- if .Values.global.tls.enabled }}
volumeMounts:
- name: consul-ca-cert
mountPath: /consul/tls/ca
readOnly: true
{{- end }}
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s sync-catalog \
-k8s-default-sync={{ .Values.syncCatalog.default }} \
{{- if (not .Values.syncCatalog.toConsul) }}
-to-consul=false \
{{- end }}
{{- if (not .Values.syncCatalog.toK8S) }}
-to-k8s=false \
{{- end }}
-consul-domain={{ .Values.global.domain }} \
{{- if .Values.syncCatalog.k8sPrefix }}
-k8s-service-prefix="{{ .Values.syncCatalog.k8sPrefix}}" \
{{- end }}
{{- if .Values.syncCatalog.k8sSourceNamespace }}
-k8s-source-namespace="{{ .Values.syncCatalog.k8sSourceNamespace}}" \
{{- end }}
{{- range $value := .Values.syncCatalog.k8sAllowNamespaces }}
-allow-k8s-namespace="{{ $value }}" \
{{- end }}
{{- range $value := .Values.syncCatalog.k8sDenyNamespaces }}
-deny-k8s-namespace="{{ $value }}" \
{{- end }}
-k8s-write-namespace=${NAMESPACE} \
{{- if (not .Values.syncCatalog.syncClusterIPServices) }}
-sync-clusterip-services=false \
{{- end }}
{{- if .Values.syncCatalog.nodePortSyncType }}
-node-port-sync-type={{ .Values.syncCatalog.nodePortSyncType }} \
{{- end }}
{{- if .Values.syncCatalog.consulWriteInterval }}
-consul-write-interval={{ .Values.syncCatalog.consulWriteInterval }} \
{{- end }}
{{- if .Values.syncCatalog.logLevel }}
-log-level={{ .Values.syncCatalog.logLevel }} \
{{- end }}
{{- if .Values.syncCatalog.k8sTag }}
-consul-k8s-tag={{ .Values.syncCatalog.k8sTag }} \
{{- end }}
{{- if .Values.syncCatalog.consulPrefix}}
-consul-service-prefix="{{ .Values.syncCatalog.consulPrefix}}" \
{{- end}}
{{- if .Values.syncCatalog.addK8SNamespaceSuffix}}
-add-k8s-namespace-suffix \
{{- end}}
{{- if .Values.global.enableConsulNamespaces }}
-enable-namespaces=true \
{{- if .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }}
-consul-destination-namespace={{ .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} \
{{- end }}
{{- if .Values.syncCatalog.consulNamespaces.mirroringK8S }}
-enable-k8s-namespace-mirroring=true \
{{- if .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }}
-k8s-namespace-mirroring-prefix={{ .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} \
{{- end }}
{{- end }}
{{- if .Values.global.bootstrapACLs }}
-consul-cross-namespace-acl-policy=cross-namespace-policy \
{{- end }}
{{- end }}
livenessProbe:
httpGet:
path: /health/ready
port: 8080
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health/ready
port: 8080
scheme: HTTP
failureThreshold: 5
initialDelaySeconds: 10
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 5
{{- if .Values.global.bootstrapACLs }}
initContainers:
- name: sync-acl-init
image: {{ .Values.global.imageK8S }}
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s acl-init \
-secret-name="{{ template "consul.fullname" . }}-catalog-sync-acl-token" \
-k8s-namespace={{ .Release.Namespace }} \
-init-type="sync"
{{- end }}
{{- if .Values.syncCatalog.nodeSelector }}
nodeSelector:
{{ tpl .Values.syncCatalog.nodeSelector . | indent 8 | trim }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,38 @@
{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled))) }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-sync-catalog
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
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:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}

View File

@@ -0,0 +1,13 @@
{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }}
{{- if $syncEnabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-sync-catalog
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}

View File

@@ -0,0 +1,61 @@
{{- if .Values.tests.enabled }}
apiVersion: v1
kind: Pod
metadata:
name: "{{ template "consul.fullname" . }}-test"
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": test-success
spec:
{{- if .Values.global.tls.enabled }}
volumes:
- name: tls-ca-cert
secret:
{{- if .Values.global.tls.caCert.secretName }}
secretName: {{ .Values.global.tls.caCert.secretName }}
{{- else }}
secretName: {{ template "consul.fullname" . }}-ca-cert
{{- end }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
{{- end }}
containers:
- name: consul-test
image: "{{ .Values.global.image }}"
env:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
{{- if .Values.global.tls.enabled }}
- name: CONSUL_HTTP_ADDR
value: https://$(HOST_IP):8501
- name: CONSUL_CACERT
value: /consul/tls/ca/tls.crt
{{- else }}
- name: CONSUL_HTTP_ADDR
value: http://$(HOST_IP):8500
{{- end }}
{{- if .Values.global.tls.enabled }}
volumeMounts:
- name: tls-ca-cert
mountPath: /consul/tls/ca
readOnly: true
{{- end }}
command:
- "/bin/sh"
- "-ec"
- |
export VALUE="{{ .Release.Name }}"
consul kv delete _consul_helm_test
consul kv put _consul_helm_test $VALUE
[ `consul kv get _consul_helm_test` = "$VALUE" ]
consul kv delete _consul_helm_test
restartPolicy: Never
{{- end }}

View File

@@ -0,0 +1,35 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-tls-init-cleanup
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
rules:
- apiGroups: [""]
resources:
- secrets
resourceNames:
{{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }}
- {{ template "consul.fullname" . }}-ca-cert
- {{ template "consul.fullname" . }}-ca-key
{{- end }}
- {{ template "consul.fullname" . }}-server-cert
verbs:
- delete
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources:
- podsecuritypolicies
verbs:
- use
resourceNames:
- {{ template "consul.fullname" . }}-tls-init-cleanup
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,22 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-tls-init-cleanup
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-tls-init-cleanup
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-tls-init-cleanup
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,54 @@
# tls-init-cleanup job deletes Kubernetes secrets created by tls-init
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "consul.fullname" . }}-tls-init-cleanup
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": pre-delete
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
metadata:
name: {{ template "consul.fullname" . }}-tls-init-cleanup
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: tls-init-cleanup
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
restartPolicy: Never
serviceAccountName: {{ template "consul.fullname" . }}-tls-init-cleanup
containers:
- name: tls-init-cleanup
image: "{{ .Values.global.image }}"
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
command:
- "/bin/sh"
- "-ec"
- |
{{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }}
curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-ca-cert \
-H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )"
curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-ca-key \
-H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )"
{{- end }}
curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-server-cert \
-H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )"
{{- end }}
{{- end }}

View File

@@ -0,0 +1,36 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if (and .Values.global.tls.enabled .Values.global.enablePodSecurityPolicies) }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-tls-init-cleanup
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
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:
- 'secret'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-tls-init-cleanup
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,32 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: {{ template "consul.fullname" . }}-tls-init
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation
rules:
- apiGroups: [""]
resources:
- secrets
verbs:
- create
{{- if .Values.global.enablePodSecurityPolicies }}
- apiGroups: ["policy"]
resources:
- podsecuritypolicies
verbs:
- use
resourceNames:
- {{ template "consul.fullname" . }}-tls-init
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,25 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: {{ template "consul.fullname" . }}-tls-init
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "consul.fullname" . }}-tls-init
subjects:
- kind: ServiceAccount
name: {{ template "consul.fullname" . }}-tls-init
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,113 @@
# tls-init job generate Consul cluster CA and certificates for the Consul servers
# and creates Kubernetes secrets for them.
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "consul.fullname" . }}-tls-init
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "1"
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
metadata:
name: {{ template "consul.fullname" . }}-tls-init
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
release: {{ .Release.Name }}
component: tls-init
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
restartPolicy: Never
serviceAccountName: {{ template "consul.fullname" . }}-tls-init
{{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }}
volumes:
- name: consul-ca-cert
secret:
secretName: {{ .Values.global.tls.caCert.secretName }}
items:
- key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }}
path: tls.crt
- name: consul-ca-key
secret:
secretName: {{ .Values.global.tls.caKey.secretName }}
items:
- key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }}
path: tls.key
{{- end }}
containers:
- name: tls-init
image: "{{ .Values.global.image }}"
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
# We're using POST requests below to create secrets via Kubernetes API.
# Note that in the subsequent runs of the job, POST requests will
# return a 409 because these secrets would already exist;
# we are ignoring these response codes.
command:
- "/bin/sh"
- "-ec"
- |
{{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }}
consul tls ca create \
-domain={{ .Values.global.domain }}
curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \
-H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.domain }}-agent-ca.pem | base64 | tr -d '\n' )\" }}" > /dev/null
curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \
-H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-key\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.key\": \"$( cat {{ .Values.global.domain }}-agent-ca-key.pem | base64 | tr -d '\n' )\" }}" > /dev/null
{{- end }}
consul tls cert create -server \
-days=730 \
{{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }}
-ca=/consul/tls/ca/cert/tls.crt \
-key=/consul/tls/ca/key/tls.key \
{{- end }}
-additional-dnsname='{{ template "consul.fullname" . }}-server' \
-additional-dnsname='*.{{ template "consul.fullname" . }}-server' \
-additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}' \
-additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc' \
{{- range .Values.global.tls.serverAdditionalIPSANs }}
-additional-ipaddress={{ . }} \
{{- end }}
{{- range .Values.global.tls.serverAdditionalDNSSANs }}
-additional-dnsname={{ . }} \
{{- end }}
-dc={{ .Values.global.datacenter }} \
-domain={{ .Values.global.domain }}
curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \
-H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-server-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"kubernetes.io/tls\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.datacenter }}-server-{{ .Values.global.domain }}-0.pem | base64 | tr -d '\n' )\", \"tls.key\": \"$( cat {{ .Values.global.datacenter }}-server-{{ .Values.global.domain }}-0-key.pem | base64 | tr -d '\n' )\" } }" > /dev/null
{{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }}
volumeMounts:
- name: consul-ca-cert
mountPath: /consul/tls/ca/cert
readOnly: true
- name: consul-ca-key
mountPath: /consul/tls/ca/key
readOnly: true
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,39 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if (and .Values.global.tls.enabled .Values.global.enablePodSecurityPolicies) }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ template "consul.fullname" . }}-tls-init
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation
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:
- 'secret'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
{{- end }}
{{- end }}

View File

@@ -0,0 +1,17 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if .Values.global.tls.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "consul.fullname" . }}-tls-init
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-delete-policy": before-hook-creation
{{- end }}
{{- end }}

View File

@@ -0,0 +1,39 @@
# UI Service for Consul Server
{{- if (and (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.enabled | toString) "-") .Values.ui.enabled) (and (eq (.Values.ui.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.service.enabled | toString) "-") .Values.ui.service.enabled) (and (eq (.Values.ui.service.enabled | toString) "-") .Values.global.enabled))) }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "consul.fullname" . }}-ui
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- if .Values.ui.service.annotations }}
annotations:
{{ tpl .Values.ui.service.annotations . | nindent 4 | trim }}
{{- end }}
spec:
selector:
app: {{ template "consul.name" . }}
release: "{{ .Release.Name }}"
component: server
ports:
{{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }}
- name: http
port: 80
targetPort: 8500
{{- end }}
{{- if .Values.global.tls.enabled }}
- name: https
port: 443
targetPort: 8501
{{- end }}
{{- if .Values.ui.service.type }}
type: {{ .Values.ui.service.type }}
{{- end }}
{{- if .Values.ui.service.additionalSpec }}
{{ tpl .Values.ui.service.additionalSpec . | nindent 2 | trim }}
{{- end }}
{{- end }}