From 13fed1118cedf88ea65a92d27f550d02fe23c41a Mon Sep 17 00:00:00 2001 From: Mike Elliott Date: Wed, 28 Feb 2018 08:33:33 -0500 Subject: Add standardized helm chart for appc This is a standardization (based on helm community best practices) of a Helm chart for the Application Controller (appc) in ONAP. How to deploy the helm chart (outside of the parent onap chart) from the local oom/kubernetes codebase. Run local helm repository in the background: $ nohup helm serve & In kubernetes directory run: $ make all 2 ways to install (--set are for testing purposes) Full onap: $ helm install onap --name onap --namespace onap --set global.pullPolicy=Never,mysql.replicaCount=2,appc.replicaCount=2 Appc only: $ helm install setup --name onap-setup --namespace onap-apps $ helm install appc --name appc --namespace onap-apps Change-Id: Ib780f979ad25ecafb08110504b5941e980ca8a95 Issue-ID: OOM-733 Signed-off-by: Mike Elliott Signed-off-by: ah415j --- kubernetes/mysql/.helmignore | 21 +++ kubernetes/mysql/Chart.yaml | 4 + kubernetes/mysql/requirements.yaml | 4 + kubernetes/mysql/templates/configmap.yaml | 18 ++ kubernetes/mysql/templates/nfs-provisoner.yaml | 62 +++++++ kubernetes/mysql/templates/pv.yaml | 22 +++ kubernetes/mysql/templates/pvc.yaml | 23 +++ kubernetes/mysql/templates/secrets.yaml | 13 ++ kubernetes/mysql/templates/service.yaml | 90 ++++++++++ kubernetes/mysql/templates/statefulset.yaml | 238 +++++++++++++++++++++++++ kubernetes/mysql/templates/storageclass.yaml | 6 + kubernetes/mysql/values.yaml | 111 ++++++++++++ 12 files changed, 612 insertions(+) create mode 100644 kubernetes/mysql/.helmignore create mode 100644 kubernetes/mysql/Chart.yaml create mode 100644 kubernetes/mysql/requirements.yaml create mode 100644 kubernetes/mysql/templates/configmap.yaml create mode 100644 kubernetes/mysql/templates/nfs-provisoner.yaml create mode 100644 kubernetes/mysql/templates/pv.yaml create mode 100644 kubernetes/mysql/templates/pvc.yaml create mode 100644 kubernetes/mysql/templates/secrets.yaml create mode 100644 kubernetes/mysql/templates/service.yaml create mode 100644 kubernetes/mysql/templates/statefulset.yaml create mode 100644 kubernetes/mysql/templates/storageclass.yaml create mode 100644 kubernetes/mysql/values.yaml (limited to 'kubernetes/mysql') diff --git a/kubernetes/mysql/.helmignore b/kubernetes/mysql/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/kubernetes/mysql/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/kubernetes/mysql/Chart.yaml b/kubernetes/mysql/Chart.yaml new file mode 100644 index 0000000000..99e7c44fb9 --- /dev/null +++ b/kubernetes/mysql/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: MySQL Server +name: mysql +version: 2.0.0 diff --git a/kubernetes/mysql/requirements.yaml b/kubernetes/mysql/requirements.yaml new file mode 100644 index 0000000000..acca8ef7e2 --- /dev/null +++ b/kubernetes/mysql/requirements.yaml @@ -0,0 +1,4 @@ +dependencies: + - name: common + version: ~2.0.0 + repository: '@local' \ No newline at end of file diff --git a/kubernetes/mysql/templates/configmap.yaml b/kubernetes/mysql/templates/configmap.yaml new file mode 100644 index 0000000000..dd2b5b7db2 --- /dev/null +++ b/kubernetes/mysql/templates/configmap.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "common.fullname" . }}-db-configmap + namespace: {{ include "common.namespace" . }} +data: + master.cnf: | + # Apply this config only on the master. + [mysqld] + log-bin + [localpathprefix] + master + slave.cnf: | + # Apply this config only on slaves. + [mysqld] + super-read-only + [localpathprefix] + slave diff --git a/kubernetes/mysql/templates/nfs-provisoner.yaml b/kubernetes/mysql/templates/nfs-provisoner.yaml new file mode 100644 index 0000000000..478224e1a1 --- /dev/null +++ b/kubernetes/mysql/templates/nfs-provisoner.yaml @@ -0,0 +1,62 @@ +#{{ if not .Values.disableNfsProvisioner }} +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + #replicas: {{ .Values.replicaCount }} + strategy: + type: Recreate + template: + metadata: + labels: + app: {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner + release: {{ .Release.Name }} + spec: + containers: + - name: {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner + image: "{{ .Values.global.nfsprovisionerRepository | default .Values.nfsprovisionerRepository }}/{{ .Values.nfsprovisionerImage }}" + imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} + ports: + - name: nfs + containerPort: {{ .Values.service.nfsPort }} + - name: mountd + containerPort: {{ .Values.service.mountdPort }} + - name: rpcbind + containerPort: {{ .Values.service.rpcbindPort }} + - name: rpcbind-udp + containerPort: {{ .Values.service.rpcbindUdpPort }} + protocol: UDP + securityContext: + capabilities: + add: + - DAC_READ_SEARCH + - SYS_RESOURCE + args: + - "-provisioner={{ include "common.fullname" . }}/nfs" + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_NAME + value: {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} + volumeMounts: + - name: export-volume + mountPath: /export + volumes: + - name: export-volume + hostPath: + path: {{ .Values.global.persistence.mountPath | default .Values.persistence.mountPath }}/{{ .Release.Namespace }}/{{ .Values.persistence.mountSubPath }} +#{{ end }} diff --git a/kubernetes/mysql/templates/pv.yaml b/kubernetes/mysql/templates/pv.yaml new file mode 100644 index 0000000000..ba128b95d0 --- /dev/null +++ b/kubernetes/mysql/templates/pv.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}} +kind: PersistentVolume +apiVersion: v1 +metadata: + name: {{ include "common.fullname" . }}-data + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.name" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" + name: {{ include "common.fullname" . }} +spec: + capacity: + storage: {{ .Values.persistence.size}} + accessModes: + - {{ .Values.persistence.accessMode }} + storageClassName: "{{ include "common.fullname" . }}-data" + persistentVolumeReclaimPolicy: {{ .Values.persistence.volumeReclaimPolicy }} + hostPath: + path: {{ .Values.global.persistence.mountPath | default .Values.persistence.mountPath }}/{{ .Release.Namespace }}/{{ .Values.persistence.mountSubPath }} +{{- end -}} diff --git a/kubernetes/mysql/templates/pvc.yaml b/kubernetes/mysql/templates/pvc.yaml new file mode 100644 index 0000000000..a2949fef36 --- /dev/null +++ b/kubernetes/mysql/templates/pvc.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ include "common.fullname" . }}-data + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +{{- if .Values.persistence.annotations }} + annotations: +{{ toYaml .Values.persistence.annotations | indent 4 }} +{{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode }} + resources: + requests: + storage: {{ .Values.persistence.size }} + storageClassName: "{{ include "common.fullname" . }}-data" +{{- end -}} \ No newline at end of file diff --git a/kubernetes/mysql/templates/secrets.yaml b/kubernetes/mysql/templates/secrets.yaml new file mode 100644 index 0000000000..7604be8239 --- /dev/null +++ b/kubernetes/mysql/templates/secrets.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.fullname" . }} + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.fullname" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + db-root-password: {{ .Values.config.dbRootPassword | b64enc | quote }} \ No newline at end of file diff --git a/kubernetes/mysql/templates/service.yaml b/kubernetes/mysql/templates/service.yaml new file mode 100644 index 0000000000..c6a28c4605 --- /dev/null +++ b/kubernetes/mysql/templates/service.yaml @@ -0,0 +1,90 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.name }} + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + ports: + - port: {{ .Values.service.internalPort }} + name: {{ .Values.service.name }} + selector: + app: {{ include "common.name" . }} + release: {{ .Release.Name }} + clusterIP: None +#{{ if not .Values.disableNfsProvisioner }} +--- +kind: Service +apiVersion: v1 +metadata: + name: {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner + namespace: {{ include "common.namespace" . }} + labels: + app: {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner +spec: + ports: + - name: nfs + port: {{ .Values.service.nfsPort }} + - name: mountd + port: {{ .Values.service.mountdPort }} + - name: rpcbind + port: {{ .Values.service.rpcbindPort }} + - name: rpcbind-udp + port: {{ .Values.service.rpcbindUdpPort }} + protocol: UDP + selector: + app: {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner +#{{ end }} +--- +# Client service for connecting to any MySQL instance for reads. +# Only master: sdnc-dbhost-0 accepts the write request. +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.name }}-read + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.name" . }} +spec: + ports: + - port: {{ .Values.service.internalPort }} + name: {{ .Values.service.name }} + selector: + app: {{ include "common.name" . }} + release: {{ .Release.Name }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.sdnctlPrefix }}-sdnctldb01 + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.name" . }} +spec: + ports: + - port: {{ .Values.service.internalPort }} + name: {{ .Values.service.name }} + selector: + app: {{ include "common.name" . }} + release: {{ .Release.Name }} + clusterIP: None +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.sdnctlPrefix }}-sdnctldb02 + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.name" . }} +spec: + ports: + - port: {{ .Values.service.internalPort }} + name: {{ .Values.service.name }} + selector: + app: {{ include "common.name" . }} + release: {{ .Release.Name }} + clusterIP: None diff --git a/kubernetes/mysql/templates/statefulset.yaml b/kubernetes/mysql/templates/statefulset.yaml new file mode 100644 index 0000000000..7b55bf2be0 --- /dev/null +++ b/kubernetes/mysql/templates/statefulset.yaml @@ -0,0 +1,238 @@ +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: {{ include "common.fullname" . }} + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + serviceName: {{ .Values.service.name }} + replicas: {{ .Values.replicaCount }} + template: + metadata: + labels: + app: {{ include "common.name" . }} + release: {{ .Release.Name }} + spec: + initContainers: +#{{ if not .Values.disableNfsProvisioner }} + - name: {{ include "common.name" . }}-readiness + command: + - /root/ready.py + args: + - --container-name + - {{ .Values.nfsprovisionerPrefix }}-nfs-provisioner + env: + - name: NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + image: "{{ .Values.global.readinessRepository }}/{{ .Values.global.readinessImage }}" + imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} +#{{ end }} + - name: init-mysql + image: "{{ .Values.repository | default .Values.repository }}/{{ .Values.image }}" + imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} + command: + - bash + - "-c" + - | + set -ex + # Generate mysql server-id from pod ordinal index. + [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 + ordinal=${BASH_REMATCH[1]} + echo BASH_REMATCH=${BASH_REMATCH} + echo [mysqld] > /mnt/conf.d/server-id.cnf + # Add an offset to avoid reserved server-id=0 value. + echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf + # Copy appropriate conf.d files from config-map to emptyDir. + if [[ $ordinal -eq 0 ]]; then + cp /mnt/config-map/master.cnf /mnt/conf.d/ + else + cp /mnt/config-map/slave.cnf /mnt/conf.d/ + fi + volumeMounts: + - name: conf + mountPath: /mnt/conf.d + - name: config-map + mountPath: /mnt/config-map + + - name: clone-mysql + image: "{{ .Values.global.xtrabackupRepository | default .Values.xtrabackupRepository }}/{{ .Values.xtrabackupImage }}" + imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.fullname" . }} + key: db-root-password + command: + - bash + - "-c" + - | + set -ex + # Skip the clone if data already exists. + [[ -d /var/lib/mysql/mysql ]] && exit 0 + # Skip the clone on master (ordinal index 0). + [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 + ordinal=${BASH_REMATCH[1]} + echo ${BASH_REMATCH} + [[ $ordinal -eq 0 ]] && exit 0 + # Clone data from previous peer. + ncat --recv-only {{ template "common.name" . }}-$(($ordinal-1)).{{ .Values.service.name }}.{{ include "common.namespace" . }} 3307 | xbstream -x -C /var/lib/mysql + # Prepare the backup. + xtrabackup --user=root --password=$MYSQL_ROOT_PASSWORD --prepare --target-dir=/var/lib/mysql + ls -l /var/lib/mysql + volumeMounts: + - name: {{ include "common.fullname" . }}-data + mountPath: /var/lib/mysql + subPath: mysql + - name: conf + mountPath: /etc/mysql/conf.d + + containers: + #sdnc-db-container + - name: {{ include "common.name" . }} + image: "{{ .Values.repository | default .Values.repository }}/{{ .Values.image }}" + imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} + ports: + - containerPort: {{ .Values.service.internalPort }} + # disable liveness probe when breakpoints set in debugger + # so K8s doesn't restart unresponsive container + {{- if eq .Values.liveness.enabled true }} + livenessProbe: + exec: + command: ["mysqladmin", "ping"] + initialDelaySeconds: {{ .Values.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.liveness.periodSeconds }} + timeoutSeconds: {{ .Values.liveness.timeoutSeconds }} + {{end -}} + readinessProbe: + tcpSocket: + port: {{ .Values.service.internalPort }} + initialDelaySeconds: {{ .Values.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.readiness.periodSeconds }} + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.fullname" . }} + key: db-root-password + - name: MYSQL_ROOT_HOST + value: '%' + - name: MYSQL_ALLOW_EMPTY_PASSWORD + value: {{ .Values.config.dbAllowEmptyPassword | default "0" | quote }} + volumeMounts: + - mountPath: /var/lib/mysql + name: {{ include "common.fullname" . }}-data + subPath: mysql + - mountPath: /etc/mysql/conf.d + name: conf + resources: +{{ toYaml .Values.resources | indent 12 }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 10 }} + {{- end -}} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 10 }} + {{- end }} + + - name: xtrabackup + image: "{{ .Values.global.xtrabackupRepository | default .Values.xtrabackupRepository }}/{{ .Values.xtrabackupImage }}" + imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "common.fullname" . }} + key: db-root-password + ports: + - containerPort: {{ .Values.xtrabackup.internalPort }} + name: xtrabackup + command: + - bash + - "-c" + - | + set -ex + cd /var/lib/mysql + ls -l + # Determine binlog position of cloned data, if any. + if [[ -f xtrabackup_slave_info ]]; then + echo "Inside xtrabackup_slave_info" + # XtraBackup already generated a partial "CHANGE MASTER TO" query + # because we're cloning from an existing slave. + mv xtrabackup_slave_info change_master_to.sql.in + # Ignore xtrabackup_binlog_info in this case (it's useless). + rm -f xtrabackup_binlog_info + elif [[ -f xtrabackup_binlog_info ]]; then + echo "Inside xtrabackup_binlog_info" + # We're cloning directly from master. Parse binlog position. + [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1 + rm xtrabackup_binlog_info + echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\ + MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in + fi + + # Check if we need to complete a clone by starting replication. + if [[ -f change_master_to.sql.in ]]; then + echo "Waiting for mysqld to be ready (accepting connections)" + [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 + ordinal=${BASH_REMATCH[1]} + echo $ordinal + until mysql --user=root --password=$MYSQL_ROOT_PASSWORD -h localhost -e "SELECT 1"; do sleep 1; done + + echo "Initializing replication from clone position" + # In case of container restart, attempt this at-most-once. + mv change_master_to.sql.in change_master_to.sql.orig + mysql --user=root --password=$MYSQL_ROOT_PASSWORD -h localhost < + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + accessMode: ReadWriteMany + size: 1Gi + mountPath: /dockerdata-nfs + mountSubPath: mysql/data + +service: + name: mysql + internalPort: 3306 + # nfs provisioner ports + nfsPort: 2049 + mountdPort: 20048 + rpcbindPort: 111 + rpcbindUdpPort: 111 + +ingress: + enabled: false + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # + # Example: + # Configure resource requests and limits + # ref: http://kubernetes.io/docs/user-guide/compute-resources/ + # Minimum memory for development is 2 CPU cores and 4GB memory + # Minimum memory for production is 4 CPU cores and 8GB memory +#resources: +# limits: +# cpu: 2 +# memory: 4Gi +# requests: +# cpu: 2 +# memory: 4Gi + +################################################################# +# Sidecar Configuration. +# +# xtrabackup configuration defaults. +################################################################# +xtrabackupRepository: gcr.io/google-samples +xtrabackupImage: xtrabackup:1.0 +xtrabackup: + internalPort: 3307 + +nfsprovisionerRepository: quay.io +nfsprovisionerImage: kubernetes_incubator/nfs-provisioner:v1.0.8 +nfsprovisionerPrefix: mysql + +sdnctlPrefix: mysql -- cgit 1.2.3-korg