Repository: karmada-io/karmada

Issue:
Failed to join cluster in Pull-Mode
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks!
-->


**What happened**:

1. karmada installed in host-cluster and api-server is publicly exposed under <domain> and is reachable and functional (can do kubectl apply  etc)
2. in on-premise cluster (private networking; but access to internet) I try to join the host-cluster:

```shell
karmadactl register <domain> --token bsbmb3.<secret> --discovery-token-ca-cert-hash sha256:bb5593ab60547232a812109d87d48d3f16834bb68fa99035e64c8beeea442dd3
[preflight] Running pre-flight checks
[prefligt] All pre-flight checks were passed
[karmada-agent-start] Waiting to perform the TLS Bootstrap
[karmada-agent-start] Waiting to construct karmada-agent kubeconfig
Unable to connect to the server: dial tcp: lookup karmada-apiserver.karmada-system.svc.cluster.local on 127.0.0.53:53: server misbehaving
```
The join fails.

**What you expected to happen**:

I expect the member cluster to be added successfully.


Hints from issue comments:
@RainbowMango: > Unable to connect to the server: dial tcp: lookup karmada-apiserver.karmada-system.svc.cluster.local on 127.0.0.53:53: server misbehaving

Can you access karmada-apiserver on the machine where running the `karmadactl register`?@maaft: yes, I can access it (via `kubectl`) from the machine where I'm running `karmadactl register`.

I'm not sure, why karmadactl even tries to resolve `karmada-apiserver.karmada-system.svc.cluster.local` on my local DNS, since I specified that karmada-api server must be found at `<domain>`?


Maybe this helps:
```shell
karmadactl register karmada-apiserver.example.com --token qffp4d.<secret> --discovery-token-ca-cert-hash sha256:bb5593ab60547232a812109d87d48d3f16834bb68fa99035e64c8beeea442dd3 --v 3
I1120 09:48:30.999314   16579 register.go:299] Registering cluster. cluster name: default
I1120 09:48:30.999360   16579 register.go:300] Registering cluster. cluster namespace: karmada-cluster
[preflight] Running pre-flight checks
I1120 09:48:30.999377   16579 register.go:422] Validating the existence of file /etc/karmada/bootstrap-karmada-agent.conf
I1120 09:48:30.999391   16579 register.go:422] Validating the existence of file /etc/karmada/karmada-agent.conf
I1120 09:48:30.999402   16579 register.go:422] Validating the existence of file /etc/karmada/pki/ca.crt
[prefligt] All pre-flight checks were passed
[karmada-agent-start] Waiting to perform the TLS Bootstrap
I1120 09:48:31.007058   16579 register.go:765] [discovery] Created cluster-info discovery client, requesting info from "karmada-apiserver.example.com"
I1120 09:48:31.063367   16579 register.go:803] [discovery] Requesting info from "karmada-apiserver.example.com" again to validate TLS against the pinned public key
I1120 09:48:31.111340   16579 register.go:820] [discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "karmada-apiserver.example.com"
I1120 09:48:31.111377   16579 register.go:437] [discovery] Using provided TLSBootstrapToken as authentication credentials for the join process
I1120 09:48:31.111399   16579 register.go:448] [discovery] writing bootstrap karmada-agent config file at /etc/karmada/bootstrap-karmada-agent.conf
I1120 09:48:31.112644   16579 register.go:457] [discovery] writing CA certificate at /etc/karmada/pki/ca.crt
[karmada-agent-start] Waiting to construct karmada-agent kubeconfig
Unable to connect to the server: dial tcp: lookup karmada-apiserver.karmada-system.svc.cluster.local on 127.0.0.53:53: server misbehaving
```
@maaft: I did some further debugging:

`karmadaClusterInfo` in `pgk/karmadactl/register/register.go:340` contains this
```json
{
  "LocationOfOrigin": "",
  "server": "https://karmada-apiserver.karmada-system.svc.cluster.local:5443",
  "certificate-authority-data": "LS0tLS1C..."
}
```

Shouldn't there be `karmada-apiserver.example.com` instead?@maaft: Okay, I think I found the issue:

1. karmada retrieves control plane info using bootstrap token
2. this info contains `karmada-apiserver.karmada-system.svc.cluster.local` and not `karmada-apiserver.example.com` 
3. agent kubeconfig is build with that info
4. agent tries to connect with that config and fails.

Can I configure the karmada apiserver such that it will tell bootstrapping clients to use `karmada-apiserver.example.com` ?@RainbowMango: cc @lonelyCZ @chaosi-zju for help@liangyuanpeng: @maaft 

This server  info is using karmada-apiserver.config, are you using `karmada-apiserver.example.com` by karmada-apiserver.config.

You can try to the blew steps:
1. change `karmada-apiserver.example.com` to `karmada-apiserver.example.com`  for karmada-apiserver.config
2. karmadactl create token with karmada-apiserver.config
3. `karmadactl registry` again
@everpeace: `karmada-apiserver.karmada-system.svc.cluster.local` comes from `default/cluster-info` configmap in the karmada controlplane in bootstrapping TLS certificate (CA certificate of the karmada control plane apiserver).

I think `karmada register` should not use the endpoint from cluster-info, but used the endpoint(bootstrap endpoint) which user passed to the command. 

It is because the endpoint in cluster-info is sometimes unreachable from member cluster as the issue reported. But, it can guarantee bootstrap endpoint can be reachable (generating kubeconfig step is after bootstrapping TLS (CA) certificate).

I think #4562 can be a fix.





Solution patch:
diff --git a/.go-version b/.go-version
index 2d27ccba1..82bfa5ce3 100644
--- a/.go-version
+++ b/.go-version
@@ -1 +1 @@
-1.23.7
+1.23.8
diff --git a/README.md b/README.md
index a76bf2eed..271b596a4 100644
--- a/README.md
+++ b/README.md
@@ -186,12 +186,12 @@ nginx   2/2     2            2           20s
 
 ## Kubernetes compatibility
 
