Skip to content
91 changes: 91 additions & 0 deletions e2e-tests/tests/haproxy/01-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,97 @@ kind: StatefulSet
apiVersion: apps/v1
metadata:
name: haproxy-haproxy
spec:
template:
spec:
containers:
- args:
- haproxy
command:
- /opt/percona/haproxy-entrypoint.sh
env:
- name: CLUSTER_TYPE
value: async
- name: LIVENESS_CHECK_TIMEOUT
value: "30"
- name: READINESS_CHECK_TIMEOUT
value: "3"
image: perconalab/percona-server-mysql-operator:main-haproxy
imagePullPolicy: Always
livenessProbe:
exec:
command:
- /opt/percona/haproxy_liveness_check.sh
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 30
name: haproxy
ports:
- containerPort: 3306
name: mysql
protocol: TCP
- containerPort: 3307
name: mysql-replicas
protocol: TCP
- containerPort: 3309
name: proxy-protocol
protocol: TCP
- containerPort: 33060
name: mysqlx
protocol: TCP
readinessProbe:
exec:
command:
- /opt/percona/haproxy_readiness_check.sh
failureThreshold: 40
periodSeconds: 5
successThreshold: 10
timeoutSeconds: 3
resources:
requests:
cpu: 600m
memory: 1G
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /opt/percona
name: bin
- mountPath: /etc/haproxy/mysql
name: haproxy-config
- mountPath: /etc/mysql/mysql-users-secret
name: users
- mountPath: /etc/mysql/mysql-tls-secret
name: tls
- mountPath: /etc/haproxy-custom/
name: config
- args:
- /opt/percona/peer-list
- -on-change=/opt/percona/haproxy_add_mysql_nodes.sh
- -service=$(MYSQL_SERVICE)
command:
- /opt/percona/haproxy-entrypoint.sh
env:
- name: MYSQL_SERVICE
value: haproxy-mysql-proxy
image: perconalab/percona-server-mysql-operator:main-haproxy
imagePullPolicy: Always
name: mysql-monit
resources:
requests:
cpu: 600m
memory: 1G
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /opt/percona
name: bin
- mountPath: /etc/haproxy/mysql
name: haproxy-config
- mountPath: /etc/mysql/mysql-users-secret
name: users
- mountPath: /etc/mysql/mysql-tls-secret
name: tls
status:
observedGeneration: 1
replicas: 3
Expand Down
5 changes: 5 additions & 0 deletions e2e-tests/tests/haproxy/01-create-cluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ commands:
| yq eval '.spec.orchestrator.enabled=true' - \
| yq eval '.spec.proxy.haproxy.enabled=true' - \
| yq eval '.spec.proxy.haproxy.size=3' - \
| yq eval '.spec.proxy.haproxy.livenessProbe.timeoutSeconds=30' - \
| yq eval '.spec.proxy.haproxy.livenessProbe.periodSeconds=10' - \
| yq eval '.spec.proxy.haproxy.readinessProbe.failureThreshold=40' - \
| yq eval '.spec.proxy.haproxy.readinessProbe.successThreshold=10' - \
| yq eval '.spec.proxy.haproxy.size=3' - \
| kubectl -n "${NAMESPACE}" apply -f -
20 changes: 20 additions & 0 deletions pkg/haproxy/haproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,24 @@ func haproxyContainer(cr *apiv1alpha1.PerconaServerMySQL) corev1.Container {
}
env = append(env, spec.Env...)

var readinessProbe, livenessProbe *corev1.Probe
if cr.CompareVersion("0.12.0") >= 0 {
readinessProbe = k8s.ExecProbe(spec.ReadinessProbe, []string{"/opt/percona/haproxy_readiness_check.sh"})
livenessProbe = k8s.ExecProbe(spec.LivenessProbe, []string{"/opt/percona/haproxy_liveness_check.sh"})

probsEnvs := []corev1.EnvVar{
{
Name: "LIVENESS_CHECK_TIMEOUT",
Value: fmt.Sprint(livenessProbe.TimeoutSeconds),
},
{
Name: "READINESS_CHECK_TIMEOUT",
Value: fmt.Sprint(readinessProbe.TimeoutSeconds),
},
}
env = append(env, probsEnvs...)
}

