Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9b963cf
test: Fix data race on policy refresh interval
yongruilin Oct 23, 2025
898c6d3
kubeadm: skip promote call when etcd member is already a voting member
wgkingk Apr 15, 2026
53eb0ad
test/compatibility_lifecycle: resolve feature names from variables
siyuanfoundation Apr 24, 2026
773bda9
kubelet: defer CRI fallback removal to 1.38
carlory May 18, 2026
7f30307
Fix job controller reporting active=0 during pod creation backoff
akhilsingh-git Jun 3, 2026
9a52eec
Update CHANGELOG/CHANGELOG-1.34.md for v1.34.9
k8s-release-robot Jun 11, 2026
a76f455
Update google.golang.org/protobuf to v1.36.12-0.20260120151049-f2248a…
dims Mar 5, 2026
204bdf0
kubeadm: use KubernetesAPICallTimeout for mandatory kubeadm-config fetch
damdo Jun 17, 2026
3bcd539
Merge pull request #139810 from damdo/automated-cherry-pick-of-139667…
k8s-ci-robot Jun 17, 2026
ff18cff
kubeadm: treat already promoted learner as successful
jihyun-huh Jun 18, 2026
086dd5b
Restore string JSON encoding of cri-api KeyValue
liggitt Jun 23, 2026
66a2fce
Merge pull request #139665 from kmala/automated-cherry-pick-of-#13745…
kubernetes-prow[bot] Jun 24, 2026
b8b6648
Make utf8 replacement char test pass on Go 1.27
liggitt Jun 24, 2026
e55c320
Merge pull request #139967 from liggitt/automated-cherry-pick-of-#139…
kubernetes-prow[bot] Jul 1, 2026
0925913
Fix vet and mock errrors
liggitt Feb 17, 2026
b750ad6
Merge pull request #139908 from jihyun-huh/automated-cherry-pick-of-#…
kubernetes-prow[bot] Jul 3, 2026
a58b4ae
Merge pull request #138977 from stmcginnis/automated-cherry-pick-of-#…
kubernetes-prow[bot] Jul 3, 2026
51fc05e
Merge pull request #139752 from akhilsingh-git/automated-cherry-pick-…
kubernetes-prow[bot] Jul 3, 2026
83b4871
Merge pull request #137650 from yongruilin/automated-cherry-pick-of-#…
kubernetes-prow[bot] Jul 3, 2026
d975162
Merge pull request #138491 from wgkingk/automated-cherry-pick-of-#138…
kubernetes-prow[bot] Jul 3, 2026
6b19b41
stop logging missing optional container annotations
HirazawaUi Jul 1, 2026
17c8878
Bump images and versions to golang 1.25.12 and update distroless-ipta…
palnabarun Jul 15, 2026
a50f221
Merge pull request #139269 from carlory/automated-cherry-pick-of-#139…
kubernetes-prow[bot] Jul 18, 2026
93813f9
Merge pull request #140320 from HirazawaUi/automated-cherry-pick-of-#…
kubernetes-prow[bot] Jul 18, 2026
bfe7383
Merge pull request #140004 from kmala/release-1.34
kubernetes-prow[bot] Jul 18, 2026
030d743
Merge pull request #140584 from palnabarun/bump-go-1.34
kubernetes-prow[bot] Jul 18, 2026
bd6c4ad
Release commit for Kubernetes v1.34.10
k8s-release-robot Jul 22, 2026
24516b4
Merge tag 'v1.34.10' into rebase-release-4.21-v1.34.10
redhat-chai-bot Jul 27, 2026
a22c701
UPSTREAM: <drop>: hack/update-vendor.sh, make update and update image
redhat-chai-bot Jul 27, 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
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.25.11
1.25.12
275 changes: 193 additions & 82 deletions CHANGELOG/CHANGELOG-1.34.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/build-image/cross/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.34.0-go1.25.11-bullseye.0
v1.34.0-go1.25.12-bullseye.0
4 changes: 2 additions & 2 deletions build/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ readonly KUBE_RSYNC_PORT="${KUBE_RSYNC_PORT:-}"
readonly KUBE_CONTAINER_RSYNC_PORT=8730

