Merge remote-tracking branch 'origin/master' into release-1.13

pull/58/head
Yang Li 2018-11-21 09:44:27 +08:00
commit 016ce1bfd2
28 changed files with 289 additions and 167 deletions

View File

@ -101,7 +101,6 @@ filename | sha512 hash
* StatefulSet is supported in `kubectl autoscale` command ([#71103](https://github.com/kubernetes/kubernetes/pull/71103), [@Pingan2017](https://github.com/Pingan2017))
* Report kube-scheduler unhealthy if leader election is deadlocked. ([#71085](https://github.com/kubernetes/kubernetes/pull/71085), [@bsalamat](https://github.com/bsalamat))
* apiserver: fixes handling and logging of panics in REST handlers ([#71076](https://github.com/kubernetes/kubernetes/pull/71076), [@liggitt](https://github.com/liggitt))
* kube-apiserver now serves OpenAPI specs for registered CRDs with defined validation schemata. Kubectl will validate client-side using those. ([#67205](https://github.com/kubernetes/kubernetes/pull/67205), [@roycaihw](https://github.com/roycaihw))
* kubelets are no longer allowed to delete their own Node API object. Prior to 1.11, in rare circumstances related to cloudprovider node ID changes, kubelets would attempt to delete/recreate their Node object at startup. Kubelets older than 1.11 are not supported running against a v1.13+ API server. If an unsupported legacy kubelet encounters this situation, a cluster admin can remove the Node object: ([#71021](https://github.com/kubernetes/kubernetes/pull/71021), [@liggitt](https://github.com/liggitt))
* `kubectl delete node/<nodeName>`
* or grant self-deletion permission explicitly:

View File

@ -43,7 +43,7 @@ const (
defaultNumberOfImages = 8
// dummyKubernetesVersion is just used for unit testing, in order to not make
// kubeadm lookup dl.k8s.io to resolve what the latest stable release is
dummyKubernetesVersion = "v1.11.0"
dummyKubernetesVersion = "v1.12.0"
)
func TestNewCmdConfigImagesList(t *testing.T) {
@ -69,12 +69,12 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) {
name: "set k8s version",
expectedImageCount: defaultNumberOfImages,
expectedImageSubstrings: []string{
":v1.11.1",
":v1.12.1",
},
configContents: []byte(dedent.Dedent(`
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: v1.11.1
kubernetesVersion: v1.12.1
`)),
},
{
@ -86,7 +86,7 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) {
configContents: []byte(dedent.Dedent(`
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: v1.11.0
kubernetesVersion: v1.12.0
`)),
},
}

View File

@ -307,6 +307,15 @@ func NewJoin(cfgPath string, defaultcfg *kubeadmapiv1beta1.JoinConfiguration, ig
if err != nil {
return nil, err
}
// override node name and CRI socket from the command line options
if defaultcfg.NodeRegistration.Name != "" {
internalCfg.NodeRegistration.Name = defaultcfg.NodeRegistration.Name
}
if defaultcfg.NodeRegistration.CRISocket != kubeadmapiv1beta1.DefaultCRISocket {
internalCfg.NodeRegistration.CRISocket = defaultcfg.NodeRegistration.CRISocket
}
if defaultcfg.ControlPlane != nil {
if err := configutil.VerifyAPIServerBindAddress(internalCfg.ControlPlane.LocalAPIEndpoint.AdvertiseAddress); err != nil {
return nil, err

View File

@ -175,7 +175,7 @@ func TestRunCreateToken(t *testing.T) {
ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{
// KubernetesVersion is not used, but we set this explicitly to avoid
// the lookup of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
KubernetesVersion: "v1.11.0",
KubernetesVersion: "v1.12.0",
},
BootstrapTokens: []kubeadmapiv1beta1.BootstrapToken{
{

View File

@ -48,11 +48,11 @@ var (
upgradeNodeConfigExample = normalizer.Examples(`
# Downloads the kubelet configuration from the ConfigMap in the cluster. Uses a specific desired kubelet version.
kubeadm upgrade node config --kubelet-version v1.12.0
kubeadm upgrade node config --kubelet-version v1.13.0
# Simulates the downloading of the kubelet configuration from the ConfigMap in the cluster with a specific desired
# version. Does not change any state locally on the node.
kubeadm upgrade node config --kubelet-version v1.12.0 --dry-run
kubeadm upgrade node config --kubelet-version v1.13.0 --dry-run
`)
)

View File

@ -377,10 +377,10 @@ var (
MasterComponents = []string{KubeAPIServer, KubeControllerManager, KubeScheduler}
// MinimumControlPlaneVersion specifies the minimum control plane version kubeadm can deploy
MinimumControlPlaneVersion = version.MustParseSemantic("v1.11.0")
MinimumControlPlaneVersion = version.MustParseSemantic("v1.12.0")
// MinimumKubeletVersion specifies the minimum version of kubelet which kubeadm supports
MinimumKubeletVersion = version.MustParseSemantic("v1.11.0")
MinimumKubeletVersion = version.MustParseSemantic("v1.12.0")
// SupportedEtcdVersion lists officially supported etcd versions with corresponding Kubernetes releases
SupportedEtcdVersion = map[uint8]string{

View File

@ -24,7 +24,7 @@ import (
utilfeature "k8s.io/apiserver/pkg/util/feature"
)
var TestMinVersion = version.MustParseSemantic("v1.11.0-alpha.1")
var TestMinVersion = version.MustParseSemantic("v1.12.0-alpha.1")
func TestKnownFeatures(t *testing.T) {
var someFeatures = FeatureList{
@ -144,12 +144,12 @@ func TestValidateVersion(t *testing.T) {
},
{ //min version but correct value given
requestedFeatures: map[string]bool{"feature2": true},
requestedVersion: "v1.11.0",
requestedVersion: "v1.12.0",
expectedError: false,
},
{ //min version and incorrect value given
requestedFeatures: map[string]bool{"feature2": true},
requestedVersion: "v1.10.2",
requestedVersion: "v1.11.2",
expectedError: true,
},
}

View File

@ -80,6 +80,7 @@ spec:
command:
- /usr/local/bin/kube-proxy
- --config=/var/lib/kube-proxy/{{ .ProxyConfigMapKey }}
- --hostname-override=$(NODE_NAME)
securityContext:
privileged: true
volumeMounts:
@ -91,6 +92,11 @@ spec:
- mountPath: /lib/modules
name: lib-modules
readOnly: true
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
hostNetwork: true
serviceAccountName: kube-proxy
volumes:

View File

@ -183,7 +183,7 @@ func TestEnsureProxyAddon(t *testing.T) {
PodSubnet: "5.6.7.8/24",
},
ImageRepository: "someRepo",
KubernetesVersion: "v1.11.0",
KubernetesVersion: "v1.12.0",
},
}

View File

@ -90,7 +90,7 @@ func CreateStackedEtcdStaticPodManifestFile(client clientset.Interface, manifest
}
// notifies the other members of the etcd cluster about the joining member
etcdPeerAddress := fmt.Sprintf("https://%s:%d", cfg.LocalAPIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenPeerPort)
etcdPeerAddress := etcdutil.GetPeerURL(cfg)
klog.V(1).Infof("Adding etcd member: %s", etcdPeerAddress)
initialCluster, err := etcdClient.AddMember(cfg.NodeRegistration.Name, etcdPeerAddress)
@ -141,10 +141,10 @@ func GetEtcdPodSpec(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil
func getEtcdCommand(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil.Member) []string {
defaultArguments := map[string]string{
"name": cfg.GetNodeName(),
"listen-client-urls": fmt.Sprintf("https://127.0.0.1:%d,https://%s:%d", kubeadmconstants.EtcdListenClientPort, cfg.LocalAPIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenClientPort),
"advertise-client-urls": fmt.Sprintf("https://%s:%d", cfg.LocalAPIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenClientPort),
"listen-peer-urls": fmt.Sprintf("https://%s:%d", cfg.LocalAPIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenPeerPort),
"initial-advertise-peer-urls": fmt.Sprintf("https://%s:%d", cfg.LocalAPIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenPeerPort),
"listen-client-urls": fmt.Sprintf("%s,%s", etcdutil.GetClientURLByIP("127.0.0.1"), etcdutil.GetClientURL(cfg)),
"advertise-client-urls": etcdutil.GetClientURL(cfg),
"listen-peer-urls": etcdutil.GetPeerURL(cfg),
"initial-advertise-peer-urls": etcdutil.GetPeerURL(cfg),
"data-dir": cfg.Etcd.Local.DataDir,
"cert-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerCertName),
"key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerKeyName),
@ -158,7 +158,7 @@ func getEtcdCommand(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil
}
if len(initialCluster) == 0 {
defaultArguments["initial-cluster"] = fmt.Sprintf("%s=https://%s:%d", cfg.GetNodeName(), cfg.LocalAPIEndpoint.AdvertiseAddress, kubeadmconstants.EtcdListenPeerPort)
defaultArguments["initial-cluster"] = fmt.Sprintf("%s=%s", cfg.GetNodeName(), etcdutil.GetPeerURL(cfg))
} else {
// NB. the joining etcd instance should be part of the initialCluster list
endpoints := []string{}

View File

@ -115,27 +115,16 @@ func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) {
func TestGetEtcdCommand(t *testing.T) {
var tests = []struct {
name string
cfg *kubeadmapi.InitConfiguration
advertiseAddress string
nodeName string
extraArgs map[string]string
initialCluster []etcdutil.Member
expected []string
}{
{
name: "Default args - with empty etcd initial cluster",
cfg: &kubeadmapi.InitConfiguration{
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
AdvertiseAddress: "1.2.3.4",
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
Name: "foo",
},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
},
},
},
},
advertiseAddress: "1.2.3.4",
nodeName: "foo",
expected: []string{
"etcd",
"--name=foo",
@ -158,21 +147,8 @@ func TestGetEtcdCommand(t *testing.T) {
},
{
name: "Default args - With an existing etcd cluster",
cfg: &kubeadmapi.InitConfiguration{
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
AdvertiseAddress: "1.2.3.4",
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
Name: "foo",
},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
},
},
},
},
advertiseAddress: "1.2.3.4",
nodeName: "foo",
initialCluster: []etcdutil.Member{
{Name: "foo", PeerURL: fmt.Sprintf("https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort)}, // NB. the joining etcd instance should be part of the initialCluster list
{Name: "bar", PeerURL: fmt.Sprintf("https://5.6.7.8:%d", kubeadmconstants.EtcdListenPeerPort)},
@ -200,25 +176,12 @@ func TestGetEtcdCommand(t *testing.T) {
},
{
name: "Extra args",
cfg: &kubeadmapi.InitConfiguration{
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
AdvertiseAddress: "1.2.3.4",
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
Name: "bar",
},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
ExtraArgs: map[string]string{
advertiseAddress: "1.2.3.4",
nodeName: "bar",
extraArgs: map[string]string{
"listen-client-urls": "https://10.0.1.10:2379",
"advertise-client-urls": "https://10.0.1.10:2379",
},
},
},
},
},
expected: []string{
"etcd",
"--name=bar",
@ -239,11 +202,51 @@ func TestGetEtcdCommand(t *testing.T) {
fmt.Sprintf("--initial-cluster=bar=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort),
},
},
{
name: "IPv6 advertise address",
advertiseAddress: "2001:db8::3",
nodeName: "foo",
expected: []string{
"etcd",
"--name=foo",
fmt.Sprintf("--listen-client-urls=https://127.0.0.1:%d,https://[2001:db8::3]:%d", kubeadmconstants.EtcdListenClientPort, kubeadmconstants.EtcdListenClientPort),
fmt.Sprintf("--advertise-client-urls=https://[2001:db8::3]:%d", kubeadmconstants.EtcdListenClientPort),
fmt.Sprintf("--listen-peer-urls=https://[2001:db8::3]:%d", kubeadmconstants.EtcdListenPeerPort),
fmt.Sprintf("--initial-advertise-peer-urls=https://[2001:db8::3]:%d", kubeadmconstants.EtcdListenPeerPort),
"--data-dir=/var/lib/etcd",
"--cert-file=" + kubeadmconstants.EtcdServerCertName,
"--key-file=" + kubeadmconstants.EtcdServerKeyName,
"--trusted-ca-file=" + kubeadmconstants.EtcdCACertName,
"--client-cert-auth=true",
"--peer-cert-file=" + kubeadmconstants.EtcdPeerCertName,
"--peer-key-file=" + kubeadmconstants.EtcdPeerKeyName,
"--peer-trusted-ca-file=" + kubeadmconstants.EtcdCACertName,
"--snapshot-count=10000",
"--peer-client-cert-auth=true",
fmt.Sprintf("--initial-cluster=foo=https://[2001:db8::3]:%d", kubeadmconstants.EtcdListenPeerPort),
},
},
}
for _, rt := range tests {
t.Run(rt.name, func(t *testing.T) {
actual := getEtcdCommand(rt.cfg, rt.initialCluster)
cfg := &kubeadmapi.InitConfiguration{
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
AdvertiseAddress: rt.advertiseAddress,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
Name: rt.nodeName,
},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
ExtraArgs: rt.extraArgs,
},
},
},
}
actual := getEtcdCommand(cfg, rt.initialCluster)
sort.Strings(actual)
sort.Strings(rt.expected)
if !reflect.DeepEqual(actual, rt.expected) {

View File

@ -35,7 +35,7 @@ func TestCreateConfigMap(t *testing.T) {
cfg := &kubeadmapi.InitConfiguration{
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodeName},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.12.0",
KubernetesVersion: "v1.13.0",
ComponentConfigs: kubeadmapi.ComponentConfigs{
Kubelet: &kubeletconfig.KubeletConfiguration{},
},

View File

@ -34,38 +34,38 @@ func TestEnforceVersionPolicies(t *testing.T) {
{
name: "minor upgrade",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.11.5",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.12.5",
},
newK8sVersion: "v1.11.5",
newK8sVersion: "v1.12.5",
},
{
name: "major upgrade",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.2",
kubeadmVersion: "v1.12.1",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.2",
kubeadmVersion: "v1.13.1",
},
newK8sVersion: "v1.12.0",
newK8sVersion: "v1.13.0",
},
{
name: "downgrade",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.11.3",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.12.3",
},
newK8sVersion: "v1.11.2",
newK8sVersion: "v1.12.2",
},
{
name: "same version upgrade",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.11.3",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.12.3",
},
newK8sVersion: "v1.11.3",
newK8sVersion: "v1.12.3",
},
{
name: "new version must be higher than v1.10.0",
@ -81,114 +81,114 @@ func TestEnforceVersionPolicies(t *testing.T) {
{
name: "upgrading two minor versions in one go is not supported",
vg: &fakeVersionGetter{
clusterVersion: "v1.10.3",
kubeletVersion: "v1.10.3",
kubeadmVersion: "v1.12.0",
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.13.0",
},
newK8sVersion: "v1.12.0",
newK8sVersion: "v1.13.0",
expectedMandatoryErrs: 1, // can't upgrade two minor versions
expectedSkippableErrs: 1, // kubelet <-> apiserver skew too large
},
{
name: "downgrading two minor versions in one go is not supported",
vg: &fakeVersionGetter{
clusterVersion: "v1.13.3",
kubeletVersion: "v1.13.3",
kubeadmVersion: "v1.13.0",
clusterVersion: "v1.14.3",
kubeletVersion: "v1.14.3",
kubeadmVersion: "v1.14.0",
},
newK8sVersion: "v1.11.3",
newK8sVersion: "v1.12.3",
expectedMandatoryErrs: 1, // can't downgrade two minor versions
expectedSkippableErrs: 1, // can't upgrade old k8s with newer kubeadm
},
{
name: "kubeadm version must be higher than the new kube version. However, patch version skews may be forced",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.11.3",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.12.3",
},
newK8sVersion: "v1.11.5",
newK8sVersion: "v1.12.5",
expectedSkippableErrs: 1,
},
{
name: "kubeadm version must be higher than the new kube version. Trying to upgrade k8s to a higher minor version than kubeadm itself should never be supported",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.11.3",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.12.3",
},
newK8sVersion: "v1.12.0",
newK8sVersion: "v1.13.0",
expectedMandatoryErrs: 1,
},
{
name: "the maximum skew between the cluster version and the kubelet versions should be one minor version. This may be forced through though.",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.10.8",
kubeadmVersion: "v1.12.0",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.11.8",
kubeadmVersion: "v1.13.0",
},
newK8sVersion: "v1.12.0",
newK8sVersion: "v1.13.0",
expectedSkippableErrs: 1,
},
{
name: "experimental upgrades supported if the flag is set",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.12.0-beta.1",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.13.0-beta.1",
},
newK8sVersion: "v1.12.0-beta.1",
newK8sVersion: "v1.13.0-beta.1",
allowExperimental: true,
},
{
name: "release candidate upgrades supported if the flag is set",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.12.0-rc.1",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.13.0-rc.1",
},
newK8sVersion: "v1.12.0-rc.1",
newK8sVersion: "v1.13.0-rc.1",
allowRCs: true,
},
{
name: "release candidate upgrades supported if the flag is set",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.12.0-rc.1",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.13.0-rc.1",
},
newK8sVersion: "v1.12.0-rc.1",
newK8sVersion: "v1.13.0-rc.1",
allowExperimental: true,
},
{
name: "the user should not be able to upgrade to an experimental version if they haven't opted into that",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.12.0-beta.1",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.13.0-beta.1",
},
newK8sVersion: "v1.12.0-beta.1",
newK8sVersion: "v1.13.0-beta.1",
allowRCs: true,
expectedSkippableErrs: 1,
},
{
name: "the user should not be able to upgrade to an release candidate version if they haven't opted into that",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.12.0-rc.1",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.13.0-rc.1",
},
newK8sVersion: "v1.12.0-rc.1",
newK8sVersion: "v1.13.0-rc.1",
expectedSkippableErrs: 1,
},
{
name: "the user can't use a newer minor version of kubeadm to upgrade an older version of kubeadm",
vg: &fakeVersionGetter{
clusterVersion: "v1.11.3",
kubeletVersion: "v1.11.3",
kubeadmVersion: "v1.12.0",
clusterVersion: "v1.12.3",
kubeletVersion: "v1.12.3",
kubeadmVersion: "v1.13.0",
},
newK8sVersion: "v1.11.6",
newK8sVersion: "v1.12.6",
expectedSkippableErrs: 1, // can't upgrade old k8s with newer kubeadm
},
}

View File

@ -282,7 +282,7 @@ func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Wa
if err != nil {
return true, errors.Wrap(err, "failed to retrieve the current etcd version")
}
currentEtcdVersionStr, ok := currentEtcdVersions[fmt.Sprintf("https://%s:%d", cfg.LocalAPIEndpoint.AdvertiseAddress, constants.EtcdListenClientPort)]
currentEtcdVersionStr, ok := currentEtcdVersions[etcdutil.GetClientURL(cfg)]
if !ok {
fmt.Println(currentEtcdVersions)
return true, errors.Wrap(err, "failed to retrieve the current etcd version")

View File

@ -471,7 +471,7 @@ func TestStaticPodControlPlane(t *testing.T) {
t.Fatalf("couldn't read temp file: %v", err)
}
newcfg, err := getConfig("v1.11.0", tempCertsDir, tmpEtcdDataDir)
newcfg, err := getConfig("v1.13.0", tempCertsDir, tmpEtcdDataDir)
if err != nil {
t.Fatalf("couldn't create config: %v", err)
}
@ -523,10 +523,11 @@ func TestStaticPodControlPlane(t *testing.T) {
if (oldHash != newHash) != rt.manifestShouldChange {
t.Errorf(
"failed StaticPodControlPlane\n%s\n\texpected manifest change: %t\n\tgot: %t",
"failed StaticPodControlPlane\n%s\n\texpected manifest change: %t\n\tgot: %t\n\tnewHash: %v",
rt.description,
rt.manifestShouldChange,
(oldHash != newHash),
newHash,
)
}
return

View File

@ -69,7 +69,7 @@ func TestUploadConfiguration(t *testing.T) {
AdvertiseAddress: "1.2.3.4",
},
ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{
KubernetesVersion: "v1.11.10",
KubernetesVersion: "v1.12.10",
},
BootstrapTokens: []kubeadmapiv1beta1.BootstrapToken{
{

View File

@ -647,13 +647,13 @@ func TestKubeletVersionCheck(t *testing.T) {
expectErrors bool
expectWarnings bool
}{
{"v1.12.2", "", false, false}, // check minimally supported version when there is no information about control plane
{"v1.9.3", "v1.9.8", true, false}, // too old kubelet (older than kubeadmconstants.MinimumKubeletVersion), should fail.
{"v1.11.0", "v1.11.5", false, false}, // kubelet within same major.minor as control plane
{"v1.11.5", "v1.11.1", false, false}, // kubelet is newer, but still within same major.minor as control plane
{"v1.11.0", "v1.12.1", false, false}, // kubelet is lower than control plane, but newer than minimally supported
{"v1.12.0-alpha.1", "v1.11.1", true, false}, // kubelet is newer (development build) than control plane, should fail.
{"v1.12.0", "v1.11.5", true, false}, // kubelet is newer (release) than control plane, should fail.
{"v1.13.2", "", false, false}, // check minimally supported version when there is no information about control plane
{"v1.11.3", "v1.11.8", true, false}, // too old kubelet (older than kubeadmconstants.MinimumKubeletVersion), should fail.
{"v1.12.0", "v1.12.5", false, false}, // kubelet within same major.minor as control plane
{"v1.12.5", "v1.12.1", false, false}, // kubelet is newer, but still within same major.minor as control plane
{"v1.12.0", "v1.13.1", false, false}, // kubelet is lower than control plane, but newer than minimally supported
{"v1.13.0-alpha.1", "v1.12.1", true, false}, // kubelet is newer (development build) than control plane, should fail.
{"v1.13.0", "v1.12.5", true, false}, // kubelet is newer (release) than control plane, should fail.
}
for _, tc := range cases {

View File

@ -183,7 +183,7 @@ Etcd:
ServerCertSANs: null
FeatureGates: null
ImageRepository: k8s.gcr.io
KubernetesVersion: v1.11.2
KubernetesVersion: v1.12.2
LocalAPIEndpoint:
AdvertiseAddress: 192.168.2.2
BindPort: 6443

View File

@ -42,12 +42,12 @@ etcd:
image: ""
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.11.2
kubernetesVersion: v1.12.2
networking:
dnsDomain: cluster.local
podSubnet: ""
serviceSubnet: 10.96.0.0/12
unifiedControlPlaneImage: "k8s.gcr.io/hyperkube:v1.11.2"
unifiedControlPlaneImage: "k8s.gcr.io/hyperkube:v1.12.2"
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0

View File

@ -42,7 +42,7 @@ etcd:
dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.11.2
kubernetesVersion: v1.12.2
networking:
dnsDomain: cluster.local
podSubnet: ""

View File

@ -32,7 +32,7 @@ etcd:
dataDir: /var/lib/etcd
imageRepository: my-company.com
kind: ClusterConfiguration
kubernetesVersion: v1.12.0
kubernetesVersion: v1.13.0
networking:
dnsDomain: cluster.global
podSubnet: 10.148.0.0/16

View File

@ -12,7 +12,7 @@ apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /var/lib/kubernetes/pki
imageRepository: my-company.com
kind: ClusterConfiguration
kubernetesVersion: v1.12.0
kubernetesVersion: v1.13.0
networking:
dnsDomain: cluster.global
podSubnet: 10.148.0.0/16

View File

@ -24,6 +24,7 @@ go_test(
embed = [":go_default_library"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/test:go_default_library",
],
)

View File

@ -20,7 +20,9 @@ import (
"context"
"crypto/tls"
"fmt"
"net"
"path/filepath"
"strconv"
"strings"
"time"
@ -171,7 +173,7 @@ func NewFromCluster(client clientset.Interface, certificatesDir string) (*Client
// Get the list of etcd endpoints from cluster status
endpoints := []string{}
for _, e := range clusterStatus.APIEndpoints {
endpoints = append(endpoints, fmt.Sprintf("https://%s:%d", e.AdvertiseAddress, constants.EtcdListenClientPort))
endpoints = append(endpoints, GetClientURLByIP(e.AdvertiseAddress))
}
klog.V(1).Infof("etcd endpoints read from pods: %s", strings.Join(endpoints, ","))
@ -358,3 +360,21 @@ func (c Client) WaitForClusterAvailable(delay time.Duration, retries int, retryI
func CheckConfigurationIsHA(cfg *kubeadmapi.Etcd) bool {
return cfg.External != nil && len(cfg.External.Endpoints) > 1
}
// GetClientURL creates an HTTPS URL that uses the configured advertise
// address and client port for the API controller
func GetClientURL(cfg *kubeadmapi.InitConfiguration) string {
return "https://" + net.JoinHostPort(cfg.LocalAPIEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenClientPort))
}
// GetPeerURL creates an HTTPS URL that uses the configured advertise
// address and peer port for the API controller
func GetPeerURL(cfg *kubeadmapi.InitConfiguration) string {
return "https://" + net.JoinHostPort(cfg.LocalAPIEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenPeerPort))
}
// GetClientURLByIP creates an HTTPS URL based on an IP address
// and the client listening port.
func GetClientURLByIP(ip string) string {
return "https://" + net.JoinHostPort(ip, strconv.Itoa(constants.EtcdListenClientPort))
}

View File

@ -17,12 +17,15 @@ limitations under the License.
package etcd
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"testing"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
)
@ -308,3 +311,90 @@ func TestCheckConfigurationIsHA(t *testing.T) {
})
}
}
func testGetURL(t *testing.T, getURLFunc func(*kubeadmapi.InitConfiguration) string, port int) {
portStr := strconv.Itoa(port)
var tests = []struct {
name string
advertiseAddress string
expectedURL string
}{
{
name: "IPv4",
advertiseAddress: "10.10.10.10",
expectedURL: fmt.Sprintf("https://10.10.10.10:%s", portStr),
},
{
name: "IPv6",
advertiseAddress: "2001:db8::2",
expectedURL: fmt.Sprintf("https://[2001:db8::2]:%s", portStr),
},
{
name: "IPv4 localhost",
advertiseAddress: "127.0.0.1",
expectedURL: fmt.Sprintf("https://127.0.0.1:%s", portStr),
},
{
name: "IPv6 localhost",
advertiseAddress: "::1",
expectedURL: fmt.Sprintf("https://[::1]:%s", portStr),
},
}
for _, test := range tests {
cfg := &kubeadmapi.InitConfiguration{
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
AdvertiseAddress: test.advertiseAddress,
},
}
url := getURLFunc(cfg)
if url != test.expectedURL {
t.Errorf("expected %s, got %s", test.expectedURL, url)
}
}
}
func TestGetClientURL(t *testing.T) {
testGetURL(t, GetClientURL, constants.EtcdListenClientPort)
}
func TestGetPeerURL(t *testing.T) {
testGetURL(t, GetClientURL, constants.EtcdListenClientPort)
}
func TestGetClientURLByIP(t *testing.T) {
portStr := strconv.Itoa(constants.EtcdListenClientPort)
var tests = []struct {
name string
ip string
expectedURL string
}{
{
name: "IPv4",
ip: "10.10.10.10",
expectedURL: fmt.Sprintf("https://10.10.10.10:%s", portStr),
},
{
name: "IPv6",
ip: "2001:db8::2",
expectedURL: fmt.Sprintf("https://[2001:db8::2]:%s", portStr),
},
{
name: "IPv4 localhost",
ip: "127.0.0.1",
expectedURL: fmt.Sprintf("https://127.0.0.1:%s", portStr),
},
{
name: "IPv6 localhost",
ip: "::1",
expectedURL: fmt.Sprintf("https://[::1]:%s", portStr),
},
}
for _, test := range tests {
url := GetClientURLByIP(test.ip)
if url != test.expectedURL {
t.Errorf("expected %s, got %s", test.expectedURL, url)
}
}
}

View File

@ -102,7 +102,7 @@ func TestCmdInitKubernetesVersion(t *testing.T) {
},
{
name: "valid version is accepted",
args: "--kubernetes-version=1.11.0",
args: "--kubernetes-version=1.12.0",
expected: true,
},
}

View File

@ -66,7 +66,7 @@ func SetupInitConfigurationFile(t *testing.T, tmpdir string, cfg *kubeadmapi.Ini
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
certificatesDir: {{.CertificatesDir}}
kubernetesVersion: v1.11.0
kubernetesVersion: v1.12.0
`)))
f, err := os.Create(cfgPath)

View File

@ -158,7 +158,7 @@ func (manager *gceServiceManager) CreateRegionalDiskOnCloudProvider(
fullyQualifiedReplicaZones := []string{}
for _, replicaZone := range replicaZones.UnsortedList() {
fullyQualifiedReplicaZones = append(
fullyQualifiedReplicaZones, manager.getReplicaZoneURI(replicaZone, true))
fullyQualifiedReplicaZones, manager.getReplicaZoneURI(replicaZone))
}
diskToCreate := &compute.Disk{
@ -359,15 +359,8 @@ func (manager *gceServiceManager) getDiskTypeURI(
}
}
func (manager *gceServiceManager) getReplicaZoneURI(zone string, useBetaAPI bool) string {
var getProjectsAPIEndpoint string
if useBetaAPI {
getProjectsAPIEndpoint = manager.getProjectsAPIEndpointBeta()
} else {
getProjectsAPIEndpoint = manager.getProjectsAPIEndpoint()
}
return getProjectsAPIEndpoint + fmt.Sprintf(
func (manager *gceServiceManager) getReplicaZoneURI(zone string) string {
return manager.getProjectsAPIEndpoint() + fmt.Sprintf(
replicaZoneURITemplateSingleZone,
manager.gce.projectID,
zone)