Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[helm] Initial Helm chart #950

Merged
merged 13 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions build/apply-certs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ kubectl create secret generic cockroachdb.client.root --namespace default --from
if [[ $NAMESPACE != "default" ]]; then
kubectl create secret generic cockroachdb.client.root --namespace "$NAMESPACE" --from-file "$CLIENTS_CERTS_DIR" --context "$CONTEXT"
fi
kubectl create secret generic cockroachdb.node --namespace "$NAMESPACE" --from-file "$NODE_CERTS_DIR" --context "$CONTEXT"
kubectl create secret generic cockroachdb.node --namespace "$NAMESPACE" --from-file "$NODE_CERTS_DIR" --context "$CONTEXT"
# The ca key is not needed for any typical operations, but might be required to sign new certificates.
$UPLOAD_CA_KEY && kubectl create secret generic cockroachdb.ca.key --namespace "$NAMESPACE" --from-file "$CA_KEY_DIR" --context "$CONTEXT"
# The ca.crt is kept in it's own secret to more easily manage cert rotation and
# adding other operators' certificates.
# adding other operators' certificates. Note that, for the purpose of the migration to helm and
# to comply with cockroach db standard configuration, ca.crt has been kept inside cockroach.* secrets.
# This secret is kept for backward compatibility.
kubectl create secret generic cockroachdb.ca.crt --namespace "$NAMESPACE" --from-file "$CA_CRT_DIR" --context "$CONTEXT"
kubectl create secret generic dss.public.certs --namespace "$NAMESPACE" --from-file "$JWT_PUBLIC_CERTS_DIR" --context "$CONTEXT"

Expand Down
14 changes: 10 additions & 4 deletions build/make-certs.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,16 @@ def main():
'*.cockroachdb',
'*.cockroachdb.%s' % cr.namespace,
'cockroachdb.%s' % cr.namespace,
'*.cockroachdb.%s.svc.cluster.local' % cr.namespace
'*.cockroachdb.%s.svc.cluster.local' % cr.namespace,
# New helm generated address
# Individual nodes
'*.dss-cockroachdb',
'*.dss-cockroachdb.%s' % cr.namespace,
'*.dss-cockroachdb.%s.svc.cluster.local' % cr.namespace,
# Internal load balancer
'dss-cockroachdb-public',
'dss-cockroachdb-public.%s' % cr.namespace,
'dss-cockroachdb-public.%s.svc.cluster.local' % cr.namespace,
])

subprocess.check_call([
Expand All @@ -147,9 +156,6 @@ def main():
'--ca-key', cr.ca_key_file]
+ node_addresses)

os.remove(os.path.join(cr.node_certs_dir, 'ca.crt'))
os.remove(os.path.join(cr.client_certs_dir, 'ca.crt'))

print('Created new node certificate in {}'.format(cr.node_certs_dir))


Expand Down
6 changes: 4 additions & 2 deletions deploy/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# DSS Deployment

**Work in progress**

