mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
kubeadm: use etcd's /health endpoint for it's liveness probe
Etcd v3.3.0 added the --listen-metrics-urls flag which allows specifying addition URLs to the already present /health and /metrics endpoints. While /health and /metrics are enabled for URLS defined with --listen-client-urls (v3+ ?) they do require HTTPS. Replace the present etcdctl based liveness probe with a standard HTTP GET v1.Probe that connects to http://127.0.0.1:2381/health. These endpoints are not reachable from the outside and only available for localhost connections.
This commit is contained in:
parent
77fca12f66
commit
99b64f1e8e
@ -86,6 +86,8 @@ const (
|
||||
|
||||
// EtcdListenClientPort defines the port etcd listen on for client traffic
|
||||
EtcdListenClientPort = 2379
|
||||
// EtcdMetricsPort is the port at which to obtain etcd metrics and health status
|
||||
EtcdMetricsPort = 2381
|
||||
|
||||
// EtcdPeerCertAndKeyBaseName defines etcd's peer certificate and key base name
|
||||
EtcdPeerCertAndKeyBaseName = "etcd/peer"
|
||||
|
@ -41,7 +41,6 @@ go_library(
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/staticpod:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/klog"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
@ -58,7 +57,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
|
||||
ImagePullPolicy: v1.PullIfNotPresent,
|
||||
Command: getAPIServerCommand(cfg, endpoint),
|
||||
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeAPIServer)),
|
||||
LivenessProbe: livenessProbe(staticpodutil.GetAPIServerProbeAddress(endpoint), int(endpoint.BindPort), v1.URISchemeHTTPS),
|
||||
LivenessProbe: staticpodutil.LivenessProbe(staticpodutil.GetAPIServerProbeAddress(endpoint), "/healthz", int(endpoint.BindPort), v1.URISchemeHTTPS),
|
||||
Resources: staticpodutil.ComponentResources("250m"),
|
||||
Env: getProxyEnvVars(),
|
||||
}, mounts.GetVolumes(kubeadmconstants.KubeAPIServer)),
|
||||
@ -68,7 +67,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
|
||||
ImagePullPolicy: v1.PullIfNotPresent,
|
||||
Command: getControllerManagerCommand(cfg),
|
||||
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeControllerManager)),
|
||||
LivenessProbe: livenessProbe(staticpodutil.GetControllerManagerProbeAddress(cfg), kubeadmconstants.InsecureKubeControllerManagerPort, v1.URISchemeHTTP),
|
||||
LivenessProbe: staticpodutil.LivenessProbe(staticpodutil.GetControllerManagerProbeAddress(cfg), "/healthz", kubeadmconstants.InsecureKubeControllerManagerPort, v1.URISchemeHTTP),
|
||||
Resources: staticpodutil.ComponentResources("200m"),
|
||||
Env: getProxyEnvVars(),
|
||||
}, mounts.GetVolumes(kubeadmconstants.KubeControllerManager)),
|
||||
@ -78,7 +77,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
|
||||
ImagePullPolicy: v1.PullIfNotPresent,
|
||||
Command: getSchedulerCommand(cfg),
|
||||
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeScheduler)),
|
||||
LivenessProbe: livenessProbe(staticpodutil.GetSchedulerProbeAddress(cfg), kubeadmconstants.InsecureSchedulerPort, v1.URISchemeHTTP),
|
||||
LivenessProbe: staticpodutil.LivenessProbe(staticpodutil.GetSchedulerProbeAddress(cfg), "/healthz", kubeadmconstants.InsecureSchedulerPort, v1.URISchemeHTTP),
|
||||
Resources: staticpodutil.ComponentResources("100m"),
|
||||
Env: getProxyEnvVars(),
|
||||
}, mounts.GetVolumes(kubeadmconstants.KubeScheduler)),
|
||||
@ -86,22 +85,6 @@ func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmap
|
||||
return staticPodSpecs
|
||||
}
|
||||
|
||||
func livenessProbe(host string, port int, scheme v1.URIScheme) *v1.Probe {
|
||||
return &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
HTTPGet: &v1.HTTPGetAction{
|
||||
Host: host,
|
||||
Path: "/healthz",
|
||||
Port: intstr.FromInt(port),
|
||||
Scheme: scheme,
|
||||
},
|
||||
},
|
||||
InitialDelaySeconds: 15,
|
||||
TimeoutSeconds: 15,
|
||||
FailureThreshold: 8,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateStaticPodFiles creates all the requested static pod files.
|
||||
func CreateStaticPodFiles(manifestDir, kustomizeDir string, cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, componentNames ...string) error {
|
||||
// gets the StaticPodSpecs, actualized for the current ClusterConfiguration
|
||||
|
@ -167,6 +167,7 @@ func GetEtcdPodSpec(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.A
|
||||
etcdVolumeName: staticpodutil.NewVolume(etcdVolumeName, cfg.Etcd.Local.DataDir, &pathType),
|
||||
certsVolumeName: staticpodutil.NewVolume(certsVolumeName, cfg.CertificatesDir+"/etcd", &pathType),
|
||||
}
|
||||
probeHostname, probePort, probeScheme := staticpodutil.GetEtcdProbeEndpoint(&cfg.Etcd)
|
||||
return staticpodutil.ComponentPod(v1.Container{
|
||||
Name: kubeadmconstants.Etcd,
|
||||
Command: getEtcdCommand(cfg, endpoint, nodeName, initialCluster),
|
||||
@ -177,10 +178,7 @@ func GetEtcdPodSpec(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.A
|
||||
staticpodutil.NewVolumeMount(etcdVolumeName, cfg.Etcd.Local.DataDir, false),
|
||||
staticpodutil.NewVolumeMount(certsVolumeName, cfg.CertificatesDir+"/etcd", false),
|
||||
},
|
||||
LivenessProbe: staticpodutil.EtcdProbe(
|
||||
&cfg.Etcd, kubeadmconstants.EtcdListenClientPort, cfg.CertificatesDir,
|
||||
kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName,
|
||||
),
|
||||
LivenessProbe: staticpodutil.LivenessProbe(probeHostname, "/health", probePort, probeScheme),
|
||||
}, etcdMounts)
|
||||
}
|
||||
|
||||
@ -202,6 +200,7 @@ func getEtcdCommand(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.A
|
||||
"peer-trusted-ca-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdCACertName),
|
||||
"peer-client-cert-auth": "true",
|
||||
"snapshot-count": "10000",
|
||||
"listen-metrics-urls": fmt.Sprintf("http://127.0.0.1:%d", kubeadmconstants.EtcdMetricsPort),
|
||||
}
|
||||
|
||||
if len(initialCluster) == 0 {
|
||||
|
@ -183,6 +183,7 @@ func TestGetEtcdCommand(t *testing.T) {
|
||||
"etcd",
|
||||
"--name=foo",
|
||||
fmt.Sprintf("--listen-client-urls=https://127.0.0.1:%d,https://1.2.3.4:%d", kubeadmconstants.EtcdListenClientPort, kubeadmconstants.EtcdListenClientPort),
|
||||
fmt.Sprintf("--listen-metrics-urls=http://127.0.0.1:%d", kubeadmconstants.EtcdMetricsPort),
|
||||
fmt.Sprintf("--advertise-client-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenClientPort),
|
||||
fmt.Sprintf("--listen-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort),
|
||||
fmt.Sprintf("--initial-advertise-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort),
|
||||
@ -211,6 +212,7 @@ func TestGetEtcdCommand(t *testing.T) {
|
||||
"etcd",
|
||||
"--name=foo",
|
||||
fmt.Sprintf("--listen-client-urls=https://127.0.0.1:%d,https://1.2.3.4:%d", kubeadmconstants.EtcdListenClientPort, kubeadmconstants.EtcdListenClientPort),
|
||||
fmt.Sprintf("--listen-metrics-urls=http://127.0.0.1:%d", kubeadmconstants.EtcdMetricsPort),
|
||||
fmt.Sprintf("--advertise-client-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenClientPort),
|
||||
fmt.Sprintf("--listen-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort),
|
||||
fmt.Sprintf("--initial-advertise-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort),
|
||||
@ -240,6 +242,7 @@ func TestGetEtcdCommand(t *testing.T) {
|
||||
"etcd",
|
||||
"--name=bar",
|
||||
"--listen-client-urls=https://10.0.1.10:2379",
|
||||
fmt.Sprintf("--listen-metrics-urls=http://127.0.0.1:%d", kubeadmconstants.EtcdMetricsPort),
|
||||
"--advertise-client-urls=https://10.0.1.10:2379",
|
||||
fmt.Sprintf("--listen-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort),
|
||||
fmt.Sprintf("--initial-advertise-peer-urls=https://1.2.3.4:%d", kubeadmconstants.EtcdListenPeerPort),
|
||||
@ -264,6 +267,7 @@ func TestGetEtcdCommand(t *testing.T) {
|
||||
"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("--listen-metrics-urls=http://127.0.0.1:%d", kubeadmconstants.EtcdMetricsPort),
|
||||
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),
|
||||
|
@ -12,6 +12,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",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
@ -31,6 +32,7 @@ go_library(
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"sort"
|
||||
@ -31,6 +30,7 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
@ -43,9 +43,6 @@ const (
|
||||
|
||||
// kubeSchedulerAddressArg represents the address argument of the kube-scheduler configuration.
|
||||
kubeSchedulerAddressArg = "address"
|
||||
|
||||
// etcdListenClientURLsArg represents the listen-client-urls argument of the etcd configuration.
|
||||
etcdListenClientURLsArg = "listen-client-urls"
|
||||
)
|
||||
|
||||
// ComponentPod returns a Pod object from the container and volume specifications
|
||||
@ -80,24 +77,6 @@ func ComponentResources(cpu string) v1.ResourceRequirements {
|
||||
}
|
||||
}
|
||||
|
||||
// EtcdProbe is a helper function for building a shell-based, etcdctl v1.Probe object to healthcheck etcd
|
||||
func EtcdProbe(cfg *kubeadmapi.Etcd, port int, certsDir string, CACertName string, CertName string, KeyName string) *v1.Probe {
|
||||
tlsFlags := fmt.Sprintf("--cacert=%[1]s/%[2]s --cert=%[1]s/%[3]s --key=%[1]s/%[4]s", certsDir, CACertName, CertName, KeyName)
|
||||
// etcd pod is alive if a linearizable get succeeds.
|
||||
cmd := fmt.Sprintf("ETCDCTL_API=3 etcdctl --endpoints=https://[%s]:%d %s get foo", GetEtcdProbeAddress(cfg), port, tlsFlags)
|
||||
|
||||
return &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
Exec: &v1.ExecAction{
|
||||
Command: []string{"/bin/sh", "-ec", cmd},
|
||||
},
|
||||
},
|
||||
InitialDelaySeconds: 15,
|
||||
TimeoutSeconds: 15,
|
||||
FailureThreshold: 8,
|
||||
}
|
||||
}
|
||||
|
||||
// NewVolume creates a v1.Volume with a hostPath mount to the specified location
|
||||
func NewVolume(name, path string, pathType *v1.HostPathType) v1.Volume {
|
||||
return v1.Volume{
|
||||
@ -238,6 +217,23 @@ func ReadStaticPodFromDisk(manifestPath string) (*v1.Pod, error) {
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
// LivenessProbe creates a Probe object with a HTTPGet handler
|
||||
func LivenessProbe(host, path string, port int, scheme v1.URIScheme) *v1.Probe {
|
||||
return &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
HTTPGet: &v1.HTTPGetAction{
|
||||
Host: host,
|
||||
Path: path,
|
||||
Port: intstr.FromInt(port),
|
||||
Scheme: scheme,
|
||||
},
|
||||
},
|
||||
InitialDelaySeconds: 15,
|
||||
TimeoutSeconds: 15,
|
||||
FailureThreshold: 8,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAPIServerProbeAddress returns the probe address for the API server
|
||||
func GetAPIServerProbeAddress(endpoint *kubeadmapi.APIEndpoint) string {
|
||||
// In the case of a self-hosted deployment, the initial host on which kubeadm --init is run,
|
||||
@ -270,51 +266,43 @@ func GetSchedulerProbeAddress(cfg *kubeadmapi.ClusterConfiguration) string {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
|
||||
// GetEtcdProbeAddress returns the etcd probe address
|
||||
func GetEtcdProbeAddress(cfg *kubeadmapi.Etcd) string {
|
||||
if cfg.Local != nil && cfg.Local.ExtraArgs != nil {
|
||||
if arg, exists := cfg.Local.ExtraArgs[etcdListenClientURLsArg]; exists {
|
||||
// Use the first url in the listen-client-urls if multiple url's are specified.
|
||||
if strings.ContainsAny(arg, ",") {
|
||||
arg = strings.Split(arg, ",")[0]
|
||||
}
|
||||
parsedURL, err := url.Parse(arg)
|
||||
if err != nil || parsedURL.Hostname() == "" {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
// Return the IP if the URL contains an address instead of a name.
|
||||
if ip := net.ParseIP(parsedURL.Hostname()); ip != nil {
|
||||
// etcdctl doesn't support auto-converting zero addresses into loopback addresses
|
||||
if ip.Equal(net.IPv4zero) {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
if ip.Equal(net.IPv6zero) {
|
||||
return net.IPv6loopback.String()
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
// Use the local resolver to try resolving the name within the URL.
|
||||
// If the name can not be resolved, return an IPv4 loopback address.
|
||||
// Otherwise, select the first valid IPv4 address.
|
||||
// If the name does not resolve to an IPv4 address, select the first valid IPv6 address.
|
||||
addrs, err := net.LookupIP(parsedURL.Hostname())
|
||||
if err != nil {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
var ip net.IP
|
||||
for _, addr := range addrs {
|
||||
if addr.To4() != nil {
|
||||
ip = addr
|
||||
break
|
||||
}
|
||||
if addr.To16() != nil && ip == nil {
|
||||
ip = addr
|
||||
}
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
// GetEtcdProbeEndpoint takes a kubeadm Etcd configuration object and attempts to parse
|
||||
// the first URL in the listen-metrics-urls argument, returning an etcd probe hostname,
|
||||
// port and scheme
|
||||
func GetEtcdProbeEndpoint(cfg *kubeadmapi.Etcd) (string, int, v1.URIScheme) {
|
||||
localhost := "127.0.0.1"
|
||||
if cfg.Local == nil || cfg.Local.ExtraArgs == nil {
|
||||
return localhost, kubeadmconstants.EtcdMetricsPort, v1.URISchemeHTTP
|
||||
}
|
||||
return "127.0.0.1"
|
||||
if arg, exists := cfg.Local.ExtraArgs["listen-metrics-urls"]; exists {
|
||||
// Use the first url in the listen-metrics-urls if multiple URL's are specified.
|
||||
arg = strings.Split(arg, ",")[0]
|
||||
parsedURL, err := url.Parse(arg)
|
||||
if err != nil {
|
||||
return localhost, kubeadmconstants.EtcdMetricsPort, v1.URISchemeHTTP
|
||||
}
|
||||
// Parse scheme
|
||||
scheme := v1.URISchemeHTTP
|
||||
if parsedURL.Scheme == "https" {
|
||||
scheme = v1.URISchemeHTTPS
|
||||
}
|
||||
// Parse hostname
|
||||
hostname := parsedURL.Hostname()
|
||||
if len(hostname) == 0 {
|
||||
hostname = localhost
|
||||
}
|
||||
// Parse port
|
||||
port := kubeadmconstants.EtcdMetricsPort
|
||||
portStr := parsedURL.Port()
|
||||
if len(portStr) != 0 {
|
||||
p, err := util.ParsePort(portStr)
|
||||
if err == nil {
|
||||
port = p
|
||||
}
|
||||
}
|
||||
return hostname, port, scheme
|
||||
}
|
||||
return localhost, kubeadmconstants.EtcdMetricsPort, v1.URISchemeHTTP
|
||||
}
|
||||
|
||||
// ManifestFilesAreEqual compares 2 files. It returns true if their contents are equal, false otherwise
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||
)
|
||||
|
||||
@ -114,130 +115,86 @@ func TestGetControllerManagerProbeAddress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdProbe(t *testing.T) {
|
||||
func TestGetEtcdProbeEndpoint(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
cfg *kubeadmapi.Etcd
|
||||
port int
|
||||
certsDir string
|
||||
cacert string
|
||||
cert string
|
||||
key string
|
||||
expected string
|
||||
name string
|
||||
cfg *kubeadmapi.Etcd
|
||||
expectedHostname string
|
||||
expectedPort int
|
||||
expectedScheme v1.URIScheme
|
||||
}{
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls IPv4 addresses",
|
||||
name: "etcd probe URL from two URLs",
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
||||
"listen-metrics-urls": "https://1.2.3.4:1234,https://4.3.2.1:2381"},
|
||||
},
|
||||
},
|
||||
port: 1,
|
||||
certsDir: "secretsA",
|
||||
cacert: "ca1",
|
||||
cert: "cert1",
|
||||
key: "key1",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
||||
expectedHostname: "1.2.3.4",
|
||||
expectedPort: 1234,
|
||||
expectedScheme: v1.URISchemeHTTPS,
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address",
|
||||
name: "etcd probe URL with HTTP scheme",
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[0:0:0:0:0:0:0:0]:2379"},
|
||||
"listen-metrics-urls": "http://1.2.3.4:1234"},
|
||||
},
|
||||
},
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
expectedHostname: "1.2.3.4",
|
||||
expectedPort: 1234,
|
||||
expectedScheme: v1.URISchemeHTTP,
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 2",
|
||||
name: "etcd probe URL without scheme should result in defaults",
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[::0:0]:2379"},
|
||||
"listen-metrics-urls": "1.2.3.4"},
|
||||
},
|
||||
},
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
expectedHostname: "127.0.0.1",
|
||||
expectedPort: kubeadmconstants.EtcdMetricsPort,
|
||||
expectedScheme: v1.URISchemeHTTP,
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 3",
|
||||
name: "etcd probe URL without port",
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[::]:2379"},
|
||||
"listen-metrics-urls": "https://1.2.3.4"},
|
||||
},
|
||||
},
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
expectedHostname: "1.2.3.4",
|
||||
expectedPort: kubeadmconstants.EtcdMetricsPort,
|
||||
expectedScheme: v1.URISchemeHTTPS,
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls unspecified IPv4 address",
|
||||
name: "etcd probe URL from defaults",
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
||||
},
|
||||
Local: &kubeadmapi.LocalEtcd{},
|
||||
},
|
||||
port: 1,
|
||||
certsDir: "secretsA",
|
||||
cacert: "ca1",
|
||||
cert: "cert1",
|
||||
key: "key1",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls IPv6 addresses",
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[2001:db8::1]:2379,http://[2001:db8::2]:2379"},
|
||||
},
|
||||
},
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[2001:db8::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
},
|
||||
{
|
||||
name: "valid IPv4 etcd probe using hostname for listen-client-urls",
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://localhost:2379"},
|
||||
},
|
||||
},
|
||||
port: 1,
|
||||
certsDir: "secretsC",
|
||||
cacert: "ca3",
|
||||
cert: "cert3",
|
||||
key: "key3",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[127.0.0.1]:1 --cacert=secretsC/ca3 --cert=secretsC/cert3 --key=secretsC/key3 get foo",
|
||||
expectedHostname: "127.0.0.1",
|
||||
expectedPort: kubeadmconstants.EtcdMetricsPort,
|
||||
expectedScheme: v1.URISchemeHTTP,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
t.Run(rt.name, func(t *testing.T) {
|
||||
actual := EtcdProbe(rt.cfg, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key)
|
||||
if actual.Handler.Exec.Command[2] != rt.expected {
|
||||
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
|
||||
rt.name, rt.expected,
|
||||
actual.Handler.Exec.Command[2])
|
||||
hostname, port, scheme := GetEtcdProbeEndpoint(rt.cfg)
|
||||
if hostname != rt.expectedHostname {
|
||||
t.Errorf("%q test case failed:\n\texpected hostname: %s\n\tgot: %s",
|
||||
rt.name, rt.expectedHostname, hostname)
|
||||
}
|
||||
if port != rt.expectedPort {
|
||||
t.Errorf("%q test case failed:\n\texpected port: %d\n\tgot: %d",
|
||||
rt.name, rt.expectedPort, port)
|
||||
}
|
||||
if scheme != rt.expectedScheme {
|
||||
t.Errorf("%q test case failed:\n\texpected scheme: %v\n\tgot: %v",
|
||||
rt.name, rt.expectedScheme, scheme)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user