diff --git a/stable/mysql/Chart.yaml b/stable/mysql/Chart.yaml index 26811b9bab..8147481d9f 100644 --- a/stable/mysql/Chart.yaml +++ b/stable/mysql/Chart.yaml @@ -1,5 +1,5 @@ name: mysql -version: 0.3.7 +version: 0.4.0 appVersion: 5.7.14 description: Fast, reliable, scalable, and easy to use open-source relational database system. diff --git a/stable/mysql/README.md b/stable/mysql/README.md index 748884ce02..6784401b94 100644 --- a/stable/mysql/README.md +++ b/stable/mysql/README.md @@ -71,6 +71,12 @@ The following table lists the configurable parameters of the MySQL chart and the | `persistence.subPath` | Subdirectory of the volume to mount | `nil` | | `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | | `configurationFiles` | List of mysql configuration files | `nil` | +| `ssl.enabled` | Setup and use SSL for MySQL connections | `false` | +| `ssl.secret` | Name of the secret containing the SSL certificates | mysql-ssl-certs | +| `ssl.certificates[0].name` | Name of the secret containing the SSL certificates | `nil` | +| `ssl.certificates[0].ca` | CA certificate | `nil` | +| `ssl.certificates[0].cert` | Server certificate (public key) | `nil` | +| `ssl.certificates[0].key` | Server key (private key) | `nil` | Some of the parameters above map to the env variables defined in the [MySQL DockerHub image](https://hub.docker.com/_/mysql/). @@ -115,3 +121,51 @@ configurationFiles: mysql_custom.cnf: |- [mysqld] ``` + +## SSL + +This chart supports configuring MySQL to use [encrypted connections](https://dev.mysql.com/doc/refman/5.7/en/encrypted-connections.html) with TLS/SSL certificates provided by the user. This is accomplished by storing the required Certificate Authority file, the server public key certificate, and the server private key as a Kubernetes secret. The SSL options for this chart support the following use cases: + +* Manage certificate secrets with helm +* Manage certificate secrets outside of helm + +## Manage certificate secrets with helm + +Include your certificate data in the `ssl.certificates` section. For example: + +``` +ssl: + enabled: false + secret: mysql-ssl-certs + certificates: + - name: mysql-ssl-certs + ca: |- + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + cert: |- + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + key: |- + -----BEGIN RSA PRIVATE KEY----- + ... + -----END RSA PRIVATE KEY----- +``` + +> **Note**: Make sure your certificate data has the correct formatting in the values file. + +## Manage certficate secrets outside of helm + +1. Ensure the certificate secret exist before installation of this chart. +2. Set the name of the certficate secret in `ssl.secret`. +3. Make sure there are no entries underneath `ssl.certificates`. + +To manually create the certificate secret from local files you can execute: +``` +kubectl create secret generic mysql-ssl-certs \ + --from-file=ca.pem=./ssl/certificate-authority.pem \ + --from-file=server-cert.pem=./ssl/server-public-key.pem \ + --from-file=server-key.pem=./ssl/server-private-key.pem +``` +> **Note**: `ca.pem`, `server-cert.pem`, and `server-key.pem` **must** be used as the key names in this generic secret. \ No newline at end of file diff --git a/stable/mysql/templates/deployment.yaml b/stable/mysql/templates/deployment.yaml index b6358f7809..a497a8aeb7 100644 --- a/stable/mysql/templates/deployment.yaml +++ b/stable/mysql/templates/deployment.yaml @@ -99,12 +99,21 @@ spec: - name: configurations mountPath: /etc/mysql/conf.d {{- end }} + {{- if .Values.ssl.enabled }} + - name: certificates + mountPath: /ssl + {{- end }} volumes: {{- if .Values.configurationFiles }} - name: configurations configMap: name: {{ template "mysql.fullname" . }} {{- end }} + {{- if .Values.ssl.enabled }} + - name: certificates + secret: + secretName: {{ .Values.ssl.secret }} + {{- end }} - name: data {{- if .Values.persistence.enabled }} persistentVolumeClaim: diff --git a/stable/mysql/templates/secrets.yaml b/stable/mysql/templates/secrets.yaml index 8048918e50..dbd1efa354 100644 --- a/stable/mysql/templates/secrets.yaml +++ b/stable/mysql/templates/secrets.yaml @@ -19,3 +19,22 @@ data: {{ else }} mysql-password: {{ randAlphaNum 10 | b64enc | quote }} {{ end }} +{{- if .Values.ssl.enabled }} +{{- range .Values.ssl.certificates }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + labels: + app: {{ template "mysql.fullname" $ }} + chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" + release: "{{ $.Release.Name }}" + heritage: "{{ $.Release.Service }}" +type: Opaque +data: + ca.pem: {{ .ca | b64enc }} + server-cert.pem: {{ .cert | b64enc }} + server-key.pem: {{ .key | b64enc }} +{{- end }} +{{- end }} diff --git a/stable/mysql/templates/tests/test-configmap.yaml b/stable/mysql/templates/tests/test-configmap.yaml new file mode 100644 index 0000000000..fad99d3e14 --- /dev/null +++ b/stable/mysql/templates/tests/test-configmap.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "mysql.fullname" . }}-test + labels: + app: {{ template "mysql.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: "{{ .Release.Service }}" + release: "{{ .Release.Name }}" +data: + run.sh: |- + {{- if .Values.ssl.enabled | and .Values.mysqlRootPassword }} + @test "Testing SSL MySQL Connection" { + mysql --host={{ template "mysql.fullname" . }} --port={{ .Values.service.port | default "3306" }} --ssl-cert=/ssl/server-cert.pem --ssl-key=ssl/server-key.pem -u root -p{{ .Values.mysqlRootPassword }} + } + {{- else if .Values.mysqlRootPassword }} + @test "Testing MySQL Connection" { + mysql --host={{ template "mysql.fullname" . }} --port={{ .Values.service.port | default "3306" }} -u root -p{{ .Values.mysqlRootPassword }} + } + {{- end }} + diff --git a/stable/mysql/templates/tests/test.yaml b/stable/mysql/templates/tests/test.yaml new file mode 100644 index 0000000000..2e2f8f8466 --- /dev/null +++ b/stable/mysql/templates/tests/test.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "mysql.fullname" . }}-test + labels: + app: {{ template "mysql.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: "{{ .Release.Service }}" + release: "{{ .Release.Name }}" + annotations: + "helm.sh/hook": test-success +spec: + initContainers: + - name: test-framework + image: dduportal/bats:0.4.0 + command: + - "bash" + - "-c" + - | + set -ex + # copy bats to tools dir + cp -R /usr/local/libexec/ /tools/bats/ + volumeMounts: + - mountPath: /tools + name: tools + containers: + - name: {{ .Release.Name }}-test + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + command: ["/tools/bats/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + - mountPath: /tools + name: tools + {{- if .Values.ssl.enabled }} + - name: certificates + mountPath: /ssl + {{- end }} + volumes: + - name: tests + configMap: + name: {{ template "mysql.fullname" . }}-test + - name: tools + emptyDir: {} + {{- if .Values.ssl.enabled }} + - name: certificates + secret: + secretName: {{ .Values.ssl.secret }} + {{- end }} + restartPolicy: Never diff --git a/stable/mysql/values.yaml b/stable/mysql/values.yaml index db02fdbbe5..fa1490bf49 100644 --- a/stable/mysql/values.yaml +++ b/stable/mysql/values.yaml @@ -73,7 +73,9 @@ configurationFiles: # mysql.cnf: |- # [mysqld] # skip-name-resolve - +# ssl-ca=/ssl/ca.pem +# ssl-cert=/ssl/server-cert.pem +# ssl-key=/ssl/server-key.pem ## Configure the service ## ref: http://kubernetes.io/docs/user-guide/services/ @@ -83,3 +85,21 @@ service: type: ClusterIP port: 3306 # nodePort: 32000 + +ssl: + enabled: false + secret: mysql-ssl-certs + certificates: +# - name: mysql-ssl-certs +# ca: |- +# -----BEGIN CERTIFICATE----- +# ... +# -----END CERTIFICATE----- +# cert: |- +# -----BEGIN CERTIFICATE----- +# ... +# -----END CERTIFICATE----- +# key: |- +# -----BEGIN RSA PRIVATE KEY----- +# ... +# -----END RSA PRIVATE KEY-----