This folder contains the increments toward the new deployment approach as described in [#874](https://github.com/interuss/dss/issues/874).

The infrastructure folder contains the terraform modules to deploy the DSS to kubernetes clusters of various cloud providers:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still true? Isn't the infrastructure folder supposed to simply set up the Infrastructure to be ready to accept Services deployment? If that is the case, it seems like DSS deployment requires Infrastructure + Services and it would be more appropriate here to say something like "The infrastructure folder contains the terraform modules to prepare infrastructure on various cloud providers to accept deployment of Services below". If that's not the case, what is the difference between Infrastructure and Services, and why is Services needed at all if Infrastructure fully deploys the DSS? Perhaps the infrastructure folder actually contain Infrastructure + Services-via-not-Helm?

It seems like it would likely be valuable to answer in the form of transferring some of the documentation from #874 to this file and/or the Infrastructure and Services READMEs (especially the definitions of Infrastructure, Services, and Operations)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#984 brings the definitions from #874 to the repository and should address your comment.
I added a Getting Started section driving the reader to the correct location to deploy the DSS from scratch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To facilitate navigation solely from the README content, it would probably be nice to enclose "infrastructure folder" and "service folder" in links to those respective folders. The links are immediately available when the README is displayed as a result of viewing the folder in GitHub (basically using it as an index.html), but they're not immediately available when viewing the README specifically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#984 regorganizes the documentation and this file now encloses all modules.


- Amazon Web Services: [terraform-aws-dss](./infrastructure/modules/terraform-aws-dss/README.md)
- Google Cloud Engine: [terraform-google-dss](./infrastructure/modules/terraform-google-dss/README.md)

The service folder contains the scripts required to deploy the DSS to a Kubernetes cluster:

- Helm Charts: [services/helm-charts](./services/helm-charts)
- Tanka: [../build/deploy/](../build/deploy)
6 changes: 6 additions & 0 deletions deploy/infrastructure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# DSS Deployment

The `modules` directory contains the terraform modules required to deploy the DSS using cloud providers.

- [terraform-aws-dss](./modules/terraform-aws-dss/README.md): Amazon Web Services deployment
barroco marked this conversation as resolved.
Show resolved Hide resolved
- [terraform-google-dss](./modules/terraform-google-dss/README.md): Google Cloud Engine deployment
5 changes: 5 additions & 0 deletions deploy/services/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Services

This folder contains the tools to deploy a DSS to a Kubernetes cluster.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this relate to Deployment of the DSS services included in the infrastructure section of deployment? When would a user use one versus the other, and how would they know to do that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file has been removed in #984 in favour of a consolidated description of all modules.


- [helm-charts/dss](./helm-charts/dss/README.md): Helm chart to deploy the DSS.
23 changes: 23 additions & 0 deletions deploy/services/helm-charts/dss/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
10 changes: 10 additions & 0 deletions deploy/services/helm-charts/dss/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v2
name: dss
description: A Helm chart to deploy the InterUSS DSS to Kubernetes
type: application
version: 0.1.0
appVersion: "snapshot"
dependencies:
- name: cockroachdb
repository: https://charts.cockroachdb.com/
version: 10.0.7
23 changes: 23 additions & 0 deletions deploy/services/helm-charts/dss/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# DSS Helm Chart
This [Helm Chart](https://helm.sh/) deploys the DSS and cockroachdb kubernetes resources.

## Requirements
1. A Kubernetes cluster should be running and you should be properly authenticated.
Requirements and instructions to create a new Kubernetes cluster can be found [here](../../../infrastructure/README.md).
2. Create the certificates and apply them to the cluster using the instructions of [section 6 and 7](../../../../build/README.md)
3. Install [Helm](https://helm.sh/) version 3.11.3 or higher

## Usage
1. Copy `values.example.yaml` to `values.dev.yaml` and edit it. See `values.schema.json` for schema definition. (Note that the key `cockroachdb` supports all values supported by the [`cockroachdb` Chart](https://github.com/cockroachdb/helm-charts/tree/master/cockroachdb#configuration)).
Note that values.yaml contains the default values and are always passed to helm.
2. Validate the configuration: `helm lint -f values.dev.yaml .`
3. Set a RELEASE_NAME to `dss`: `export RELEASE_NAME=dss`
It is temporarily the only release name possible.
4. Set the kube client context of your , example: `export KUBE_CONTEXT=gke_interuss-deploy-example_europe-west6-a_dss-dev-w6`
5. Run `helm dep update --kube-context=$KUBE_CONTEXT`
6. Install the chart: `helm install --kube-context=$KUBE_CONTEXT -f values.dev.yaml $RELEASE_NAME .`

### Update the chart
When changing the values in values.dev.yaml, values.yaml, the templates or upgrading the helm chart dependencies, changes can be applied to the cluster using the following command:

1. Run `helm upgrade --kube-context=$KUBE_CONTEXT -f values.dev.yaml $RELEASE_NAME .`
26 changes: 26 additions & 0 deletions deploy/services/helm-charts/dss/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- define "cockroachImage" -}}
{{ (printf "%s:%s" $.Values.cockroachdb.image.repository $.Values.cockroachdb.image.tag) }}
{{- end -}}

{{- define "cockroachHost" -}}
{{- printf "%s-public.default" $.Values.cockroachdb.fullnameOverride -}}
{{- end -}}

{{- define "init-container-wait-for-http" -}}
- name: wait-for-{{.serviceName}}
image: alpine:3.17.3
command: [ 'sh', '-c', "until wget -nv {{.url}}; do echo waiting for {{.serviceName}}; sleep 2; done" ]
{{- end -}}

{{- define "init-container-wait-for-schema" -}}
{{/*For some reason, calling the template cockroachImage fails here.*/}}
- name: wait-for-schema-{{.schemaName}}
image: {{.cockroachImage}}
volumeMounts:
{{- include "ca-certs:volumeMount" . | nindent 4 }}
{{- include "client-certs:volumeMount" . | nindent 4 }}
command:
- sh
- -c
- "/cockroach/cockroach sql --certs-dir /cockroach/cockroach-certs/ --host {{.cockroachHost}} --port \"26257\" --format raw -e \"SELECT * FROM crdb_internal.databases where name = '{{.schemaName}}';\" | grep {{.schemaName}}"
{{- end -}}
26 changes: 26 additions & 0 deletions deploy/services/helm-charts/dss/templates/_networking-aws.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- define "aws-lb-default-annotations" -}}
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-name: {{.name}}
service.beta.kubernetes.io/aws-load-balancer-eip-allocations: {{.ip}}
service.beta.kubernetes.io/aws-load-balancer-subnets: {{.subnet}}
service.beta.kubernetes.io/aws-load-balancer-type: external
{{- end -}}

{{- define "aws-lb-crdb-annotations" -}}
{{- include "aws-lb-default-annotations" . }}
{{- end -}}

{{- define "aws-lb-spec" -}}
loadBalancerClass: service.k8s.aws/nlb
{{- end -}}

{{- define "aws-ingress-dss-gateway-annotations" -}}
{{- include "aws-lb-default-annotations" . }}
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: {{.certName}}
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
{{- end -}}

{{- define "aws-ingress-spec" -}}
loadBalancerClass: service.k8s.aws/nlb
{{- end -}}
15 changes: 15 additions & 0 deletions deploy/services/helm-charts/dss/templates/_networking-google.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{- define "google-lb-crdb-annotations" -}}
{{- end -}}

