Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed Aug 18, 2018
0 parents commit ef0d2cb
Show file tree
Hide file tree
Showing 28 changed files with 765 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.DS_Store
.terraform/
terraform.tfstate*
terraform.tfvars
values.yaml
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Consul Helm Chart

This repository contains the official HashiCorp Helm chart for installing
and configuring Consul on Kubernetes. This chart supports multiple use
cases of Consul on Kubernetes depending on the values provided.

## Prerequisites

To use the charts here, [Helm](https://helm.sh/) must be installed in your
Kubernetes cluster. Setting up Kubernetes and Helm and is outside the scope
of this README. Please refer to the Kubernetes and Helm documentation.

## Testing

The Helm charts are tested in two forms: [Bats](https://github.com/bats-core/bats-core)
tests and `helm test` tests. The Bats tests test changing Helm chart values and
the effect on the install. The `helm test` tests verify that a deployed chart
appears healthy.

To run the Bats test: `kubectl` must be configured locally to be authenticated
to a running Kubernetes cluster with Helm installed. With that in place,
just run bats:

bats ./charts/consul/test

If the tests fail, deployed resources in the Kubernetes cluster may not
be properly cleaned up. We recommend recycling the Kubernetes cluster to
start from a clean slate.

**Note:** There is a Terraform configuration in the
[terraform/ directory](https://github.com/hashicorp/consul-k8s/tree/master/terraform)
that can be used to quickly bring up a GKE cluster and configure
`kubectl` and `helm` locally. This can be used to quickly spin up a test
cluster.
8 changes: 8 additions & 0 deletions charts/consul/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
name: consul
version: 0.1.0
description: Install and configure Consul on Kubernetes.
home: https://www.consul.io
sources:
- https://github.com/hashicorp/consul
- https://github.com/hashicorp/consul-k8s
26 changes: 26 additions & 0 deletions charts/consul/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{/*
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). If release name contains chart name it will
be used as a full name.
*/}}
{{- define "consul.namePrefix" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- 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.
*/}}
{{- define "consul.pdb.maxUnavailable" -}}
{{- if .Values.server.disruptionBudget.maxUnavailable -}}
{{ .Values.server.disruptionBudget.maxUnavailable -}}
{{- else -}}
{{- ceil (sub (div (int .Values.server.replicas) 2) 1) -}}
{{- end -}}
{{- end -}}
85 changes: 85 additions & 0 deletions charts/consul/templates/client-daemonset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# DaemonSet to run the Consul clients on every node.
{{- if .Values.client.enabled }}
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: consul
spec:
selector:
matchLabels:
app: consul
template:
metadata:
labels:
app: consul
annotations:
"consul.hashicorp.com/connect-inject": "false"
spec:
terminationGracePeriodSeconds: 10

# Consul agents require a directory for data, even clients. The data
# is okay to be wiped though if the Pod is removed, so just use an
# emptyDir volume.
volumes:
- name: data
emptyDir: {}

containers:
- name: consul
image: "{{ .Values.client.image }}"
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
command:
- "/bin/sh"
- "-ec"
- |
exec /bin/consul agent \
-advertise="${POD_IP}" \
-bind=0.0.0.0 \
-client=0.0.0.0 \
-datacenter={{ .Values.server.datacenter }} \
-data-dir=/consul/data \
{{- 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-server-{{ $index }}.consul-server.${NAMESPACE}.svc \
{{- end }}
{{- end }}
{{- end }}
-domain={{ .Values.common.domain }}
volumeMounts:
- name: data
mountPath: /consul/data
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- consul leave
ports:
- containerPort: 8500
hostPort: 8500
name: http
- containerPort: 8301
name: serflan
- containerPort: 8302
name: serfwan
- containerPort: 8300
name: server
- containerPort: 8600
name: dns
resources:
{{ toYaml .Values.server.resources | indent 12 }}
{{- end }}
69 changes: 69 additions & 0 deletions charts/consul/templates/connect-inject-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# The deployment for running the Connect sidecar injector
{{- if .Values.connectInject.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: consul-connect-injector-webhook-deployment
labels:
app: consul-connect-injector
spec:
replicas: 1
selector:
matchLabels:
app: consul-connect-injector
template:
metadata:
labels:
app: consul-connect-injector
spec:
containers:
- name: sidecar-injector
image: us.gcr.io/mitchellh-k8s/consul-k8s:latest
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
command:
- "/bin/sh"
- "-ec"
- |
consul-k8s inject \
-default-inject={{ .Values.connectInject.default }} \
-listen=:8080 \
{{- 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-connect-injector-cfg \
-tls-auto-hosts=consul-connect-injector-svc,consul-connect-injector-svc.${NAMESPACE},consul-connect-injector-svc.${NAMESPACE}.svc
{{- end }}
livenessProbe:
tcpSocket:
port: 8080
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 .Values.connectInject.certs.secretName }}
volumeMounts:
- name: certs
mountPath: /etc/connect-injector/certs
readOnly: true
volumes:
- name: certs
secret:
secretName: {{ .Values.connectInject.certs.secretName }}
{{- end }}
{{- end }}
26 changes: 26 additions & 0 deletions charts/consul/templates/connect-inject-mutatingwebhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# The MutatingWebhookConfiguration to enable the Connect injector.
{{- if (.Values.connectInject.enabled) and (.Values.connectInject.caBundle) }}
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: consul-connect-injector-cfg
labels:
app: consul-connect-injector
webhooks:
- name: consul-connect-injector.consul.hashicorp.com
clientConfig:
service:
name: consul-connect-injector-svc
namespace: default
path: "/mutate"
caBundle: {{ .Values.connectInject.caBundle }}
rules:
- operations: [ "CREATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
{{- if .Values.connectInject.namespaceSelector }}
namespaceSelector:
{{ tpl .Values.connectInject.namespaceSelector . | indent 6 }}
{{- end }}
{{- end }}
16 changes: 16 additions & 0 deletions charts/consul/templates/connect-inject-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# The service for the Connect sidecar injector
{{- if .Values.connectInject.enabled }}
apiVersion: v1
kind: Service
metadata:
name: consul-connect-injector-svc
labels:
app: consul-connect-injector
spec:
ports:
- port: 443
targetPort: 8080
selector:
app: consul-connect-injector
{{- end }}

10 changes: 10 additions & 0 deletions charts/consul/templates/server-config-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# StatefulSet to run the actual Consul server cluster.
{{- if .Values.server.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: consul-server-config
data:
extra-from-values.json: |-
{{ tpl .Values.server.extraConfig . | indent 4 }}
{{- end }}
13 changes: 13 additions & 0 deletions charts/consul/templates/server-disruptionbudget.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# PodDisruptionBudget to prevent degrading the server cluster through
# voluntary cluster changes.
{{- if (.Values.server.enabled) and (.Values.server.disruptionBudget.enabled) }}
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: consul-pdb
spec:
maxUnavailable: {{ template "consul.pdb.maxUnavailable" . }}
selector:
matchLabels:
app: consul-server
{{- end }}
51 changes: 51 additions & 0 deletions charts/consul/templates/server-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# 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 .Values.server.enabled }}
apiVersion: v1
kind: Service
metadata:
name: consul-server
labels:
name: consul-server
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:
- name: http
port: 8500
targetPort: 8500
- 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
port: 8600
targetPort: 8600
selector:
app: consul-server
{{- end }}
Loading

0 comments on commit ef0d2cb

Please sign in to comment.