Skip to content

Commit

Permalink
Merge pull request #155 from zhyass/script
Browse files Browse the repository at this point in the history
add post-start and pre-stop script
  • Loading branch information
andyli029 authored Jul 30, 2021
2 parents 79babb2 + d6e3c7a commit fff1968
Show file tree
Hide file tree
Showing 28 changed files with 1,129 additions and 312 deletions.
10 changes: 8 additions & 2 deletions api/v1alpha1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,15 @@ type ClusterSpec struct {
// +kubebuilder:default:=3
Replicas *int32 `json:"replicas,omitempty"`

// The number of pods from that set that must still be available after the
// eviction, even in the absence of the evicted pod
// +optional
// +kubebuilder:default:="50%"
MinAvailable string `json:"minAvailable,omitempty"`

// MysqlOpts is the options of MySQL container.
// +optional
// +kubebuilder:default:={rootPassword: "", rootHost: "127.0.0.1", user: "qc_usr", password: "Qing@123", database: "qingcloud", initTokuDB: true, resources: {limits: {cpu: "500m", memory: "1Gi"}, requests: {cpu: "100m", memory: "256Mi"}}}
// +kubebuilder:default:={rootPassword: "", rootHost: "localhost", user: "qc_usr", password: "Qing@123", database: "qingcloud", initTokuDB: true, resources: {limits: {cpu: "500m", memory: "1Gi"}, requests: {cpu: "100m", memory: "256Mi"}}}
MysqlOpts MysqlOpts `json:"mysqlOpts,omitempty"`

// XenonOpts is the options of xenon container.
Expand Down Expand Up @@ -80,7 +86,7 @@ type MysqlOpts struct {

// The root user's host.
// +optional
// +kubebuilder:default:="127.0.0.1"
// +kubebuilder:default:="localhost"
RootHost string `json:"rootHost,omitempty"`

// Username of new user to create.
Expand Down
297 changes: 275 additions & 22 deletions charts/mysql-operator/crds/mysql.radondb.com_clusters.yaml

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions charts/mysql-operator/templates/cluster_rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ rules:
- get
- patch
- update
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand Down
8 changes: 7 additions & 1 deletion cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ func (c *Cluster) Validate() error {
return fmt.Errorf("spec.mysqlOpts.user cannot be root|%s|%s|%s", utils.ReplicationUser, utils.OperatorUser, utils.MetricsUser)
}

// https://github.com/percona/percona-docker/blob/main/percona-server-5.7/ps-entry.sh#L159
// ERROR 1396 (HY000): Operation CREATE USER failed for 'root'@'127.0.0.1'.
if c.Spec.MysqlOpts.RootHost == "127.0.0.1" {
return fmt.Errorf("spec.mysqlOpts.rootHost cannot be 127.0.0.1")
}

return nil
}

Expand Down Expand Up @@ -248,7 +254,7 @@ func (c *Cluster) EnsureVolumeClaimTemplates(schema *runtime.Scheme) ([]corev1.P
// GetNameForResource returns the name of a resource from above
func (c *Cluster) GetNameForResource(name utils.ResourceName) string {
switch name {
case utils.StatefulSet, utils.ConfigMap, utils.HeadlessSVC:
case utils.StatefulSet, utils.ConfigMap, utils.HeadlessSVC, utils.PodDisruptionBudget:
return fmt.Sprintf("%s-mysql", c.Name)
case utils.LeaderService:
return fmt.Sprintf("%s-leader", c.Name)
Expand Down
44 changes: 2 additions & 42 deletions cluster/container/init_mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
},
MysqlVersion: "5.7",
MysqlOpts: mysqlv1alpha1.MysqlOpts{
RootHost: "localhost",
InitTokuDB: false,
},
},
Expand All @@ -54,11 +55,6 @@ var (
Name: utils.ConfVolumeName,
MountPath: utils.ConfVolumeMountPath,
},
{
Name: utils.ConfMapVolumeName,
MountPath: utils.MyCnfMountPath,
SubPath: "my.cnf",
},
{
Name: utils.DataVolumeName,
MountPath: utils.DataVolumeMountPath,
Expand All @@ -82,7 +78,7 @@ var (
},
{
Name: "MYSQL_ROOT_HOST",
Value: "127.0.0.1",
Value: "localhost",
},
{
Name: "MYSQL_INIT_ONLY",
Expand All @@ -100,42 +96,6 @@ var (
},
},
},
{
Name: "MYSQL_DATABASE",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: sctName,
},
Key: "mysql-database",
Optional: &optTrue,
},
},
},
{
Name: "MYSQL_USER",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: sctName,
},
Key: "mysql-user",
Optional: &optTrue,
},
},
},
{
Name: "MYSQL_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: sctName,
},
Key: "mysql-password",
Optional: &optTrue,
},
},
},
}
initMysqlCase = EnsureContainer("init-mysql", &testInitMysqlCluster)
)
Expand Down
11 changes: 10 additions & 1 deletion cluster/container/init_sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package container

