Skip to content

Commit 7ebce2e

Browse files
kvapslllamnypsircthulhulexfrei
committed
feat(kubeovn): build the chart and image in-tree
kubeovn was the last package whose chart and image were produced by a separate repository: packages/system/kubeovn pulled a tarball from the latest cozystack/kubeovn-chart tag at update time, and that repository built and pushed the image. The wrapper existed only to cache the upstream chart; with the current caching that reason is gone, and the split cost a second repository, a second release step, and a package whose provenance a reader could not follow without leaving the tree. Move the wrapper in, shaped like packages/system/cilium: update pulls the upstream kube-ovn chart directly and applies patches/mtu.diff, and image builds images/kubeovn and pins the digest into values.yaml. The MTU patch already carried monorepo-relative paths, so it applies here unchanged. Also carries cozystack/kubeovn-chart#5, which never got a tag: pin OVN_IPSEC_KEY_DIR under /var/lib. The kube-ovn default sits in /etc/origin, which a Talos node cannot create, so enabling IPsec left the node without ESP security associations. Co-authored-by: Timofei Larkin <[email protected]> Co-authored-by: Kirill Ilin <[email protected]> Co-authored-by: Aleksei Sviridkin <[email protected]> Assisted-By: Claude Signed-off-by: Andrei Kvapil <[email protected]>
1 parent 8b461f0 commit 7ebce2e

5 files changed

Lines changed: 175 additions & 4 deletions

File tree

‎packages/system/kubeovn/Makefile‎

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
KUBEOVN_TAG=$(shell awk '$$1 == "appVersion:" {print $$2}' charts/kube-ovn/Chart.yaml)
2+
13
export NAME=kubeovn
24
export NAMESPACE=cozy-$(NAME)
35

@@ -8,7 +10,27 @@ test:
810
helm unittest .
911

