Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ca70949
refactor(yurtadm/yurthub): extract reusable host lifecycle helpers fo…
Vacant-lot07734 Mar 15, 2026
01ccc70
refactor(kubelet): unify traffic redirection helpers for yurthub conv…
Vacant-lot07734 Mar 15, 2026
9bdeb6c
Revert "refactor(kubelet): unify traffic redirection helpers for yurt…
Vacant-lot07734 Mar 15, 2026
c9a5093
feat(node-servant): switch convert and revert to systemd-based yurthu…
Vacant-lot07734 Mar 15, 2026
8b9415c
refactor(node-servant): unify conversion job rendering for controller…
Vacant-lot07734 Mar 15, 2026
3cae7f0
feat(yurt-manager): add YurtNodeConversionController for label-driven…
Vacant-lot07734 Mar 16, 2026
1206e9d
feat(yurt-manager): restart node workloads after conversion and prote…
Vacant-lot07734 Mar 17, 2026
634cc04
fix(nodepool): enqueue old pool when nodepool label is removed
Vacant-lot07734 Mar 17, 2026
046ebd4
docs: add comments for yurt node conversion flow
Vacant-lot07734 Mar 17, 2026
ac4f757
refactor(node-servant): embed yurthub in image and remove download flags
Vacant-lot07734 Mar 22, 2026
ed0aa40
refactor(yurtnodeconversion): restart workloads from node-servant job
Vacant-lot07734 Mar 24, 2026
0f60a63
fix(node-servant): crictl ps warning pollution
Vacant-lot07734 Mar 25, 2026
1f8fc82
fix(yurtnodeconversion): keep failed nodes cordoned and avoid mutatin…
Vacant-lot07734 Mar 28, 2026
9fa367f
test(e2e): migrate yurthub conversion coverage to label-driven contro…
Vacant-lot07734 Mar 28, 2026
2e8c7c7
refactor(node-servant): reduce complexity in conversion and runtime h…
Vacant-lot07734 Mar 29, 2026
e4d03d9
refactor(node-servant): simplify convert options for edge-only flow
Vacant-lot07734 Mar 29, 2026
e3482ab
refactor(yurt-node-conversion): ruduce func Reconcile complexity)
Vacant-lot07734 Apr 2, 2026
029101b
feat(yurt-node-conversion): skip non-edge nodepool node convert
Vacant-lot07734 Apr 2, 2026
12d4cdb
refactor(yurt-node-conversion): optimize stale job cleanup and e2e he…
Vacant-lot07734 Apr 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions charts/yurt-manager/templates/yurt-manager-auto-generated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ metadata:
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: yurt-manager-yurt-node-conversion-controller
namespace: {{ .Release.Namespace }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: yurt-manager-yurt-static-set-controller
namespace: {{ .Release.Namespace }}
Expand Down Expand Up @@ -883,6 +889,44 @@ rules:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: yurt-manager-yurt-node-conversion-controller
rules:
- apiGroups:
- ""
resources:
- nodes
- nodes/status
verbs:
- get
- patch
- update
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- apiGroups:
- apps.openyurt.io
resources:
- nodepools
verbs:
- get
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- delete
- get
- patch
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: yurt-manager-yurt-static-set-controller
rules:
Expand Down Expand Up @@ -1186,6 +1230,19 @@ subjects:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: yurt-manager-yurt-node-conversion-controller-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: yurt-manager-yurt-node-conversion-controller
subjects:
- kind: ServiceAccount
name: yurt-manager-yurt-node-conversion-controller
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: yurt-manager-yurt-static-set-controller-binding
roleRef:
Expand Down
7 changes: 7 additions & 0 deletions cmd/yurt-manager/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type YurtManagerOptions struct {
CsrApproverController *CsrApproverControllerOptions
NodePoolController *NodePoolControllerOptions
YurtStaticSetController *YurtStaticSetControllerOptions
YurtNodeConversionController *YurtNodeConversionControllerOptions
YurtAppSetController *YurtAppSetControllerOptions
PlatformAdminController *PlatformAdminControllerOptions
NodeLifeCycleController *NodeLifecycleControllerOptions
Expand All @@ -57,6 +58,7 @@ func NewYurtManagerOptions() (*YurtManagerOptions, error) {
CsrApproverController: NewCsrApproverControllerOptions(),
NodePoolController: NewNodePoolControllerOptions(),
YurtStaticSetController: NewYurtStaticSetControllerOptions(),
YurtNodeConversionController: NewYurtNodeConversionControllerOptions(),
YurtAppSetController: NewYurtAppSetControllerOptions(),
PlatformAdminController: NewPlatformAdminControllerOptions(),
NodeLifeCycleController: NewNodeLifecycleControllerOptions(),
Expand Down Expand Up @@ -85,6 +87,7 @@ func (y *YurtManagerOptions) Flags(allControllers, disabledByDefaultControllers
y.NodePoolController.AddFlags(fss.FlagSet("nodepool controller"))
y.YurtAppSetController.AddFlags(fss.FlagSet("yurtappset controller"))
y.YurtStaticSetController.AddFlags(fss.FlagSet("yurtstaticset controller"))
y.YurtNodeConversionController.AddFlags(fss.FlagSet("yurtnodeconversion controller"))
y.PlatformAdminController.AddFlags(fss.FlagSet("iot controller"))
y.NodeLifeCycleController.AddFlags(fss.FlagSet("nodelifecycle controller"))
y.NodeBucketController.AddFlags(fss.FlagSet("nodebucket controller"))
Expand All @@ -111,6 +114,7 @@ func (y *YurtManagerOptions) Validate(allControllers []string, controllerAliases
errs = append(errs, y.NodePoolController.Validate()...)
errs = append(errs, y.YurtAppSetController.Validate()...)
errs = append(errs, y.YurtStaticSetController.Validate()...)
errs = append(errs, y.YurtNodeConversionController.Validate()...)
errs = append(errs, y.PlatformAdminController.Validate()...)
errs = append(errs, y.NodeLifeCycleController.Validate()...)
errs = append(errs, y.NodeBucketController.Validate()...)
Expand Down Expand Up @@ -150,6 +154,9 @@ func (y *YurtManagerOptions) ApplyTo(c *config.Config, controllerAliases map[str
if err := y.YurtStaticSetController.ApplyTo(&c.ComponentConfig.YurtStaticSetController); err != nil {
return err
}
if err := y.YurtNodeConversionController.ApplyTo(&c.ComponentConfig.YurtNodeConversionController); err != nil {
return err
}
if err := y.PlatformAdminController.ApplyTo(&c.ComponentConfig.PlatformAdminController); err != nil {
return err
}
Expand Down
70 changes: 70 additions & 0 deletions cmd/yurt-manager/app/options/yurtnodeconversioncontroller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
Copyright 2026 The OpenYurt Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package options

import (
"fmt"

"github.com/spf13/pflag"

"github.com/openyurtio/openyurt/pkg/yurtmanager/controller/yurtnodeconversion/config"
)

type YurtNodeConversionControllerOptions struct {
*config.YurtNodeConversionControllerConfiguration
}

func NewYurtNodeConversionControllerOptions() *YurtNodeConversionControllerOptions {
return &YurtNodeConversionControllerOptions{
&config.YurtNodeConversionControllerConfiguration{
ConcurrentYurtNodeConversionWorkers: 3,
},
}
}

// AddFlags adds flags related to YurtNodeConversion for yurt-manager to the specified FlagSet.
func (o *YurtNodeConversionControllerOptions) AddFlags(fs *pflag.FlagSet) {
if o == nil {
return
}

fs.Int32Var(&o.ConcurrentYurtNodeConversionWorkers, "concurrent-yurtnodeconversion-workers", o.ConcurrentYurtNodeConversionWorkers, "The number of node conversion objects that are allowed to reconcile concurrently. Larger number = more responsive conversion, but more CPU (and network) load")
}

// ApplyTo fills up YurtNodeConversion config with options.
func (o *YurtNodeConversionControllerOptions) ApplyTo(cfg *config.YurtNodeConversionControllerConfiguration) error {
if o == nil {
return nil
}

cfg.ConcurrentYurtNodeConversionWorkers = o.ConcurrentYurtNodeConversionWorkers

return nil
}

// Validate checks validation of YurtNodeConversionControllerOptions.
func (o *YurtNodeConversionControllerOptions) Validate() []error {
if o == nil {
return nil
}

errs := []error{}
if o.ConcurrentYurtNodeConversionWorkers <= 0 {
errs = append(errs, fmt.Errorf("concurrent-yurtnodeconversion-workers(%d) is invalid, should greater than 0", o.ConcurrentYurtNodeConversionWorkers))
}
return errs
}
2 changes: 2 additions & 0 deletions cmd/yurt-manager/names/controller_names.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
GatewayDNSController = "gateway-dns-controller"
NodeLifeCycleController = "node-life-cycle-controller"
NodeBucketController = "node-bucket-controller"
YurtNodeConversionController = "yurt-node-conversion-controller"
LoadBalancerSetController = "load-balancer-set-controller"
HubLeaderController = "hubleader-controller"
HubLeaderConfigController = "hubleaderconfig-controller"
Expand All @@ -59,6 +60,7 @@ func YurtManagerControllerAliases() map[string]string {
"gatewaydns": GatewayDNSController,
"nodelifecycle": NodeLifeCycleController,
"nodebucket": NodeBucketController,
"yurtnodeconversion": YurtNodeConversionController,
"loadbalancerset": LoadBalancerSetController,
"hubleader": HubLeaderController,
"hubleaderconfig": HubLeaderConfigController,
Expand Down
10 changes: 5 additions & 5 deletions cmd/yurt-node-servant/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ import (
func NewConvertCmd() *cobra.Command {
o := nodeconverter.NewConvertOptions()
cmd := &cobra.Command{
Use: "convert --working-mode",
Use: "convert",
Short: "",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("node-servant version: %#v\n", projectinfo.Get())
if o.Version {
return
}

cmd.Flags().VisitAll(func(flag *pflag.Flag) {
klog.Infof("FLAG: --%s=%q", flag.Name, flag.Value)
})

if err := o.Complete(cmd.Flags()); err != nil {
klog.Fatalf("complete options: %v", err)
}

if err := o.Validate(); err != nil {
klog.Fatalf("validate options: %v", err)
}
Expand Down
13 changes: 5 additions & 8 deletions cmd/yurt-node-servant/revert/revert.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ func NewRevertCmd() *cobra.Command {
Use: "revert",
Short: "",
Run: func(cmd *cobra.Command, args []string) {
if err := o.Complete(cmd.Flags()); err != nil {
if err := o.Complete(); err != nil {
klog.Fatalf("could not complete the revert option: %s", err)
}
if err := o.Validate(); err != nil {
klog.Fatalf("could not validate the revert option: %s", err)
}

r := revert.NewReverterWithOptions(o)
if err := r.Do(); err != nil {
Expand All @@ -42,13 +45,7 @@ func NewRevertCmd() *cobra.Command {
},
Args: cobra.NoArgs,
}
setFlags(cmd)

o.AddFlags(cmd.Flags())
return cmd
}

// setFlags sets flags.
func setFlags(cmd *cobra.Command) {
cmd.Flags().String("kubeadm-conf-path", "",
"The path to kubelet service conf that is used by kubelet component to join the cluster on the edge node.")
}
3 changes: 2 additions & 1 deletion hack/dockerfiles/build/Dockerfile.node-servant
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ ARG TARGETOS TARGETARCH MIRROR_REPO
RUN if [ ! -z "${MIRROR_REPO+x}" ]; then sed -i "s/dl-cdn.alpinelinux.org/${MIRROR_REPO}/g" /etc/apk/repositories; fi && \
apk add ca-certificates bash libc6-compat && update-ca-certificates && rm /var/cache/apk/*
COPY ./_output/local/bin/${TARGETOS}/${TARGETARCH}/yurt-node-servant /usr/local/bin/node-servant
COPY ./_output/local/bin/${TARGETOS}/${TARGETARCH}/yurthub /usr/local/bin/yurthub
COPY hack/lib/node-servant-entry.sh /usr/local/bin/entry.sh
RUN chmod +x /usr/local/bin/entry.sh
RUN chmod +x /usr/local/bin/entry.sh
8 changes: 7 additions & 1 deletion hack/dockerfiles/release/Dockerfile.node-servant
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ FROM --platform=${BUILDPLATFORM} golang:1.24.1 as builder
ADD . /build
ARG TARGETOS TARGETARCH IMAGE_TAG GOPROXY MIRROR_REPO
WORKDIR /build/
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} IMAGE_TAG=${IMAGE_TAG} make build WHAT=cmd/yurt-node-servant
RUN CGO_ENABLED=0 \
GOOS=${TARGETOS} \
GOARCH=${TARGETARCH} \
IMAGE_TAG=${IMAGE_TAG} \
make build WHAT="cmd/yurt-node-servant cmd/yurthub"


FROM --platform=${TARGETPLATFORM} alpine:3.17
ARG TARGETOS TARGETARCH MIRROR_REPO
RUN if [ ! -z "${MIRROR_REPO+x}" ]; then sed -i "s/dl-cdn.alpinelinux.org/${MIRROR_REPO}/g" /etc/apk/repositories; fi && \
apk add ca-certificates bash libc6-compat && update-ca-certificates && rm /var/cache/apk/*
COPY --from=builder /build/_output/local/bin/${TARGETOS}/${TARGETARCH}/yurt-node-servant /usr/local/bin/node-servant
COPY --from=builder /build/_output/local/bin/${TARGETOS}/${TARGETARCH}/yurthub /usr/local/bin/yurthub
COPY hack/lib/node-servant-entry.sh /usr/local/bin/entry.sh
RUN chmod +x /usr/local/bin/entry.sh
4 changes: 3 additions & 1 deletion hack/lib/node-servant-entry.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ fi

mkdir -p /openyurt/usr/local/servant
cp /usr/local/bin/node-servant /openyurt/usr/local/servant/
if [ -f /usr/local/bin/yurthub ]; then
cp /usr/local/bin/yurthub /openyurt/usr/local/servant/
fi

chmod -R +x /openyurt/usr/local/servant/
chroot /openyurt /usr/local/servant/node-servant "$@"
rm -rf /openyurt/usr/local/servant

18 changes: 16 additions & 2 deletions hack/make-rules/image_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,21 @@ readonly IMAGE_TARGETS=(

http_proxy=${http_proxy:-}
https_proxy=${https_proxy:-}
targets=${@:-${IMAGE_TARGETS[@]}}
targets=("$@")
if [[ ${#targets[@]} -eq 0 ]]; then
targets=("${IMAGE_TARGETS[@]}")
fi

build_targets=("${targets[@]}")
for target in "${targets[@]}"; do
if [[ ${target} == "yurt-node-servant" ]]; then
if [[ ! " ${build_targets[*]} " =~ " yurthub " ]]; then
build_targets+=("yurthub")
fi
break
fi
done

REGION=${REGION:-}
IMAGE_REPO=${IMAGE_REPO:-"openyurt"}
IMAGE_TAG=${IMAGE_TAG:-$(get_image_tag)}
Expand Down Expand Up @@ -88,7 +102,7 @@ docker run \
--env GOCACHE=/tmp/ \
${DOCKER_EXTRA_ENVS} \
${BUILD_BASE_IMAGE} \
/bin/bash -c "git config --global --add safe.directory /build && GIT_VERSION=${GIT_VERSION} ./hack/make-rules/build.sh ${targets[@]}"
/bin/bash -c "git config --global --add safe.directory /build && GIT_VERSION=${GIT_VERSION} ./hack/make-rules/build.sh ${build_targets[*]}"

# build images
for image in ${targets[@]}; do
Expand Down
1 change: 0 additions & 1 deletion hack/make-rules/local-up-openyurt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ readonly REQUIRED_CMD=(
readonly REQUIRED_IMAGES=(
openyurt/node-servant
openyurt/yurt-manager
openyurt/yurthub
openyurt/yurt-iot-dock
)

Expand Down
1 change: 1 addition & 0 deletions pkg/node-servant/components/kubelet.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const (
apiserverAddrRegularExpression = "server: (http(s)?:\\/\\/)?[\\w][-\\w]{0,62}(\\.[\\w][-\\w]{0,62})*(:[\\d]{1,5})?"

kubeAdmFlagsEnvFile = "/var/lib/kubelet/kubeadm-flags.env"
fileMode = 0666
dirMode = 0755
)

Expand Down
Loading
Loading