diff --git a/applications/gafaelfawr/README.md b/applications/gafaelfawr/README.md index abd63b00bb..2da47d2fbf 100644 --- a/applications/gafaelfawr/README.md +++ b/applications/gafaelfawr/README.md @@ -13,18 +13,17 @@ Authentication and identity system | Key | Type | Default | Description | |-----|------|---------|-------------| | affinity | object | `{}` | Affinity rules for the Gafaelfawr frontend pod | -| cloudsql.affinity | object | `{}` | Affinity rules for the Cloud SQL Proxy pod | +| cloudsql.affinity | object | `{}` | Affinity rules for the standalone Cloud SQL Proxy pod | | cloudsql.enabled | bool | `false` | Enable the Cloud SQL Auth Proxy, used with Cloud SQL databases on Google Cloud. This will be run as a sidecar for the main Gafaelfawr pods, and as a separate service (behind a `NetworkPolicy`) for other, lower-traffic services. | | cloudsql.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for Cloud SQL Auth Proxy images | | cloudsql.image.repository | string | `"gcr.io/cloudsql-docker/gce-proxy"` | Cloud SQL Auth Proxy image to use | -| cloudsql.image.schemaUpdateTagSuffix | string | `"-alpine"` | Tag suffix to use for the proxy for schema updates | | cloudsql.image.tag | string | `"1.37.4"` | Cloud SQL Auth Proxy tag to use | | cloudsql.instanceConnectionName | string | None, must be set if Cloud SQL Auth Proxy is enabled | Instance connection name for a Cloud SQL PostgreSQL instance | -| cloudsql.nodeSelector | object | `{}` | Node selection rules for the Cloud SQL Proxy pod | -| cloudsql.podAnnotations | object | `{}` | Annotations for the Cloud SQL Proxy pod | -| cloudsql.resources | object | See `values.yaml` | Resource limits and requests for the Cloud SQL Proxy pod | +| cloudsql.nodeSelector | object | `{}` | Node selection rules for the standalone Cloud SQL Proxy pod | +| cloudsql.podAnnotations | object | `{}` | Annotations for the standalone Cloud SQL Proxy pod | +| cloudsql.resources | object | See `values.yaml` | Resource limits and requests for the Cloud SQL Proxy container | | cloudsql.serviceAccount | string | None, must be set if Cloud SQL Auth Proxy is enabled | The Google service account that has an IAM binding to the `gafaelfawr` Kubernetes service account and has the `cloudsql.client` role | -| cloudsql.tolerations | list | `[]` | Tolerations for the Cloud SQL Proxy pod | +| cloudsql.tolerations | list | `[]` | Tolerations for the standalone Cloud SQL Proxy pod | | config.afterLogoutUrl | string | Top-level page of this Phalanx environment | Where to send the user after they log out | | config.baseInternalUrl | string | FQDN under `svc.cluster.local` | URL for direct connections to the Gafaelfawr service, bypassing the Ingress. Must use a service name of `gafaelfawr` and port 8080. | | config.cilogon.clientId | string | `nil` | CILogon client ID. One and only one of this, `config.github.clientId`, or `config.oidc.clientId` must be set. | diff --git a/applications/gafaelfawr/templates/_helpers.tpl b/applications/gafaelfawr/templates/_helpers.tpl index db3296b108..4794b5e495 100644 --- a/applications/gafaelfawr/templates/_helpers.tpl +++ b/applications/gafaelfawr/templates/_helpers.tpl @@ -26,6 +26,35 @@ app.kubernetes.io/name: "gafaelfawr" app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} +{{/* +Cloud SQL Auth Proxy sidecar container +*/}} +{{- define "gafaelfawr.cloudsqlSidecar" -}} +- name: "cloud-sql-proxy" + command: + - "/cloud_sql_proxy" + - "-ip_address_types=PRIVATE" + - "-log_debug_stdout=true" + - "-structured_logs=true" + - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" + image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" + imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} + {{- with .Values.cloudsql.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + restartPolicy: "Always" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "all" + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 +{{- end }} + {{/* Common environment variables */}} diff --git a/applications/gafaelfawr/templates/deployment.yaml b/applications/gafaelfawr/templates/deployment.yaml index a93d0e42f5..d016e2357e 100644 --- a/applications/gafaelfawr/templates/deployment.yaml +++ b/applications/gafaelfawr/templates/deployment.yaml @@ -29,30 +29,6 @@ spec: automountServiceAccountToken: false {{- end }} containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - command: - - "/cloud_sql_proxy" - - "-ip_address_types=PRIVATE" - - "-log_debug_stdout=true" - - "-structured_logs=true" - - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - {{- with .Values.cloudsql.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - {{- end }} - name: "gafaelfawr" env: {{- include "gafaelfawr.envVars" (dict "Chart" .Chart "Release" .Release "Values" .Values "sidecar" true) | nindent 12 }} @@ -129,6 +105,10 @@ spec: - name: "tmp" mountPath: "/tmp" {{- end }} + {{- if .Values.cloudsql.enabled }} + initContainers: + {{- include "gafaelfawr.cloudsqlSidecar" | nindent 8 }} + {{- end }} securityContext: runAsNonRoot: true runAsUser: 1000 diff --git a/applications/gafaelfawr/templates/job-schema-update.yaml b/applications/gafaelfawr/templates/job-schema-update.yaml index 59e211ce75..354dc5ec06 100644 --- a/applications/gafaelfawr/templates/job-schema-update.yaml +++ b/applications/gafaelfawr/templates/job-schema-update.yaml @@ -29,56 +29,10 @@ spec: automountServiceAccountToken: false {{- end }} containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - # Running the sidecar as normal causes it to keep running and thus - # the Pod never exits, the Job never finishes, and the hook blocks - # the sync. Have the main pod signal the sidecar by writing to a - # file on a shared emptyDir file system, and use a simple watcher - # loop in shell in the sidecar container to terminate the proxy when - # the main container finishes. - # - # Based on https://stackoverflow.com/questions/41679364/ - command: - - "/bin/sh" - - "-c" - args: - - | - /cloud_sql_proxy -ip_address_types=PRIVATE -log_debug_stdout=true -structured_logs=true -instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432 & - PID=$! - while true; do - if [[ -f "/lifecycle/main-terminated" ]]; then - kill $PID - exit 0 - fi - sleep 1 - done - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}{{ .Values.cloudsql.image.schemaUpdateTagSuffix }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - {{- with .Values.cloudsql.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - volumeMounts: - - name: "lifecycle" - mountPath: "/lifecycle" - {{- end }} - name: "gafaelfawr" command: - - "/bin/sh" - - "-c" - - | - gafaelfawr update-schema - touch /lifecycle/main-terminated + - "gafaelfawr" + - "update-schema" env: {{- include "gafaelfawr.envVars" (dict "Chart" .Chart "Release" .Release "Values" .Values "sidecar" true) | nindent 12 }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" @@ -97,8 +51,10 @@ spec: - name: "config" mountPath: "/etc/gafaelfawr" readOnly: true - - name: "lifecycle" - mountPath: "/lifecycle" + {{- if .Values.cloudsql.enabled }} + initContainers: + {{- include "gafaelfawr.cloudsqlSidecar" | nindent 8 }} + {{- end }} restartPolicy: "Never" securityContext: runAsNonRoot: true @@ -108,8 +64,6 @@ spec: - name: "config" configMap: name: "gafaelfawr" - - name: "lifecycle" - emptyDir: {} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/applications/gafaelfawr/values.yaml b/applications/gafaelfawr/values.yaml index 30d4305cff..ecb1fdf67f 100644 --- a/applications/gafaelfawr/values.yaml +++ b/applications/gafaelfawr/values.yaml @@ -318,9 +318,6 @@ cloudsql: # -- Cloud SQL Auth Proxy tag to use tag: "1.37.4" - # -- Tag suffix to use for the proxy for schema updates - schemaUpdateTagSuffix: "-alpine" - # -- Pull policy for Cloud SQL Auth Proxy images pullPolicy: "IfNotPresent" @@ -333,7 +330,7 @@ cloudsql: # @default -- None, must be set if Cloud SQL Auth Proxy is enabled serviceAccount: "" - # -- Resource limits and requests for the Cloud SQL Proxy pod + # -- Resource limits and requests for the Cloud SQL Proxy container # @default -- See `values.yaml` resources: limits: @@ -343,17 +340,17 @@ cloudsql: cpu: "5m" memory: "7Mi" - # -- Annotations for the Cloud SQL Proxy pod - podAnnotations: {} + # -- Affinity rules for the standalone Cloud SQL Proxy pod + affinity: {} - # -- Node selection rules for the Cloud SQL Proxy pod + # -- Node selection rules for the standalone Cloud SQL Proxy pod nodeSelector: {} - # -- Tolerations for the Cloud SQL Proxy pod - tolerations: [] + # -- Annotations for the standalone Cloud SQL Proxy pod + podAnnotations: {} - # -- Affinity rules for the Cloud SQL Proxy pod - affinity: {} + # -- Tolerations for the standalone Cloud SQL Proxy pod + tolerations: [] maintenance: # -- Cron schedule string for Gafaelfawr data consistency audit (in UTC) diff --git a/applications/times-square/README.md b/applications/times-square/README.md index 94841cef6c..67be91782f 100644 --- a/applications/times-square/README.md +++ b/applications/times-square/README.md @@ -18,8 +18,7 @@ An API service for managing and rendering parameterized Jupyter notebooks. | cloudsql.enabled | bool | `false` | Enable the Cloud SQL Auth Proxy sidecar, used with Cloud SQL databases on Google Cloud | | cloudsql.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for Cloud SQL Auth Proxy images | | cloudsql.image.repository | string | `"gcr.io/cloudsql-docker/gce-proxy"` | Cloud SQL Auth Proxy image to use | -| cloudsql.image.resources | object | see `values.yaml` | Resource requests and limits for Cloud SQL pod | -| cloudsql.image.schemaUpdateTagSuffix | string | `"-alpine"` | Tag suffix to use for the proxy for schema updates | +| cloudsql.image.resources | object | See `values.yaml` | Resource requests and limits for Cloud SQL pod | | cloudsql.image.tag | string | `"1.37.4"` | Cloud SQL Auth Proxy tag to use | | cloudsql.instanceConnectionName | string | `""` | Instance connection name for a Cloud SQL PostgreSQL instance | | cloudsql.serviceAccount | string | `""` | The Google service account that has an IAM binding to the `times-square` Kubernetes service accounts and has the `cloudsql.client` role | diff --git a/applications/times-square/templates/_helpers.tpl b/applications/times-square/templates/_helpers.tpl index 4fe2a60721..75f1cd4407 100644 --- a/applications/times-square/templates/_helpers.tpl +++ b/applications/times-square/templates/_helpers.tpl @@ -50,6 +50,34 @@ app.kubernetes.io/name: {{ include "times-square.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} +{{/* +Cloud SQL Auth Proxy sidecar container +*/}} +{{- define "times-square.cloudsqlSidecar" -}} +- name: "cloud-sql-proxy" + command: + - "/cloud_sql_proxy" + - "-ip_address_types=PRIVATE" + - "-log_debug_stdout=true" + - "-structured_logs=true" + - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" + image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" + imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} + {{- with .Values.cloudsql.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + restartPolicy: "Always" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "all" + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 +{{- end }} {{/* Create the name of the service account to use diff --git a/applications/times-square/templates/deployment.yaml b/applications/times-square/templates/deployment.yaml index 7b6691c1a1..4a2d9af51b 100644 --- a/applications/times-square/templates/deployment.yaml +++ b/applications/times-square/templates/deployment.yaml @@ -40,26 +40,6 @@ spec: runAsUser: 1000 runAsGroup: 1000 containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - command: - - "/cloud_sql_proxy" - - "-ip_address_types=PRIVATE" - - "-log_debug_stdout=true" - - "-structured_logs=true" - - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" - {{- end }} - name: {{ .Chart.Name }} securityContext: allowPrivilegeEscalation: false @@ -122,6 +102,10 @@ spec: secretKeyRef: name: {{ template "times-square.fullname" . }}-secret key: "TS_SENTRY_DSN" + {{- if .Values.cloudsql.enabled }} + initContainers: + {{- include "times-square.cloudsqlSidecar" | nindent 8 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/applications/times-square/templates/job-schema-update.yaml b/applications/times-square/templates/job-schema-update.yaml index 16b086c729..532fb91e64 100644 --- a/applications/times-square/templates/job-schema-update.yaml +++ b/applications/times-square/templates/job-schema-update.yaml @@ -28,56 +28,10 @@ spec: automountServiceAccountToken: false {{- end }} containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - # Running the sidecar as normal causes it to keep running and thus - # the Pod never exits, the Job never finishes, and the hook blocks - # the sync. Have the main pod signal the sidecar by writing to a - # file on a shared emptyDir file system, and use a simple watcher - # loop in shell in the sidecar container to terminate the proxy when - # the main container finishes. - # - # Based on https://stackoverflow.com/questions/41679364/ - command: - - "/bin/sh" - - "-c" - args: - - | - /cloud_sql_proxy -ip_address_types=PRIVATE -log_debug_stdout=true -structured_logs=true -instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432 & - PID=$! - while true; do - if [[ -f "/lifecycle/main-terminated" ]]; then - kill $PID - exit 0 - fi - sleep 1 - done - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}{{ .Values.cloudsql.image.schemaUpdateTagSuffix }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - {{- with .Values.cloudsql.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - volumeMounts: - - name: "lifecycle" - mountPath: "/lifecycle" - {{- end }} - name: "times-square" command: - - "/bin/sh" - - "-c" - - | - times-square update-db-schema - touch /lifecycle/main-terminated + - "times-square" + - "update-db-schema" image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy | quote }} {{- with .Values.resources }} @@ -124,17 +78,15 @@ spec: secretKeyRef: name: {{ template "times-square.fullname" . }}-secret key: "TS_SLACK_WEBHOOK_URL" - volumeMounts: - - name: "lifecycle" - mountPath: "/lifecycle" + {{- if .Values.cloudsql.enabled }} + initContainers: + {{- include "times-square.cloudsqlSidecar" | nindent 8 }} + {{- end }} restartPolicy: "Never" securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 - volumes: - - name: "lifecycle" - emptyDir: {} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/applications/times-square/templates/worker-deployment.yaml b/applications/times-square/templates/worker-deployment.yaml index 06abe33ca0..b61636119e 100644 --- a/applications/times-square/templates/worker-deployment.yaml +++ b/applications/times-square/templates/worker-deployment.yaml @@ -40,26 +40,6 @@ spec: runAsUser: 1000 runAsGroup: 1000 containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - command: - - "/cloud_sql_proxy" - - "-ip_address_types=PRIVATE" - - "-log_debug_stdout=true" - - "-structured_logs=true" - - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" - {{- end }} - name: {{ .Chart.Name }} securityContext: allowPrivilegeEscalation: false @@ -107,6 +87,10 @@ spec: secretKeyRef: name: {{ template "times-square.fullname" . }}-secret key: "TS_SENTRY_DSN" + {{- if .Values.cloudsql.enabled }} + initContainers: + {{- include "times-square.cloudsqlSidecar" | nindent 8 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/applications/times-square/values.yaml b/applications/times-square/values.yaml index ec3f19bbbd..3be62f7506 100644 --- a/applications/times-square/values.yaml +++ b/applications/times-square/values.yaml @@ -165,14 +165,11 @@ cloudsql: # -- Cloud SQL Auth Proxy tag to use tag: "1.37.4" - # -- Tag suffix to use for the proxy for schema updates - schemaUpdateTagSuffix: "-alpine" - # -- Pull policy for Cloud SQL Auth Proxy images pullPolicy: "IfNotPresent" # -- Resource requests and limits for Cloud SQL pod - # @default -- see `values.yaml` + # @default -- See `values.yaml` resources: limits: cpu: "1" diff --git a/applications/wobbly/README.md b/applications/wobbly/README.md index 638ee59fe1..75350a2e0a 100644 --- a/applications/wobbly/README.md +++ b/applications/wobbly/README.md @@ -14,7 +14,6 @@ IVOA UWS database storage | cloudsql.enabled | bool | `false` | Enable the Cloud SQL Auth Proxy sidecar, used with Cloud SQL databases on Google Cloud | | cloudsql.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for Cloud SQL Auth Proxy images | | cloudsql.image.repository | string | `"gcr.io/cloudsql-docker/gce-proxy"` | Cloud SQL Auth Proxy image to use | -| cloudsql.image.schemaUpdateTagSuffix | string | `"-alpine"` | Tag suffix to use for the proxy for schema updates | | cloudsql.image.tag | string | `"1.37.4"` | Cloud SQL Auth Proxy tag to use | | cloudsql.instanceConnectionName | string | None, must be set if Cloud SQL is used | Instance connection name for a Cloud SQL PostgreSQL instance | | cloudsql.resources | object | See `values.yaml` | Resource limits and requests for the Cloud SQL Proxy container | diff --git a/applications/wobbly/templates/_helpers.tpl b/applications/wobbly/templates/_helpers.tpl index 502c712698..9e89eba49d 100644 --- a/applications/wobbly/templates/_helpers.tpl +++ b/applications/wobbly/templates/_helpers.tpl @@ -24,3 +24,32 @@ Selector labels app.kubernetes.io/name: "wobbly" app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} + +{{/* +Cloud SQL Auth Proxy sidecar container +*/}} +{{- define "wobbly.cloudsqlSidecar" -}} +- name: "cloud-sql-proxy" + command: + - "/cloud_sql_proxy" + - "-ip_address_types=PRIVATE" + - "-log_debug_stdout=true" + - "-structured_logs=true" + - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" + image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" + imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} + {{- with .Values.cloudsql.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + restartPolicy: "Always" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "all" + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 +{{- end }} diff --git a/applications/wobbly/templates/cronjob-maintenance.yaml b/applications/wobbly/templates/cronjob-maintenance.yaml index 3b4db08b52..4ad7e88c3d 100644 --- a/applications/wobbly/templates/cronjob-maintenance.yaml +++ b/applications/wobbly/templates/cronjob-maintenance.yaml @@ -31,55 +31,10 @@ spec: automountServiceAccountToken: false {{- end }} containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - # Running the sidecar as normal causes it to keep running and - # thus the Pod never exits, the Job never finishes, and the hook - # blocks the sync. Have the main pod signal the sidecar by - # writing to a file on a shared emptyDir file system, and use a - # simple watcher loop in shell in the sidecar container to - # terminate the proxy when the main container finishes. - # - # Based on https://stackoverflow.com/questions/41679364/ - command: - - "/bin/sh" - - "-c" - - | - /cloud_sql_proxy -ip_address_types=PRIVATE -log_debug_stdout=true -structured_logs=true -instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432 & - PID=$! - while true; do - if [[ -f "/lifecycle/main-terminated" ]]; then - kill $PID - exit 0 - fi - sleep 1 - done - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}{{ .Values.cloudsql.image.schemaUpdateTagSuffix }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - {{- with .Values.cloudsql.resources }} - resources: - {{- toYaml . | nindent 16 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - volumeMounts: - - name: "lifecycle" - mountPath: "/lifecycle" - {{- end }} - name: {{ .Chart.Name }} command: - - "/bin/sh" - - "-c" - - | - wobbly expire - touch /lifecycle/main-terminated + - "wobbly" + - "expire" env: - name: "WOBBLY_DATABASE_PASSWORD" valueFrom: @@ -125,8 +80,6 @@ spec: - "all" readOnlyRootFilesystem: true volumeMounts: - - name: "lifecycle" - mountPath: "/lifecycle" {{- if .Values.config.metrics.enabled }} - name: "kafka" mountPath: "/etc/wobbly-kafka/ca.crt" @@ -141,6 +94,10 @@ spec: readOnly: true subPath: "ssl.keystore.key" {{- end }} + {{- if .Values.cloudsql.enabled }} + initContainers: + {{- include "wobbly.cloudsqlSidecar" | nindent 12 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 12 }} @@ -155,8 +112,6 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} volumes: - - name: "lifecycle" - emptyDir: {} {{- if .Values.config.metrics.enabled }} - name: "kafka" secret: diff --git a/applications/wobbly/templates/deployment.yaml b/applications/wobbly/templates/deployment.yaml index ff0d580310..6abe51d403 100644 --- a/applications/wobbly/templates/deployment.yaml +++ b/applications/wobbly/templates/deployment.yaml @@ -29,30 +29,6 @@ spec: automountServiceAccountToken: false {{- end }} containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - command: - - "/cloud_sql_proxy" - - "-ip_address_types=PRIVATE" - - "-log_debug_stdout=true" - - "-structured_logs=true" - - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - {{- with .Values.cloudsql.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - {{- end }} - name: {{ .Chart.Name }} env: - name: "WOBBLY_DATABASE_PASSWORD" @@ -136,6 +112,10 @@ spec: readOnly: true subPath: "ssl.keystore.key" {{- end }} + {{- if .Values.cloudsql.enabled }} + initContainers: + {{- include "wobbly.cloudsqlSidecar" | nindent 8 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/applications/wobbly/templates/job-schema-update.yaml b/applications/wobbly/templates/job-schema-update.yaml index 45dd412115..12531fd66a 100644 --- a/applications/wobbly/templates/job-schema-update.yaml +++ b/applications/wobbly/templates/job-schema-update.yaml @@ -31,56 +31,10 @@ spec: automountServiceAccountToken: false {{- end }} containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - # Running the sidecar as normal causes it to keep running and thus - # the Pod never exits, the Job never finishes, and the hook blocks - # the sync. Have the main pod signal the sidecar by writing to a - # file on a shared emptyDir file system, and use a simple watcher - # loop in shell in the sidecar container to terminate the proxy when - # the main container finishes. - # - # Based on https://stackoverflow.com/questions/41679364/ - command: - - "/bin/sh" - - "-c" - args: - - | - /cloud_sql_proxy -ip_address_types=PRIVATE -log_debug_stdout=true -structured_logs=true -instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432 & - PID=$! - while true; do - if [[ -f "/lifecycle/main-terminated" ]]; then - kill $PID - exit 0 - fi - sleep 1 - done - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}{{ .Values.cloudsql.image.schemaUpdateTagSuffix }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - {{- with .Values.cloudsql.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - volumeMounts: - - name: "lifecycle" - mountPath: "/lifecycle" - {{- end }} - name: "wobbly" command: - - "/bin/sh" - - "-c" - - | - wobbly update-schema - touch /lifecycle/main-terminated + - "wobbly" + - "update-schema" env: - name: "WOBBLY_DATABASE_PASSWORD" valueFrom: @@ -121,8 +75,6 @@ spec: - "all" readOnlyRootFilesystem: true volumeMounts: - - name: "lifecycle" - mountPath: "/lifecycle" {{- if .Values.config.metrics.enabled }} - name: "kafka" mountPath: "/etc/wobbly-kafka/ca.crt" @@ -137,6 +89,10 @@ spec: readOnly: true subPath: "ssl.keystore.key" {{- end }} + {{- if .Values.cloudsql.enabled }} + initContainers: + {{- include "wobbly.cloudsqlSidecar" | nindent 8 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -151,8 +107,6 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} volumes: - - name: "lifecycle" - emptyDir: {} {{- if .Values.config.metrics.enabled }} - name: "kafka" secret: diff --git a/applications/wobbly/values.yaml b/applications/wobbly/values.yaml index 59394a4db3..99f10b8a78 100644 --- a/applications/wobbly/values.yaml +++ b/applications/wobbly/values.yaml @@ -102,9 +102,6 @@ cloudsql: # -- Cloud SQL Auth Proxy tag to use tag: "1.37.4" - # -- Tag suffix to use for the proxy for schema updates - schemaUpdateTagSuffix: "-alpine" - # -- Pull policy for Cloud SQL Auth Proxy images pullPolicy: "IfNotPresent" diff --git a/charts/cadc-tap/templates/tap-deployment.yaml b/charts/cadc-tap/templates/tap-deployment.yaml index 022751cd8d..d65364d868 100644 --- a/charts/cadc-tap/templates/tap-deployment.yaml +++ b/charts/cadc-tap/templates/tap-deployment.yaml @@ -26,30 +26,6 @@ spec: automountServiceAccountToken: false {{- end }} containers: - {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - command: - - "/cloud_sql_proxy" - - "-ip_address_types=PRIVATE" - - "-log_debug_stdout=true" - - "-structured_logs=true" - - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - {{- with .Values.cloudsql.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 - {{- end }} - name: "tap-server" {{- if eq .Values.config.backend "pg" }} image: "{{ .Values.config.pg.image.repository }}:{{ .Values.config.pg.image.tag }}" @@ -159,6 +135,32 @@ spec: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 + {{- if .Values.cloudsql.enabled }} + initContainers: + - name: "cloud-sql-proxy" + command: + - "/cloud_sql_proxy" + - "-ip_address_types=PRIVATE" + - "-log_debug_stdout=true" + - "-structured_logs=true" + - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" + image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" + imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} + {{- with .Values.cloudsql.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + restartPolicy: "Always" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "all" + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + {{- end }} volumes: - name: "google-creds" secret: diff --git a/charts/cadc-tap/tests/tap-deployment_test.yaml b/charts/cadc-tap/tests/tap-deployment_test.yaml index 411db02a05..68bef71837 100644 --- a/charts/cadc-tap/tests/tap-deployment_test.yaml +++ b/charts/cadc-tap/tests/tap-deployment_test.yaml @@ -70,13 +70,13 @@ tests: name: "ssotap" asserts: - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.username=mydb" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.url=jdbc:postgresql://localhost:5432/mydb" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.password=" - equal: path: spec.template.spec.serviceAccountName @@ -105,13 +105,13 @@ tests: pullPolicy: "IfNotPresent" asserts: - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.username=mydb" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.url=jdbc:postgresql://localhost:5432/mydb" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.password=" - equal: path: spec.template.spec.serviceAccountName @@ -131,7 +131,7 @@ tests: path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.url=jdbc:postgresql://cadc-tap-uws-db/" - - it: should create two containers if cloudsql is enabled + - it: should create an init containers if cloudsql is enabled set: global: host: "example.com" @@ -154,8 +154,8 @@ tests: pullPolicy: "IfNotPresent" asserts: - lengthEqual: - path: spec.template.spec.containers - count: 2 + path: spec.template.spec.initContainers + count: 1 - it: should setup TAP_SCHEMA database configuration set: @@ -199,31 +199,31 @@ tests: gcsBucketType: "S3" asserts: - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.username=mydb" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.url=jdbc:postgresql://localhost:5432/mydb" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Duws.password=" - equal: path: spec.template.spec.serviceAccountName value: "sa" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Dqservuser.username=qsmaster" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Dqservuser.url=jdbc:mysql://qserv:30040/" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Dgcs_bucket=async-results.lsst.codes" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Dgcs_bucket_url=https://async-results.codes:8080" - matchRegex: - path: spec.template.spec.containers[1].env[0].value + path: spec.template.spec.containers[0].env[0].value pattern: "-Dgcs_bucket_type=S3" - it: Test that deployment build fails when cloudsql is enabled but no instanceConnectionName @@ -231,6 +231,7 @@ tests: cloudsql: enabled: true serviceAccount: "sa@xyz" + database: "mydb" global: host: "example.com" asserts: diff --git a/docs/developers/helm-chart/cloud-sql.rst b/docs/developers/helm-chart/cloud-sql.rst index d01fe68a4f..57a9cfbb04 100644 --- a/docs/developers/helm-chart/cloud-sql.rst +++ b/docs/developers/helm-chart/cloud-sql.rst @@ -30,34 +30,36 @@ Running a Cloud SQL sidecar container A sidecar container is the best approach if the only portions of your application that need to access Cloud SQL are long-running deployments, and particularly if there is only one such deployment. If your application uses a ``CronJob`` or other type of short-lived pod, you may find it easier to run a proxy service as described below. -To set up the Cloud SQL proxy, add code like the following to the ``spec.template.spec.containers`` field of your deployment: +To set up the Cloud SQL proxy, add code like the following to the ``spec.template.spec`` field of your deployment: .. code-block:: yaml :caption: templates/deployment.yaml {{- if .Values.cloudsql.enabled }} - - name: "cloud-sql-proxy" - command: - - "/cloud_sql_proxy" - - "-ip_address_types=PRIVATE" - - "-log_debug_stdout=true" - - "-structured_logs=true" - - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" - image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" - imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} - {{- with .Values.cloudsql.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "all" - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - runAsGroup: 65532 + initContainers: + - name: "cloud-sql-proxy" + command: + - "/cloud_sql_proxy" + - "-ip_address_types=PRIVATE" + - "-log_debug_stdout=true" + - "-structured_logs=true" + - "-instances={{ required "cloudsql.instanceConnectionName must be specified" .Values.cloudsql.instanceConnectionName }}=tcp:5432" + image: "{{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }}" + imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy | quote }} + {{- with .Values.cloudsql.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + restartPolicy: "Always" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "all" + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 {{- end }} The corresponding additional stanza for :file:`values.yaml` is: