Проблема, с которой вы столкнулись, связана с тем, что в версии, предшествующей v1.10.3 kubeadm
, подавляется ошибка соединения.Вот почему вы не можете точно увидеть, что происходит, и можете подумать о некоторых ошибках в файле конфигурации.
Вот проблема , связанная с вашей проблемой.
В версии 1.10.3 исправление было введено в PR # 60585 , так что теперь вы должны увидеть ошибки подключения и выяснить, как их исправить.
В любом случае ваша проблема вызвана проблемой с подключением к конечным точкам кластера etcd.
https://192.168.0.10:2379/version
https://192.168.0.11:2379/version
https://192.168.0.12:2379/version
Вы можете попытаться подключиться к этим конечным точкам, используя команду curl
с узла, на котором вы запускаете kubeadm init
, используя свои сертификаты из файла конфигурации:
caFile: /etc/kubernetes/pki/etcd/ca.pem
certFile: /etc/kubernetes/pki/etcd/client.pem
keyFile: /etc/kubernetes/pki/etcd/client-key.pem
Вотпример:
curl --cacert /etc/kubernetes/pki/etcd/ca.pem --cert /etc/kubernetes/pki/etcd/client.pem --key /etc/kubernetes/pki/etcd/client-key.pem -L https://192.168.0.10:2379/version
{"etcdserver":"3.3.2","etcdcluster":"3.3.0"}
Если вы получили ошибку соединения, вы должны исправить эту проблему до инициализации кластера.
Это часть кода, связанная с проверкой версии внешнего сервера etcd.Он был скопирован из основной ветки :
// Check validates external etcd version
// TODO: Use the official etcd Golang client for this instead?
func (evc ExternalEtcdVersionCheck) Check() (warnings, errors []error) {
glog.V(1).Infoln("validating the external etcd version")
// Return quickly if the user isn't using external etcd
if evc.Etcd.External.Endpoints == nil {
return nil, nil
}
var config *tls.Config
var err error
if config, err = evc.configRootCAs(config); err != nil {
errors = append(errors, err)
return nil, errors
}
if config, err = evc.configCertAndKey(config); err != nil {
errors = append(errors, err)
return nil, errors
}
client := evc.getHTTPClient(config)
for _, endpoint := range evc.Etcd.External.Endpoints {
if _, err := url.Parse(endpoint); err != nil {
errors = append(errors, fmt.Errorf("failed to parse external etcd endpoint %s : %v", endpoint, err))
continue
}
resp := etcdVersionResponse{}
var err error
versionURL := fmt.Sprintf("%s/%s", endpoint, "version")
if tmpVersionURL, err := purell.NormalizeURLString(versionURL, purell.FlagRemoveDuplicateSlashes); err != nil {
errors = append(errors, fmt.Errorf("failed to normalize external etcd version url %s : %v", versionURL, err))
continue
} else {
versionURL = tmpVersionURL
}
##### Here we connect to endpoint and request version info
if err = getEtcdVersionResponse(client, versionURL, &resp); err != nil {
errors = append(errors, err)
continue
}
##### Here we print that error message in case of error on the previous step
etcdVersion, err := semver.Parse(resp.Etcdserver)
if err != nil {
errors = append(errors, fmt.Errorf("couldn't parse external etcd version %q: %v", resp.Etcdserver, err))
continue
}
if etcdVersion.LT(minExternalEtcdVersion) {
errors = append(errors, fmt.Errorf("this version of kubeadm only supports external etcd version >= %s. Current version: %s", kubeadmconstants.MinExternalEtcdVersion, resp.Etcdserver))
continue
}
}
return nil, errors
}
....
func getEtcdVersionResponse(client *http.Client, url string, target interface{}) error {
loopCount := externalEtcdRequestRetries + 1
var err error
var stopRetry bool
for loopCount > 0 {
if loopCount <= externalEtcdRequestRetries {
time.Sleep(externalEtcdRequestInterval)
}
stopRetry, err = func() (stopRetry bool, err error) {
r, err := client.Get(url)
if err != nil {
loopCount--
return false, err #### <-- this line was fixed by replacing "return false, nil"
}
defer r.Body.Close()
if r != nil && r.StatusCode >= 500 && r.StatusCode <= 599 {
loopCount--
return false, fmt.Errorf("server responded with non-successful status: %s", r.Status)
}
return true, json.NewDecoder(r.Body).Decode(target)
}()
if stopRetry {
break
}
}
return err
}