Skip to content

Commit 834936b

Browse files
Switch IPPool agent to Deployment with rolling updates
1 parent e9b4ebb commit 834936b

File tree

18 files changed

+1020
-374
lines changed

18 files changed

+1020
-374
lines changed

chart/crds/network.harvesterhci.io_ippools.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ spec:
150150
type: object
151151
status:
152152
properties:
153-
agentPodRef:
153+
agentDeploymentRef:
154154
properties:
155155
image:
156156
type: string

chart/templates/rbac.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ rules:
1818
- apiGroups: [ "" ]
1919
resources: [ "namespaces" ]
2020
verbs: [ "get", "watch", "list" ]
21-
- apiGroups: [ "" ]
22-
resources: [ "pods" ]
23-
verbs: [ "watch", "list" ]
21+
- apiGroups: [ "apps" ]
22+
resources: [ "deployments" ]
23+
verbs: [ "get", "watch", "list" ]
2424
- apiGroups: [ "kubevirt.io" ]
2525
resources: [ "virtualmachines" ]
2626
verbs: [ "get", "watch", "list" ]
@@ -122,11 +122,11 @@ rules:
122122
apiVersion: rbac.authorization.k8s.io/v1
123123
kind: Role
124124
metadata:
125-
name: {{ include "harvester-vm-dhcp-controller.name" . }}-pod-manager
125+
name: {{ include "harvester-vm-dhcp-controller.name" . }}-deployment-manager
126126
rules:
127-
- apiGroups: [ "" ]
128-
resources: [ "pods" ]
129-
verbs: [ "get", "create", "delete" ]
127+
- apiGroups: [ "apps" ]
128+
resources: [ "deployments" ]
129+
verbs: [ "get", "create", "update", "delete" ]
130130
---
131131
apiVersion: rbac.authorization.k8s.io/v1
132132
kind: Role
@@ -157,13 +157,13 @@ subjects:
157157
apiVersion: rbac.authorization.k8s.io/v1
158158
kind: RoleBinding
159159
metadata:
160-
name: {{ include "harvester-vm-dhcp-controller.name" . }}-manage-pods
160+
name: {{ include "harvester-vm-dhcp-controller.name" . }}-manage-deployments
161161
labels:
162162
{{- include "harvester-vm-dhcp-controller.labels" . | nindent 4 }}
163163
roleRef:
164164
apiGroup: rbac.authorization.k8s.io
165165
kind: Role
166-
name: {{ include "harvester-vm-dhcp-controller.name" . }}-pod-manager
166+
name: {{ include "harvester-vm-dhcp-controller.name" . }}-deployment-manager
167167
subjects:
168168
- kind: ServiceAccount
169169
name: {{ include "harvester-vm-dhcp-controller.serviceAccountName" . }}

