feat(offsite): 世界归档与数据库备份加密同步到异地 S3,reaper 确认异地副本后才删除世界
This commit is contained in:
27 files changed
+2928
-51
No files matched your search
@@ -1029,6 +1029,43 @@ func backupPVC(p Params) *corev1.PersistentVolumeClaim {
|
||||
}
|
||||
}
|
||||
|
||||
// VolumeBinderPod mounts pvc and exits at once. A WaitForFirstConsumer volume
|
||||
// (k3s local-path) has no directory until a pod uses it, and on a rebuilt node
|
||||
// nothing has yet, so `felis offsite fetch-worlds` runs this to have the
|
||||
// archive volume provisioned before it writes the archives back into it. It
|
||||
// runs as the control-plane identity, which the archive volume's files already
|
||||
// belong to (fsGroup).
|
||||
func VolumeBinderPod(ns, pvc, image string) *corev1.Pod {
|
||||
return &corev1.Pod{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "felis-bind-" + pvc + "-",
|
||||
Namespace: ns,
|
||||
Labels: map[string]string{LabelName: appName, LabelComponent: "volume-binder"},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
RestartPolicy: corev1.RestartPolicyNever,
|
||||
AutomountServiceAccountToken: boolPtr(false),
|
||||
SecurityContext: hardenedPodSecurityContext(),
|
||||
Containers: []corev1.Container{{
|
||||
Name: "bind",
|
||||
Image: image,
|
||||
Command: []string{felisBinaryPath, "version"},
|
||||
SecurityContext: hardenedContainerSecurityContext(),
|
||||
VolumeMounts: []corev1.VolumeMount{{Name: "archives", MountPath: "/archives"}},
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("10m"), corev1.ResourceMemory: resource.MustParse("16Mi")},
|
||||
Limits: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("100m"), corev1.ResourceMemory: resource.MustParse("64Mi")},
|
||||
},
|
||||
}},
|
||||
Volumes: []corev1.Volume{{
|
||||
Name: "archives",
|
||||
VolumeSource: corev1.VolumeSource{PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pvc}},
|
||||
}},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// registryLabels are the registry's recommended labels. Note the absence of
|
||||
// part-of=felis-control-plane: that is what keeps the registry out of the RCON
|
||||
// NetworkPolicy peer's reach (asserted in workloads_test.go).
|
||||
|
||||
@@ -164,6 +164,35 @@ func TestControlPlanePods_Hardened(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestVolumeBinderPod pins the pod `felis offsite fetch-worlds` runs to get the
|
||||
// archive volume provisioned: hardened like the control plane (it runs in the
|
||||
// Minecraft namespace under PSA), mounting the named claim, gone once it exits.
|
||||
func TestVolumeBinderPod(t *testing.T) {
|
||||
pod := VolumeBinderPod("minecraft", "felis-backups", "registry.example/felis:1")
|
||||
ps := pod.Spec
|
||||
if pod.Namespace != "minecraft" || pod.GenerateName == "" || ps.RestartPolicy != corev1.RestartPolicyNever {
|
||||
t.Fatalf("pod meta = %+v, restart %s", pod.ObjectMeta, ps.RestartPolicy)
|
||||
}
|
||||
if ps.SecurityContext == nil || ps.SecurityContext.RunAsNonRoot == nil || !*ps.SecurityContext.RunAsNonRoot ||
|
||||
ps.SecurityContext.SeccompProfile == nil || ps.SecurityContext.SeccompProfile.Type != corev1.SeccompProfileTypeRuntimeDefault {
|
||||
t.Errorf("pod security context = %+v", ps.SecurityContext)
|
||||
}
|
||||
if ps.AutomountServiceAccountToken == nil || *ps.AutomountServiceAccountToken {
|
||||
t.Error("the binder needs no API token")
|
||||
}
|
||||
c := ps.Containers[0]
|
||||
if got := append(append([]string{}, c.Command...), c.Args...); !containsSeq(got, []string{felisBinaryPath, "version"}) {
|
||||
t.Errorf("command = %v", got)
|
||||
}
|
||||
if sc := c.SecurityContext; sc == nil || sc.AllowPrivilegeEscalation == nil || *sc.AllowPrivilegeEscalation ||
|
||||
sc.Capabilities == nil || len(sc.Capabilities.Drop) == 0 || sc.Capabilities.Drop[0] != "ALL" {
|
||||
t.Errorf("container security context = %+v", c.SecurityContext)
|
||||
}
|
||||
if len(ps.Volumes) != 1 || ps.Volumes[0].PersistentVolumeClaim == nil || ps.Volumes[0].PersistentVolumeClaim.ClaimName != "felis-backups" {
|
||||
t.Errorf("volumes = %+v", ps.Volumes)
|
||||
}
|
||||
}
|
||||
|
||||
// TestAPIDeployment_Wiring pins the api entrypoint, the credential plumbing, and
|
||||
// the FELIS_IMAGE passthrough.
|
||||
func TestAPIDeployment_Wiring(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user