diff --git a/cmd/dra-example-kubeletplugin/driver.go b/cmd/dra-example-kubeletplugin/driver.go index 0f6e224c..a8cfa1e4 100644 --- a/cmd/dra-example-kubeletplugin/driver.go +++ b/cmd/dra-example-kubeletplugin/driver.go @@ -53,15 +53,22 @@ func NewDriver(ctx context.Context, config *Config) (*driver, error) { } driver.state = state - helper, err := kubeletplugin.Start( - ctx, - driver, + kubeletPluginOptions := []kubeletplugin.Option{ kubeletplugin.KubeClient(config.coreclient), kubeletplugin.NodeName(config.flags.nodeName), kubeletplugin.DriverName(consts.DriverName), kubeletplugin.RegistrarDirectoryPath(config.flags.kubeletRegistrarDirectoryPath), kubeletplugin.PluginDataDirectoryPath(config.DriverPluginPath()), - ) + } + + // Enable seamless upgrades when both seamless upgrades are enabled and POD_UID is available + if config.flags.seamlessUpgrades && config.flags.podUID != "" { + kubeletPluginOptions = append(kubeletPluginOptions, + kubeletplugin.RollingUpdate(types.UID(config.flags.podUID)), + ) + } + + helper, err := kubeletplugin.Start(ctx, driver, kubeletPluginOptions...) if err != nil { return nil, err } diff --git a/cmd/dra-example-kubeletplugin/health.go b/cmd/dra-example-kubeletplugin/health.go index 47f813d7..67d7fd3f 100644 --- a/cmd/dra-example-kubeletplugin/health.go +++ b/cmd/dra-example-kubeletplugin/health.go @@ -63,9 +63,12 @@ func startHealthcheck(ctx context.Context, config *Config) (*healthcheck, error) regSockPath := (&url.URL{ Scheme: "unix", - // TODO: this needs to adapt when seamless upgrades - // are enabled and the filename includes a uid. - Path: path.Join(config.flags.kubeletRegistrarDirectoryPath, consts.DriverName+"-reg.sock"), + Path: func() string { + if config.flags.seamlessUpgrades && config.flags.podUID != "" { + return path.Join(config.flags.kubeletRegistrarDirectoryPath, consts.DriverName+"-"+config.flags.podUID+"-reg.sock") + } + return path.Join(config.flags.kubeletRegistrarDirectoryPath, consts.DriverName+"-reg.sock") + }(), }).String() log.Info("connecting to registration socket", "path", regSockPath) regConn, err := grpc.NewClient( @@ -78,7 +81,12 @@ func startHealthcheck(ctx context.Context, config *Config) (*healthcheck, error) draSockPath := (&url.URL{ Scheme: "unix", - Path: path.Join(config.DriverPluginPath(), "dra.sock"), + Path: func() string { + if config.flags.seamlessUpgrades && config.flags.podUID != "" { + return path.Join(config.DriverPluginPath(), "dra-"+config.flags.podUID+".sock") + } + return path.Join(config.DriverPluginPath(), "dra.sock") + }(), }).String() log.Info("connecting to DRA socket", "path", draSockPath) draConn, err := grpc.NewClient( diff --git a/cmd/dra-example-kubeletplugin/main.go b/cmd/dra-example-kubeletplugin/main.go index e0cfaf9c..4ea40c4a 100644 --- a/cmd/dra-example-kubeletplugin/main.go +++ b/cmd/dra-example-kubeletplugin/main.go @@ -49,6 +49,8 @@ type Flags struct { kubeletRegistrarDirectoryPath string kubeletPluginsDirectoryPath string healthcheckPort int + podUID string + seamlessUpgrades bool } type Config struct { @@ -115,6 +117,18 @@ func newApp() *cli.App { Destination: &flags.healthcheckPort, EnvVars: []string{"HEALTHCHECK_PORT"}, }, + &cli.StringFlag{ + Name: "pod-uid", + Usage: "UID of the pod (used for seamless upgrades to create unique socket names).", + Destination: &flags.podUID, + EnvVars: []string{"POD_UID"}, + }, + &cli.BoolFlag{ + Name: "seamless-upgrades", + Usage: "Enable seamless upgrades support. When enabled, the driver will use rolling update mode if pod-uid is available.", + Destination: &flags.seamlessUpgrades, + EnvVars: []string{"SEAMLESS_UPGRADES"}, + }, } cliFlags = append(cliFlags, flags.kubeClientConfig.Flags()...) cliFlags = append(cliFlags, flags.loggingConfig.Flags()...) diff --git a/deployments/helm/dra-example-driver/templates/kubeletplugin.yaml b/deployments/helm/dra-example-driver/templates/kubeletplugin.yaml index bcf44ffd..36f2eec8 100644 --- a/deployments/helm/dra-example-driver/templates/kubeletplugin.yaml +++ b/deployments/helm/dra-example-driver/templates/kubeletplugin.yaml @@ -14,7 +14,38 @@ spec: app.kubernetes.io/component: kubeletplugin {{- with .Values.kubeletPlugin.updateStrategy }} updateStrategy: + {{- if $.Values.kubeletPlugin.seamlessUpgrades.enabled }} + {{- $strategy := . }} + {{- range $key, $value := . }} + {{- if eq $key "rollingUpdate" }} + {{ $key }}: + maxSurge: 1 + maxUnavailable: 0 + {{- range $subkey, $subvalue := $value }} + {{- if and (ne $subkey "maxSurge") (ne $subkey "maxUnavailable") }} + {{ $subkey }}: {{ $subvalue }} + {{- end }} + {{- end }} + {{- else }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }} + {{- else }} {{- toYaml . | nindent 4 }} + {{- end }} + {{- else }} + updateStrategy: + type: {{ .Values.kubeletPlugin.updateStrategy.type | default "RollingUpdate" }} + {{- if eq (.Values.kubeletPlugin.updateStrategy.type | default "RollingUpdate") "RollingUpdate" }} + rollingUpdate: + {{- if .Values.kubeletPlugin.seamlessUpgrades.enabled }} + maxSurge: 1 + maxUnavailable: 0 + {{- else }} + maxSurge: {{ .Values.kubeletPlugin.updateStrategy.rollingUpdate.maxSurge | default 0 }} + maxUnavailable: {{ .Values.kubeletPlugin.updateStrategy.rollingUpdate.maxUnavailable | default 1 }} + {{- end }} + {{- end }} {{- end }} template: metadata: @@ -80,6 +111,14 @@ spec: - name: HEALTHCHECK_PORT value: {{ .Values.kubeletPlugin.containers.plugin.healthcheckPort | quote }} {{- end }} + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + {{- if .Values.kubeletPlugin.seamlessUpgrades.enabled }} + - name: SEAMLESS_UPGRADES + value: "true" + {{- end }} volumeMounts: - name: plugins-registry mountPath: {{ .Values.kubeletPlugin.kubeletRegistrarDirectoryPath | quote }} diff --git a/deployments/helm/dra-example-driver/values.yaml b/deployments/helm/dra-example-driver/values.yaml index e58c9d33..4fcf3722 100644 --- a/deployments/helm/dra-example-driver/values.yaml +++ b/deployments/helm/dra-example-driver/values.yaml @@ -47,6 +47,8 @@ controller: kubeletPlugin: numDevices: 8 priorityClassName: "system-node-critical" + seamlessUpgrades: + enabled: true updateStrategy: type: RollingUpdate podAnnotations: {}