|
|
|
@@ -26,7 +26,6 @@ import (
|
|
|
|
|
"net/http"
|
|
|
|
|
"net/url"
|
|
|
|
|
"os"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
@@ -55,7 +54,6 @@ import (
|
|
|
|
|
clientgoclientset "k8s.io/client-go/kubernetes"
|
|
|
|
|
"k8s.io/client-go/rest"
|
|
|
|
|
"k8s.io/client-go/util/keyutil"
|
|
|
|
|
cloudprovider "k8s.io/cloud-provider"
|
|
|
|
|
cliflag "k8s.io/component-base/cli/flag"
|
|
|
|
|
"k8s.io/component-base/cli/globalflag"
|
|
|
|
|
_ "k8s.io/component-base/metrics/prometheus/workqueue" // for workqueue metric registration
|
|
|
|
@@ -71,8 +69,6 @@ import (
|
|
|
|
|
"k8s.io/kubernetes/pkg/capabilities"
|
|
|
|
|
"k8s.io/kubernetes/pkg/controlplane"
|
|
|
|
|
"k8s.io/kubernetes/pkg/controlplane/reconcilers"
|
|
|
|
|
"k8s.io/kubernetes/pkg/controlplane/tunneler"
|
|
|
|
|
"k8s.io/kubernetes/pkg/features"
|
|
|
|
|
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
|
|
|
|
|
"k8s.io/kubernetes/pkg/kubeapiserver"
|
|
|
|
|
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
|
|
|
@@ -186,19 +182,14 @@ func Run(completeOptions completedServerRunOptions, stopCh <-chan struct{}) erro
|
|
|
|
|
|
|
|
|
|
// CreateServerChain creates the apiservers connected via delegation.
|
|
|
|
|
func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan struct{}) (*aggregatorapiserver.APIAggregator, error) {
|
|
|
|
|
nodeTunneler, proxyTransport, err := CreateNodeDialer(completedOptions)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kubeAPIServerConfig, serviceResolver, pluginInitializer, err := CreateKubeAPIServerConfig(completedOptions, nodeTunneler, proxyTransport)
|
|
|
|
|
kubeAPIServerConfig, serviceResolver, pluginInitializer, err := CreateKubeAPIServerConfig(completedOptions)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If additional API servers are added, they should be gated.
|
|
|
|
|
apiExtensionsConfig, err := createAPIExtensionsConfig(*kubeAPIServerConfig.GenericConfig, kubeAPIServerConfig.ExtraConfig.VersionedInformers, pluginInitializer, completedOptions.ServerRunOptions, completedOptions.MasterCount,
|
|
|
|
|
serviceResolver, webhook.NewDefaultAuthenticationInfoResolverWrapper(proxyTransport, kubeAPIServerConfig.GenericConfig.EgressSelector, kubeAPIServerConfig.GenericConfig.LoopbackClientConfig))
|
|
|
|
|
serviceResolver, webhook.NewDefaultAuthenticationInfoResolverWrapper(kubeAPIServerConfig.ExtraConfig.ProxyTransport, kubeAPIServerConfig.GenericConfig.EgressSelector, kubeAPIServerConfig.GenericConfig.LoopbackClientConfig))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -213,7 +204,7 @@ func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// aggregator comes last in the chain
|
|
|
|
|
aggregatorConfig, err := createAggregatorConfig(*kubeAPIServerConfig.GenericConfig, completedOptions.ServerRunOptions, kubeAPIServerConfig.ExtraConfig.VersionedInformers, serviceResolver, proxyTransport, pluginInitializer)
|
|
|
|
|
aggregatorConfig, err := createAggregatorConfig(*kubeAPIServerConfig.GenericConfig, completedOptions.ServerRunOptions, kubeAPIServerConfig.ExtraConfig.VersionedInformers, serviceResolver, kubeAPIServerConfig.ExtraConfig.ProxyTransport, pluginInitializer)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -236,72 +227,27 @@ func CreateKubeAPIServer(kubeAPIServerConfig *controlplane.Config, delegateAPISe
|
|
|
|
|
return kubeAPIServer, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreateNodeDialer creates the dialer infrastructure to connect to the nodes.
|
|
|
|
|
func CreateNodeDialer(s completedServerRunOptions) (tunneler.Tunneler, *http.Transport, error) {
|
|
|
|
|
// Setup nodeTunneler if needed
|
|
|
|
|
var nodeTunneler tunneler.Tunneler
|
|
|
|
|
// CreateProxyTransport creates the dialer infrastructure to connect to the nodes.
|
|
|
|
|
func CreateProxyTransport() *http.Transport {
|
|
|
|
|
var proxyDialerFn utilnet.DialFunc
|
|
|
|
|
if len(s.SSHUser) > 0 {
|
|
|
|
|
// Get ssh key distribution func, if supported
|
|
|
|
|
var installSSHKey tunneler.InstallSSHKey
|
|
|
|
|
|
|
|
|
|
if utilfeature.DefaultFeatureGate.Enabled(features.DisableCloudProviders) && cloudprovider.IsDeprecatedInternal(s.CloudProvider.CloudProvider) {
|
|
|
|
|
cloudprovider.DisableWarningForProvider(s.CloudProvider.CloudProvider)
|
|
|
|
|
return nil, nil, fmt.Errorf("cloud provider %q and ssh-user %q was specified, but built-in cloud providers are disabled. "+
|
|
|
|
|
"Please set --cloud-provider=external and use an external network proxy, see https://github.com/kubernetes-sigs/apiserver-network-proxy",
|
|
|
|
|
s.CloudProvider.CloudProvider, s.SSHUser)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cloudprovider.DeprecationWarningForProvider(s.CloudProvider.CloudProvider)
|
|
|
|
|
cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider.CloudProvider, s.CloudProvider.CloudConfigFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, fmt.Errorf("cloud provider could not be initialized: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if cloud != nil {
|
|
|
|
|
if instances, supported := cloud.Instances(); supported {
|
|
|
|
|
installSSHKey = instances.AddSSHKeyToAllInstances
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if s.KubeletConfig.Port == 0 {
|
|
|
|
|
return nil, nil, fmt.Errorf("must enable kubelet port if proxy ssh-tunneling is specified")
|
|
|
|
|
}
|
|
|
|
|
if s.KubeletConfig.ReadOnlyPort == 0 {
|
|
|
|
|
return nil, nil, fmt.Errorf("must enable kubelet readonly port if proxy ssh-tunneling is specified")
|
|
|
|
|
}
|
|
|
|
|
// Set up the nodeTunneler
|
|
|
|
|
// TODO(cjcullen): If we want this to handle per-kubelet ports or other
|
|
|
|
|
// kubelet listen-addresses, we need to plumb through options.
|
|
|
|
|
healthCheckPath := &url.URL{
|
|
|
|
|
Scheme: "http",
|
|
|
|
|
Host: net.JoinHostPort("127.0.0.1", strconv.FormatUint(uint64(s.KubeletConfig.ReadOnlyPort), 10)),
|
|
|
|
|
Path: "healthz",
|
|
|
|
|
}
|
|
|
|
|
nodeTunneler = tunneler.New(s.SSHUser, s.SSHKeyfile, healthCheckPath, installSSHKey)
|
|
|
|
|
|
|
|
|
|
// Use the nodeTunneler's dialer when proxying to pods, services, and nodes
|
|
|
|
|
proxyDialerFn = nodeTunneler.Dial
|
|
|
|
|
}
|
|
|
|
|
// Proxying to pods and services is IP-based... don't expect to be able to verify the hostname
|
|
|
|
|
proxyTLSClientConfig := &tls.Config{InsecureSkipVerify: true}
|
|
|
|
|
proxyTransport := utilnet.SetTransportDefaults(&http.Transport{
|
|
|
|
|
DialContext: proxyDialerFn,
|
|
|
|
|
TLSClientConfig: proxyTLSClientConfig,
|
|
|
|
|
})
|
|
|
|
|
return nodeTunneler, proxyTransport, nil
|
|
|
|
|
return proxyTransport
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreateKubeAPIServerConfig creates all the resources for running the API server, but runs none of them
|
|
|
|
|
func CreateKubeAPIServerConfig(
|
|
|
|
|
s completedServerRunOptions,
|
|
|
|
|
nodeTunneler tunneler.Tunneler,
|
|
|
|
|
proxyTransport *http.Transport,
|
|
|
|
|
) (
|
|
|
|
|
func CreateKubeAPIServerConfig(s completedServerRunOptions) (
|
|
|
|
|
*controlplane.Config,
|
|
|
|
|
aggregatorapiserver.ServiceResolver,
|
|
|
|
|
[]admission.PluginInitializer,
|
|
|
|
|
error,
|
|
|
|
|
) {
|
|
|
|
|
proxyTransport := CreateProxyTransport()
|
|
|
|
|
|
|
|
|
|
genericConfig, versionedInformers, serviceResolver, pluginInitializers, admissionPostStartHook, storageFactory, err := buildGenericConfig(s.ServerRunOptions, proxyTransport)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, nil, err
|
|
|
|
@@ -339,8 +285,6 @@ func CreateKubeAPIServerConfig(
|
|
|
|
|
EnableLogsSupport: s.EnableLogsHandler,
|
|
|
|
|
ProxyTransport: proxyTransport,
|
|
|
|
|
|
|
|
|
|
Tunneler: nodeTunneler,
|
|
|
|
|
|
|
|
|
|
ServiceIPRange: s.PrimaryServiceClusterIPRange,
|
|
|
|
|
APIServerServiceIP: s.APIServerServiceIP,
|
|
|
|
|
SecondaryServiceIPRange: s.SecondaryServiceClusterIPRange,
|
|
|
|
@@ -386,10 +330,6 @@ func CreateKubeAPIServerConfig(
|
|
|
|
|
return nil, nil, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if nodeTunneler != nil {
|
|
|
|
|
// Use the nodeTunneler's dialer to connect to the kubelet
|
|
|
|
|
config.ExtraConfig.KubeletClientConfig.Dial = nodeTunneler.Dial
|
|
|
|
|
}
|
|
|
|
|
if config.GenericConfig.EgressSelector != nil {
|
|
|
|
|
// Use the config.GenericConfig.EgressSelector lookup to find the dialer to connect to the kubelet
|
|
|
|
|
config.ExtraConfig.KubeletClientConfig.Lookup = config.GenericConfig.EgressSelector.Lookup
|
|
|
|
|