return corev1.Container{
Name: AppName,
Image: spec.Image,
Expand All @@ -302,6 +320,8 @@ func haproxyContainer(cr *apiv1alpha1.PerconaServerMySQL) corev1.Container {
EnvFrom: spec.EnvFrom,
Command: []string{"/opt/percona/haproxy-entrypoint.sh"},
Args: []string{"haproxy"},
ReadinessProbe: readinessProbe,
LivenessProbe: livenessProbe,
Ports: []corev1.ContainerPort{
{
Name: "mysql",
Expand Down
99 changes: 99 additions & 0 deletions pkg/haproxy/haproxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,103 @@ func TestStatefulset(t *testing.T) {
sts = StatefulSet(cluster, initImage, configHash, tlsHash, secret)
assert.Equal(t, tolerations, sts.Spec.Template.Spec.Tolerations)
})

t.Run("probes", func(t *testing.T) {
cluster := cr.DeepCopy()
cluster.Spec.CRVersion = "0.12.0"
sts := StatefulSet(cluster, initImage, configHash, tlsHash, secret)
var hContainer *corev1.Container
for _, c := range sts.Spec.Template.Spec.Containers {
if c.Name == AppName {
hContainer = &c
}
}
if hContainer == nil {
t.Fatal("haproxy container is not found")
}

expectedReadinessProbe := corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{Command: []string{"/opt/percona/haproxy_readiness_check.sh"}},
},
TimeoutSeconds: 3,
PeriodSeconds: 5,
FailureThreshold: 3,
SuccessThreshold: 1,
}
expectedLivenessProbe := corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{Command: []string{"/opt/percona/haproxy_liveness_check.sh"}},
},
TimeoutSeconds: 3,
PeriodSeconds: 5,
FailureThreshold: 3,
SuccessThreshold: 1,
}

assert.Equal(t, expectedReadinessProbe, *hContainer.ReadinessProbe)
assert.Equal(t, expectedLivenessProbe, *hContainer.LivenessProbe)

cluster.Spec.Proxy.HAProxy.ReadinessProbe = corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Command: []string{"invalid-command"},
},
},
InitialDelaySeconds: 10,
TimeoutSeconds: 20,
PeriodSeconds: 30,
SuccessThreshold: 40,
FailureThreshold: 50,
TerminationGracePeriodSeconds: new(int64),
}
cluster.Spec.Proxy.HAProxy.LivenessProbe = corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Command: []string{"invalid-command"},
},
},
InitialDelaySeconds: 11,
TimeoutSeconds: 21,
PeriodSeconds: 31,
SuccessThreshold: 41,
FailureThreshold: 51,
TerminationGracePeriodSeconds: new(int64),
}
sts = StatefulSet(cluster, initImage, configHash, tlsHash, secret)
for _, c := range sts.Spec.Template.Spec.Containers {
if c.Name == AppName {
hContainer = &c
}
}
if hContainer == nil {
t.Fatal("haproxy container is not found")
}

expectedReadinessProbe = corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{Command: []string{"/opt/percona/haproxy_readiness_check.sh"}},
},
InitialDelaySeconds: 10,
TimeoutSeconds: 20,
PeriodSeconds: 30,
SuccessThreshold: 40,
FailureThreshold: 50,
TerminationGracePeriodSeconds: new(int64),
}
expectedLivenessProbe = corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{Command: []string{"/opt/percona/haproxy_liveness_check.sh"}},
},
InitialDelaySeconds: 11,
TimeoutSeconds: 21,
PeriodSeconds: 31,
SuccessThreshold: 41,
FailureThreshold: 51,
TerminationGracePeriodSeconds: new(int64),
}

assert.Equal(t, expectedReadinessProbe, *hContainer.ReadinessProbe)
assert.Equal(t, expectedLivenessProbe, *hContainer.LivenessProbe)
})
}
Loading