docs/ippool-agent-deployment.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
name: ippool-agent-deployment-reconcile
3+
description: Plan to move IPPool agents from Pods to Deployments and reconcile via operator pattern.
4+
---
5+
6+
# Plan
7+
8+
Obiettivo: passare da agent Pod a Deployment per ogni IPPool e riconciliare con pattern operator, aggiornando API, controller, RBAC e test.
9+
10+
## Requirements
11+
- Ogni IPPool crea/gestisce un Deployment agent (repliche=1) con la stessa logica di rete/affinity/args attuale.
12+
- Reconcile idempotente: crea/aggiorna/monitor/cleanup del Deployment.
13+
- Upgrade immagine rispettando `hold-ippool-agent-upgrade`.
14+
15+
## Scope
16+
- In: IPPool controller, API/CRD status, codegen, RBAC, test.
17+
- Out: logica DHCP/IPAM/VMNetCfg non correlata.
18+
19+
## Files and entry points
20+
- `pkg/controller/ippool/controller.go`
21+
- `pkg/controller/ippool/common.go`
22+
- `pkg/apis/network.harvesterhci.io/v1alpha1/ippool.go`
23+
- `pkg/codegen/main.go`, `pkg/config/context.go`
24+
- `pkg/util/fakeclient`, `pkg/controller/ippool/controller_test.go`
25+
- `chart/templates/rbac.yaml`, `chart/crds/network.harvesterhci.io_ippools.yaml`
26+
- `pkg/data/data.go`
27+
28+
## Data model / API changes
29+
- Sostituire `status.agentPodRef` con `status.agentDeploymentRef` (nuovo `DeploymentReference`).
30+
31+
## Action items
32+
[ ] Aggiungere client/controller apps/v1 Deployment (codegen + Management) e fakeclient.
33+
[ ] Implementare `prepareAgentDeployment` e aggiornare Deploy/Monitor/Cleanup per Deployment.
34+
[ ] Aggiornare watch `relatedresource` su Deployment con label ippool.
35+
[ ] Aggiornare builder/status helpers e test per Deployment.
36+
[ ] Aggiornare RBAC per `deployments` (get/list/watch/create/update/delete).
37+
[ ] Rigenerare codegen/CRD/bindata.
38+
39+
## Testing and validation
40+
- `go test ./...` (o `go test ./pkg/controller/ippool -run TestHandler_`).
41+
- `go generate` per rigenerare CRD/client/bindata.
42+
43+
## Risks and edge cases
44+
- Breaking change CRD status.
45+
- Strategia Deployment (Recreate vs RollingUpdate) impatta continuita DHCP.
46+
- Namespace agent != IPPool: relazione via label, non ownerRef.
47+
48+
## Open questions
49+
- Posso usare `agentDeploymentRef` al posto di `agentPodRef` anche se breaking?
50+
- Preferisci `Recreate` o `RollingUpdate` per i Deployment agent?
51+
52+
---
53+
54+
# IPPool agent su Deployment
55+
56+
Questo documento descrive logica e modifiche introdotte per spostare l'agent IPPool
57+
da Pod singolo a Deployment, con riconciliazione di tipo operator e strategia
58+
RollingUpdate.
59+
60+
## Obiettivo
61+
- Ogni IPPool crea e gestisce un Deployment dedicato (repliche=1).
62+
- Riconciliazione idempotente che crea o aggiorna il Deployment quando cambia la configurazione.
63+
- Upgrade immagine controllato dall'annotazione `network.harvesterhci.io/hold-ippool-agent-upgrade`.
64+
- Migrazione centrata sul nuovo riferimento di stato `agentDeploymentRef`.
65+
66+
## Flusso di riconciliazione
67+
### DeployAgent
68+
- Recupera ClusterNetwork dalla NetworkAttachmentDefinition (label `network.harvesterhci.io/clusternetwork`).
69+
- Calcola l'immagine desiderata (rispetta l'annotazione di hold).
70+
- Costruisce il Deployment desiderato via `prepareAgentDeployment`.
71+
- Se `status.agentDeploymentRef` e valorizzato:
72+
- Verifica UID e che il Deployment non sia in deletion.
73+
- Richiede selector immutabile (errore se diverge).
74+
- Aggiorna labels, strategy, replicas, template e container se differiscono.
75+
- Aggiorna `agentDeploymentRef` con namespace/nome/UID.
76+
- Se il Deployment non esiste o lo status e vuoto, crea il Deployment e registra lo status.
77+
78+
### MonitorAgent
79+
- Se `noAgent` e true, non fa nulla; se IPPool e in pausa, ritorna errore.
80+
- Verifica esistenza, UID e immagine del container rispetto allo status.
81+
- Verifica readiness usando `ObservedGeneration` e repliche `Updated/Available`.
82+
- In caso di mismatch o non readiness, ritorna errore (non cancella il Deployment).
83+
84+
### Cleanup
85+
- Elimina il Deployment associato e pulisce IPAM/MAC/metriche.
86+
- Usato su pause o rimozione IPPool.
87+
88+
## Dettagli implementativi
89+
- Nome Deployment derivato da `util.SafeAgentConcatName`.
90+
- Labels: `network.harvesterhci.io/vm-dhcp-controller=agent` + labels IPPool namespace/nome.
91+
- Pod template con annotazione Multus `k8s.v1.cni.cncf.io/networks`.
92+
- Init container `ip-setter` per configurare `eth1`; container `agent` con probes `/healthz` e `/readyz`.
93+
- Container defaults (ImagePullPolicy e TerminationMessage*) esplicitati per evitare reconcile loop.
94+
- Strategia RollingUpdate: `maxUnavailable=0`, `maxSurge=1`.
95+
96+
## Cambiamenti di stato/CRD
97+
- `status.agentPodRef` sostituito da `status.agentDeploymentRef`.
98+
- Nuova struct `DeploymentReference` con namespace, name, image, UID.
99+
- CRD aggiornata e bindata rigenerata.
100+
101+
## Watch e relazione risorse
102+
- Watch su Deployment con label `vm-dhcp-controller=agent`.
103+
- Mapping IPPool tramite label `ippool-namespace` e `ippool-name`.
104+
105+
## RBAC
106+
- Aggiunti permessi `deployments` per controller (get/list/watch).
107+
- Role dedicato `*-deployment-manager` con create/update/delete.
108+
- Binding aggiornato da `manage-pods` a `manage-deployments`.
109+
110+
## Codegen e generated
111+
- Aggiunto gruppo apps/v1 alla codegen per controller/cache Deployment.
112+
- Nuovi controller generati in `pkg/generated/controllers/apps`.
113+
- Nuovo fake client per Deployment in `pkg/util/fakeclient/deployment.go`.
114+
115+
## Modifiche al codice (file principali)
116+
- `pkg/controller/ippool/controller.go`: DeployAgent/MonitorAgent/cleanup aggiornati per Deployment.
117+
- `pkg/controller/ippool/common.go`: `prepareAgentDeployment` e builder di supporto.
118+
- `pkg/apis/network.harvesterhci.io/v1alpha1/ippool.go`: nuovo status field e tipo reference.
119+
- `pkg/config/context.go`: AppsFactory aggiunta al bootstrap.
120+
- `pkg/codegen/main.go`: codegen apps/v1 e rigenerazione dei controller.
121+
- `chart/templates/rbac.yaml` e `chart/crds/network.harvesterhci.io_ippools.yaml`: RBAC/CRD aggiornate.
122+
123+
## Compatibilita e migrazione
124+
- `status.agentPodRef` non e piu letto; eventuali Pod legacy non sono piu gestiti.
125+
- RollingUpdate con `maxSurge=1` puo generare un secondo agent temporaneo.
126+
- Se esiste un Deployment con selector differente, la reconcile fallisce per evitare adozioni errate.
127+
128+
## Test
129+
- Eseguito `go test ./...`.

