Skip to content

Commit 8f7fde1

Browse files
committed
Improve KIND deployment reliability
KIND clusters fail to deploy out of the box due to three issues: webhook race conditions, a removed container image, and missing third-party services. - Wait for cert-manager and DWS webhooks to be functional before deploying dependent modules (cmd/main.go) - Update submodules to include gcr.io -> registry.k8s.io fix for kube-rbac-proxy - Auto-inject system CA certificates into KIND nodes for corporate proxy environments (tools/kind.sh) - Copy overlay-legacy.yaml-template so init installs cert-manager and mpi-operator without modifying shared config Signed-off-by: Anthony Floeder <anthony.floeder@hpe.com>
1 parent 956206d commit 8f7fde1

6 files changed

Lines changed: 155 additions & 5 deletions

File tree

cmd/main.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ func (cmd *DeployCmd) Run(ctx *Context) error {
104104
return nil
105105
}
106106

107+
// Wait for prerequisites that this module needs.
108+
if err := waitForModulePrereqs(ctx, module); err != nil {
109+
return err
110+
}
111+
107112
if err := createSystemConfigFromSOS(ctx, system, module); err != nil {
108113
return err
109114
}
@@ -1044,6 +1049,100 @@ func getExampleOverlay(ctx *Context, system *config.System, module string) (stri
10441049
return "", nil
10451050
}
10461051

