alasio 4.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/src/cluster/host.js +47 -0
- package/dist/cli/src/cluster/host.js.map +1 -0
- package/dist/cli/src/commands/init.js +10 -6
- package/dist/cli/src/commands/init.js.map +1 -1
- package/dist/cli/src/commands/status.js +11 -4
- package/dist/cli/src/commands/status.js.map +1 -1
- package/dist/cli/src/commands/uninstall.js +4 -2
- package/dist/cli/src/commands/uninstall.js.map +1 -1
- package/dist/cli/src/commands/up.js +5 -3
- package/dist/cli/src/commands/up.js.map +1 -1
- package/dist/cli/src/kube/api.js +6 -0
- package/dist/cli/src/kube/api.js.map +1 -1
- package/dist/cli/src/kube/apply.js +78 -13
- package/dist/cli/src/kube/apply.js.map +1 -1
- package/dist/cli/src/kube/rollout.js +31 -3
- package/dist/cli/src/kube/rollout.js.map +1 -1
- package/dist/cli/src/main.js +2 -1
- package/dist/cli/src/main.js.map +1 -1
- package/dist/cli/src/manifests/alasio.js +43 -16
- package/dist/cli/src/manifests/alasio.js.map +1 -1
- package/dist/cli/src/manifests/config.js +106 -2
- package/dist/cli/src/manifests/config.js.map +1 -1
- package/dist/cli/src/manifests/index.js +6 -1
- package/dist/cli/src/manifests/index.js.map +1 -1
- package/dist/cli/src/manifests/juicefs-csi.js +303 -0
- package/dist/cli/src/manifests/juicefs-csi.js.map +1 -0
- package/dist/cli/src/manifests/neon.js +97 -14
- package/dist/cli/src/manifests/neon.js.map +1 -1
- package/dist/cli/src/manifests/network-policies.js +37 -0
- package/dist/cli/src/manifests/network-policies.js.map +1 -1
- package/dist/cli/src/manifests/object-store.js +2 -1
- package/dist/cli/src/manifests/object-store.js.map +1 -1
- package/dist/cli/src/manifests/valkey.js +95 -0
- package/dist/cli/src/manifests/valkey.js.map +1 -0
- package/dist/cli/src/manifests/workspace-storage.js +134 -0
- package/dist/cli/src/manifests/workspace-storage.js.map +1 -0
- package/dist/cli/src/release.js +5 -5
- package/dist/src/kube/config.js +6 -1
- package/dist/src/kube/config.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,9 +4,13 @@ import { lakeObjects } from "./lake.js";
|
|
|
4
4
|
import { neonObjects } from "./neon.js";
|
|
5
5
|
import { networkPolicyObjects } from "./network-policies.js";
|
|
6
6
|
import { objectStoreObjects } from "./object-store.js";
|
|
7
|
+
import { workspaceStorageObjects } from "./workspace-storage.js";
|
|
7
8
|
export { decodeInstallConfig, InstallConfig, InstallConfigError } from "./config.js";
|
|
8
9
|
export { NAMESPACE } from "./common.js";
|
|
9
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* The objects of the installation `config` describes: agent-sandbox's, alasio's, Neon's,
|
|
12
|
+
* the object store's, the lake's, workspace storage's, and the NetworkPolicies.
|
|
13
|
+
*/
|
|
10
14
|
export function manifests(config) {
|
|
11
15
|
return [
|
|
12
16
|
...agentSandboxObjects(config),
|
|
@@ -14,6 +18,7 @@ export function manifests(config) {
|
|
|
14
18
|
...neonObjects(config),
|
|
15
19
|
...objectStoreObjects(config),
|
|
16
20
|
...lakeObjects(config),
|
|
21
|
+
...workspaceStorageObjects(config),
|
|
17
22
|
...networkPolicyObjects(config),
|
|
18
23
|
];
|
|
19
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/manifests/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/manifests/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,kBAAkB,EAA0B,MAAM,aAAa,CAAC;AAC7G,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,MAAqB;IAC7C,OAAO;QACL,GAAG,mBAAmB,CAAC,MAAM,CAAC;QAC9B,GAAG,aAAa,CAAC,MAAM,CAAC;QACxB,GAAG,WAAW,CAAC,MAAM,CAAC;QACtB,GAAG,kBAAkB,CAAC,MAAM,CAAC;QAC7B,GAAG,WAAW,CAAC,MAAM,CAAC;QACtB,GAAG,uBAAuB,CAAC,MAAM,CAAC;QAClC,GAAG,oBAAoB,CAAC,MAAM,CAAC;KAChC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { imageReference } from "../images.js";
|
|
2
|
+
import { VOLUME_DRIVER_LABEL } from "../kube/apply.js";
|
|
3
|
+
import { goJson } from "./common.js";
|
|
4
|
+
/** The driver's name, which StorageClasses name as their provisioner. */
|
|
5
|
+
export const CSI_DRIVER = "csi.juicefs.com";
|
|
6
|
+
const VERSION = "v0.33.0";
|
|
7
|
+
const CONTROLLER = "juicefs-csi-controller";
|
|
8
|
+
const NODE = "juicefs-csi-node";
|
|
9
|
+
const CONFIG = "juicefs-csi-driver-config";
|
|
10
|
+
const CONTROLLER_ACCOUNT = "juicefs-csi-controller-sa";
|
|
11
|
+
const NODE_ACCOUNT = "juicefs-csi-node-sa";
|
|
12
|
+
/** The PriorityClass of mount pods. */
|
|
13
|
+
const MOUNT_PRIORITY_CLASS = "alasio-juicefs-mount";
|
|
14
|
+
/** The labels of the node service's mount pods. */
|
|
15
|
+
export const MOUNT_POD_LABELS = { "app.kubernetes.io/name": "juicefs-mount" };
|
|
16
|
+
/** The labels that select the controller's and the node service's pods, upstream's but for its version. */
|
|
17
|
+
export const CONTROLLER_POD_LABELS = { app: CONTROLLER, "app.kubernetes.io/name": "juicefs-csi-driver", "app.kubernetes.io/instance": "juicefs-csi-driver" };
|
|
18
|
+
export const NODE_POD_LABELS = { app: NODE, "app.kubernetes.io/name": "juicefs-csi-driver", "app.kubernetes.io/instance": "juicefs-csi-driver" };
|
|
19
|
+
/** The selector of the controller's, the node service's and the mount pods' pods, by their name labels. */
|
|
20
|
+
export const JUICEFS_PODS_SELECTOR = `app.kubernetes.io/name in (${MOUNT_POD_LABELS["app.kubernetes.io/name"]}, ${CONTROLLER_POD_LABELS["app.kubernetes.io/name"]})`;
|
|
21
|
+
/** Where each of those pods serves its Prometheus metrics (administration/monitoring.md). */
|
|
22
|
+
export const JUICEFS_METRICS_PORT = 9567;
|
|
23
|
+
/** The label of what the driver needs to delete its volumes' data, which alasio keeps while they remain. */
|
|
24
|
+
export const VOLUME_DRIVER = { [VOLUME_DRIVER_LABEL]: CSI_DRIVER };
|
|
25
|
+
/** The labels of the driver's objects: upstream's, at its version, managed by alasio, and needed by its volumes. */
|
|
26
|
+
const LABELS = {
|
|
27
|
+
"app.kubernetes.io/name": "juicefs-csi-driver",
|
|
28
|
+
"app.kubernetes.io/instance": "juicefs-csi-driver",
|
|
29
|
+
"app.kubernetes.io/version": VERSION,
|
|
30
|
+
"app.kubernetes.io/managed-by": "alasio",
|
|
31
|
+
...VOLUME_DRIVER,
|
|
32
|
+
};
|
|
33
|
+
/** Where the controller and node service keep mount points and the client's configuration, on the node. */
|
|
34
|
+
const MOUNT_PATH = "/var/lib/juicefs/volume";
|
|
35
|
+
const CONFIG_PATH = "/var/lib/juicefs/config";
|
|
36
|
+
/** The controller's socket, which its sidecars reach it by. */
|
|
37
|
+
const CONTROLLER_SOCKET_DIR = "/var/lib/csi/sockets/pluginproxy/";
|
|
38
|
+
/**
|
|
39
|
+
* The driver's configuration, its ConfigMap's config.yaml: one patch, for the mount pods
|
|
40
|
+
* of workspace storage's class. Mount options here take precedence over a volume's, and
|
|
41
|
+
* reach mount pods made after a change.
|
|
42
|
+
*/
|
|
43
|
+
export function driverConfig({ workspaceStorage }) {
|
|
44
|
+
const { csi, storageClassName, cacheSizeMiB, backupInterval } = workspaceStorage;
|
|
45
|
+
return {
|
|
46
|
+
enableNodeSelector: false,
|
|
47
|
+
mountPodPatch: [{
|
|
48
|
+
pvcSelector: { matchStorageClassName: storageClassName },
|
|
49
|
+
ceMountImage: imageReference(csi.mountImage),
|
|
50
|
+
resources: csi.mountPod.resources,
|
|
51
|
+
mountOptions: [
|
|
52
|
+
// The read cache, bounded, and keeping a fifth of the node's disk free.
|
|
53
|
+
`cache-size=${cacheSizeMiB}`,
|
|
54
|
+
"free-space-ratio=0.2",
|
|
55
|
+
`backup-meta=${backupInterval}`,
|
|
56
|
+
],
|
|
57
|
+
// Ready once the mount answers as FUSE's. A mount pod mounts its volume's directory
|
|
58
|
+
// alone (as `subdir`), so that is the mount's root, and nothing is under it by the
|
|
59
|
+
// volume's path; unmounted, the root is the node's own directory.
|
|
60
|
+
readinessProbe: { exec: { command: ["sh", "-c", 'test "$(stat --file-system --format=%T ${MOUNT_POINT})" = fuseblk'] }, initialDelaySeconds: 5, periodSeconds: 10, failureThreshold: 3 },
|
|
61
|
+
}],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** What the controller and node service are told alike: where they are, where mount pods keep their mounts, and the pods' priority. */
|
|
65
|
+
function pluginEnv({ workspaceStorage }) {
|
|
66
|
+
return [
|
|
67
|
+
{ name: "NODE_NAME", valueFrom: { fieldRef: { fieldPath: "spec.nodeName" } } },
|
|
68
|
+
{ name: "JUICEFS_MOUNT_NAMESPACE", valueFrom: { fieldRef: { fieldPath: "metadata.namespace" } } },
|
|
69
|
+
{ name: "POD_NAME", valueFrom: { fieldRef: { fieldPath: "metadata.name" } } },
|
|
70
|
+
{ name: "JUICEFS_MOUNT_PATH", value: MOUNT_PATH },
|
|
71
|
+
{ name: "JUICEFS_CONFIG_PATH", value: CONFIG_PATH },
|
|
72
|
+
{ name: "JUICEFS_MOUNT_PRIORITY_NAME", value: MOUNT_PRIORITY_CLASS },
|
|
73
|
+
{ name: "JUICEFS_MOUNT_PREEMPTION_POLICY", value: "Never" },
|
|
74
|
+
...(workspaceStorage.csi.shareMountPod ? [{ name: "FS_SHARE_MOUNT", value: "true" }] : []),
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
/** The plugin's liveness, which its liveness-probe sidecar answers on the plugin's healthz port. */
|
|
78
|
+
const PLUGIN_PROBE = { httpGet: { path: "/healthz", port: "healthz" }, initialDelaySeconds: 10, periodSeconds: 10, timeoutSeconds: 3, failureThreshold: 5 };
|
|
79
|
+
/** The liveness-probe sidecar, for the plugin's socket in `socketVolume`. */
|
|
80
|
+
function livenessProbe({ workspaceStorage }, socketVolume) {
|
|
81
|
+
return {
|
|
82
|
+
name: "liveness-probe",
|
|
83
|
+
image: imageReference(workspaceStorage.csi.livenessProbeImage),
|
|
84
|
+
args: ["--csi-address=/csi/csi.sock", "--health-port=9909"],
|
|
85
|
+
resources: { requests: { cpu: "5m", memory: "16Mi" }, limits: { memory: "64Mi" } },
|
|
86
|
+
volumeMounts: [{ name: socketVolume, mountPath: "/csi" }],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** A rule granting `verbs` on `resources` of `apiGroups`. */
|
|
90
|
+
function rule(apiGroups, resources, verbs) {
|
|
91
|
+
return { apiGroups, resources, verbs };
|
|
92
|
+
}
|
|
93
|
+
/** Who the controller and node service are, and what they may do, as upstream grants it. */
|
|
94
|
+
function identities({ workspaceStorage }) {
|
|
95
|
+
const { namespace } = workspaceStorage.csi;
|
|
96
|
+
const account = (name) => ({ apiVersion: "v1", kind: "ServiceAccount", metadata: { name, namespace, labels: LABELS } });
|
|
97
|
+
const role = (name, rules) => ({
|
|
98
|
+
apiVersion: "rbac.authorization.k8s.io/v1",
|
|
99
|
+
kind: "ClusterRole",
|
|
100
|
+
metadata: { name, labels: LABELS },
|
|
101
|
+
rules,
|
|
102
|
+
});
|
|
103
|
+
const binding = (name, roleName, accountName) => ({
|
|
104
|
+
apiVersion: "rbac.authorization.k8s.io/v1",
|
|
105
|
+
kind: "ClusterRoleBinding",
|
|
106
|
+
metadata: { name, labels: LABELS },
|
|
107
|
+
subjects: [{ kind: "ServiceAccount", name: accountName, namespace }],
|
|
108
|
+
roleRef: { apiGroup: "rbac.authorization.k8s.io", kind: "ClusterRole", name: roleName },
|
|
109
|
+
});
|
|
110
|
+
const provisioner = "juicefs-external-provisioner-role";
|
|
111
|
+
const nodeService = "juicefs-csi-external-node-service-role";
|
|
112
|
+
return [
|
|
113
|
+
account(CONTROLLER_ACCOUNT),
|
|
114
|
+
account(NODE_ACCOUNT),
|
|
115
|
+
role(provisioner, [
|
|
116
|
+
rule([""], ["persistentvolumes"], ["get", "list", "watch", "create", "delete", "patch"]),
|
|
117
|
+
rule([""], ["persistentvolumeclaims", "persistentvolumeclaims/status"], ["get", "list", "watch", "update", "patch"]),
|
|
118
|
+
rule(["storage.k8s.io"], ["storageclasses"], ["get", "list", "watch"]),
|
|
119
|
+
rule([""], ["events"], ["list", "watch", "create", "update", "patch"]),
|
|
120
|
+
rule(["storage.k8s.io"], ["csinodes"], ["get", "list", "watch"]),
|
|
121
|
+
rule([""], ["nodes"], ["get", "list", "watch"]),
|
|
122
|
+
rule([""], ["secrets"], ["get", "list", "watch", "create", "update", "patch", "delete"]),
|
|
123
|
+
rule([""], ["pods", "pods/log"], ["get", "list", "watch", "create", "update", "patch", "delete"]),
|
|
124
|
+
rule(["batch"], ["jobs"], ["get", "create", "update", "patch", "delete", "list", "watch"]),
|
|
125
|
+
rule([""], ["endpoints"], ["get", "list", "watch", "create", "update", "patch"]),
|
|
126
|
+
rule(["apps"], ["daemonsets"], ["get", "list"]),
|
|
127
|
+
rule(["coordination.k8s.io"], ["leases"], ["get", "watch", "list", "delete", "update", "create"]),
|
|
128
|
+
rule([""], ["configmaps"], ["get", "watch", "list", "delete", "update", "create"]),
|
|
129
|
+
]),
|
|
130
|
+
role(nodeService, [
|
|
131
|
+
rule([""], ["pods"], ["get", "list", "create", "update", "delete", "patch", "watch"]),
|
|
132
|
+
rule([""], ["pods/log"], ["get"]),
|
|
133
|
+
rule([""], ["secrets"], ["get", "create", "update", "delete", "patch"]),
|
|
134
|
+
rule(["batch"], ["jobs"], ["get", "create", "update", "delete", "patch"]),
|
|
135
|
+
rule([""], ["nodes"], ["get", "list"]),
|
|
136
|
+
rule([""], ["nodes/proxy"], ["*"]),
|
|
137
|
+
rule([""], ["persistentvolumes", "persistentvolumeclaims"], ["get", "list"]),
|
|
138
|
+
rule([""], ["pods/exec"], ["create"]),
|
|
139
|
+
rule([""], ["events"], ["create", "get"]),
|
|
140
|
+
rule(["storage.k8s.io"], ["storageclasses"], ["get", "watch"]),
|
|
141
|
+
rule([""], ["configmaps"], ["get", "update"]),
|
|
142
|
+
]),
|
|
143
|
+
binding("juicefs-csi-provisioner-binding", provisioner, CONTROLLER_ACCOUNT),
|
|
144
|
+
binding("juicefs-csi-node-service-binding", nodeService, NODE_ACCOUNT),
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
/** The controller: the plugin, provisioning, and the resizer, which grows a volume's quota as its claim grows. */
|
|
148
|
+
function controller(config) {
|
|
149
|
+
const { csi } = config.workspaceStorage;
|
|
150
|
+
return {
|
|
151
|
+
apiVersion: "apps/v1",
|
|
152
|
+
kind: "StatefulSet",
|
|
153
|
+
metadata: { name: CONTROLLER, namespace: csi.namespace, labels: { ...LABELS, "app.kubernetes.io/component": "controller" } },
|
|
154
|
+
spec: {
|
|
155
|
+
serviceName: CONTROLLER,
|
|
156
|
+
replicas: 1,
|
|
157
|
+
selector: { matchLabels: CONTROLLER_POD_LABELS },
|
|
158
|
+
template: {
|
|
159
|
+
metadata: { labels: { ...LABELS, ...CONTROLLER_POD_LABELS } },
|
|
160
|
+
spec: {
|
|
161
|
+
serviceAccountName: CONTROLLER_ACCOUNT,
|
|
162
|
+
priorityClassName: "system-cluster-critical",
|
|
163
|
+
tolerations: [{ key: "CriticalAddonsOnly", operator: "Exists" }],
|
|
164
|
+
containers: [
|
|
165
|
+
{
|
|
166
|
+
name: "juicefs-plugin",
|
|
167
|
+
image: imageReference(csi.image),
|
|
168
|
+
args: ["--endpoint=$(CSI_ENDPOINT)", "--logtostderr", "--nodeid=$(NODE_NAME)", "--leader-election", "--provisioner=true", "--config=/etc/config/config.yaml"],
|
|
169
|
+
env: [{ name: "CSI_ENDPOINT", value: `unix://${CONTROLLER_SOCKET_DIR}csi.sock` }, ...pluginEnv(config)],
|
|
170
|
+
ports: [{ name: "healthz", containerPort: 9909, protocol: "TCP" }],
|
|
171
|
+
livenessProbe: PLUGIN_PROBE,
|
|
172
|
+
// It mounts the file system itself, to make and remove volumes' directories.
|
|
173
|
+
securityContext: { privileged: true, capabilities: { add: ["SYS_ADMIN"] } },
|
|
174
|
+
resources: csi.controller.resources,
|
|
175
|
+
volumeMounts: [
|
|
176
|
+
{ name: "socket-dir", mountPath: CONTROLLER_SOCKET_DIR },
|
|
177
|
+
{ name: "jfs-dir", mountPath: "/jfs", mountPropagation: "Bidirectional" },
|
|
178
|
+
{ name: "jfs-root-dir", mountPath: "/root/.juicefs", mountPropagation: "Bidirectional" },
|
|
179
|
+
{ name: "juicefs-config", mountPath: "/etc/config" },
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "csi-resizer",
|
|
184
|
+
image: imageReference(csi.resizerImage),
|
|
185
|
+
args: ["--csi-address=$(ADDRESS)", "--timeout=20s", "--leader-election", "--v=2"],
|
|
186
|
+
env: [{ name: "ADDRESS", value: `${CONTROLLER_SOCKET_DIR}csi.sock` }],
|
|
187
|
+
resources: { requests: { cpu: "5m", memory: "24Mi" }, limits: { memory: "128Mi" } },
|
|
188
|
+
volumeMounts: [{ name: "socket-dir", mountPath: CONTROLLER_SOCKET_DIR }],
|
|
189
|
+
},
|
|
190
|
+
livenessProbe(config, "socket-dir"),
|
|
191
|
+
],
|
|
192
|
+
volumes: [
|
|
193
|
+
{ name: "socket-dir", emptyDir: {} },
|
|
194
|
+
{ name: "jfs-dir", hostPath: { path: MOUNT_PATH, type: "DirectoryOrCreate" } },
|
|
195
|
+
{ name: "jfs-root-dir", hostPath: { path: CONFIG_PATH, type: "DirectoryOrCreate" } },
|
|
196
|
+
{ name: "juicefs-config", configMap: { name: CONFIG } },
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/** The node service: the plugin, which makes mount pods and binds their mounts into pods, and the registrar, which names it to kubelet. */
|
|
204
|
+
function nodeService(config) {
|
|
205
|
+
const { csi } = config.workspaceStorage;
|
|
206
|
+
const pluginDir = `/var/lib/kubelet/csi-plugins/${CSI_DRIVER}/`;
|
|
207
|
+
return {
|
|
208
|
+
apiVersion: "apps/v1",
|
|
209
|
+
kind: "DaemonSet",
|
|
210
|
+
metadata: { name: NODE, namespace: csi.namespace, labels: { ...LABELS, "app.kubernetes.io/component": "node" } },
|
|
211
|
+
spec: {
|
|
212
|
+
selector: { matchLabels: NODE_POD_LABELS },
|
|
213
|
+
template: {
|
|
214
|
+
metadata: { labels: { ...LABELS, ...NODE_POD_LABELS } },
|
|
215
|
+
spec: {
|
|
216
|
+
serviceAccountName: NODE_ACCOUNT,
|
|
217
|
+
priorityClassName: "system-node-critical",
|
|
218
|
+
dnsPolicy: "ClusterFirstWithHostNet",
|
|
219
|
+
tolerations: [{ key: "CriticalAddonsOnly", operator: "Exists" }],
|
|
220
|
+
containers: [
|
|
221
|
+
{
|
|
222
|
+
name: "juicefs-plugin",
|
|
223
|
+
image: imageReference(csi.image),
|
|
224
|
+
args: ["--endpoint=$(CSI_ENDPOINT)", "--logtostderr", "--nodeid=$(NODE_NAME)", "--enable-manager=true", "--config=/etc/config/config.yaml"],
|
|
225
|
+
env: [
|
|
226
|
+
{ name: "CSI_ENDPOINT", value: "unix:/csi/csi.sock" },
|
|
227
|
+
{ name: "HOST_IP", valueFrom: { fieldRef: { fieldPath: "status.hostIP" } } },
|
|
228
|
+
{ name: "KUBELET_PORT", value: "10250" },
|
|
229
|
+
...pluginEnv(config),
|
|
230
|
+
],
|
|
231
|
+
ports: [{ name: "healthz", containerPort: 9909, protocol: "TCP" }],
|
|
232
|
+
livenessProbe: PLUGIN_PROBE,
|
|
233
|
+
securityContext: { privileged: true },
|
|
234
|
+
resources: csi.node.resources,
|
|
235
|
+
volumeMounts: [
|
|
236
|
+
{ name: "kubelet-dir", mountPath: "/var/lib/kubelet", mountPropagation: "Bidirectional" },
|
|
237
|
+
{ name: "plugin-dir", mountPath: "/csi" },
|
|
238
|
+
{ name: "device-dir", mountPath: "/dev" },
|
|
239
|
+
{ name: "jfs-dir", mountPath: "/jfs", mountPropagation: "Bidirectional" },
|
|
240
|
+
{ name: "jfs-root-dir", mountPath: "/root/.juicefs", mountPropagation: "Bidirectional" },
|
|
241
|
+
{ name: "juicefs-config", mountPath: "/etc/config" },
|
|
242
|
+
// Where it keeps each mount's FUSE descriptor, by which a mount pod that
|
|
243
|
+
// crashes comes back under the same mount (guide/configurations.md
|
|
244
|
+
// "Automatic mount point recovery").
|
|
245
|
+
{ name: "jfs-fuse-fd", mountPath: "/tmp" },
|
|
246
|
+
],
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "node-driver-registrar",
|
|
250
|
+
image: imageReference(csi.registrarImage),
|
|
251
|
+
args: ["--csi-address=$(ADDRESS)", "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)", "--v=5"],
|
|
252
|
+
env: [{ name: "ADDRESS", value: "/csi/csi.sock" }, { name: "DRIVER_REG_SOCK_PATH", value: `${pluginDir}csi.sock` }],
|
|
253
|
+
resources: { requests: { cpu: "5m", memory: "16Mi" }, limits: { memory: "64Mi" } },
|
|
254
|
+
volumeMounts: [{ name: "plugin-dir", mountPath: "/csi" }, { name: "registration-dir", mountPath: "/registration" }],
|
|
255
|
+
},
|
|
256
|
+
livenessProbe(config, "plugin-dir"),
|
|
257
|
+
],
|
|
258
|
+
volumes: [
|
|
259
|
+
{ name: "kubelet-dir", hostPath: { path: "/var/lib/kubelet", type: "Directory" } },
|
|
260
|
+
{ name: "plugin-dir", hostPath: { path: pluginDir, type: "DirectoryOrCreate" } },
|
|
261
|
+
{ name: "registration-dir", hostPath: { path: "/var/lib/kubelet/plugins_registry/", type: "Directory" } },
|
|
262
|
+
{ name: "device-dir", hostPath: { path: "/dev", type: "Directory" } },
|
|
263
|
+
{ name: "jfs-dir", hostPath: { path: MOUNT_PATH, type: "DirectoryOrCreate" } },
|
|
264
|
+
{ name: "jfs-root-dir", hostPath: { path: CONFIG_PATH, type: "DirectoryOrCreate" } },
|
|
265
|
+
{ name: "juicefs-config", configMap: { name: CONFIG } },
|
|
266
|
+
{ name: "jfs-fuse-fd", hostPath: { path: "/var/run/juicefs-csi", type: "DirectoryOrCreate" } },
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/** The driver's objects, unless the cluster already has the driver: the CSIDriver and the mount pods' PriorityClass among them, which are the cluster's. */
|
|
274
|
+
export function juicefsCsiObjects(config) {
|
|
275
|
+
const { csi } = config.workspaceStorage;
|
|
276
|
+
if (!csi.enabled)
|
|
277
|
+
return [];
|
|
278
|
+
const csiDriver = {
|
|
279
|
+
apiVersion: "storage.k8s.io/v1",
|
|
280
|
+
kind: "CSIDriver",
|
|
281
|
+
metadata: { name: CSI_DRIVER, labels: LABELS },
|
|
282
|
+
spec: { attachRequired: false, podInfoOnMount: true },
|
|
283
|
+
};
|
|
284
|
+
const priorityClass = {
|
|
285
|
+
apiVersion: "scheduling.k8s.io/v1",
|
|
286
|
+
kind: "PriorityClass",
|
|
287
|
+
metadata: { name: MOUNT_PRIORITY_CLASS, labels: LABELS },
|
|
288
|
+
// As high as a pod's may be, so mount pods outlast the workspaces they serve, and
|
|
289
|
+
// never preempting, so a new one evicts nothing.
|
|
290
|
+
value: 1_000_000_000,
|
|
291
|
+
preemptionPolicy: "Never",
|
|
292
|
+
globalDefault: false,
|
|
293
|
+
description: "JuiceFS's mount pods, which serve alasio's workspaces",
|
|
294
|
+
};
|
|
295
|
+
const configMap = {
|
|
296
|
+
apiVersion: "v1",
|
|
297
|
+
kind: "ConfigMap",
|
|
298
|
+
metadata: { name: CONFIG, namespace: csi.namespace, labels: LABELS },
|
|
299
|
+
data: { "config.yaml": goJson(driverConfig(config), " ") },
|
|
300
|
+
};
|
|
301
|
+
return [csiDriver, priorityClass, ...identities(config), configMap, controller(config), nodeService(config)];
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=juicefs-csi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"juicefs-csi.js","sourceRoot":"","sources":["../../../../src/manifests/juicefs-csi.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { imageReference } from "../images.js";
|
|
2
2
|
import { claimSpec, componentName, databaseSecret, given, goJson, helperResources, imagePullSecrets, NAMESPACE, neonName, otelEnv, RELEASE, restrictedContainer, s3Endpoint, script, selectorLabels, sha256, stackLabels, stackPodSpec, waitFor, waitForObjectStore, } from "./common.js";
|
|
3
|
+
import { JUICEFS_METRICS_PORT, JUICEFS_PODS_SELECTOR, VOLUME_DRIVER } from "./juicefs-csi.js";
|
|
4
|
+
import { VALKEY, VALKEY_PORT } from "./valkey.js";
|
|
5
|
+
import { VALKEY_ADDRESS, workspacesBucketUrl } from "./workspace-storage.js";
|
|
3
6
|
/** A Service of the stack's: its name and component, selecting the component's pods, on `ports`. */
|
|
4
7
|
function service(name, component, ports) {
|
|
5
8
|
return {
|
|
@@ -14,13 +17,13 @@ function secretVariable(secret, key) {
|
|
|
14
17
|
return { name: key, valueFrom: { secretKeyRef: { name: secret, key } } };
|
|
15
18
|
}
|
|
16
19
|
/**
|
|
17
|
-
* The stack's secrets, made once and kept, and each service's rendered from them,
|
|
18
|
-
* neon/control/kube-setup.ts: a Job, which applying alasio runs to completion before
|
|
20
|
+
* The stack's secrets, made once and kept, and each service's rendered from them, workspace
|
|
21
|
+
* storage's among them when it is on, by neon/control/kube-setup.ts: a Job, which applying alasio runs to completion before
|
|
19
22
|
* anything else of alasio starts (../kube/apply.ts).
|
|
20
23
|
*/
|
|
21
24
|
function setup(config) {
|
|
22
25
|
const name = neonName("setup");
|
|
23
|
-
const { objectStore } = config;
|
|
26
|
+
const { objectStore, workspaceStorage } = config;
|
|
24
27
|
const metadata = { name, namespace: NAMESPACE, labels: stackLabels("neon-setup") };
|
|
25
28
|
const serviceAccount = { apiVersion: "v1", kind: "ServiceAccount", metadata };
|
|
26
29
|
const role = {
|
|
@@ -66,6 +69,16 @@ function setup(config) {
|
|
|
66
69
|
{ name: "S3_REGION", value: objectStore.external.region },
|
|
67
70
|
{ name: "S3_BUCKET_NEON", value: objectStore.buckets.neon },
|
|
68
71
|
{ name: "S3_BUCKET_LAKE", value: objectStore.buckets.lake },
|
|
72
|
+
...(workspaceStorage.enabled
|
|
73
|
+
? [
|
|
74
|
+
{ name: "WORKSPACES_NAME", value: workspaceStorage.name },
|
|
75
|
+
{ name: "WORKSPACES_BUCKET", value: objectStore.buckets.workspaces },
|
|
76
|
+
{ name: "WORKSPACES_BUCKET_URL", value: workspacesBucketUrl(config) },
|
|
77
|
+
{ name: "WORKSPACES_TRASH_DAYS", value: String(workspaceStorage.trashDays) },
|
|
78
|
+
{ name: "VALKEY_ADDRESS", value: VALKEY_ADDRESS },
|
|
79
|
+
{ name: "WORKSPACES_SECRET_LABELS", value: JSON.stringify(VOLUME_DRIVER) },
|
|
80
|
+
]
|
|
81
|
+
: []),
|
|
69
82
|
...(objectStore.bundled.enabled ? [] : [
|
|
70
83
|
{ name: "S3_EXTERNAL", value: "1" },
|
|
71
84
|
{ name: "S3_ACCESS_KEY", valueFrom: { secretKeyRef: { name: objectStore.external.existingSecret, key: "accessKey" } } },
|
|
@@ -486,10 +499,13 @@ function compute(config) {
|
|
|
486
499
|
}
|
|
487
500
|
/**
|
|
488
501
|
* A logical dump of alasio's database, restorable into any Postgres whatever becomes of
|
|
489
|
-
* the stack, to the object store's backups bucket,
|
|
502
|
+
* the stack, to the object store's backups bucket, and beside it, with workspace storage,
|
|
503
|
+
* the newest dump JuiceFS has made of its file system's metadata, which it makes in the
|
|
504
|
+
* workspaces bucket's `<name>/meta/`; of each, the last `keep` are kept.
|
|
490
505
|
*/
|
|
491
506
|
function backup(config) {
|
|
492
507
|
const component = "neon-backup";
|
|
508
|
+
const { objectStore, workspaceStorage } = config;
|
|
493
509
|
const dump = {
|
|
494
510
|
name: "dump",
|
|
495
511
|
image: imageReference(config.neon.computeImage),
|
|
@@ -514,13 +530,26 @@ function backup(config) {
|
|
|
514
530
|
command: [
|
|
515
531
|
"/bin/sh",
|
|
516
532
|
"-c",
|
|
517
|
-
script("set -eu", 's3() { aws s3 --endpoint-url "$S3_ENDPOINT" "$@"; }',
|
|
533
|
+
script("set -eu", 's3() { aws s3 --endpoint-url "$S3_ENDPOINT" "$@"; }',
|
|
534
|
+
// Deletes all but the newest KEEP of the backups whose names match $1, which sort by when they were made.
|
|
535
|
+
"prune() { s3 ls \"s3://$BUCKET/\" | awk '{print $4}' | grep \"$1\" | sort -r | tail -n +$((KEEP + 1)) \\", ' | while read -r old; do s3 rm "s3://$BUCKET/$old"; done; }', "stamp=$(date -u +%Y%m%dT%H%M%SZ)", 's3 cp /backup/alasio.dump "s3://$BUCKET/alasio-$stamp.dump"', "prune '^alasio-.*\\.dump$'", ...(workspaceStorage.enabled
|
|
536
|
+
? [
|
|
537
|
+
'meta="s3://$WORKSPACES_BUCKET/$WORKSPACES_NAME/meta/"',
|
|
538
|
+
"dump=$(s3 ls \"$meta\" | awk '{print $4}' | grep '^dump-.*\\.json\\.gz$' | sort -r | head -n 1)",
|
|
539
|
+
// None until a workspace's volume has been mounted for a while.
|
|
540
|
+
'if [ -n "$dump" ]; then s3 cp "$meta$dump" "s3://$BUCKET/$WORKSPACES_NAME-$dump"; else echo "JuiceFS has dumped no metadata of $WORKSPACES_NAME yet"; fi',
|
|
541
|
+
'prune "^$WORKSPACES_NAME-dump-.*\\.json\\.gz$"',
|
|
542
|
+
]
|
|
543
|
+
: [])),
|
|
518
544
|
],
|
|
519
545
|
env: [
|
|
520
546
|
{ name: "S3_ENDPOINT", value: s3Endpoint(config) },
|
|
521
|
-
{ name: "BUCKET", value:
|
|
547
|
+
{ name: "BUCKET", value: objectStore.buckets.backups },
|
|
522
548
|
{ name: "KEEP", value: String(config.neon.backup.keep) },
|
|
523
|
-
|
|
549
|
+
...(workspaceStorage.enabled
|
|
550
|
+
? [{ name: "WORKSPACES_BUCKET", value: objectStore.buckets.workspaces }, { name: "WORKSPACES_NAME", value: workspaceStorage.name }]
|
|
551
|
+
: []),
|
|
552
|
+
{ name: "AWS_DEFAULT_REGION", value: objectStore.external.region },
|
|
524
553
|
{ name: "HOME", value: "/tmp" },
|
|
525
554
|
],
|
|
526
555
|
envFrom: [{ secretRef: { name: neonName("s3-admin") } }],
|
|
@@ -558,14 +587,16 @@ function backup(config) {
|
|
|
558
587
|
}
|
|
559
588
|
/**
|
|
560
589
|
* The stack's telemetry: every Neon service's, SeaweedFS's and the lake's Prometheus
|
|
561
|
-
* metrics,
|
|
562
|
-
*
|
|
563
|
-
*
|
|
590
|
+
* metrics, and with workspace storage JuiceFS's and Valkey's, scraped and sent on as OTLP
|
|
591
|
+
* where alasio's telemetry goes, when it goes anywhere. JuiceFS's are its driver's and
|
|
592
|
+
* mount pods', found among the pods of the driver's namespace, which the collector may
|
|
593
|
+
* list; Valkey's are read with its password. Its pod carries its configuration's
|
|
594
|
+
* checksum, so it is replaced when that changes.
|
|
564
595
|
*/
|
|
565
596
|
function collector(config, endpoint) {
|
|
566
597
|
const name = neonName("collector");
|
|
567
598
|
const component = "neon-collector";
|
|
568
|
-
const { telemetry } = config;
|
|
599
|
+
const { telemetry, workspaceStorage } = config;
|
|
569
600
|
const safekeeper = neonName("safekeeper");
|
|
570
601
|
const targets = {
|
|
571
602
|
pageserver: [`${neonName("pageserver")}:9898`],
|
|
@@ -576,19 +607,51 @@ function collector(config, endpoint) {
|
|
|
576
607
|
...(config.objectStore.bundled.enabled ? { seaweedfs: [`${componentName("seaweedfs")}:9327`] } : {}),
|
|
577
608
|
...(config.lake.enabled ? { lake: [`${componentName("lake")}:9464`] } : {}),
|
|
578
609
|
};
|
|
610
|
+
// Each running pod at its address, on the metrics port, named by its pod. The
|
|
611
|
+
// collector reads `$` as the start of a variable, and `$$` as a `$`.
|
|
612
|
+
const juicefs = {
|
|
613
|
+
job_name: "juicefs",
|
|
614
|
+
scrape_interval: "30s",
|
|
615
|
+
kubernetes_sd_configs: [{
|
|
616
|
+
role: "pod",
|
|
617
|
+
namespaces: { names: [workspaceStorage.csi.namespace] },
|
|
618
|
+
selectors: [{ role: "pod", label: JUICEFS_PODS_SELECTOR }],
|
|
619
|
+
}],
|
|
620
|
+
relabel_configs: [
|
|
621
|
+
{ source_labels: ["__meta_kubernetes_pod_phase"], regex: "Running", action: "keep" },
|
|
622
|
+
{ source_labels: ["__meta_kubernetes_pod_ip"], target_label: "__address__", replacement: `$$1:${JUICEFS_METRICS_PORT}` },
|
|
623
|
+
{ source_labels: ["__meta_kubernetes_pod_name"], target_label: "pod" },
|
|
624
|
+
],
|
|
625
|
+
};
|
|
579
626
|
const collectorConfig = {
|
|
580
627
|
receivers: {
|
|
581
628
|
prometheus: {
|
|
582
629
|
config: {
|
|
583
|
-
scrape_configs:
|
|
630
|
+
scrape_configs: [
|
|
631
|
+
...Object.keys(targets).sort().map((job) => ({ job_name: job, scrape_interval: "30s", static_configs: [{ targets: targets[job] }] })),
|
|
632
|
+
...(workspaceStorage.enabled ? [juicefs] : []),
|
|
633
|
+
],
|
|
584
634
|
},
|
|
585
635
|
},
|
|
636
|
+
...(workspaceStorage.enabled
|
|
637
|
+
? {
|
|
638
|
+
redis: {
|
|
639
|
+
endpoint: `${VALKEY}:${VALKEY_PORT}`,
|
|
640
|
+
password: "${env:VALKEY_PASSWORD}",
|
|
641
|
+
collection_interval: "30s",
|
|
642
|
+
// How near it is to refusing writes: used memory against this.
|
|
643
|
+
metrics: { "redis.maxmemory": { enabled: true } },
|
|
644
|
+
},
|
|
645
|
+
}
|
|
646
|
+
: {}),
|
|
586
647
|
},
|
|
587
648
|
processors: { resource: { attributes: [{ key: "service.namespace", value: "alasio-neon", action: "upsert" }] }, batch: {} },
|
|
588
649
|
exporters: { otlphttp: { endpoint, ...(telemetry.headersSecret ? { headers: "${file:/etc/otelcol/headers/headers.yaml}" } : {}) } },
|
|
589
650
|
service: {
|
|
590
651
|
telemetry: { metrics: { level: "none" } },
|
|
591
|
-
pipelines: {
|
|
652
|
+
pipelines: {
|
|
653
|
+
metrics: { receivers: ["prometheus", ...(workspaceStorage.enabled ? ["redis"] : [])], processors: ["resource", "batch"], exporters: ["otlphttp"] },
|
|
654
|
+
},
|
|
592
655
|
},
|
|
593
656
|
};
|
|
594
657
|
const configMap = {
|
|
@@ -607,12 +670,14 @@ function collector(config, endpoint) {
|
|
|
607
670
|
template: {
|
|
608
671
|
metadata: { labels: stackLabels(component), annotations: { "checksum/config": sha256(goJson(collectorConfig)) } },
|
|
609
672
|
spec: {
|
|
673
|
+
...(workspaceStorage.enabled ? { serviceAccountName: name } : {}),
|
|
610
674
|
...stackPodSpec(config),
|
|
611
675
|
containers: [{
|
|
612
676
|
name: "collector",
|
|
613
677
|
image: imageReference(config.neon.collector.image),
|
|
614
678
|
imagePullPolicy: "IfNotPresent",
|
|
615
679
|
args: ["--config=/etc/otelcol/config.yaml"],
|
|
680
|
+
...(workspaceStorage.enabled ? { env: [{ name: "VALKEY_PASSWORD", valueFrom: { secretKeyRef: { name: VALKEY, key: "password" } } }] } : {}),
|
|
616
681
|
securityContext: { ...restrictedContainer(), readOnlyRootFilesystem: true },
|
|
617
682
|
resources: config.neon.collector.resources,
|
|
618
683
|
volumeMounts: [
|
|
@@ -632,7 +697,25 @@ function collector(config, endpoint) {
|
|
|
632
697
|
},
|
|
633
698
|
},
|
|
634
699
|
};
|
|
635
|
-
|
|
700
|
+
if (!workspaceStorage.enabled)
|
|
701
|
+
return [configMap, deployment];
|
|
702
|
+
// Who the collector is, and that it may find JuiceFS's pods in the driver's namespace.
|
|
703
|
+
const serviceAccount = { apiVersion: "v1", kind: "ServiceAccount", metadata: { name, namespace: NAMESPACE, labels: stackLabels(component) } };
|
|
704
|
+
const metadata = { name, namespace: workspaceStorage.csi.namespace, labels: stackLabels(component) };
|
|
705
|
+
const role = {
|
|
706
|
+
apiVersion: "rbac.authorization.k8s.io/v1",
|
|
707
|
+
kind: "Role",
|
|
708
|
+
metadata,
|
|
709
|
+
rules: [{ apiGroups: [""], resources: ["pods"], verbs: ["get", "list", "watch"] }],
|
|
710
|
+
};
|
|
711
|
+
const binding = {
|
|
712
|
+
apiVersion: "rbac.authorization.k8s.io/v1",
|
|
713
|
+
kind: "RoleBinding",
|
|
714
|
+
metadata,
|
|
715
|
+
subjects: [{ kind: "ServiceAccount", name, namespace: NAMESPACE }],
|
|
716
|
+
roleRef: { apiGroup: "rbac.authorization.k8s.io", kind: "Role", name },
|
|
717
|
+
};
|
|
718
|
+
return [serviceAccount, role, binding, configMap, deployment];
|
|
636
719
|
}
|
|
637
720
|
/** Neon's objects, when it runs. */
|
|
638
721
|
export function neonObjects(config) {
|