{{- define "google-lb-spec" -}}
loadBalancerIP: {{.ip}}
{{- end -}}

{{- define "google-ingress-dss-gateway-annotations" -}}
kubernetes.io/ingress.allow-http: "false"
kubernetes.io/ingress.global-static-ip-name: {{.ip}}
networking.gke.io/managed-certificates: {{.certName}}
{{- end -}}

{{- define "google-ingress-spec" -}}
{{- end -}}
38 changes: 38 additions & 0 deletions deploy/services/helm-charts/dss/templates/_volumes.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{{- define "ca-certs:volume" -}}
- name: ca-certs
secret:
defaultMode: 256
secretName: cockroachdb.ca.crt
{{- end -}}
{{- define "ca-certs:volumeMount" -}}
- mountPath: /cockroach/cockroach-certs/ca.crt
name: ca-certs
subPath: ca.crt
{{- end -}}

{{- define "client-certs:volume" -}}
- name: client-certs
secret:
defaultMode: 256
secretName: cockroachdb.client.root
{{- end -}}
{{- define "client-certs:volumeMount" -}}
- mountPath: /cockroach/cockroach-certs/client.root.crt
name: client-certs
subPath: client.root.crt
- mountPath: /cockroach/cockroach-certs/client.root.key
name: client-certs
subPath: client.root.key
{{- end -}}