pkg/apis/network.harvesterhci.io/v1alpha1/ippool.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ type IPPoolStatus struct {
119119

120120
// +optional
121121
// +kubebuilder:validation:Optional
122-
AgentPodRef *PodReference `json:"agentPodRef,omitempty"`
122+
AgentDeploymentRef *DeploymentReference `json:"agentDeploymentRef,omitempty"`
123123

124124
// +optional
125125
// +kubebuilder:validation:Optional
@@ -132,7 +132,7 @@ type IPv4Status struct {
132132
Available int `json:"available"`
133133
}
134134

135-
type PodReference struct {
135+
type DeploymentReference struct {
136136
Namespace string `json:"namespace,omitempty"`
137137
Name string `json:"name,omitempty"`
138138
Image string `json:"image,omitempty"`

pkg/apis/network.harvesterhci.io/v1alpha1/zz_generated_deepcopy.go

Lines changed: 19 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/codegen/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
controllergen "github.com/rancher/wrangler/v3/pkg/controller-gen"
1010
"github.com/rancher/wrangler/v3/pkg/controller-gen/args"
1111
"github.com/sirupsen/logrus"
12+
appsv1 "k8s.io/api/apps/v1"
1213
corev1 "k8s.io/api/core/v1"
1314
kubevirtv1 "kubevirt.io/api/core/v1"
1415
)
@@ -48,6 +49,11 @@ func main() {
4849
corev1.Pod{},
4950
},
5051
},
52+
appsv1.SchemeGroupVersion.Group: {
53+
Types: []interface{}{
54+
appsv1.Deployment{},
55+
},
56+
},
5157
cniv1.SchemeGroupVersion.Group: {
5258
Types: []interface{}{
5359
cniv1.NetworkAttachmentDefinition{},

pkg/config/context.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/harvester/vm-dhcp-controller/pkg/cache"
2525
"github.com/harvester/vm-dhcp-controller/pkg/crd"
2626
"github.com/harvester/vm-dhcp-controller/pkg/dhcp"
27+
ctlapps "github.com/harvester/vm-dhcp-controller/pkg/generated/controllers/apps"
2728
ctlcore "github.com/harvester/vm-dhcp-controller/pkg/generated/controllers/core"
2829
ctlcni "github.com/harvester/vm-dhcp-controller/pkg/generated/controllers/k8s.cni.cncf.io"
2930
ctlkubevirt "github.com/harvester/vm-dhcp-controller/pkg/generated/controllers/kubevirt.io"
@@ -96,6 +97,7 @@ type Management struct {
9697

9798
HarvesterNetworkFactory *ctlnetwork.Factory
9899

100+
AppsFactory *ctlapps.Factory
99101
CniFactory *ctlcni.Factory
100102
CoreFactory *ctlcore.Factory
101103
KubeVirtFactory *ctlkubevirt.Factory
@@ -169,6 +171,13 @@ func SetupManagement(ctx context.Context, restConfig *rest.Config, options *Cont
169171
management.CoreFactory = core
170172
management.starters = append(management.starters, core)
171173

174+
apps, err := ctlapps.NewFactoryFromConfigWithOptions(restConfig, opts)
175+
if err != nil {
176+
return nil, err
177+
}
178+
management.AppsFactory = apps
179+
management.starters = append(management.starters, apps)
180+
172181
cni, err := ctlcni.NewFactoryFromConfigWithOptions(restConfig, opts)
173182
if err != nil {
174183
return nil, err

0 commit comments

Comments
 (0)