import (
"fmt"
"strconv"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -69,6 +70,14 @@ func (c *initSidecar) getEnvVars() []corev1.EnvVar {
Name: "SERVICE_NAME",
Value: c.GetNameForResource(utils.HeadlessSVC),
},
{
Name: "STATEFULSET_NAME",
Value: c.GetNameForResource(utils.StatefulSet),
},
{
Name: "REPLICAS",
Value: fmt.Sprintf("%d", *c.Spec.Replicas),
},
{
Name: "ADMIT_DEFEAT_HEARBEAT_COUNT",
Value: strconv.Itoa(int(*c.Spec.XenonOpts.AdmitDefeatHearbeatCount)),
Expand All @@ -78,7 +87,7 @@ func (c *initSidecar) getEnvVars() []corev1.EnvVar {
Value: strconv.Itoa(int(*c.Spec.XenonOpts.ElectionTimeout)),
},
{
Name: "MY_MYSQL_VERSION",
Name: "MYSQL_VERSION",
Value: c.GetMySQLVersion(),
},
getEnvVarFromSecret(sctName, "MYSQL_ROOT_PASSWORD", "root-password", false),
Expand Down
51 changes: 49 additions & 2 deletions cluster/container/init_sidecar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package container

import (
"fmt"
"strconv"
"testing"

Expand All @@ -32,11 +33,13 @@ import (
var (
defeatCount int32 = 1
electionTimeout int32 = 5
replicas int32 = 3
initSidecarMysqlCluster = mysqlv1alpha1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Name: "sample",
},
Spec: mysqlv1alpha1.ClusterSpec{
Replicas: &replicas,
PodSpec: mysqlv1alpha1.PodSpec{
SidecarImage: "sidecar image",
Resources: corev1.ResourceRequirements{
Expand Down Expand Up @@ -80,6 +83,14 @@ var (
Name: "SERVICE_NAME",
Value: "sample-mysql",
},
{
Name: "STATEFULSET_NAME",
Value: "sample-mysql",
},
{
Name: "REPLICAS",
Value: fmt.Sprintf("%d", *testInitSidecarCluster.Spec.Replicas),
},
{
Name: "ADMIT_DEFEAT_HEARBEAT_COUNT",
Value: strconv.Itoa(int(*testInitSidecarCluster.Spec.XenonOpts.AdmitDefeatHearbeatCount)),
Expand All @@ -89,7 +100,7 @@ var (
Value: strconv.Itoa(int(*testInitSidecarCluster.Spec.XenonOpts.ElectionTimeout)),
},
{
Name: "MY_MYSQL_VERSION",
Name: "MYSQL_VERSION",
Value: "5.7.33",
},
{
Expand All @@ -104,6 +115,42 @@ var (
},
},
},
{
Name: "MYSQL_DATABASE",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: sctName,
},
Key: "mysql-database",
Optional: &optTrue,
},
},
},
{
Name: "MYSQL_USER",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: sctName,
},
Key: "mysql-user",
Optional: &optTrue,
},
},
},
{
Name: "MYSQL_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: sctName,
},
Key: "mysql-password",
Optional: &optTrue,
},
},
},
{
Name: "MYSQL_REPL_USER",
ValueFrom: &corev1.EnvVarSource{
Expand Down Expand Up @@ -228,7 +275,7 @@ func TestGetInitSidecarEnvVar(t *testing.T) {
Cluster: &testToKuDBMysqlCluster,
}
tokudbCase := EnsureContainer("init-sidecar", &testTokuDBCluster)
testTokuDBEnv := make([]corev1.EnvVar, 13)
testTokuDBEnv := make([]corev1.EnvVar, 18)
copy(testTokuDBEnv, defaultInitSidecarEnvs)
testTokuDBEnv = append(testTokuDBEnv, corev1.EnvVar{
Name: "INIT_TOKUDB",
Expand Down
11 changes: 3 additions & 8 deletions cluster/container/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func TestGetMysqlLivenessProbe(t *testing.T) {
livenessProbe := &corev1.Probe{
Handler: corev1.Handler{
Exec: &corev1.ExecAction{
Command: []string{"sh", "-c", "mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD}"},
Command: []string{"sh", "-c", "mysqladmin --defaults-file=/etc/mysql/client.conf ping"},
},
},
InitialDelaySeconds: 30,
Expand All @@ -123,7 +123,7 @@ func TestGetMysqlReadinessProbe(t *testing.T) {
readinessProbe := &corev1.Probe{
Handler: corev1.Handler{
Exec: &corev1.ExecAction{
Command: []string{"sh", "-c", `mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1"`},
Command: []string{"sh", "-c", `test $(mysql --defaults-file=/etc/mysql/client.conf -NB -e "SELECT 1") -eq 1`},
},
},
InitialDelaySeconds: 10,
Expand All @@ -139,12 +139,7 @@ func TestGetMysqlVolumeMounts(t *testing.T) {
volumeMounts := []corev1.VolumeMount{
{
Name: "conf",
MountPath: "/etc/mysql/conf.d",
},
{
Name: "config-map",
MountPath: "/etc/mysql/my.cnf",
SubPath: "my.cnf",
MountPath: "/etc/mysql",
},
{
Name: "data",
Expand Down
10 changes: 6 additions & 4 deletions cluster/container/xenon.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ limitations under the License.
package container

import (
"fmt"

corev1 "k8s.io/api/core/v1"

"github.com/radondb/radondb-mysql-kubernetes/cluster"
Expand Down Expand Up @@ -55,11 +53,15 @@ func (c *xenon) getEnvVars() []corev1.EnvVar {

// getLifecycle get the container lifecycle.
func (c *xenon) getLifecycle() *corev1.Lifecycle {
arg := fmt.Sprintf("until (xenoncli xenon ping && xenoncli cluster add %s) > /dev/null 2>&1; do sleep 2; done", c.CreatePeers())
return &corev1.Lifecycle{
PostStart: &corev1.Handler{
Exec: &corev1.ExecAction{
Command: []string{"sh", "-c", arg},
Command: []string{"sh", "-c", "/scripts/post-start.sh"},
},
},
PreStop: &corev1.Handler{
Exec: &corev1.ExecAction{
Command: []string{"sh", "-c", "/scripts/pre-stop.sh"},
},
},
}
Expand Down
9 changes: 6 additions & 3 deletions cluster/container/xenon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,12 @@ func TestGetXenonLifecycle(t *testing.T) {
lifecycle := &corev1.Lifecycle{
PostStart: &corev1.Handler{
Exec: &corev1.ExecAction{
Command: []string{"sh", "-c",
"until (xenoncli xenon ping && xenoncli cluster add sample-mysql-0.sample-mysql.default:8801) > /dev/null 2>&1; do sleep 2; done",
},
Command: []string{"sh", "-c", "/scripts/post-start.sh"},
},
},
PreStop: &corev1.Handler{
Exec: &corev1.ExecAction{
Command: []string{"sh", "-c", "/scripts/pre-stop.sh"},
},
},
}
Expand Down
22 changes: 1 addition & 21 deletions cluster/syncer/config_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ func NewConfigMapSyncer(cli client.Client, c *cluster.Cluster) syncer.Interface
}

cm.Data = map[string]string{
"my.cnf": data,
"leader-start.sh": buildLeaderStart(c),
"leader-stop.sh": buildLeaderStop(c),
"my.cnf": data,
}

return nil
Expand Down Expand Up @@ -117,21 +115,3 @@ func writeConfigs(cfg *ini.File) (string, error) {
}
return buf.String(), nil
}

// buildLeaderStart build the leader-start.sh.
func buildLeaderStart(c *cluster.Cluster) string {
return fmt.Sprintf(`#!/usr/bin/env bash
curl -X PATCH -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" -H "Content-Type: application/json-patch+json" \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/%s/pods/$HOSTNAME \
-d '[{"op": "replace", "path": "/metadata/labels/role", "value": "leader"}]'
`, c.Namespace)
}

// buildLeaderStop build the leader-stop.sh.
func buildLeaderStop(c *cluster.Cluster) string {
return fmt.Sprintf(`#!/usr/bin/env bash
curl -X PATCH -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" -H "Content-Type: application/json-patch+json" \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/%s/pods/$HOSTNAME \
-d '[{"op": "replace", "path": "/metadata/labels/role", "value": "follower"}]'
`, c.Namespace)
}
Loading

0 comments on commit fff1968

Please sign in to comment.