{{- define "public-certs:volume" -}}
- name: public-certs
secret:
defaultMode: 256
secretName: dss.public.certs
{{- end -}}
{{- define "public-certs:volumeMount" -}}
- mountPath: /public-certs
name: public-certs
{{- end -}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{{- $cloudProvider := $.Values.global.cloudProvider}}

# Node Gateways
{{- range $i, $lb := .Values.loadBalancers.cockroachdbNodes }}
---
apiVersion: v1
kind: Service
metadata:
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
{{- include (printf "%s-lb-crdb-annotations" $cloudProvider)
(dict
"name" (printf "%s-%s" "cockroach-db-external-node" ( $i | toString) )
"ip" $lb.ip
"subnet" $lb.subnet
"cloudProvider" $cloudProvider
) | nindent 4
}}
labels:
app: cockroachdb
name: cockroach-db-external-node-{{$i}}
name: cockroach-db-external-node-{{$i}}
namespace: default
spec:
{{- include (printf "%s-lb-spec" $cloudProvider) (dict "ip" $lb.ip) | nindent 2}}
ports:
- name: cockroach-db-external-node-{{$i}}
port: 26257
targetPort: 26257
publishNotReadyAddresses: true
selector:
statefulset.kubernetes.io/pod-name: {{$.Release.Name}}-cockroachdb-{{$i}}
type: LoadBalancer
{{- end }}
81 changes: 81 additions & 0 deletions deploy/services/helm-charts/dss/templates/dss-core-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{{- $dss := .Values.dss -}}
{{- $cockroachImage := (include "cockroachImage" .) -}}
{{- $cockroachHost := (include "cockroachHost" .) -}}
{{- $waitForCockroachDB := include "init-container-wait-for-http" (dict "serviceName" "cockroachdb" "url" (printf "http://%s:8080/health" $cockroachHost)) -}}
{{- $waitForRIDSchema := include "init-container-wait-for-schema" (dict "schemaName" "rid" "cockroachImage" $cockroachImage "cockroachHost" $cockroachHost) -}}
{{- $waitForSCDSchema := include "init-container-wait-for-schema" (dict "schemaName" "scd" "cockroachImage" $cockroachImage "cockroachHost" $cockroachHost) -}}

---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
name: {{.Release.Name}}-core-service
name: {{.Release.Name}}-core-service
spec:
minReadySeconds: 30
replicas: 3
selector:
matchLabels:
app: {{.Release.Name}}-core-service
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: {{.Release.Name}}-core-service
spec:
initContainers:
{{- $waitForCockroachDB | nindent 8 }}
{{- $waitForRIDSchema | nindent 8 }}
{{- $waitForSCDSchema | nindent 8 }}
containers:
- args:
- --accepted_jwt_audiences={{$dss.conf.hostname}}
- --addr=:8080
- --cockroach_host={{$cockroachHost}}
- --cockroach_port=26257
- --cockroach_ssl_dir=/cockroach/cockroach-certs
- --cockroach_ssl_mode=verify-full
- --cockroach_user=root
- --dump_requests=true
- --enable_scd={{$dss.enableScd | default true}}
- --garbage_collector_spec=@every 30m
- --gcp_prof_service_name=
{{- if $dss.conf.jwksEndpoint }}
- --jwks_endpoint={{ $dss.jwksEndpoint }}
{{- end }}
{{- if $dss.conf.jwksKeyIds }}
- --jwks_key_ids={{ $dss.jwksKeyIds | join "," }}
{{- end }}
- --locality={{ .Values.cockroachdb.conf.locality }}
{{- if $dss.conf.pubKeys}}
- --public_key_files={{ $dss.conf.pubKeys | join "," }}
{{- end }}
command:
- core-service
image: {{ $dss.image }}
imagePullPolicy: Always
name: core-service
ports:
- containerPort: 8080
name: http
readinessProbe:
httpGet:
path: /healthy
port: 8080
stdin: false
tty: false
volumeMounts:
{{- include "ca-certs:volumeMount" . | nindent 12 }}
{{- include "client-certs:volumeMount" . | nindent 12 }}
{{- include "public-certs:volumeMount" . | nindent 12 }}
imagePullSecrets: []
terminationGracePeriodSeconds: 30
volumes:
{{- include "ca-certs:volume" . | nindent 8 }}
{{- include "client-certs:volume" . | nindent 8 }}
{{- include "public-certs:volume" . | nindent 8 }}
37 changes: 37 additions & 0 deletions deploy/services/helm-charts/dss/templates/dss-ingress-aws.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{{- $cloudProvider := $.Values.global.cloudProvider}}
{{- if eq $cloudProvider "aws" }}
{{/*
AWS application load balancer Ingress do not support elastic ip assignment yet. Therefore, the
ingress is replaced by a network load balancer (Kubernetes Service of type Load Balancer)
*/}}
{{- with $.Values.loadBalancers.dssGateway }}
---
apiVersion: v1
kind: Service
metadata:
annotations:
{{- include (printf "%s-ingress-dss-gateway-annotations" $cloudProvider)
(merge .
(dict
"name" "dss-gateway-external"
"cloudProvider" $cloudProvider
)
) | nindent 4
}}
labels:
app: {{$.Release.Name}}-core-service
name: {{$.Release.Name}}-dss-gateway
name: {{$.Release.Name}}-dss-gateway
namespace: default
spec:
{{- include (printf "%s-ingress-spec" $cloudProvider) . | nindent 2 }}
ports:
- name: http
port: 443
protocol: TCP
targetPort: 8080
selector:
app: {{$.Release.Name}}-core-service
type: LoadBalancer
{{- end }}
{{- end }}
Loading
Loading