diff --git a/02-k8s-bootstrap/index.ts b/02-k8s-bootstrap/index.ts index 1836e69..5732777 100644 --- a/02-k8s-bootstrap/index.ts +++ b/02-k8s-bootstrap/index.ts @@ -215,7 +215,32 @@ const joinWorker2 = new command.remote.Command( ); // --------------------------------------------------------------------------- -// Step 5: Read kubeconfig from master-1, patch server URL for external access +// Step 5: Format and mount Longhorn disks +// --------------------------------------------------------------------------- + +const workers = [worker1Ip, worker2Ip]; +const workerSshReader = [waitWorker1Ssh, waitWorker2Ssh]; + +const mountLonghornDisks = workers.map((worker, i) => { + return new command.remote.Command( + `mount-longhorn-disk-${i}`, + { + connection: conn(worker), + create: `set -euo pipefail; + DISK_ID=$(ls /dev/disk/by-id/ | grep 'scsi1'); + DISK_PATH="/dev/disk/by-id/$DISK_ID"; + sudo blkid "$DISK_PATH" >/dev/null 2>&1 || sudo mkfs.ext4 "$DISK_PATH"; + sudo mkdir -p /mnt/longhorn-extra; + echo ""$DISK_PATH" /mnt/longhorn-extra ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab; + sudo mount -a; + df -h /mnt/longhorn-extra`, + }, + { dependsOn: workerSshReader[i] }, + ); +}); + +// --------------------------------------------------------------------------- +// Step 6: Read kubeconfig from master-1, patch server URL for external access // --------------------------------------------------------------------------- const getKubeconfig = new command.remote.Command( diff --git a/03-k8s-infra/index.ts b/03-k8s-infra/index.ts index b0ccd60..1af3eab 100644 --- a/03-k8s-infra/index.ts +++ b/03-k8s-infra/index.ts @@ -122,7 +122,7 @@ new k8s.apiextensions.CustomResource( // ── Longhorn ────────────────────────────────────────────────────────────── - new k8s.helm.v3.Release( +const longhorn = new k8s.helm.v3.Release( "longhorn", { name: "longhorn", @@ -133,14 +133,46 @@ new k8s.apiextensions.CustomResource( version: "1.12.0", values: { defaultSettings: { - defaultReplicaCount: 3, - podDeletionPolicyWhenNodeIsDown: "delete-pod-and-force-delete-pod", + defaultReplicaCount: 2, + nodeDownPodDeletionPolicy: "delete-both-statefulset-and-deployment-pod", + createDefaultDiskLabeledNodes: true, }, }, }, opts(), ); +// Patches Longhorn instances to use the mountend Longhorn storage on the worker nodes. +const workerLonghornDiskPatches = ["k3s-worker-1", "k3s-worker-2"].map( + (nodeName) => + new k8s.apiextensions.CustomResourcePatch( + `${nodeName}-longhorn-disks`, + { + apiVersion: "longhorn.io/v1beta2", + kind: "Node", + metadata: { + name: nodeName, + namespace: "longhorn-system", + annotations: { "pulumi.com/patchForce": "true" }, + }, + spec: { + disks: { + "longhorn-extra": { + allowScheduling: true, + diskDriver: "", + diskType: "filesystem", + evictionRequested: false, + path: "/mnt/longhorn-extra", + storageReserved: 0, + tags: [], + }, + }, + }, + }, + opts({ dependsOn: [longhorn] }), + ), +); + // ── kube-vip ──────────── const kubeVipNamespace = "kube-system";