fix(images): 服务器镜像在创建时固定到仓库 digest,更换镜像需确认备份,安装器重建前先固定旧服并推送不可变版本标签
This commit is contained in:
29 files changed
+1149
-29
No files matched your search
@@ -234,11 +234,13 @@ func loginToInternalAPI(p Params) *networkingv1.NetworkPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
// RegistryIngressPolicy fences the registry pod: only build pods reach its port.
|
||||
// Everything else that uses the registry runs on the node — containerd's pulls and
|
||||
// the installer's pushes both arrive through the loopback hostPort — and Kubernetes
|
||||
// never blocks resident-node traffic. Write authorization is the gate's job; this
|
||||
// policy keeps every other pod from even trying.
|
||||
// RegistryIngressPolicy fences the registry pod: only build pods and felis-api
|
||||
// reach its port. Build pods push what they build; felis-api reads a manifest
|
||||
// digest to pin a new server's image (internal/imagepin). Everything else that
|
||||
// uses the registry runs on the node — containerd's pulls and the installer's
|
||||
// pushes both arrive through the loopback hostPort — and Kubernetes never blocks
|
||||
// resident-node traffic. Write authorization is the gate's job (felis-api holds no
|
||||
// registry credential); this policy keeps every other pod from even trying.
|
||||
func RegistryIngressPolicy(p Params) *networkingv1.NetworkPolicy {
|
||||
p = p.withDefaults()
|
||||
tcp := corev1.ProtocolTCP
|
||||
@@ -246,11 +248,22 @@ func RegistryIngressPolicy(p Params) *networkingv1.NetworkPolicy {
|
||||
np := netpol("felis-registry-ingress", p.RegistryNamespace,
|
||||
metav1.LabelSelector{MatchLabels: registryLabels()},
|
||||
[]networkingv1.NetworkPolicyIngressRule{{
|
||||
From: []networkingv1.NetworkPolicyPeer{{
|
||||
NamespaceSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"kubernetes.io/metadata.name": p.BuildNamespace},
|
||||
From: []networkingv1.NetworkPolicyPeer{
|
||||
{
|
||||
NamespaceSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"kubernetes.io/metadata.name": p.BuildNamespace},
|
||||
},
|
||||
},
|
||||
}},
|
||||
{
|
||||
NamespaceSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"kubernetes.io/metadata.name": p.ControlNamespace},
|
||||
},
|
||||
PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{
|
||||
LabelPartOf: controlPlanePartOf,
|
||||
LabelComponent: ComponentAPI,
|
||||
}},
|
||||
},
|
||||
},
|
||||
Ports: []networkingv1.NetworkPolicyPort{{Protocol: &tcp, Port: &port}},
|
||||
}},
|
||||
)
|
||||
|
||||
@@ -307,7 +307,7 @@ func TestLoginToInternalAPI_SelectsOnlyTheSystemLoginPod(t *testing.T) {
|
||||
// TestRegistryIngress_BuildNamespaceOnly pins who may dial the registry pod: build
|
||||
// pods, on the registry port. Game servers and the control plane never pull
|
||||
// through the Service — containerd pulls over the node's loopback hostPort.
|
||||
func TestRegistryIngress_BuildNamespaceOnly(t *testing.T) {
|
||||
func TestRegistryIngress_BuildNamespaceAndAPI(t *testing.T) {
|
||||
p := testParams().withDefaults()
|
||||
np := RegistryIngressPolicy(p)
|
||||
if np.Namespace != p.RegistryNamespace {
|
||||
@@ -319,14 +319,27 @@ func TestRegistryIngress_BuildNamespaceOnly(t *testing.T) {
|
||||
if mapSelectorMatches(np.Spec.PodSelector.MatchLabels, APIDeployment(p).Spec.Template.Labels) {
|
||||
t.Error("registry ingress must not also fence the api pod")
|
||||
}
|
||||
if len(np.Spec.Ingress) != 1 || len(np.Spec.Ingress[0].From) != 1 {
|
||||
t.Fatalf("registry ingress shape = %+v, want one rule, one peer", np.Spec.Ingress)
|
||||
if len(np.Spec.Ingress) != 1 || len(np.Spec.Ingress[0].From) != 2 {
|
||||
t.Fatalf("registry ingress shape = %+v, want one rule, two peers", np.Spec.Ingress)
|
||||
}
|
||||
peer := np.Spec.Ingress[0].From[0]
|
||||
if peer.PodSelector != nil || peer.IPBlock != nil || peer.NamespaceSelector == nil ||
|
||||
peer.NamespaceSelector.MatchLabels["kubernetes.io/metadata.name"] != p.BuildNamespace {
|
||||
t.Errorf("registry ingress peer = %+v, want the whole %s namespace", peer, p.BuildNamespace)
|
||||
}
|
||||
// The second peer is felis-api alone: it selects the api pod and not the
|
||||
// operator's, both of which live in the control namespace.
|
||||
api := np.Spec.Ingress[0].From[1]
|
||||
if api.IPBlock != nil || api.NamespaceSelector == nil || api.PodSelector == nil ||
|
||||
api.NamespaceSelector.MatchLabels["kubernetes.io/metadata.name"] != p.ControlNamespace {
|
||||
t.Fatalf("registry ingress api peer = %+v, want pods in %s", api, p.ControlNamespace)
|
||||
}
|
||||
if !mapSelectorMatches(api.PodSelector.MatchLabels, APIDeployment(p).Spec.Template.Labels) {
|
||||
t.Errorf("registry ingress api peer %v does not select the api pod", api.PodSelector)
|
||||
}
|
||||
if mapSelectorMatches(api.PodSelector.MatchLabels, OperatorDeployment(p).Spec.Template.Labels) {
|
||||
t.Errorf("registry ingress api peer %v also selects the operator pod", api.PodSelector)
|
||||
}
|
||||
assertSinglePort(t, np.Spec.Ingress[0].Ports, int(p.RegistryPort))
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user