-|                       | Kubernetes 1.16 | Kubernetes 1.17 | Kubernetes 1.18 | Kubernetes 1.19 | Kubernetes 1.20 | Kubernetes 1.21 | Kubernetes 1.22 | Kubernetes 1.23 | Kubernetes 1.24 | Kubernetes 1.25 | Kubernetes 1.26 | Kubernetes 1.27 | Kubernetes 1.28 | Kubernetes 1.29 |
-|-----------------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|
-| Karmada v1.7          | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               |
-| Karmada v1.8          | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               |
-| Karmada v1.9          | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               |
-| Karmada HEAD (master) | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               |
+|                       | Kubernetes 1.16 | Kubernetes 1.17 | Kubernetes 1.18 | Kubernetes 1.19 | Kubernetes 1.20 | Kubernetes 1.21 | Kubernetes 1.22 | Kubernetes 1.23 | Kubernetes 1.24 | Kubernetes 1.25 | Kubernetes 1.26 | Kubernetes 1.27 | Kubernetes 1.28 | Kubernetes 1.29 | Kubernetes 1.30 | Kubernetes 1.31 | Kubernetes 1.32 |
+|-----------------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|
+| Karmada v1.11         | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               |
+| Karmada v1.12         | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               |
+| Karmada v1.13         | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               |
+| Karmada HEAD (master) | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               | ✓               |
 
 Key:
 * `✓` Karmada and the Kubernetes version are exactly compatible.
diff --git a/docs/CHANGELOG/CHANGELOG-1.11.md b/docs/CHANGELOG/CHANGELOG-1.11.md
index 890acf4fc..aa9f2c925 100644
--- a/docs/CHANGELOG/CHANGELOG-1.11.md
+++ b/docs/CHANGELOG/CHANGELOG-1.11.md
@@ -2,49 +2,55 @@
 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
 **Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*
 