# These are the default versions (image tags) for their respective base images.
readonly __default_distroless_iptables_version=v0.8.11
readonly __default_go_runner_version=v2.4.0-go1.25.11-bookworm.0
readonly __default_distroless_iptables_version=v0.8.14
readonly __default_go_runner_version=v2.4.0-go1.25.12-bookworm.0
readonly __default_setcap_version=bookworm-v1.0.6

# These are the base images for the Docker-wrapped binaries.
Expand Down
6 changes: 3 additions & 3 deletions build/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ dependencies:
# should also be updated, but go-runner is much harder to exploit and has
# far less relevancy to go updates for Kubernetes more generally.
- name: "registry.k8s.io/kube-cross: dependents"
version: v1.34.0-go1.25.11-bullseye.0
version: v1.34.0-go1.25.12-bullseye.0
refPaths:
- path: build/build-image/cross/VERSION

Expand Down Expand Up @@ -166,15 +166,15 @@ dependencies:
match: registry\.k8s\.io\/build-image\/debian-base:[a-zA-Z]+\-v((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)

- name: "registry.k8s.io/distroless-iptables: dependents"
version: v0.8.11
version: v0.8.14
refPaths:
- path: build/common.sh
match: __default_distroless_iptables_version=
- path: test/utils/image/manifest.go
match: configs\[DistrolessIptables\] = Config{list\.BuildImageRegistry, "distroless-iptables", "v([0-9]+)\.([0-9]+)\.([0-9]+)"}

- name: "registry.k8s.io/go-runner: dependents"
version: v2.4.0-go1.25.11-bookworm.0
version: v2.4.0-go1.25.12-bookworm.0
refPaths:
- path: build/common.sh
match: __default_go_runner_version=
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ func getInternalCfg(cfgPath string, client kubernetes.Interface, cfg kubeadmapiv
getNodeRegistration := true
getAPIEndpoint := staticpodutil.IsControlPlaneNode()
getComponentConfigs := true
internalcfg, err := configutil.FetchInitConfigurationFromCluster(client, printer, logPrefix, getNodeRegistration, getAPIEndpoint, getComponentConfigs)
internalcfg, err := configutil.FetchInitConfigurationFromCluster(client, printer, logPrefix, getNodeRegistration, getAPIEndpoint, getComponentConfigs, true)
if err == nil {
printer.Println() // add empty line to separate the FetchInitConfigurationFromCluster output from the command output
// certificate renewal or expiration checking doesn't depend on a running cluster, which means the CertificatesDir
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ func fetchInitConfiguration(client clientset.Interface) (*kubeadmapi.InitConfigu
getNodeRegistration := false
getAPIEndpoint := false
getComponentConfigs := true
initConfiguration, err := configutil.FetchInitConfigurationFromCluster(client, nil, "preflight", getNodeRegistration, getAPIEndpoint, getComponentConfigs)
initConfiguration, err := configutil.FetchInitConfigurationFromCluster(client, nil, "preflight", getNodeRegistration, getAPIEndpoint, getComponentConfigs, false)
if err != nil {
return nil, errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap")
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func newResetData(cmd *cobra.Command, opts *resetOptions, in io.Reader, out io.W
getNodeRegistration := true
getAPIEndpoint := staticpodutil.IsControlPlaneNode()
getComponentConfigs := true
initCfg, err = configutil.FetchInitConfigurationFromCluster(client, nil, "reset", getNodeRegistration, getAPIEndpoint, getComponentConfigs)
initCfg, err = configutil.FetchInitConfigurationFromCluster(client, nil, "reset", getNodeRegistration, getAPIEndpoint, getComponentConfigs, true)
if err != nil {
klog.Warningf("[reset] Unable to fetch the kubeadm-config ConfigMap from cluster: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/upgrade/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ func newApplyData(cmd *cobra.Command, args []string, applyFlags *applyFlags) (*a
getNodeRegistration := true
isControlPlaneNode := true
getComponentConfigs := true
initCfg, err := configutil.FetchInitConfigurationFromCluster(client, nil, "upgrade", getNodeRegistration, isControlPlaneNode, getComponentConfigs)
initCfg, err := configutil.FetchInitConfigurationFromCluster(client, nil, "upgrade", getNodeRegistration, isControlPlaneNode, getComponentConfigs, false)
if err != nil {
if apierrors.IsNotFound(err) {
_, _ = printer.Printf("[upgrade] In order to upgrade, a ConfigMap called %q in the %q namespace must exist.\n", constants.KubeadmConfigConfigMap, metav1.NamespaceSystem)
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/upgrade/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func enforceRequirements(flagSet *pflag.FlagSet, flags *applyPlanFlags, args []s
getNodeRegistration := true
getAPIEndpoint := staticpodutil.IsControlPlaneNode()
getComponentConfigs := true
initCfg, err := configutil.FetchInitConfigurationFromCluster(client, printer, "upgrade/config", getNodeRegistration, getAPIEndpoint, getComponentConfigs)
initCfg, err := configutil.FetchInitConfigurationFromCluster(client, printer, "upgrade/config", getNodeRegistration, getAPIEndpoint, getComponentConfigs, false)
if err != nil {
return nil, nil, nil, nil, errors.Wrap(err, "[upgrade/init config] FATAL")
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/kubeadm/app/cmd/upgrade/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func validateManifestsPath(manifests ...string) (err error) {
}

// FetchInitConfigurationFunc defines the signature of the function which will fetch InitConfiguration from cluster.
type FetchInitConfigurationFunc func(client clientset.Interface, printer output.Printer, logPrefix string, getNodeRegistration, getAPIEndpoint, getComponentConfigs bool) (*kubeadmapi.InitConfiguration, error)
type FetchInitConfigurationFunc func(client clientset.Interface, printer output.Printer, logPrefix string, getNodeRegistration, getAPIEndpoint, getComponentConfigs, shortConfigMapGet bool) (*kubeadmapi.InitConfiguration, error)

func runDiff(fs *pflag.FlagSet, flags *diffFlags, args []string, fetchInitConfigurationFromCluster FetchInitConfigurationFunc) error {
externalCfg := &v1beta4.UpgradeConfiguration{}
Expand All @@ -123,7 +123,7 @@ func runDiff(fs *pflag.FlagSet, flags *diffFlags, args []string, fetchInitConfig
getNodeRegistration := true
getAPIEndpoint := staticpodutil.IsControlPlaneNode()
getComponentConfigs := false
initCfg, err := fetchInitConfigurationFromCluster(client, &output.TextPrinter{}, "upgrade/diff", getNodeRegistration, getAPIEndpoint, getComponentConfigs)
initCfg, err := fetchInitConfigurationFromCluster(client, &output.TextPrinter{}, "upgrade/diff", getNodeRegistration, getAPIEndpoint, getComponentConfigs, false)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/upgrade/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func createTestRunDiffFile(contents []byte) (string, error) {
return file.Name(), nil
}

func fakeFetchInitConfig(client clientset.Interface, printer output.Printer, logPrefix string, getNodeRegistration, getAPIEndpoint, getComponentConfigs bool) (*kubeadmapi.InitConfiguration, error) {
func fakeFetchInitConfig(client clientset.Interface, printer output.Printer, logPrefix string, getNodeRegistration, getAPIEndpoint, getComponentConfigs, shortConfigMapGet bool) (*kubeadmapi.InitConfiguration, error) {
return &kubeadmapi.InitConfiguration{
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.0.1",
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/upgrade/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func newNodeData(cmd *cobra.Command, nodeOptions *nodeOptions, out io.Writer) (*
getNodeRegistration := true
getAPIEndpoint := isControlPlaneNode
getComponentConfigs := true
initCfg, err := configutil.FetchInitConfigurationFromCluster(client, nil, "upgrade", getNodeRegistration, getAPIEndpoint, getComponentConfigs)
initCfg, err := configutil.FetchInitConfigurationFromCluster(client, nil, "upgrade", getNodeRegistration, getAPIEndpoint, getComponentConfigs, false)
if err != nil {
return nil, errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap")
}
Expand Down
35 changes: 30 additions & 5 deletions cmd/kubeadm/app/util/config/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"time"

authv1 "k8s.io/api/authentication/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
errorsutil "k8s.io/apimachinery/pkg/util/errors"
Expand All @@ -51,8 +52,10 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
)

// FetchInitConfigurationFromCluster fetches configuration from a ConfigMap in the cluster
func FetchInitConfigurationFromCluster(client clientset.Interface, printer output.Printer, logPrefix string, getNodeRegistration, getAPIEndpoint, getComponentConfigs bool) (*kubeadmapi.InitConfiguration, error) {
// FetchInitConfigurationFromCluster fetches configuration from a ConfigMap in the cluster.
// If shortConfigMapGet is true, a short retry is used when fetching the kubeadm-config ConfigMap,
// which is suitable for callers like "kubeadm reset" that don't need a long retry.
func FetchInitConfigurationFromCluster(client clientset.Interface, printer output.Printer, logPrefix string, getNodeRegistration, getAPIEndpoint, getComponentConfigs, shortConfigMapGet bool) (*kubeadmapi.InitConfiguration, error) {
if printer == nil {
printer = &output.TextPrinter{}
}
Expand All @@ -61,7 +64,7 @@ func FetchInitConfigurationFromCluster(client clientset.Interface, printer outpu
_, _ = printer.Printf("[%s] Use 'kubeadm init phase upload-config kubeadm --config your-config-file' to re-upload it.\n", logPrefix)

// Fetch the actual config from cluster
cfg, err := getInitConfigurationFromCluster(constants.KubernetesDir, client, getNodeRegistration, getAPIEndpoint, getComponentConfigs)
cfg, err := getInitConfigurationFromCluster(constants.KubernetesDir, client, getNodeRegistration, getAPIEndpoint, getComponentConfigs, shortConfigMapGet)
if err != nil {
return nil, err
}
Expand All @@ -78,9 +81,31 @@ func FetchInitConfigurationFromCluster(client clientset.Interface, printer outpu
}

// getInitConfigurationFromCluster is separate only for testing purposes, don't call it directly, use FetchInitConfigurationFromCluster instead
func getInitConfigurationFromCluster(kubeconfigDir string, client clientset.Interface, getNodeRegistration, getAPIEndpoint, getComponentConfigs bool) (*kubeadmapi.InitConfiguration, error) {
func getInitConfigurationFromCluster(kubeconfigDir string, client clientset.Interface, getNodeRegistration, getAPIEndpoint, getComponentConfigs, shortConfigMapGet bool) (*kubeadmapi.InitConfiguration, error) {
// Also, the config map really should be KubeadmConfigConfigMap...
configMap, err := apiclient.GetConfigMapWithShortRetry(client, metav1.NamespaceSystem, constants.KubeadmConfigConfigMap)
var configMap *v1.ConfigMap
var err error
if shortConfigMapGet {
configMap, err = apiclient.GetConfigMapWithShortRetry(client, metav1.NamespaceSystem, constants.KubeadmConfigConfigMap)
} else {
var lastErr error
err = wait.PollUntilContextTimeout(context.Background(),
constants.KubernetesAPICallRetryInterval,
kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
true, func(_ context.Context) (bool, error) {
var err error
configMap, err = client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(
context.Background(), constants.KubeadmConfigConfigMap, metav1.GetOptions{})
if err == nil {
return true, nil
}
lastErr = err
return false, nil
})
if err != nil {
err = lastErr
}
}
if err != nil {
return nil, errors.Wrap(err, "failed to get config map")
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/util/config/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ func TestGetInitConfigurationFromCluster(t *testing.T) {
}

getComponentConfigs := true
cfg, err := getInitConfigurationFromCluster(tmpdir, client, rt.getNodeRegistration, rt.getAPIEndpoint, getComponentConfigs)
cfg, err := getInitConfigurationFromCluster(tmpdir, client, rt.getNodeRegistration, rt.getAPIEndpoint, getComponentConfigs, true)
if rt.expectedError != (err != nil) {
t.Errorf("unexpected return err from getInitConfigurationFromCluster: %v", err)
return
Expand Down
42 changes: 37 additions & 5 deletions cmd/kubeadm/app/util/etcd/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,14 +584,17 @@ func (c *Client) getMemberStatus(memberID uint64) (isLearner bool, started bool,
func (c *Client) MemberPromote(learnerID uint64) error {
var (
lastError error
isLearner bool
isStarted bool
learnerIDUint = strconv.FormatUint(learnerID, 16)
)

klog.V(1).Infof("[etcd] Waiting for a learner to start: %s", learnerIDUint)

err := wait.PollUntilContextTimeout(context.Background(), constants.EtcdAPICallRetryInterval, kubeadmapi.GetActiveTimeouts().EtcdAPICall.Duration,
true, func(_ context.Context) (bool, error) {
isLearner, started, err := c.getMemberStatus(learnerID)
var err error
isLearner, isStarted, err = c.getMemberStatus(learnerID)
if err != nil {
lastError = errors.WithMessagef(err, "failed to get member %s status", learnerIDUint)
return false, nil
Expand All @@ -600,7 +603,7 @@ func (c *Client) MemberPromote(learnerID uint64) error {
klog.V(1).Infof("[etcd] Member %s was already promoted.", learnerIDUint)
return true, nil
}
if !started {
if !isStarted {
klog.V(1).Infof("[etcd] Member %s is not started yet. Waiting for it to be started.", learnerIDUint)
lastError = errors.Errorf("the etcd member %s is not started", learnerIDUint)
return false, nil
Expand All @@ -611,6 +614,10 @@ func (c *Client) MemberPromote(learnerID uint64) error {
return lastError
}

if !isLearner {
return nil
}

klog.V(1).Infof("[etcd] Promoting a learner as a voting member: %s", learnerIDUint)

cli, err := c.newEtcdClient(c.Endpoints)
Expand All @@ -626,14 +633,39 @@ func (c *Client) MemberPromote(learnerID uint64) error {
// 2. context deadline exceeded
// 3. peer URLs already exists
// Once the client provides a way to check if the etcd learner is ready to promote, the retry logic can be revisited.
var promoteResp *clientv3.MemberPromoteResponse
var memberList []*etcdserverpb.Member
err = wait.PollUntilContextTimeout(context.Background(), constants.EtcdAPICallRetryInterval, kubeadmapi.GetActiveTimeouts().EtcdAPICall.Duration,
true, func(_ context.Context) (bool, error) {
// MemberPromote can return a transient client-side error even if the
// promotion already succeeded on the etcd side. Check the current
// member state before attempting another promotion so that retries
// remain idempotent.
resp, statusErr := c.listMembersOnce()
if statusErr != nil {
klog.V(5).Infof("[etcd] Failed to list members before promoting learner %s: %v", learnerIDUint, statusErr)
lastError = statusErr
return false, nil
}

for _, m := range resp.Members {
if m.ID != learnerID {
continue
}

if !m.IsLearner {
klog.V(1).Infof("[etcd] Member %s is already a voting member, treating promotion as successful", learnerIDUint)
memberList = resp.Members
return true, nil
}
break
}

ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout)
defer cancel()
promoteResp, err = cli.MemberPromote(ctx, learnerID)
promoteResp, err := cli.MemberPromote(ctx, learnerID)
if err == nil {
klog.V(1).Infof("[etcd] The learner was promoted as a voting member: %s", learnerIDUint)
memberList = promoteResp.Members
return true, nil
}
klog.V(5).Infof("[etcd] Promoting the learner %s failed: %v", learnerIDUint, err)
Expand All @@ -644,7 +676,7 @@ func (c *Client) MemberPromote(learnerID uint64) error {
return lastError
}

for _, m := range promoteResp.Members {
for _, m := range memberList {
if m.ID == learnerID {
parsedPeerAddrs, err := url.Parse(m.PeerURLs[0])
if err != nil {
Expand Down
Loading