1052+
// Modules that require cert-manager webhook to be ready before deploying.
1053+
var modulesCertManager = []string{
1054+
"lustre-fs-operator",
1055+
"dws",
1056+
"nnf-sos",
1057+
}
1058+
1059+
// Modules that require the DWS controller-manager to be ready before deploying,
1060+
// because they use DWS CRDs that have a conversion webhook served by DWS.
1061+
var modulesDWSController = []string{
1062+
"nnf-sos",
1063+
"nnf-dm",
1064+
}
1065+
1066+
// waitForModulePrereqs waits for prerequisite services that a module depends on.
1067+
func waitForModulePrereqs(ctx *Context, module string) error {
1068+
if ctx.DryRun {
1069+
return nil
1070+
}
1071+
1072+
for _, m := range modulesCertManager {
1073+
if m == module {
1074+
if err := waitForCertManagerWebhook(ctx); err != nil {
1075+
return err
1076+
}
1077+
break
1078+
}
1079+
}
1080+
1081+
for _, m := range modulesDWSController {
1082+
if m == module {
1083+
if err := waitForDWSControllerManager(ctx); err != nil {
1084+
return err
1085+
}
1086+
break
1087+
}
1088+
}
1089+
1090+
return nil
1091+
}
1092+
1093+
// waitForCertManagerWebhook waits for the cert-manager webhook to be ready and
1094+
// functional. Modules that create cert-manager Certificate or Issuer resources
1095+
// need this webhook to be operational.
1096+
func waitForCertManagerWebhook(ctx *Context) error {
1097+
fmt.Println(" Waiting for cert-manager webhook...")
1098+
cmd := exec.Command("kubectl", "wait", "deploy", "-n", "cert-manager",
1099+
"--timeout=180s", "cert-manager-webhook",
1100+
"--for", "jsonpath={.status.availableReplicas}=1")
1101+
if _, err := runCommand(ctx, cmd); err != nil {
1102+
return fmt.Errorf("cert-manager webhook deployment not ready: %w", err)
1103+
}
1104+
1105+
// The deployment being available doesn't guarantee the webhook is
1106+
// functional. Verify by attempting a server-side dry-run of an Issuer.
1107+
fmt.Println(" Verifying cert-manager webhook is functional...")
1108+
for attempts := 0; attempts < 60; attempts++ {
1109+
cmd = exec.Command("kubectl", "apply", "--dry-run=server", "-f", "-")
1110+
cmd.Stdin = strings.NewReader(`apiVersion: cert-manager.io/v1
1111+
kind: Issuer
1112+
metadata:
1113+
name: deploy-dryrun-test
1114+
namespace: default
1115+
spec:
1116+
selfSigned: {}
1117+
`)
1118+
if out, err := cmd.CombinedOutput(); err == nil {
1119+
_ = out
1120+
break
1121+
}
1122+
if attempts == 59 {
1123+
return fmt.Errorf("cert-manager webhook not functional after 120s")
1124+
}
1125+
time.Sleep(2 * time.Second)
1126+
}
1127+
1128+
return nil
1129+
}
1130+
1131+
// waitForDWSControllerManager waits for the DWS controller-manager to be fully
1132+
// ready. The DWS controller-manager serves the CRD conversion webhook needed by
1133+
// modules that access DWS custom resources with multiple API versions.
1134+
func waitForDWSControllerManager(ctx *Context) error {
1135+
fmt.Println(" Waiting for DWS controller-manager...")
1136+
cmd := exec.Command("kubectl", "wait", "deploy", "-n", "dws-system",
1137+
"--timeout=180s", "dws-controller-manager",
1138+
"--for", "jsonpath={.status.availableReplicas}=1")
1139+
if _, err := runCommand(ctx, cmd); err != nil {
1140+
return fmt.Errorf("DWS controller-manager not ready: %w", err)
1141+
}
1142+
1143+
return nil
1144+
}
1145+
10471146
func deployModule(ctx *Context, system *config.System, module string) error {
10481147

10491148
cmd := exec.Command("make", "deploy")

dws

nnf-dm

nnf-sos

tools/kind.sh

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
# Copyright 2021-2024 Hewlett Packard Enterprise Development LP
3+
# Copyright 2021-2026 Hewlett Packard Enterprise Development LP
44
# Other additional copyright holders may be indicated within.
55
#
66
# The entirety of this work is licensed under the Apache License,
@@ -32,6 +32,51 @@ function clear_mock_fs {
3232
fi
3333
}
3434

35+
function inject_ca_certs {
36+
local certs="$KIND_CA_CERTS"
37+
local tmp_certs=""
38+
39+
# If KIND_CA_CERTS is not set, auto-extract system CA certs.
40+
if [[ -z "$certs" ]]; then
41+
tmp_certs=$(mktemp /tmp/kind-ca-certs.XXXXXX.pem)
42+
if [[ "$(uname)" == "Darwin" ]]; then
43+
if [[ -f /Library/Keychains/System.keychain ]]; then
44+
security find-certificate -a -p /Library/Keychains/System.keychain > "$tmp_certs" 2>/dev/null
45+
fi
46+
else
47+
# Linux: copy the system CA bundle.
48+
if [[ -f /etc/ssl/certs/ca-certificates.crt ]]; then
49+
cp /etc/ssl/certs/ca-certificates.crt "$tmp_certs"
50+
elif [[ -f /etc/pki/tls/certs/ca-bundle.crt ]]; then
51+
cp /etc/pki/tls/certs/ca-bundle.crt "$tmp_certs"
52+
fi
53+
fi
54+
55+
if [[ ! -s "$tmp_certs" ]]; then
56+
echo "WARNING: Could not extract system CA certificates. Set KIND_CA_CERTS to a PEM file if image pulls fail with TLS errors."
57+
rm -f "$tmp_certs"
58+
return
59+
fi
60+
certs="$tmp_certs"
61+
fi
62+
63+
if [[ ! -f "$certs" ]]; then
64+
echo "ERROR: KIND_CA_CERTS file not found: $certs"
65+
return 1
66+
fi
67+
68+
echo "Injecting CA certificates from $certs into KIND nodes..."
69+
for node in $(kind get nodes); do
70+
docker cp "$certs" "$node:/usr/local/share/ca-certificates/extra-ca-certs.crt"
71+
docker exec "$node" update-ca-certificates
72+
docker exec "$node" systemctl restart containerd
73+
echo " $node: done"
74+
done
75+
76+
# Clean up temp file if we created one.
77+
[[ -n "$tmp_certs" ]] && rm -f "$tmp_certs"
78+
}
79+
3580
function create_cluster {
3681
CONFIG=kind-config.yaml
3782

@@ -92,6 +137,12 @@ EOF
92137

93138
kind create cluster --wait 60s --image=kindest/node:v1.31.2 --config $CONFIG
94139

140+
# If corporate/custom CA certificates are available, inject them into
141+
# each KIND node so containerd can pull from registries behind a TLS
142+
# intercepting proxy. Set KIND_CA_CERTS to a PEM file path, or it
143+
# defaults to /tmp/corporate-certs.pem.
144+
inject_ca_certs
145+
95146
# Use the same init routines that we use on real hardware.
96147
# This applies taints and labels to rabbit nodes, and installs other
97148
# services that rabbit software requires.

0 commit comments

Comments
 (0)