-- [v1.11.7](#v1117)
-  - [Downloads for v1.11.7](#downloads-for-v1117)
-  - [Changelog since v1.11.6](#changelog-since-v1116)
+- [v1.11.8](#v1118)
+  - [Downloads for v1.11.8](#downloads-for-v1118)
+  - [Changelog since v1.11.7](#changelog-since-v1117)
     - [Changes by Kind](#changes-by-kind)
       - [Bug Fixes](#bug-fixes)
       - [Others](#others)
-- [v1.11.6](#v1116)
-  - [Downloads for v1.11.6](#downloads-for-v1116)
-  - [Changelog since v1.11.5](#changelog-since-v1115)
+- [v1.11.7](#v1117)
+  - [Downloads for v1.11.7](#downloads-for-v1117)
+  - [Changelog since v1.11.6](#changelog-since-v1116)
     - [Changes by Kind](#changes-by-kind-1)
       - [Bug Fixes](#bug-fixes-1)
       - [Others](#others-1)
-- [v1.11.5](#v1115)
-  - [Downloads for v1.11.5](#downloads-for-v1115)
-  - [Changelog since v1.11.4](#changelog-since-v1114)
+- [v1.11.6](#v1116)
+  - [Downloads for v1.11.6](#downloads-for-v1116)
+  - [Changelog since v1.11.5](#changelog-since-v1115)
     - [Changes by Kind](#changes-by-kind-2)
       - [Bug Fixes](#bug-fixes-2)
       - [Others](#others-2)
+- [v1.11.5](#v1115)
+  - [Downloads for v1.11.5](#downloads-for-v1115)
+  - [Changelog since v1.11.4](#changelog-since-v1114)
+    - [Changes by Kind](#changes-by-kind-3)
+      - [Bug Fixes](#bug-fixes-3)
+      - [Others](#others-3)
 - [v1.11.4](#v1114)
   - [Downloads for v1.11.4](#downloads-for-v1114)
   - [Changelog since v1.11.3](#changelog-since-v1113)
-    - [Changes by Kind](#changes-by-kind-3)
+    - [Changes by Kind](#changes-by-kind-4)
       - [Urgent Upgrade Notes](#urgent-upgrade-notes)
-      - [Bug Fixes](#bug-fixes-3)
-      - [Others](#others-3)
+      - [Bug Fixes](#bug-fixes-4)
+      - [Others](#others-4)
 - [v1.11.3](#v1113)
   - [Downloads for v1.11.3](#downloads-for-v1113)
   - [Changelog since v1.11.2](#changelog-since-v1112)
-    - [Changes by Kind](#changes-by-kind-4)
-      - [Bug Fixes](#bug-fixes-4)
-      - [Others](#others-4)
-- [v1.11.2](#v1112)
-  - [Downloads for v1.11.2](#downloads-for-v1112)
-  - [Changelog since v1.11.1](#changelog-since-v1111)
     - [Changes by Kind](#changes-by-kind-5)
       - [Bug Fixes](#bug-fixes-5)
       - [Others](#others-5)
-- [v1.11.1](#v1111)
-  - [Downloads for v1.11.1](#downloads-for-v1111)
-  - [Changelog since v1.11.0](#changelog-since-v1110)
+- [v1.11.2](#v1112)
+  - [Downloads for v1.11.2](#downloads-for-v1112)
+  - [Changelog since v1.11.1](#changelog-since-v1111)
     - [Changes by Kind](#changes-by-kind-6)
       - [Bug Fixes](#bug-fixes-6)
       - [Others](#others-6)
+- [v1.11.1](#v1111)
+  - [Downloads for v1.11.1](#downloads-for-v1111)
+  - [Changelog since v1.11.0](#changelog-since-v1110)
+    - [Changes by Kind](#changes-by-kind-7)
+      - [Bug Fixes](#bug-fixes-7)
+      - [Others](#others-7)
 - [v1.11.0](#v1110)
   - [Downloads for v1.11.0](#downloads-for-v1110)
   - [What's New](#whats-new)
@@ -55,7 +61,7 @@
   - [Other Notable Changes](#other-notable-changes)
     - [API Changes](#api-changes)
     - [Deprecation](#deprecation)
-    - [Bug Fixes](#bug-fixes-7)
+    - [Bug Fixes](#bug-fixes-8)
     - [Security](#security)
     - [Features & Enhancements](#features--enhancements)
   - [Other](#other)
@@ -66,6 +72,20 @@
 
 <!-- END doctoc generated TOC please keep comment here to allow auto update -->
 
+# v1.11.8
+## Downloads for v1.11.8
+
+Download v1.11.8 in the [v1.11.8 release page](https://github.com/karmada-io/karmada/releases/tag/v1.11.8).
+
+## Changelog since v1.11.7
+### Changes by Kind
+#### Bug Fixes
+- `karmada-agent`: Fixed a panic issue where the agent does not need to report secret when registering cluster. ([#6224](https://github.com/karmada-io/karmada/pull/6224), @jabellard)
+- `karmada-controller-manager`: Fixed the issue that the gracefulEvictionTask of ResourceBinding can not be cleared in case of schedule fails. ([#6236](https://github.com/karmada-io/karmada/pull/6236), @XiShanYongYe-Chang)
+
+#### Others
+None.
+
 # v1.11.7
 ## Downloads for v1.11.7
 
diff --git a/docs/CHANGELOG/CHANGELOG-1.12.md b/docs/CHANGELOG/CHANGELOG-1.12.md
index ba088fe90..ac6bd6f7a 100644
--- a/docs/CHANGELOG/CHANGELOG-1.12.md
+++ b/docs/CHANGELOG/CHANGELOG-1.12.md
@@ -2,30 +2,36 @@
 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
 **Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*
 
-- [v1.12.4](#v1124)
-  - [Downloads for v1.12.4](#downloads-for-v1124)
-  - [Changelog since v1.12.3](#changelog-since-v1123)
+- [v1.12.5](#v1125)
+  - [Downloads for v1.12.5](#downloads-for-v1125)
+  - [Changelog since v1.12.4](#changelog-since-v1124)
     - [Changes by Kind](#changes-by-kind)
       - [Bug Fixes](#bug-fixes)
       - [Others](#others)
-- [v1.12.3](#v1123)
-  - [Downloads for v1.12.3](#downloads-for-v1123)
-  - [Changelog since v1.12.2](#changelog-since-v1122)
+- [v1.12.4](#v1124)
+  - [Downloads for v1.12.4](#downloads-for-v1124)
+  - [Changelog since v1.12.3](#changelog-since-v1123)
     - [Changes by Kind](#changes-by-kind-1)
       - [Bug Fixes](#bug-fixes-1)
       - [Others](#others-1)
-- [v1.12.2](#v1122)
-  - [Downloads for v1.12.2](#downloads-for-v1122)
-  - [Changelog since v1.12.1](#changelog-since-v1121)
+- [v1.12.3](#v1123)
+  - [Downloads for v1.12.3](#downloads-for-v1123)
+  - [Changelog since v1.12.2](#changelog-since-v1122)
     - [Changes by Kind](#changes-by-kind-2)
       - [Bug Fixes](#bug-fixes-2)
       - [Others](#others-2)
-- [v1.12.1](#v1121)
-  - [Downloads for v1.12.1](#downloads-for-v1121)
-  - [Changelog since v1.12.0](#changelog-since-v1120)
+- [v1.12.2](#v1122)
+  - [Downloads for v1.12.2](#downloads-for-v1122)
+  - [Changelog since v1.12.1](#changelog-since-v1121)
     - [Changes by Kind](#changes-by-kind-3)
       - [Bug Fixes](#bug-fixes-3)
       - [Others](#others-3)
+- [v1.12.1](#v1121)
+  - [Downloads for v1.12.1](#downloads-for-v1121)
+  - [Changelog since v1.12.0](#changelog-since-v1120)
+    - [Changes by Kind](#changes-by-kind-4)
+      - [Bug Fixes](#bug-fixes-4)
+      - [Others](#others-4)
 - [v1.12.0](#v1120)
   - [Downloads for v1.12.0](#downloads-for-v1120)
   - [What's New](#whats-new)
@@ -36,7 +42,7 @@
   - [Other Notable Changes](#other-notable-changes)
     - [API Changes](#api-changes)
     - [Deprecation](#deprecation)
-    - [Bug Fixes](#bug-fixes-4)
+    - [Bug Fixes](#bug-fixes-5)
     - [Security](#security)
     - [Features & Enhancements](#features--enhancements)
   - [Other](#other)
@@ -48,11 +54,11 @@
   - [Downloads for v1.12.0-beta.0](#downloads-for-v1120-beta0)
   - [Changelog since v1.12.0-alpha.1](#changelog-since-v1120-alpha1)
   - [Urgent Update Notes](#urgent-update-notes)
-  - [Changes by Kind](#changes-by-kind-4)
+  - [Changes by Kind](#changes-by-kind-5)
     - [API Changes](#api-changes-1)
     - [Features & Enhancements](#features--enhancements-1)
     - [Deprecation](#deprecation-1)
-    - [Bug Fixes](#bug-fixes-5)
+    - [Bug Fixes](#bug-fixes-6)
     - [Security](#security-1)
   - [Other](#other-1)
     - [Dependencies](#dependencies-1)
@@ -62,11 +68,11 @@
   - [Downloads for v1.12.0-alpha.1](#downloads-for-v1120-alpha1)
   - [Changelog since v1.11.0](#changelog-since-v1110)
   - [Urgent Update Notes](#urgent-update-notes-1)
-  - [Changes by Kind](#changes-by-kind-5)
+  - [Changes by Kind](#changes-by-kind-6)
     - [API Changes](#api-changes-2)
     - [Features & Enhancements](#features--enhancements-2)
     - [Deprecation](#deprecation-2)
-    - [Bug Fixes](#bug-fixes-6)
+    - [Bug Fixes](#bug-fixes-7)
     - [Security](#security-2)
   - [Other](#other-2)
     - [Dependencies](#dependencies-2)
@@ -75,6 +81,21 @@
 
 <!-- END doctoc generated TOC please keep comment here to allow auto update -->
 
+# v1.12.5
+## Downloads for v1.12.5
+
+Download v1.12.5 in the [v1.12.5 release page](https://github.com/karmada-io/karmada/releases/tag/v1.12.5).
+
+## Changelog since v1.12.4
+### Changes by Kind
+#### Bug Fixes
+- `karmada-agent`: Fixed a panic issue where the agent does not need to report secret when registering cluster. ([#6223](https://github.com/karmada-io/karmada/pull/6223), @jabellard)
+- `karmada-controller-manager`: Fixed the issue that the gracefulEvictionTask of ResourceBinding can not be cleared in case of schedule fails. ([#6235](https://github.com/karmada-io/karmada/pull/6235), @XiShanYongYe-Chang)
+- `helm`: Fixed the issue where the required ServiceAccount was missing when the certificate mode was set to custom. ([#6241](https://github.com/karmada-io/karmada/pull/6241), @seanlaii)
+
+#### Others
+None.
+
 # v1.12.4
 ## Downloads for v1.12.4
 
diff --git a/docs/CHANGELOG/CHANGELOG-1.13.md b/docs/CHANGELOG/CHANGELOG-1.13.md
index 21d789333..3f06e1bc9 100644
--- a/docs/CHANGELOG/CHANGELOG-1.13.md
+++ b/docs/CHANGELOG/CHANGELOG-1.13.md
@@ -2,6 +2,12 @@
 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
 **Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*
 
+- [v1.13.1](#v1131)
+  - [Downloads for v1.13.1](#downloads-for-v1131)
+  - [Changelog since v1.13.0](#changelog-since-v1130)
+    - [Changes by Kind](#changes-by-kind)
+      - [Bug Fixes](#bug-fixes)
+      - [Others](#others)
 - [v1.13.0](#v1130)
   - [Downloads for v1.13.0](#downloads-for-v1130)
   - [Urgent Update Notes](#urgent-update-notes)
@@ -14,7 +20,7 @@
   - [Other Notable Changes](#other-notable-changes)
     - [API Changes](#api-changes)
     - [Deprecation](#deprecation)
-    - [Bug Fixes](#bug-fixes)
+    - [Bug Fixes](#bug-fixes-1)
     - [Security](#security)
     - [Features & Enhancements](#features--enhancements)
   - [Other](#other)
@@ -26,11 +32,11 @@
   - [Downloads for v1.13.0-rc.0](#downloads-for-v1130-rc0)
   - [Changelog since v1.13.0-beta.0](#changelog-since-v1130-beta0)
   - [Urgent Update Notes](#urgent-update-notes-1)
-  - [Changes by Kind](#changes-by-kind)
+  - [Changes by Kind](#changes-by-kind-1)
     - [API Changes](#api-changes-1)
     - [Features & Enhancements](#features--enhancements-1)
     - [Deprecation](#deprecation-1)
-    - [Bug Fixes](#bug-fixes-1)
+    - [Bug Fixes](#bug-fixes-2)
     - [Security](#security-1)
   - [Other](#other-1)
     - [Dependencies](#dependencies-1)
@@ -40,11 +46,11 @@
   - [Downloads for v1.13.0-beta.0](#downloads-for-v1130-beta0)
   - [Changelog since v1.13.0-alpha.2](#changelog-since-v1130-alpha2)
   - [Urgent Update Notes](#urgent-update-notes-2)
-  - [Changes by Kind](#changes-by-kind-1)
+  - [Changes by Kind](#changes-by-kind-2)
     - [API Changes](#api-changes-2)
     - [Features & Enhancements](#features--enhancements-2)
     - [Deprecation](#deprecation-2)
-    - [Bug Fixes](#bug-fixes-2)
+    - [Bug Fixes](#bug-fixes-3)
     - [Security](#security-2)
   - [Other](#other-2)
     - [Dependencies](#dependencies-2)
@@ -54,11 +60,11 @@
   - [Downloads for v1.13.0-alpha.2](#downloads-for-v1130-alpha2)
   - [Changelog since v1.13.0-alpha.1](#changelog-since-v1130-alpha1)
   - [Urgent Update Notes](#urgent-update-notes-3)
-  - [Changes by Kind](#changes-by-kind-2)
+  - [Changes by Kind](#changes-by-kind-3)
     - [API Changes](#api-changes-3)
     - [Features & Enhancements](#features--enhancements-3)
     - [Deprecation](#deprecation-3)
-    - [Bug Fixes](#bug-fixes-3)
+    - [Bug Fixes](#bug-fixes-4)
     - [Security](#security-3)
   - [Other](#other-3)
     - [Dependencies](#dependencies-3)
@@ -68,11 +74,11 @@
   - [Downloads for v1.13.0-alpha.1](#downloads-for-v1130-alpha1)
   - [Changelog since v1.12.0](#changelog-since-v1120)
   - [Urgent Update Notes](#urgent-update-notes-4)
-  - [Changes by Kind](#changes-by-kind-3)
+  - [Changes by Kind](#changes-by-kind-4)
     - [API Changes](#api-changes-4)
     - [Features & Enhancements](#features--enhancements-4)
     - [Deprecation](#deprecation-4)
-    - [Bug Fixes](#bug-fixes-4)
+    - [Bug Fixes](#bug-fixes-5)
     - [Security](#security-4)
   - [Other](#other-4)
     - [Dependencies](#dependencies-4)
@@ -81,6 +87,22 @@
 
 <!-- END doctoc generated TOC please keep comment here to allow auto update -->
 
+# v1.13.1
+## Downloads for v1.13.1
+
+Download v1.13.1 in the [v1.13.1 release page](https://github.com/karmada-io/karmada/releases/tag/v1.13.1).
+
+## Changelog since v1.13.0
+### Changes by Kind
+#### Bug Fixes
+- `karmada-operator`: The `karmada-app` label key previously used for control plane components and for the components of the operator itself has been changed to the more idiomatic `app.kubernetes.io/name` label key. ([#6200](https://github.com/karmada-io/karmada/pull/6200), @jabellard)
+- `karmada-agent`: Fixed a panic issue where the agent does not need to report secret when registering cluster. ([#6222](https://github.com/karmada-io/karmada/pull/6222), @jabellard)
+- `karmada-controller-manager`: Fixed the issue that the gracefulEvictionTask of ResourceBinding can not be cleared in case of schedule fails. ([#6234](https://github.com/karmada-io/karmada/pull/6234), @XiShanYongYe-Chang)
+- `helm`: Fixed the issue where the required ServiceAccount was missing when the certificate mode was set to custom. ([#6242](https://github.com/karmada-io/karmada/pull/6242), @seanlaii)
+
+#### Others
+None.
+
 # v1.13.0
 ## Downloads for v1.13.0
 
diff --git a/docs/CHANGELOG/CHANGELOG-1.14.md b/docs/CHANGELOG/CHANGELOG-1.14.md
new file mode 100644
index 000000000..2e8b0c929
--- /dev/null
+++ b/docs/CHANGELOG/CHANGELOG-1.14.md
@@ -0,0 +1,66 @@
+<!-- START doctoc generated TOC please keep comment here to allow auto update -->
+<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
+**Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*
+
+- [v1.14.0-alpha.1](#v1140-alpha1)
+  - [Downloads for v1.14.0-alpha.1](#downloads-for-v1140-alpha1)
+  - [Changelog since v1.13.0](#changelog-since-v1130)
+  - [Urgent Update Notes](#urgent-update-notes)
+  - [Changes by Kind](#changes-by-kind)
+    - [API Changes](#api-changes)
+    - [Features & Enhancements](#features--enhancements)
+    - [Deprecation](#deprecation)
+    - [Bug Fixes](#bug-fixes)
+    - [Security](#security)
+  - [Other](#other)
+    - [Dependencies](#dependencies)
+    - [Helm Charts](#helm-charts)
+    - [Instrumentation](#instrumentation)
+
+<!-- END doctoc generated TOC please keep comment here to allow auto update -->
+
+# v1.14.0-alpha.1
+## Downloads for v1.14.0-alpha.1
+
+Download v1.14.0-alpha.1 in the [v1.14.0-alpha.1 release page](https://github.com/karmada-io/karmada/releases/tag/v1.14.0-alpha.1).
+
+## Changelog since v1.13.0
+
+## Urgent Update Notes
+
+## Changes by Kind
+
+### API Changes
+- Introduced `spec.customCertificate.leafCertValidityDays` field in `Karmada` API to specify a custom validity period in days for control plane leaf certificates (e.g., API server certificate). When not explicitly set, the default validity period of 1 year is used. ([#6193](https://github.com/karmada-io/karmada/pull/6193), @jabellard)
+
+### Features & Enhancements
+- `karmada-controller-manager`: All controller reconcile frequency will honor a unified rate limiter configuration(--rate-limiter-*). ([#6145](https://github.com/karmada-io/karmada/pull/6145), @CharlesQQ)
+- `karmada-agent`: All controller reconcile frequency will honor a unified rate limiter configuration(--rate-limiter-*). ([#6145](https://github.com/karmada-io/karmada/pull/6145), @CharlesQQ)
+
+### Deprecation
+- `karmadactl`: The flag `--ca-cert-path` of `register`, which has been deprecated in release-1.13, now has been removed. ([#6191](https://github.com/karmada-io/karmada/pull/6191), @husnialhamdani)
+- The label `propagation.karmada.io/instruction` now has been deprecated in favor of the field(`.spec.suspendDispatching`) in Work API, the label will be removed in future releases. ([#6043](https://github.com/karmada-io/karmada/pull/6043), @vie-serendipity)
+
+### Bug Fixes
+- `karmada-agent`: Fixed a panic issue where the agent does not need to report secret when registering cluster. ([#6214](https://github.com/karmada-io/karmada/pull/6214), @jabellard)
+- `karmada-operator`: The `karmada-app` label key previously used for control plane components and for the components of the operator itself has been changed to the more idiomatic `app.kubernetes.io/name` label key. ([#6180](https://github.com/karmada-io/karmada/pull/6180), @jabellard)
+- `karmada-controller-manager`: Fixed the issue that the gracefulEvictionTask of ResourceBinding can not be cleared in case of schedule fails. ([#6227](https://github.com/karmada-io/karmada/pull/6227), @XiShanYongYe-Chang)
+- `helm`: Fixed the issue where the required ServiceAccount was missing when the certificate mode was set to custom. ([#6188](https://github.com/karmada-io/karmada/pull/6188), @seanlaii)
+- Unify the rate limiter for different clients in each component to access karmada-apiserver. Access may be restricted in large-scale environments compared to before the modification. Administrators can avoid this situation by adjusting upward the rate limit parameters 'kube-api-qps' and 'kube-api-burst' for each component to access karmada-apiserver, and adjusting 'cluster-api-qps' and 'cluster-api-burst' for scheduler-estimator to access member cluster apiserver. ([#6095](https://github.com/karmada-io/karmada/pull/6095), @zach593)
+
+### Security
+None.
+
+## Other
+### Dependencies
+- Karmada is now built with Golang v1.23.7. ([#6218](https://github.com/karmada-io/karmada/pull/6218), @seanlaii)
+- Bump golang.org/x/net to 0.37.0. ([#6225](https://github.com/karmada-io/karmada/pull/6225), @seanlaii)
+- Bump mockery to v2.53.3 to remove the hashicorp packages. ([#6212](https://github.com/karmada-io/karmada/pull/6212), @seanlaii)
+
+### Helm Charts
+- `HELM Chart`: OpenID Connect based auth can be configured for the Karmada API server when installing via Helm. ([#6159](https://github.com/karmada-io/karmada/pull/6159), @tw-mnewman)
+- `Helm chart`: Added helm index for 1.13 release. ([#6196](https://github.com/karmada-io/karmada/pull/6196), @zhzhuang-zju)
+
+### Instrumentation
+- `karmada-controller-manager`: metric `recreate_resource_to_cluster` has been merged into `create_resource_to_cluster`. ([#6148](https://github.com/karmada-io/karmada/pull/6148), @zach593)
+- `karmada-operator`: Introduced `karmada_build_info` metrics to emit the build info, as well as a bunch of Go runtime metrics. ([#6044](https://github.com/karmada-io/karmada/pull/6044), @dongjiang1989)
diff --git a/go.mod b/go.mod
index a18296cd4..daf780b6f 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/karmada-io/karmada
 
-go 1.23.7 // keep in sync with .go-version
+go 1.23.8 // keep in sync with .go-version
 
 require (
 	github.com/adhocore/gronx v1.6.3
diff --git a/pkg/controllers/multiclusterservice/mcs_controller.go b/pkg/controllers/multiclusterservice/mcs_controller.go
index 438902783..edc8fc5b4 100644
--- a/pkg/controllers/multiclusterservice/mcs_controller.go
+++ b/pkg/controllers/multiclusterservice/mcs_controller.go
@@ -149,7 +149,7 @@ func (c *MCSController) retrieveMultiClusterService(ctx context.Context, mcs *ne
 			continue
 		}
 
-		if providerClusters.Has(clusterName) && c.IsClusterReady(ctx, clusterName) {
+		if providerClusters.Has(clusterName) {
 			continue
 		}
 
@@ -524,17 +524,6 @@ func (c *MCSController) updateMultiClusterServiceStatus(ctx context.Context, mcs
 	})
 }
 
-// IsClusterReady checks whether the cluster is ready.
-func (c *MCSController) IsClusterReady(ctx context.Context, clusterName string) bool {
-	cluster := &clusterv1alpha1.Cluster{}
-	if err := c.Client.Get(ctx, types.NamespacedName{Name: clusterName}, cluster); err != nil {
-		klog.Errorf("Failed to get cluster object(%s):%v", clusterName, err)
-		return false
-	}
-
-	return util.IsClusterReady(&cluster.Status)
-}
-
 // SetupWithManager creates a controller and register to controller manager.
 func (c *MCSController) SetupWithManager(mgr controllerruntime.Manager) error {
 	mcsPredicateFunc := predicate.Funcs{
diff --git a/pkg/karmadactl/addons/utils/helpers.go b/pkg/karmadactl/addons/utils/helpers.go
index bb0a79b45..c67b84fcd 100644
--- a/pkg/karmadactl/addons/utils/helpers.go
+++ b/pkg/karmadactl/addons/utils/helpers.go
@@ -19,6 +19,7 @@ package utils
 import (
 	"context"
 	"fmt"
+	"time"
 
 	appsv1 "k8s.io/api/apps/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -35,7 +36,7 @@ var (
 	// This blocks until the Deployment's observed generation and ready replicas match the desired state,
 	// ensuring it is fully rolled out.
 	WaitForDeploymentRollout = func(c clientset.Interface, dep *appsv1.Deployment, timeoutSeconds int) error {
-		return cmdutil.WaitForDeploymentRollout(c, dep, timeoutSeconds)
+		return cmdutil.WaitForDeploymentRollout(c, dep, time.Duration(timeoutSeconds)*time.Second)
 	}
 )
 
diff --git a/pkg/karmadactl/cmdinit/utils/deploy.go b/pkg/karmadactl/cmdinit/utils/deploy.go
index 2c5194c1f..2143c98e0 100644
--- a/pkg/karmadactl/cmdinit/utils/deploy.go
+++ b/pkg/karmadactl/cmdinit/utils/deploy.go
@@ -18,6 +18,7 @@ package utils
 
 import (
 	"context"
+	"time"
 
 	appsv1 "k8s.io/api/apps/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -32,5 +33,5 @@ func CreateDeployAndWait(kubeClientSet kubernetes.Interface, deployment *appsv1.
 	if _, err := kubeClientSet.AppsV1().Deployments(deployment.GetNamespace()).Create(context.TODO(), deployment, metav1.CreateOptions{}); err != nil {
 		klog.Warning(err)
 	}
-	return util.WaitForDeploymentRollout(kubeClientSet, deployment, waitComponentReadyTimeout)
+	return util.WaitForDeploymentRollout(kubeClientSet, deployment, time.Duration(waitComponentReadyTimeout)*time.Second)
 }
diff --git a/pkg/karmadactl/register/register.go b/pkg/karmadactl/register/register.go
index 6c33ce831..b8dbfe714 100644
--- a/pkg/karmadactl/register/register.go
+++ b/pkg/karmadactl/register/register.go
@@ -437,7 +437,7 @@ func (o *CommandRegisterOption) EnsureNecessaryResourcesExistInMemberCluster(boo
 		return err
 	}
 
-	if err = cmdutil.WaitForDeploymentRollout(o.memberClusterClient, KarmadaAgentDeployment, int(o.Timeout)); err != nil {
+	if err = cmdutil.WaitForDeploymentRollout(o.memberClusterClient, KarmadaAgentDeployment, o.Timeout); err != nil {
 		return err
 	}
 
diff --git a/pkg/karmadactl/util/check.go b/pkg/karmadactl/util/check.go
index fedf901ac..8c8be3a29 100644
--- a/pkg/karmadactl/util/check.go
+++ b/pkg/karmadactl/util/check.go
@@ -59,10 +59,10 @@ func WaitForStatefulSetRollout(c kubernetes.Interface, sts *appsv1.StatefulSet,
 	return nil
 }
 
-// WaitForDeploymentRollout  wait for Deployment reaches the ready state or timeout.
-func WaitForDeploymentRollout(c kubernetes.Interface, dep *appsv1.Deployment, timeoutSeconds int) error {
+// WaitForDeploymentRollout wait for Deployment reaches the ready state or timeout.
+func WaitForDeploymentRollout(c kubernetes.Interface, dep *appsv1.Deployment, timeout time.Duration) error {
 	var lastErr error
-	pollError := wait.PollUntilContextTimeout(context.TODO(), time.Second, time.Duration(timeoutSeconds)*time.Second, true, func(ctx context.Context) (bool, error) {
+	pollError := wait.PollUntilContextTimeout(context.TODO(), time.Second, timeout, true, func(ctx context.Context) (bool, error) {
 		d, err := c.AppsV1().Deployments(dep.GetNamespace()).Get(ctx, dep.GetName(), metav1.GetOptions{})
 		if err != nil {
 			lastErr = err



Test patch:
diff --git a/pkg/controllers/multiclusterservice/mcs_controller_test.go b/pkg/controllers/multiclusterservice/mcs_controller_test.go
index 0008277a0..5a80f263f 100644
--- a/pkg/controllers/multiclusterservice/mcs_controller_test.go
+++ b/pkg/controllers/multiclusterservice/mcs_controller_test.go
@@ -727,72 +727,6 @@ func TestClaimMultiClusterServiceForService(t *testing.T) {
 	}
 }
 
-func TestIsClusterReady(t *testing.T) {
-	tests := []struct {
-		name          string
-		clusterName   string
-		clusterObj    *clusterv1alpha1.Cluster
-		expectedReady bool
-	}{
-		{
-			name:        "cluster is ready",
-			clusterName: "ready-cluster",
-			clusterObj: &clusterv1alpha1.Cluster{
-				ObjectMeta: metav1.ObjectMeta{
-					Name: "ready-cluster",
-				},
-				Status: clusterv1alpha1.ClusterStatus{
-					Conditions: []metav1.Condition{
-						{
-							Type:   clusterv1alpha1.ClusterConditionReady,
-							Status: metav1.ConditionTrue,
-						},
-					},
-				},
-			},
-			expectedReady: true,
-		},
-		{
-			name:        "cluster is not ready",
-			clusterName: "not-ready-cluster",
-			clusterObj: &clusterv1alpha1.Cluster{
-				ObjectMeta: metav1.ObjectMeta{
-					Name: "not-ready-cluster",
-				},
-				Status: clusterv1alpha1.ClusterStatus{
-					Conditions: []metav1.Condition{
-						{
-							Type:   clusterv1alpha1.ClusterConditionReady,
-							Status: metav1.ConditionFalse,
-						},
-					},
-				},
-			},
-			expectedReady: false,
-		},
-		{
-			name:          "cluster does not exist",
-			clusterName:   "non-existent-cluster",
-			clusterObj:    nil,
-			expectedReady: false,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			var objects []runtime.Object
-			if tt.clusterObj != nil {
-				objects = append(objects, tt.clusterObj)
-			}
-
-			controller := newFakeController(objects...)
-
-			ready := controller.IsClusterReady(context.Background(), tt.clusterName)
-			assert.Equal(t, tt.expectedReady, ready, "IsClusterReady() result does not match expected")
-		})
-	}
-}
-
 func TestServiceHasCrossClusterMultiClusterService(t *testing.T) {
 	tests := []struct {
 		name     string
diff --git a/test/e2e/suites/base/karmadactl_test.go b/test/e2e/suites/base/karmadactl_test.go
index 9db5ef4cd..6c3d89ab4 100644
--- a/test/e2e/suites/base/karmadactl_test.go
+++ b/test/e2e/suites/base/karmadactl_test.go
@@ -1542,6 +1542,148 @@ func WriteYamlToFile(obj interface{}, filePath string) error {
 	return nil
 }
 
+var _ = framework.SerialDescribe("Karmadactl register testing", ginkgo.Ordered, ginkgo.Labels{NeedCreateCluster}, func() {
+	var (
+		newClusterName, clusterContext                 string
+		homeDir, kubeConfigPath, controlPlane          string
+		karmadaAPIEndpoint, karmadaAPIEndpointExpected string
+		token, discoveryTokenCACertHash                string
+	)
+
+	ginkgo.BeforeAll(func() {
+		ginkgo.By("Initialize dependencies", func() {
+			// Initialize member cluster variables.
+			newClusterName = "member-e2e-" + rand.String(RandomStrLength)
+			homeDir = os.Getenv("HOME")
+			kubeConfigPath = fmt.Sprintf("%s/.kube/%s.config", homeDir, newClusterName)
+			controlPlane = fmt.Sprintf("%s-control-plane", newClusterName)
+			clusterContext = fmt.Sprintf("kind-%s", newClusterName)
+		})
+
+		ginkgo.By(fmt.Sprintf("Creating cluster: %s", newClusterName), func() {
+			err := createCluster(newClusterName, kubeConfigPath, controlPlane, clusterContext)
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		})
+
+		ginkgo.By("Extract Karmada API server endpoint", func() {
+			var err error
+			karmadaAPIEndpointExpected, err = extractAPIServerEndpoint(kubeconfig, "karmada-apiserver")
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		})
+
+		ginkgo.By("Generate token and discovery token CA cert hash", func() {
+			cmd := framework.NewKarmadactlCommand(
+				kubeconfig, karmadaContext, karmadactlPath, "", karmadactlTimeout,
+				"token", "create", "--print-register-command="+"true",
+			)
+			output, err := cmd.ExecOrDie()
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+
+			// Extract the endpoint for Karmada APIServer.
+			endpointRegex := regexp.MustCompile(`(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5})`)
+			karmadaAPIEndpoint = endpointRegex.FindString(output)
+			gomega.Expect(karmadaAPIEndpoint).Should(gomega.Equal(karmadaAPIEndpointExpected))
+
+			// Extract token.
+			tokenRegex := regexp.MustCompile(`--token\s+(\S+)`)
+			tokenMatches := tokenRegex.FindStringSubmatch(output)
+			gomega.Expect(len(tokenMatches)).Should(gomega.BeNumerically(">", 1))
+			token = tokenMatches[1]
+
+			// Extract discovery token CA cert hash.
+			hashRegex := regexp.MustCompile(`--discovery-token-ca-cert-hash\s+(\S+)`)
+			hashMatches := hashRegex.FindStringSubmatch(output)
+			gomega.Expect(len(hashMatches)).Should(gomega.BeNumerically(">", 1))
+			discoveryTokenCACertHash = hashMatches[1]
+		})
+	})
+
+	ginkgo.AfterEach(func() {
+		ginkgo.By(fmt.Sprintf("Unregistering cluster: %s", newClusterName), func() {
+			cmd := framework.NewKarmadactlCommand(
+				kubeconfig, karmadaContext, karmadactlPath, "", 5*options.DefaultKarmadactlCommandDuration,
+				"unregister", "--cluster-kubeconfig", kubeConfigPath, newClusterName,
+			)
+			_, err := cmd.ExecOrDie()
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+		})
+	})
+
+	ginkgo.AfterAll(func() {
+		ginkgo.By(fmt.Sprintf("Deleting clusters: %s", newClusterName), func() {
+			err := deleteCluster(newClusterName, kubeConfigPath)
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			_ = os.Remove(kubeConfigPath)
+		})
+	})
+
+	ginkgo.It("should register a cluster without CA verification", func() {
+		ginkgo.By("Register the new cluster in Karmada without CA verification", func() {
+			cmd := framework.NewKarmadactlCommand(
+				"", karmadaContext, karmadactlPath, "", karmadactlTimeout*5, "register", karmadaAPIEndpoint, "--token", token,
+				"--discovery-token-unsafe-skip-ca-verification="+"true", "--kubeconfig="+kubeConfigPath,
+				"--cluster-name", newClusterName, "--karmada-agent-image", "docker.io/karmada/karmada-agent:latest",
+			)
+			output, err := cmd.ExecOrDie()
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			gomega.Expect(output).Should(gomega.ContainSubstring(fmt.Sprintf("cluster(%s) is joined successfully", newClusterName)))
+		})
+
+		ginkgo.By("Wait for the new cluster to be ready", func() {
+			framework.WaitClusterFitWith(controlPlaneClient, newClusterName, func(cluster *clusterv1alpha1.Cluster) bool {
+				return meta.IsStatusConditionPresentAndEqual(cluster.Status.Conditions, clusterv1alpha1.ClusterConditionReady, metav1.ConditionTrue)
+			})
+		})
+	})
+
+	ginkgo.It("should register a cluster with CA verification", func() {
+		ginkgo.By("Register the new cluster in Karmada with CA verification", func() {
+			cmd := framework.NewKarmadactlCommand(
+				"", karmadaContext, karmadactlPath, "", karmadactlTimeout*5, "register", karmadaAPIEndpoint,
+				"--token", token, "--discovery-token-ca-cert-hash", discoveryTokenCACertHash,
+				"--kubeconfig="+kubeConfigPath, "--cluster-name", newClusterName,
+				"--karmada-agent-image", "docker.io/karmada/karmada-agent:latest",
+			)
+			output, err := cmd.ExecOrDie()
+			gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
+			gomega.Expect(output).Should(gomega.ContainSubstring(fmt.Sprintf("cluster(%s) is joined successfully", newClusterName)))
+		})
+
+		ginkgo.By("Wait for the new cluster to be ready", func() {
+			framework.WaitClusterFitWith(controlPlaneClient, newClusterName, func(cluster *clusterv1alpha1.Cluster) bool {
+				return meta.IsStatusConditionPresentAndEqual(cluster.Status.Conditions, clusterv1alpha1.ClusterConditionReady, metav1.ConditionTrue)
+			})
+		})
+	})
+})
+
+// extractAPIServerEndpoint extracts the given clusterName API endpoint from a kubeconfig file.
+//
+// Parameters:
+// - kubeConfigPath: The file path to the kubeconfig file.
+//
+// Returns:
+// - string: The extracted API server endpoint without the "https://" prefix.
+// - error: An error if:
+//   - the kubeconfig file cannot be read
+//   - the YAML format is invalid
+//   - the given clusterName is not found
+func extractAPIServerEndpoint(kubeConfigPath string, clusterName string) (string, error) {
+	config, err := clientcmd.LoadFromFile(kubeConfigPath)
+	if err != nil {
+		return "", err
+	}
+
+	for name, cluster := range config.Clusters {
+		if name == clusterName {
+			endpointWithoutPrefix := strings.TrimPrefix(cluster.Server, "https://")
+			return endpointWithoutPrefix, nil
+		}
+	}
+
+	return "", fmt.Errorf("%s endpoint not found in kubeconfig", clusterName)
+}
+
 // extractPropagationPolicyName extracts the propagation policy name from the input string.
 //
 // Parameters: