Skip to content

Commit 5fc56be

Browse files
authored
Headless mode readiness probe (#192)
1 parent 29dc0e4 commit 5fc56be

File tree

10 files changed

+58
-24
lines changed

10 files changed

+58
-24
lines changed

.dockerignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
.github
22
.idea
33
agent
4-
build/_output
54
zz_*
65
vendor/
76
scripts/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ If you want to deploy the operator on OpenShift you will have to provide the env
111111
112112
See [here](deploy/crds/mongodb.com_v1_mongodb_openshift_cr.yaml) for an example of how to provide the required configuration for a MongoDB ReplicaSet.
113113
114-
See [here](deploy/operator_openshift.yaml) for an example of how to configure the Operator deployment.
114+
See [here](deploy/openshift/operator_openshift.yaml) for an example of how to configure the Operator deployment.
115115
116116
#### Example
117117

agent/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ RUN mkdir -p agent \
2121
&& rm -r mongodb-mms-automation-agent-*
2222

2323
RUN mkdir -p /var/lib/mongodb-mms-automation/probes/ \
24-
&& curl --retry 3 https://readinessprobe-test.s3-us-west-1.amazonaws.com/readiness -o /var/lib/mongodb-mms-automation/probes/readinessprobe \
24+
&& curl --retry 3 https://readinessprobe.s3-us-west-1.amazonaws.com/readiness -o /var/lib/mongodb-mms-automation/probes/readinessprobe \
2525
&& chmod +x /var/lib/mongodb-mms-automation/probes/readinessprobe \
2626
&& mkdir -p /var/log/mongodb-mms-automation/ \
2727
&& chmod -R +wr /var/log/mongodb-mms-automation/ \

build/Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ ENV OPERATOR=/usr/local/bin/mongodb-kubernetes-operator \
44
USER_UID=1001 \
55
USER_NAME=mongodb-kubernetes-operator
66

7+
RUN apt-get update && \
8+
apt-get install -y curl
9+
10+
ENV manifest_version=4.4
11+
RUN mkdir -p /content/ \
12+
&& chmod -R +r /content/ \
13+
&& curl --fail --retry 3 -o /usr/local/version_manifest.json "https://opsmanager.mongodb.com/static/version_manifest/${manifest_version}.json"
14+
715
# install operator binary
816
COPY build/_output/bin/mongodb-kubernetes-operator ${OPERATOR}
917

File renamed without changes.

pkg/controller/mongodb/build_statefulset_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func assertStatefulSetIsBuiltCorrectly(t *testing.T, mdb mdbv1.MongoDB, sts *app
4747
assert.Equal(t, mdb.Namespace, sts.Namespace)
4848
assert.Equal(t, appsv1.RollingUpdateStatefulSetStrategyType, sts.Spec.UpdateStrategy.Type)
4949
assert.Equal(t, operatorServiceAccountName, sts.Spec.Template.Spec.ServiceAccountName)
50-
assert.Len(t, sts.Spec.Template.Spec.Containers[0].Env, 1)
50+
assert.Len(t, sts.Spec.Template.Spec.Containers[0].Env, 4)
5151
assert.Len(t, sts.Spec.Template.Spec.Containers[1].Env, 1)
5252

5353
agentContainer := sts.Spec.Template.Spec.Containers[0]

pkg/controller/mongodb/replica_set_controller.go

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,18 @@ const (
6363
mongodbImageEnv = "MONGODB_IMAGE"
6464
mongodbRepoUrl = "MONGODB_REPO_URL"
6565
mongodbToolsVersionEnv = "MONGODB_TOOLS_VERSION"
66+
headlessAgentEnv = "HEADLESS_AGENT"
67+
podNamespaceEnv = "POD_NAMESPACE"
68+
automationConfigEnv = "AUTOMATION_CONFIG_MAP"
6669

67-
AutomationConfigKey = "automation-config"
70+
AutomationConfigKey = "cluster-config.json"
6871
agentName = "mongodb-agent"
6972
mongodbName = "mongod"
7073
versionUpgradeHookName = "mongod-posthook"
7174
dataVolumeName = "data-volume"
7275
versionManifestFilePath = "/usr/local/version_manifest.json"
7376
readinessProbePath = "/var/lib/mongodb-mms-automation/probes/readinessprobe"
74-
clusterFilePath = "/var/lib/automation/config/automation-config"
77+
clusterFilePath = "/var/lib/automation/config/cluster-config.json"
7578
operatorServiceAccountName = "mongodb-kubernetes-operator"
7679
agentHealthStatusFilePathValue = "/var/log/mongodb-mms-automation/healthstatus/agent-health-status.json"
7780

@@ -185,7 +188,7 @@ func (r *ReplicaSetReconciler) Reconcile(request reconcile.Request) (reconcile.R
185188
if err := r.ensureAutomationConfig(mdb); err != nil {
186189
return status.Update(r.client.Status(), &mdb,
187190
statusOptions().
188-
withMessage(Error, fmt.Sprintf("error creating automation config config map: %s", err)).
191+
withMessage(Error, fmt.Sprintf("error creating automation config secret: %s", err)).
189192
withFailedPhase(),
190193
)
191194
}
@@ -249,6 +252,7 @@ func (r *ReplicaSetReconciler) Reconcile(request reconcile.Request) (reconcile.R
249252
if !ready {
250253
return status.Update(r.client.Status(), &mdb,
251254
statusOptions().
255+
withMembers(int(currentSts.Status.ReadyReplicas)).
252256
withMessage(Info, fmt.Sprintf("StatefulSet %s/%s is not yet ready, retrying in 10 seconds", mdb.Namespace, mdb.Name)).
253257
withPendingPhase(10),
254258
)
@@ -356,7 +360,7 @@ func (r *ReplicaSetReconciler) isStatefulSetReady(mdb mdbv1.MongoDB, existingSta
356360
//some issues with nil/empty maps not being compared correctly otherwise
357361
areEqual := bytes.Equal(stsCopyBytes, stsBytes)
358362

359-
isReady := statefulset.IsReady(*existingStatefulSet, mdb.Spec.Members)
363+
isReady := statefulset.IsReady(*existingStatefulSet, mdb.ReplicasThisReconciliation())
360364
if existingStatefulSet.Spec.UpdateStrategy.Type == appsv1.OnDeleteStatefulSetStrategyType && !isReady {
361365
r.log.Info("StatefulSet has left ready state, version upgrade in progress")
362366
annotations := map[string]string{
@@ -492,6 +496,7 @@ func buildService(mdb mdbv1.MongoDB) corev1.Service {
492496
SetServiceType(corev1.ServiceTypeClusterIP).
493497
SetClusterIP("None").
494498
SetPort(27017).
499+
SetPublishNotReadyAddresses(true).
495500
Build()
496501
}
497502

@@ -519,17 +524,17 @@ func (r ReplicaSetReconciler) buildAutomationConfigSecret(mdb mdbv1.MongoDB) (co
519524

520525
authModification, err := scram.EnsureScram(r.client, mdb.ScramCredentialsNamespacedName(), mdb)
521526
if err != nil {
522-
return corev1.Secret{}, err
527+
return corev1.Secret{}, errors.Errorf("could not ensure scram credentials: %s", err)
523528
}
524529

525530
tlsModification, err := getTLSConfigModification(r.client, mdb)
526531
if err != nil {
527-
return corev1.Secret{}, err
532+
return corev1.Secret{}, errors.Errorf("could not configure TLS modification: %s", err)
528533
}
529534

530535
currentAC, err := getCurrentAutomationConfig(r.client, mdb)
531536
if err != nil {
532-
return corev1.Secret{}, err
537+
return corev1.Secret{}, errors.Errorf("could not read existing automation config: %s", err)
533538
}
534539

535540
ac, err := buildAutomationConfig(
@@ -540,11 +545,11 @@ func (r ReplicaSetReconciler) buildAutomationConfigSecret(mdb mdbv1.MongoDB) (co
540545
tlsModification,
541546
)
542547
if err != nil {
543-
return corev1.Secret{}, err
548+
return corev1.Secret{}, fmt.Errorf("could not build automation config: %s", err)
544549
}
545550
acBytes, err := json.Marshal(ac)
546551
if err != nil {
547-
return corev1.Secret{}, err
552+
return corev1.Secret{}, fmt.Errorf("could not marshal automation config: %s", err)
548553
}
549554

550555
return secret.Builder().
@@ -590,7 +595,7 @@ func isChangingVersion(mdb mdbv1.MongoDB) bool {
590595
return false
591596
}
592597

593-
func mongodbAgentContainer(volumeMounts []corev1.VolumeMount) container.Modification {
598+
func mongodbAgentContainer(automationConfigSecretName string, volumeMounts []corev1.VolumeMount) container.Modification {
594599
return container.Apply(
595600
container.WithName(agentName),
596601
container.WithImage(os.Getenv(agentImageEnv)),
@@ -609,6 +614,23 @@ func mongodbAgentContainer(volumeMounts []corev1.VolumeMount) container.Modifica
609614
},
610615
),
611616
container.WithEnvs(
617+
corev1.EnvVar{
618+
Name: headlessAgentEnv,
619+
Value: "true",
620+
},
621+
corev1.EnvVar{
622+
Name: podNamespaceEnv,
623+
ValueFrom: &corev1.EnvVarSource{
624+
FieldRef: &corev1.ObjectFieldSelector{
625+
APIVersion: "v1",
626+
FieldPath: "metadata.namespace",
627+
},
628+
},
629+
},
630+
corev1.EnvVar{
631+
Name: automationConfigEnv,
632+
Value: automationConfigSecretName,
633+
},
612634
corev1.EnvVar{
613635
Name: agentHealthStatusFilePathEnv,
614636
Value: agentHealthStatusFilePathValue,
@@ -705,7 +727,7 @@ func buildStatefulSetModificationFunction(mdb mdbv1.MongoDB) statefulset.Modific
705727
podtemplatespec.WithVolume(hooksVolume),
706728
podtemplatespec.WithVolume(automationConfigVolume),
707729
podtemplatespec.WithServiceAccount(operatorServiceAccountName),
708-
podtemplatespec.WithContainer(agentName, mongodbAgentContainer([]corev1.VolumeMount{agentHealthStatusVolumeMount, automationConfigVolumeMount, dataVolume})),
730+
podtemplatespec.WithContainer(agentName, mongodbAgentContainer(mdb.AutomationConfigSecretName(), []corev1.VolumeMount{agentHealthStatusVolumeMount, automationConfigVolumeMount, dataVolume})),
709731
podtemplatespec.WithContainer(mongodbName, mongodbContainer(mdb.Spec.Version, []corev1.VolumeMount{mongodHealthStatusVolumeMount, dataVolume, hooksVolumeMount})),
710732
podtemplatespec.WithInitContainer(versionUpgradeHookName, versionUpgradeHookInit([]corev1.VolumeMount{hooksVolumeMount})),
711733
buildTLSPodSpecModification(mdb),

pkg/controller/mongodb/replicaset_controller_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ func TestReplicaSet_IsScaledDown_OneMember_AtATime_WhenItAlreadyExists(t *testin
432432
assert.Equal(t, true, res.Requeue)
433433
assert.Equal(t, 4, mdb.Status.Members)
434434

435+
makeStatefulSetReady(t, mgr.GetClient(), mdb)
436+
435437
res, err = r.Reconcile(reconcile.Request{NamespacedName: mdb.NamespacedName()})
436438

437439
assert.NoError(t, err)
@@ -472,6 +474,8 @@ func TestReplicaSet_IsScaledUp_OneMember_AtATime_WhenItAlreadyExists(t *testing.
472474
assert.Equal(t, true, res.Requeue)
473475
assert.Equal(t, 4, mdb.Status.Members)
474476

477+
makeStatefulSetReady(t, mgr.GetClient(), mdb)
478+
475479
res, err = r.Reconcile(reconcile.Request{NamespacedName: mdb.NamespacedName()})
476480

477481
assert.NoError(t, err)
@@ -522,7 +526,7 @@ func TestReplicaSet_IsScaledUpToDesiredMembers_WhenFirstCreated(t *testing.T) {
522526

523527
func TestOpenshift_Configuration(t *testing.T) {
524528
sts := performReconciliationAndGetStatefulSet(t, "openshift_mdb.yaml")
525-
assert.Equal(t, "MANAGED_SECURITY_CONTEXT", sts.Spec.Template.Spec.Containers[0].Env[1].Name)
529+
assert.Equal(t, "MANAGED_SECURITY_CONTEXT", sts.Spec.Template.Spec.Containers[0].Env[3].Name)
526530
assert.Equal(t, "MANAGED_SECURITY_CONTEXT", sts.Spec.Template.Spec.Containers[1].Env[1].Name)
527531
}
528532

@@ -631,8 +635,8 @@ func makeStatefulSetReady(t *testing.T, c k8sClient.Client, mdb mdbv1.MongoDB) {
631635
sts := appsv1.StatefulSet{}
632636
err := c.Get(context.TODO(), mdb.NamespacedName(), &sts)
633637
assert.NoError(t, err)
634-
sts.Status.ReadyReplicas = int32(mdb.Spec.Members)
635-
sts.Status.UpdatedReplicas = int32(mdb.Spec.Members)
638+
sts.Status.ReadyReplicas = int32(mdb.ReplicasThisReconciliation())
639+
sts.Status.UpdatedReplicas = int32(mdb.ReplicasThisReconciliation())
636640
err = c.Update(context.TODO(), &sts)
637641
assert.NoError(t, err)
638642
}

scripts/dev/dump_diagnostic.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ def dump_automation_configs(namespace: str) -> None:
9494
return
9595
for mdb in mongodb_resources:
9696
name = mdb["metadata"]["name"]
97-
dump_secret_keys_namespaced(namespace, ["automation-config"], f"{name}-config")
97+
dump_secret_keys_namespaced(
98+
namespace, ["cluster-config.json"], f"{name}-config"
99+
)
98100

99101

100102
def dump_all(namespace: str) -> None:

scripts/dev/e2e.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@
77
load_yaml_from_file,
88
)
99
import k8s_conditions
10-
import k8s_request_data
1110
import dump_diagnostic
1211
from dockerutil import build_and_push_image
1312
from typing import Dict
1413
from dev_config import load_config, DevConfig
1514
from kubernetes import client, config
1615
import argparse
17-
import time
1816
import os
1917
import sys
2018
import yaml
@@ -78,11 +76,12 @@ def _prepare_testrunner_environment(config_file: str) -> None:
7876
)
7977

8078

81-
def create_kube_config() -> None:
79+
def create_kube_config(config_file: str) -> None:
8280
"""Replicates the local kubeconfig file (pointed at by KUBECONFIG),
8381
as a ConfigMap."""
8482
corev1 = client.CoreV1Api()
8583
print("Creating kube-config ConfigMap")
84+
dev_config = load_config(config_file)
8685

8786
svc = corev1.read_namespaced_service("kubernetes", "default")
8887

@@ -104,7 +103,7 @@ def create_kube_config() -> None:
104103
)
105104

106105
k8s_conditions.ignore_if_already_exists(
107-
lambda: corev1.create_namespaced_config_map("default", config_map)
106+
lambda: corev1.create_namespaced_config_map(dev_config.namespace, config_map)
108107
)
109108

110109

@@ -318,7 +317,7 @@ def main() -> int:
318317
config.load_kube_config()
319318

320319
dev_config = load_config(args.config_file)
321-
create_kube_config()
320+
create_kube_config(args.config_file)
322321

323322
try:
324323
build_and_push_images(args, dev_config)

0 commit comments

Comments
 (0)