diff --git a/charts/tidb-drainer/.helmignore b/charts/tidb-drainer/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/tidb-drainer/.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/charts/tidb-drainer/Chart.yaml b/charts/tidb-drainer/Chart.yaml new file mode 100644 index 0000000000..4794f6cb1c --- /dev/null +++ b/charts/tidb-drainer/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +description: A Helm chart for TiDB Binlog drainer. +name: tidb-drainer +version: dev +home: https://github.com/pingcap/tidb-operator +sources: + - https://github.com/pingcap/tidb-operator +keywords: + - newsql + - htap + - database + - mysql + - cdc diff --git a/charts/tidb-drainer/templates/NOTES.txt b/charts/tidb-drainer/templates/NOTES.txt new file mode 100644 index 0000000000..a7cbad366c --- /dev/null +++ b/charts/tidb-drainer/templates/NOTES.txt @@ -0,0 +1,6 @@ +StatefulSet {{ include "drainer.name" . }} installed. + +1. Watch if the drainer instance gets created: + watch kubectl get pod -n {{ .Release.Namespace }} {{ include "drainer.name" . }}-0 +2. Check if the drainer instance works properly: + kubectl logs -f -n {{ .Release.Namespace }} {{ include "drainer.name" . }}-0 \ No newline at end of file diff --git a/charts/tidb-drainer/templates/_helpers.tpl b/charts/tidb-drainer/templates/_helpers.tpl new file mode 100644 index 0000000000..082f3615cc --- /dev/null +++ b/charts/tidb-drainer/templates/_helpers.tpl @@ -0,0 +1,25 @@ +{{- define "drainer.name" -}} +{{ .Values.clusterName }}-{{ .Release.Name }}-drainer +{{- end -}} + +{{/* +Encapsulate config data for consistent digest calculation +*/}} +{{- define "drainer-configmap.data" -}} +config-file: |- + {{- if .Values.config }} +{{ .Values.config | indent 2 }} + {{- end -}} +{{- end -}} + +{{- define "drainer-configmap.name" -}} +{{ include "drainer.name" . }}-{{ include "drainer-configmap.data" . | sha256sum | trunc 8 }} +{{- end -}} + +{{- define "helm-toolkit.utils.template" -}} +{{- $name := index . 0 -}} +{{- $context := index . 1 -}} +{{- $last := base $context.Template.Name }} +{{- $wtf := $context.Template.Name | replace $last $name -}} +{{ include $wtf $context }} +{{- end -}} diff --git a/charts/tidb-drainer/templates/drainer-configmap.yaml b/charts/tidb-drainer/templates/drainer-configmap.yaml new file mode 100644 index 0000000000..f64ecf0a6b --- /dev/null +++ b/charts/tidb-drainer/templates/drainer-configmap.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "drainer-configmap.name" . }} + labels: + app.kubernetes.io/name: {{ include "drainer-configmap.name" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: drainer + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} +data: +{{ include "drainer-configmap.data" . | indent 2 }} diff --git a/charts/tidb-drainer/templates/drainer-service.yaml b/charts/tidb-drainer/templates/drainer-service.yaml new file mode 100644 index 0000000000..215d893d37 --- /dev/null +++ b/charts/tidb-drainer/templates/drainer-service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "drainer.name" . }} + labels: + app.kubernetes.io/name: {{ include "drainer.name" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: drainer + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} +spec: + clusterIP: None + ports: + - name: drainer + port: 8249 + selector: + app.kubernetes.io/name: {{ include "drainer.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: drainer diff --git a/charts/tidb-drainer/templates/drainer-statefulset.yaml b/charts/tidb-drainer/templates/drainer-statefulset.yaml new file mode 100644 index 0000000000..0590373f7b --- /dev/null +++ b/charts/tidb-drainer/templates/drainer-statefulset.yaml @@ -0,0 +1,78 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "drainer.name" . }} + labels: + app.kubernetes.io/name: {{ include "drainer.name" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: drainer + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ include "drainer.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: drainer + serviceName: {{ include "drainer.name" . }} + replicas: 1 + template: + metadata: + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: "/metrics" + prometheus.io/port: "8249" + labels: + app.kubernetes.io/name: {{ include "drainer.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: drainer + spec: + containers: + - name: drainer + image: {{ .Values.baseImage }}:{{ .Values.clusterVersion }} + imagePullPolicy: {{ .Values.imagePullPolicy | default "IfNotPresent" }} + command: + - /bin/sh + - -c + - |- +{{ tuple "scripts/_start_drainer.sh.tpl" . | include "helm-toolkit.utils.template" | indent 10 }} + ports: + - containerPort: 8249 + name: drainer + volumeMounts: + - name: data + mountPath: /data + - name: config + mountPath: /etc/drainer + resources: +{{ toYaml .Values.resources | indent 10 }} + volumes: + - name: config + configMap: + name: {{ include "drainer-configmap.name" . }} + items: + - key: config-file + path: drainer.toml + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.storageClassName }} + resources: + requests: + storage: {{ .Values.storage }} diff --git a/charts/tidb-drainer/templates/scripts/_start_drainer.sh.tpl b/charts/tidb-drainer/templates/scripts/_start_drainer.sh.tpl new file mode 100644 index 0000000000..1bc0b1d66b --- /dev/null +++ b/charts/tidb-drainer/templates/scripts/_start_drainer.sh.tpl @@ -0,0 +1,34 @@ +set -euo pipefail + +domain=`echo ${HOSTNAME}`.{{ include "drainer.name" . }} + +elapseTime=0 +period=1 +threshold=30 +while true; do + sleep ${period} + elapseTime=$(( elapseTime+period )) + + if [[ ${elapseTime} -ge ${threshold} ]] + then + echo "waiting for drainer domain ready timeout" >&2 + exit 1 + fi + + if nslookup ${domain} 2>/dev/null + then + echo "nslookup domain ${domain} success" + break + else + echo "nslookup domain ${domain} failed" >&2 + fi +done + +/drainer \ +-L={{ .Values.logLevel | default "info" }} \ +-pd-urls=http://{{ .Values.clusterName }}-pd:2379 \ +-addr=`echo ${HOSTNAME}`.{{ include "drainer.name" . }}:8249 \ +-config=/etc/drainer/drainer.toml \ +-disable-detect={{ .Values.disableDetect | default false }} \ +-initial-commit-ts={{ .Values.initialCommitTs | default 0 }} \ +-log-file="" diff --git a/charts/tidb-drainer/values.yaml b/charts/tidb-drainer/values.yaml new file mode 100644 index 0000000000..e327c0f750 --- /dev/null +++ b/charts/tidb-drainer/values.yaml @@ -0,0 +1,52 @@ +# Default values for tidb-drainer. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates + +# clusterName is the TiDB cluster name that should backup from or restore to. +clusterName: demo +clusterVersion: v3.0.1 + +baseImage: pingcap/tidb-binlog +imagePullPolicy: IfNotPresent + +logLevel: info +# storageClassName is a StorageClass provides a way for administrators to describe the "classes" of storage they offer. +# different classes might map to quality-of-service levels, or to backup policies, +# or to arbitrary policies determined by the cluster administrators. +# refer to https://kubernetes.io/docs/concepts/storage/storage-classes +storageClassName: local-storage +storage: 10Gi +# disbale detect causality +disableDetect: false +# if drainer donesn't have checkpoint, use initial commitTS to initial checkpoint +initialCommitTs: 0 + +# Refer to https://github.com/pingcap/tidb-binlog/blob/master/cmd/drainer/drainer.toml +config: | + [syncer] + worker-count = 16 + detect-interval = 10 + disable-dispatch = false + ignore-schemas = "INFORMATION_SCHEMA,PERFORMANCE_SCHEMA,mysql" + safe-mode = false + txn-batch = 20 + db-type = "pb" + [syncer.to] + dir = "/data/pb" + compression = "gzip" + +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:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m +nodeSelector: {} + +tolerations: [] + +affinity: {} \ No newline at end of file diff --git a/tests/pkg/metrics/annotation_util.go b/tests/pkg/metrics/annotation_util.go index 65c4320452..13385ee7cc 100644 --- a/tests/pkg/metrics/annotation_util.go +++ b/tests/pkg/metrics/annotation_util.go @@ -92,7 +92,6 @@ func initErrorMetric() prometheus.Counter { }) } - //AddAnnotation adds an annotation to grafana. func (cli *Client) AddAnnotation(annotation Annotation) error { body, err := annotation.getBody()