1012
update:
11-
rm -rf charts values.yaml Chart.yaml
12-
tag=$$(git ls-remote --tags --sort="v:refname" https://github.com/cozystack/kubeovn-chart | awk -F'[/^]' 'END{print $$3}') && \
13-
curl -sSL https://github.com/cozystack/kubeovn-chart/archive/refs/tags/$${tag}.tar.gz | \
14-
tar xzvf - --strip 2 kubeovn-chart-$${tag#*v}/chart
13+
rm -rf charts
14+
tag=$$(git ls-remote --tags --sort="v:refname" https://github.com/kubeovn/kube-ovn | awk -F'[/^]' '{print $$3}' | grep '^v1\.15\.' | tail -n1) && \
15+
curl -sSL https://github.com/kubeovn/kube-ovn/archive/refs/tags/$${tag}.tar.gz | \
16+
tar -xzf - --strip 1 kube-ovn-$${tag#*v}/charts/kube-ovn
17+
# Teach the CNI DaemonSet to honour an explicit MTU: upstream derives it from
18+
# the node interface, which is wrong when the underlay is encapsulated.
19+
patch --no-backup-if-mismatch -p4 < patches/mtu.diff
20+
version=$$(awk '$$1 == "appVersion:" {print $$2}' charts/kube-ovn/Chart.yaml) && \
21+
$(SED_INPLACE) -e "s/ARG VERSION=.*/ARG VERSION=$${version}/" images/kubeovn/Dockerfile && \
22+
$(SED_INPLACE) -e "s/ARG TAG=.*/ARG TAG=v$${version}/" images/kubeovn/Dockerfile
23+
24+
image:
25+
docker buildx build images/kubeovn \
26+
$(call image-tags,kubeovn,v$(KUBEOVN_TAG)) \
27+
$(call cache-args,kubeovn) \
28+
--metadata-file images/kubeovn.json \
29+
$(BUILDX_ARGS)
30+
ADDRESS="$(REGISTRY)" \
31+
yq -i '.global.registry.address = strenv(ADDRESS)' values.yaml
32+
REPOSITORY="kubeovn" \
33+
yq -i '.global.images.kubeovn.repository = strenv(REPOSITORY)' values.yaml
34+
TAG="$(IMAGE_TAG)@$$(yq e '."containerimage.digest"' images/kubeovn.json -o json -r)" \
35+
yq -i '.global.images.kubeovn.tag = strenv(TAG)' values.yaml
36+
rm -f images/kubeovn.json
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# syntax = docker/dockerfile:experimental
2+
ARG VERSION="1.15.10"
3+
ARG BASE_TAG=v$VERSION
4+
5+
FROM golang:1.26-bookworm as builder
6+
7+
ARG TAG="v1.15.10"
8+
RUN git clone --branch ${TAG} --depth 1 https://github.com/kubeovn/kube-ovn /source
9+
10+
WORKDIR /source
11+
12+
COPY patches /patches
13+
RUN git apply /patches/*.diff
14+
RUN make build-go
15+
16+
WORKDIR /source/dist/images
17+
18+
# imported from https://github.com/kubeovn/kube-ovn/blob/master/dist/images/Dockerfile
19+
FROM kubeovn/kube-ovn-base:$BASE_TAG AS setcap
20+
21+
COPY --from=builder /source/dist/images/*.sh /kube-ovn/
22+
COPY --from=builder /source/dist/images/kubectl-ko /kube-ovn/kubectl-ko
23+
COPY --from=builder /source/dist/images/01-kube-ovn.conflist /kube-ovn/01-kube-ovn.conflist
24+
25+
COPY --from=builder /source/dist/images/kube-ovn /kube-ovn/kube-ovn
26+
COPY --from=builder /source/dist/images/kube-ovn-cmd /kube-ovn/kube-ovn-cmd
27+
COPY --from=builder /source/dist/images/kube-ovn-daemon /kube-ovn/kube-ovn-daemon
28+
COPY --from=builder /source/dist/images/kube-ovn-controller /kube-ovn/kube-ovn-controller
29+
RUN ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-monitor && \
30+
ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-speaker && \
31+
ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-webhook && \
32+
ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-leader-checker && \
33+
ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-ic-controller && \
34+
ln -s /kube-ovn/kube-ovn-controller /kube-ovn/kube-ovn-pinger && \
35+
setcap CAP_NET_BIND_SERVICE+eip /kube-ovn/kube-ovn-cmd && \
36+
setcap CAP_NET_RAW,CAP_NET_BIND_SERVICE+eip /kube-ovn/kube-ovn-controller && \
37+
setcap CAP_NET_ADMIN,CAP_NET_RAW,CAP_NET_BIND_SERVICE,CAP_SYS_ADMIN+eip /kube-ovn/kube-ovn-daemon
38+
39+
FROM kubeovn/kube-ovn-base:$BASE_TAG
40+
41+
COPY --chmod=0644 --from=builder /source/dist/images/logrotate/* /etc/logrotate.d/
42+
COPY --from=builder /source/dist/images/grace_stop_ovn_controller /usr/share/ovn/scripts/grace_stop_ovn_controller
43+
44+
COPY --from=setcap /kube-ovn /kube-ovn
45+
RUN /kube-ovn/iptables-wrapper-installer.sh --no-sanity-check
46+
47+
WORKDIR /kube-ovn
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
diff --git a/pkg/controller/pod.go b/pkg/controller/pod.go
2+
--- a/pkg/controller/pod.go
3+
+++ b/pkg/controller/pod.go
4+
@@ -1061,6 +1061,7 @@
5+
}
6+
}
7+
}
8+
+ var hasAliveVMSibling bool
9+
isVMPod, vmName := isVMPod(pod)
10+
if isVMPod && c.config.EnableKeepVMIP {
11+
ports, err := c.OVNNbClient.ListNormalLogicalSwitchPorts(true, map[string]string{"pod": podKey})
12+
@@ -1081,6 +1082,18 @@
13+
if !isOwnerRefToDel {
14+
klog.Infof("try keep ip for vm pod %s", podKey)
15+
keepIPCR = true
16+
+ // The VM LSP is shared across every virt-launcher pod of the VM
17+
+ // (ExternalIDs["pod"] is keyed by VM name). Port-group memberships,
18+
+ // however, belong to whichever virt-launcher pod is currently
19+
+ // running the VM. If another live sibling exists (e.g. a
20+
+ // live-migration destination while the completed source is being
21+
+ // GC'd), its memberships must not be wiped out.
22+
+ siblings, listErr := c.podsLister.Pods(pod.Namespace).List(labels.Everything())
23+
+ if listErr != nil {
24+
+ klog.Errorf("failed to list pods in namespace %s: %v", pod.Namespace, listErr)
25+
+ return listErr
26+
+ }
27+
+ hasAliveVMSibling = hasAliveSiblingVMPod(siblings, vmName, pod.Name)
28+
}
29+
}
30+
if keepIPCR {
31+
@@ -1106,12 +1119,18 @@
32+
return err
33+
}
34+
if keepIPCR {
35+
- // always remove lsp from port groups
36+
- for _, port := range ports {
37+
- klog.Infof("remove lsp %s from all port groups", port.Name)
38+
- if err = c.OVNNbClient.RemovePortFromPortGroups(port.Name); err != nil {
39+
- klog.Errorf("failed to remove lsp %s from all port groups: %v", port.Name, err)
40+
- return err
41+
+ // always remove lsp from port groups, unless another live virt-launcher
42+
+ // pod owns the memberships (e.g. live-migration destination while the
43+
+ // completed source is being GC'd).
44+
+ if hasAliveVMSibling {
45+
+ klog.Infof("skip removing lsp from port groups: another alive virt-launcher pod exists for vm %s/%s", pod.Namespace, vmName)
46+
+ } else {
47+
+ for _, port := range ports {
48+
+ klog.Infof("remove lsp %s from all port groups", port.Name)
49+
+ if err = c.OVNNbClient.RemovePortFromPortGroups(port.Name); err != nil {
50+
+ klog.Errorf("failed to remove lsp %s from all port groups: %v", port.Name, err)
51+
+ return err
52+
+ }
53+
}
54+
}
55+
} else {
56+
@@ -2358,6 +2377,27 @@
57+
return false, ""
58+
}
59+
60+
+// hasAliveSiblingVMPod reports whether pods contains any alive virt-launcher
61+
+// pod owned by the VMI vmName, excluding the pod with name excludePodName.
62+
+// It is used to decide whether a VM LSP's port-group memberships are still
63+
+// owned by another running sibling (e.g. a live-migration destination) when a
64+
+// completed/GC'd source pod is being processed.
65+
+func hasAliveSiblingVMPod(pods []*v1.Pod, vmName, excludePodName string) bool {
66+
+ for _, p := range pods {
67+
+ if p == nil || p.Name == excludePodName {
68+
+ continue
69+
+ }
70+
+ isVM, name := isVMPod(p)
71+
+ if !isVM || name != vmName {
72+
+ continue
73+
+ }
74+
+ if isPodAlive(p) {
75+
+ return true
76+
+ }
77+
+ }
78+
+ return false
79+
+}
80+
+
81+
func isOwnsByTheVM(vmi metav1.Object) (bool, string) {
82+
for _, owner := range vmi.GetOwnerReferences() {
83+
if owner.Kind == util.KindVirtualMachine &&
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml
2+
--- a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml
3+
+++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml
4+
@@ -122,6 +122,9 @@
5+
- --set-vxlan-tx-off={{- .Values.func.SET_VXLAN_TX_OFF }}
6+
- --non-primary-cni-mode={{- .Values.cni_conf.NON_PRIMARY_CNI }}
7+
+ {{- with .Values.mtu }}
8+
+ - --mtu={{ . }}
9+
+ {{- end }}
10+
securityContext:
11+
runAsUser: 0
12+
privileged: false

‎packages/system/kubeovn/values.yaml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@ kube-ovn:
1414
cni_conf:
1515
CNI_CONFIG_PRIORITY: "10"
1616
MOUNT_LOCAL_BIN_DIR: false
17+
# These three directories are hostPaths on every node. The kube-ovn defaults
18+
# place them under /etc/origin, which a Talos node cannot create: its root
19+
# filesystem is read-only, so the container fails at create time with
20+
# "mkdir /etc/origin: read-only file system". Keep them under the writable
21+
# /var/lib. OVN_IPSEC_KEY_DIR only takes effect with func.ENABLE_OVN_IPSEC
22+
# on, where its absence leaves the node without ESP security associations.
1723
OPENVSWITCH_DIR: "/var/lib/openvswitch"
24+
OVN_IPSEC_KEY_DIR: "/var/lib/ovs_ipsec_keys"
1825
OVN_DIR: "/var/lib/ovn"
1926
DISABLE_MODULES_MANAGEMENT: true
2027
ovn-central:

0 commit comments

Comments
 (0)