2015-02-02 21:54:52 +00:00
|
|
|
/*
|
2015-05-01 16:19:44 +00:00
|
|
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
2015-02-02 21:54:52 +00:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2015-02-07 21:55:35 +00:00
|
|
|
// Package app does all of the work necessary to configure and run a
|
|
|
|
// Kubernetes app process.
|
|
|
|
package app
|
2015-02-02 21:54:52 +00:00
|
|
|
|
|
|
|
import (
|
2015-08-20 17:01:37 +00:00
|
|
|
"errors"
|
2015-02-02 21:54:52 +00:00
|
|
|
"net/http"
|
2015-03-30 19:00:21 +00:00
|
|
|
_ "net/http/pprof"
|
2015-02-02 21:54:52 +00:00
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
|
2015-12-25 00:27:57 +00:00
|
|
|
"k8s.io/kubernetes/cmd/kube-proxy/app/options"
|
2015-08-09 18:07:36 +00:00
|
|
|
"k8s.io/kubernetes/pkg/api"
|
2015-09-03 21:43:19 +00:00
|
|
|
"k8s.io/kubernetes/pkg/client/record"
|
2015-09-21 10:05:22 +00:00
|
|
|
kubeclient "k8s.io/kubernetes/pkg/client/unversioned"
|
2015-08-13 19:01:50 +00:00
|
|
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
|
|
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
2015-08-11 02:47:13 +00:00
|
|
|
"k8s.io/kubernetes/pkg/proxy"
|
2015-09-21 10:05:22 +00:00
|
|
|
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
|
2015-08-11 02:47:13 +00:00
|
|
|
"k8s.io/kubernetes/pkg/proxy/iptables"
|
2015-08-08 00:07:15 +00:00
|
|
|
"k8s.io/kubernetes/pkg/proxy/userspace"
|
2015-08-09 18:07:36 +00:00
|
|
|
"k8s.io/kubernetes/pkg/types"
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/util"
|
2015-08-14 16:36:15 +00:00
|
|
|
utildbus "k8s.io/kubernetes/pkg/util/dbus"
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/util/exec"
|
2015-08-11 02:47:13 +00:00
|
|
|
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
|
2015-08-09 18:07:36 +00:00
|
|
|
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
2015-08-04 00:28:33 +00:00
|
|
|
"k8s.io/kubernetes/pkg/util/oom"
|
2015-02-02 21:54:52 +00:00
|
|
|
|
|
|
|
"github.com/golang/glog"
|
2015-10-12 14:33:39 +00:00
|
|
|
"github.com/spf13/cobra"
|
2015-02-02 21:54:52 +00:00
|
|
|
"github.com/spf13/pflag"
|
|
|
|
)
|
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
type ProxyServer struct {
|
2015-09-01 13:35:38 +00:00
|
|
|
Client *kubeclient.Client
|
2015-12-25 00:27:57 +00:00
|
|
|
Config *options.ProxyServerConfig
|
2015-10-01 22:22:32 +00:00
|
|
|
IptInterface utiliptables.Interface
|
|
|
|
Proxier proxy.ProxyProvider
|
2015-09-01 13:35:38 +00:00
|
|
|
Broadcaster record.EventBroadcaster
|
2015-10-01 22:22:32 +00:00
|
|
|
Recorder record.EventRecorder
|
2015-12-29 23:37:33 +00:00
|
|
|
Conntracker Conntracker // if nil, ignored
|
2015-02-02 21:54:52 +00:00
|
|
|
}
|
|
|
|
|
2015-09-21 21:25:57 +00:00
|
|
|
const (
|
|
|
|
proxyModeUserspace = "userspace"
|
|
|
|
proxyModeIptables = "iptables"
|
2015-12-25 00:27:57 +00:00
|
|
|
experimentalProxyModeAnnotation = options.ExperimentalProxyModeAnnotation
|
2015-10-09 23:52:23 +00:00
|
|
|
betaProxyModeAnnotation = "net.beta.kubernetes.io/proxy-mode"
|
2015-09-21 21:25:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func checkKnownProxyMode(proxyMode string) bool {
|
|
|
|
switch proxyMode {
|
|
|
|
case "", proxyModeUserspace, proxyModeIptables:
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
func NewProxyServer(
|
2015-09-01 13:35:38 +00:00
|
|
|
client *kubeclient.Client,
|
2015-12-25 00:27:57 +00:00
|
|
|
config *options.ProxyServerConfig,
|
2015-09-21 10:05:22 +00:00
|
|
|
iptInterface utiliptables.Interface,
|
|
|
|
proxier proxy.ProxyProvider,
|
2015-09-01 13:35:38 +00:00
|
|
|
broadcaster record.EventBroadcaster,
|
2015-09-21 10:05:22 +00:00
|
|
|
recorder record.EventRecorder,
|
2015-12-29 23:37:33 +00:00
|
|
|
conntracker Conntracker,
|
2015-09-21 10:05:22 +00:00
|
|
|
) (*ProxyServer, error) {
|
|
|
|
return &ProxyServer{
|
2015-09-01 13:35:38 +00:00
|
|
|
Client: client,
|
2015-10-01 22:22:32 +00:00
|
|
|
Config: config,
|
|
|
|
IptInterface: iptInterface,
|
|
|
|
Proxier: proxier,
|
2015-09-01 13:35:38 +00:00
|
|
|
Broadcaster: broadcaster,
|
2015-10-01 22:22:32 +00:00
|
|
|
Recorder: recorder,
|
2015-12-29 23:37:33 +00:00
|
|
|
Conntracker: conntracker,
|
2015-09-21 10:05:22 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2015-10-12 14:33:39 +00:00
|
|
|
// NewProxyCommand creates a *cobra.Command object with default parameters
|
|
|
|
func NewProxyCommand() *cobra.Command {
|
2015-12-25 00:27:57 +00:00
|
|
|
s := options.NewProxyConfig()
|
2015-10-12 14:33:39 +00:00
|
|
|
s.AddFlags(pflag.CommandLine)
|
|
|
|
cmd := &cobra.Command{
|
|
|
|
Use: "kube-proxy",
|
|
|
|
Long: `The Kubernetes network proxy runs on each node. This
|
|
|
|
reflects services as defined in the Kubernetes API on each node and can do simple
|
|
|
|
TCP,UDP stream forwarding or round robin TCP,UDP forwarding across a set of backends.
|
|
|
|
Service cluster ips and ports are currently found through Docker-links-compatible
|
|
|
|
environment variables specifying ports opened by the service proxy. There is an optional
|
|
|
|
addon that provides cluster DNS for these cluster IPs. The user must create a service
|
|
|
|
with the apiserver API to configure the proxy.`,
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
return cmd
|
|
|
|
}
|
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
// NewProxyServerDefault creates a new ProxyServer object with default parameters.
|
2015-12-25 00:27:57 +00:00
|
|
|
func NewProxyServerDefault(config *options.ProxyServerConfig) (*ProxyServer, error) {
|
2015-08-20 17:01:37 +00:00
|
|
|
protocol := utiliptables.ProtocolIpv4
|
2015-09-21 10:05:22 +00:00
|
|
|
if config.BindAddress.To4() == nil {
|
2015-08-20 17:01:37 +00:00
|
|
|
protocol = utiliptables.ProtocolIpv6
|
|
|
|
}
|
|
|
|
|
2015-09-29 02:08:38 +00:00
|
|
|
// Create a iptables utils.
|
|
|
|
execer := exec.New()
|
|
|
|
dbus := utildbus.New()
|
|
|
|
iptInterface := utiliptables.New(execer, dbus, protocol)
|
|
|
|
|
2015-12-29 23:37:33 +00:00
|
|
|
// We omit creation of pretty much everything if we run in cleanup mode
|
2015-09-21 10:05:22 +00:00
|
|
|
if config.CleanupAndExit {
|
|
|
|
return &ProxyServer{
|
2015-10-01 03:13:13 +00:00
|
|
|
Config: config,
|
2015-09-29 02:08:38 +00:00
|
|
|
IptInterface: iptInterface,
|
2015-09-21 10:05:22 +00:00
|
|
|
}, nil
|
2015-08-20 17:01:37 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 16:49:13 +00:00
|
|
|
// TODO(vmarmol): Use container config for this.
|
2015-09-28 08:00:43 +00:00
|
|
|
var oomAdjuster *oom.OOMAdjuster
|
2015-09-21 10:05:22 +00:00
|
|
|
if config.OOMScoreAdj != 0 {
|
2015-09-29 02:08:38 +00:00
|
|
|
oomAdjuster = oom.NewOOMAdjuster()
|
2015-09-28 08:00:43 +00:00
|
|
|
if err := oomAdjuster.ApplyOOMScoreAdj(0, config.OOMScoreAdj); err != nil {
|
2015-09-21 10:05:22 +00:00
|
|
|
glog.V(2).Info(err)
|
|
|
|
}
|
2015-02-02 21:54:52 +00:00
|
|
|
}
|
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
if config.ResourceContainer != "" {
|
|
|
|
// Run in its own container.
|
|
|
|
if err := util.RunInResourceContainer(config.ResourceContainer); err != nil {
|
|
|
|
glog.Warningf("Failed to start in resource-only container %q: %v", config.ResourceContainer, err)
|
|
|
|
} else {
|
|
|
|
glog.V(2).Infof("Running in resource-only container %q", config.ResourceContainer)
|
|
|
|
}
|
2015-04-14 16:49:13 +00:00
|
|
|
}
|
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
// Create a Kube Client
|
2015-08-09 18:07:36 +00:00
|
|
|
// define api config source
|
2015-09-21 10:05:22 +00:00
|
|
|
if config.Kubeconfig == "" && config.Master == "" {
|
2015-08-09 18:07:36 +00:00
|
|
|
glog.Warningf("Neither --kubeconfig nor --master was specified. Using default API client. This might not work.")
|
|
|
|
}
|
|
|
|
// This creates a client, first loading any specified kubeconfig
|
|
|
|
// file, and then overriding the Master flag, if non-empty.
|
|
|
|
kubeconfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
2015-09-21 10:05:22 +00:00
|
|
|
&clientcmd.ClientConfigLoadingRules{ExplicitPath: config.Kubeconfig},
|
|
|
|
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: config.Master}}).ClientConfig()
|
2015-08-09 18:07:36 +00:00
|
|
|
if err != nil {
|
2015-09-21 10:05:22 +00:00
|
|
|
return nil, err
|
2015-08-09 18:07:36 +00:00
|
|
|
}
|
2015-10-12 15:56:15 +00:00
|
|
|
|
|
|
|
// Override kubeconfig qps/burst settings from flags
|
2015-10-20 12:33:48 +00:00
|
|
|
kubeconfig.QPS = config.KubeAPIQPS
|
|
|
|
kubeconfig.Burst = config.KubeAPIBurst
|
2015-10-12 15:56:15 +00:00
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
client, err := kubeclient.New(kubeconfig)
|
2015-08-09 18:07:36 +00:00
|
|
|
if err != nil {
|
|
|
|
glog.Fatalf("Invalid API configuration: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
// Create event recorder
|
|
|
|
hostname := nodeutil.GetHostname(config.HostnameOverride)
|
2015-08-09 18:07:36 +00:00
|
|
|
eventBroadcaster := record.NewBroadcaster()
|
2015-09-21 10:05:22 +00:00
|
|
|
recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "kube-proxy", Host: hostname})
|
2015-08-09 18:07:36 +00:00
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
var proxier proxy.ProxyProvider
|
|
|
|
var endpointsHandler proxyconfig.EndpointsConfigHandler
|
2015-09-21 21:25:57 +00:00
|
|
|
|
2015-10-27 06:08:37 +00:00
|
|
|
proxyMode := getProxyMode(config.ProxyMode, client.Nodes(), hostname, iptInterface)
|
|
|
|
if proxyMode == proxyModeIptables {
|
2015-08-11 02:47:13 +00:00
|
|
|
glog.V(2).Info("Using iptables Proxier.")
|
2015-10-15 01:48:35 +00:00
|
|
|
proxierIptables, err := iptables.NewProxier(iptInterface, execer, config.IptablesSyncPeriod, config.MasqueradeAll)
|
2015-08-11 02:47:13 +00:00
|
|
|
if err != nil {
|
|
|
|
glog.Fatalf("Unable to create proxier: %v", err)
|
|
|
|
}
|
|
|
|
proxier = proxierIptables
|
|
|
|
endpointsHandler = proxierIptables
|
2015-08-20 17:01:37 +00:00
|
|
|
// No turning back. Remove artifacts that might still exist from the userspace Proxier.
|
|
|
|
glog.V(2).Info("Tearing down userspace rules. Errors here are acceptable.")
|
2015-09-21 10:05:22 +00:00
|
|
|
userspace.CleanupLeftovers(iptInterface)
|
2015-08-11 02:47:13 +00:00
|
|
|
} else {
|
|
|
|
glog.V(2).Info("Using userspace Proxier.")
|
|
|
|
// This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for
|
|
|
|
// our config.EndpointsConfigHandler.
|
|
|
|
loadBalancer := userspace.NewLoadBalancerRR()
|
|
|
|
// set EndpointsConfigHandler to our loadBalancer
|
|
|
|
endpointsHandler = loadBalancer
|
|
|
|
|
2015-10-16 21:52:58 +00:00
|
|
|
proxierUserspace, err := userspace.NewProxier(loadBalancer, config.BindAddress, iptInterface, config.PortRange, config.IptablesSyncPeriod, config.UDPIdleTimeout)
|
2015-08-11 02:47:13 +00:00
|
|
|
if err != nil {
|
2015-09-08 18:03:45 +00:00
|
|
|
glog.Fatalf("Unable to create proxier: %v", err)
|
2015-08-11 02:47:13 +00:00
|
|
|
}
|
|
|
|
proxier = proxierUserspace
|
2015-08-20 17:01:37 +00:00
|
|
|
// Remove artifacts from the pure-iptables Proxier.
|
|
|
|
glog.V(2).Info("Tearing down pure-iptables proxy rules. Errors here are acceptable.")
|
2015-09-21 10:05:22 +00:00
|
|
|
iptables.CleanupLeftovers(iptInterface)
|
2015-02-02 21:54:52 +00:00
|
|
|
}
|
2015-09-21 10:05:22 +00:00
|
|
|
iptInterface.AddReloadFunc(proxier.Sync)
|
2015-02-02 21:54:52 +00:00
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
// Create configs (i.e. Watches for Services and Endpoints)
|
2015-02-02 21:54:52 +00:00
|
|
|
// Note: RegisterHandler() calls need to happen before creation of Sources because sources
|
|
|
|
// only notify on changes, and the initial update (on process start) may be lost if no handlers
|
|
|
|
// are registered yet.
|
2015-09-21 10:05:22 +00:00
|
|
|
serviceConfig := proxyconfig.NewServiceConfig()
|
|
|
|
serviceConfig.RegisterHandler(proxier)
|
2015-02-02 21:54:52 +00:00
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
endpointsConfig := proxyconfig.NewEndpointsConfig()
|
|
|
|
endpointsConfig.RegisterHandler(endpointsHandler)
|
|
|
|
|
|
|
|
proxyconfig.NewSourceAPI(
|
2015-06-28 19:28:10 +00:00
|
|
|
client,
|
2015-10-15 01:48:35 +00:00
|
|
|
config.ConfigSyncPeriod,
|
2015-04-17 07:18:07 +00:00
|
|
|
serviceConfig.Channel("api"),
|
|
|
|
endpointsConfig.Channel("api"),
|
|
|
|
)
|
|
|
|
|
2015-09-01 13:35:38 +00:00
|
|
|
config.NodeRef = &api.ObjectReference{
|
2015-09-21 10:05:22 +00:00
|
|
|
Kind: "Node",
|
|
|
|
Name: hostname,
|
|
|
|
UID: types.UID(hostname),
|
|
|
|
Namespace: "",
|
|
|
|
}
|
2015-12-29 23:37:33 +00:00
|
|
|
|
|
|
|
conntracker := realConntracker{}
|
|
|
|
|
|
|
|
return NewProxyServer(client, config, iptInterface, proxier, eventBroadcaster, recorder, conntracker)
|
2015-09-21 10:05:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Run runs the specified ProxyServer. This should never exit (unless CleanupAndExit is set).
|
2015-12-25 00:27:57 +00:00
|
|
|
func (s *ProxyServer) Run() error {
|
2015-09-21 10:05:22 +00:00
|
|
|
// remove iptables rules and exit
|
|
|
|
if s.Config.CleanupAndExit {
|
|
|
|
encounteredError := userspace.CleanupLeftovers(s.IptInterface)
|
|
|
|
encounteredError = iptables.CleanupLeftovers(s.IptInterface) || encounteredError
|
|
|
|
if encounteredError {
|
|
|
|
return errors.New("Encountered an error while tearing down rules.")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-09-01 13:35:38 +00:00
|
|
|
s.Broadcaster.StartRecordingToSink(s.Client.Events(""))
|
|
|
|
|
2015-09-21 10:05:22 +00:00
|
|
|
// Start up Healthz service if requested
|
|
|
|
if s.Config.HealthzPort > 0 {
|
2015-08-24 01:59:15 +00:00
|
|
|
go util.Until(func() {
|
2015-09-21 10:05:22 +00:00
|
|
|
err := http.ListenAndServe(s.Config.HealthzBindAddress.String()+":"+strconv.Itoa(s.Config.HealthzPort), nil)
|
2015-02-02 21:54:52 +00:00
|
|
|
if err != nil {
|
|
|
|
glog.Errorf("Starting health server failed: %v", err)
|
|
|
|
}
|
2015-08-24 01:59:15 +00:00
|
|
|
}, 5*time.Second, util.NeverStop)
|
2015-02-02 21:54:52 +00:00
|
|
|
}
|
|
|
|
|
2015-12-29 23:37:33 +00:00
|
|
|
// Tune conntrack, if requested
|
|
|
|
if s.Conntracker != nil {
|
|
|
|
if s.Config.ConntrackMax > 0 {
|
|
|
|
if err := s.Conntracker.SetMax(s.Config.ConntrackMax); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if s.Config.ConntrackTCPTimeoutEstablished > 0 {
|
|
|
|
if err := s.Conntracker.SetTCPEstablishedTimeout(s.Config.ConntrackTCPTimeoutEstablished); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Birth Cry after the birth is successful
|
|
|
|
s.birthCry()
|
|
|
|
|
2015-02-02 21:54:52 +00:00
|
|
|
// Just loop forever for now...
|
2015-09-21 10:05:22 +00:00
|
|
|
s.Proxier.SyncLoop()
|
2015-02-02 21:54:52 +00:00
|
|
|
return nil
|
|
|
|
}
|
2015-08-09 18:07:36 +00:00
|
|
|
|
2015-09-21 21:25:57 +00:00
|
|
|
type nodeGetter interface {
|
|
|
|
Get(hostname string) (*api.Node, error)
|
|
|
|
}
|
|
|
|
|
2015-10-27 06:08:37 +00:00
|
|
|
func getProxyMode(proxyMode string, client nodeGetter, hostname string, iptver iptables.IptablesVersioner) string {
|
|
|
|
if proxyMode == proxyModeUserspace {
|
|
|
|
return proxyModeUserspace
|
|
|
|
} else if proxyMode == proxyModeIptables {
|
|
|
|
return tryIptablesProxy(iptver)
|
2015-09-21 21:25:57 +00:00
|
|
|
} else if proxyMode != "" {
|
2015-10-27 06:08:37 +00:00
|
|
|
glog.V(1).Infof("Flag proxy-mode=%q unknown, assuming iptables proxy", proxyMode)
|
|
|
|
return tryIptablesProxy(iptver)
|
2015-09-21 21:25:57 +00:00
|
|
|
}
|
|
|
|
// proxyMode == "" - choose the best option.
|
|
|
|
if client == nil {
|
2015-10-27 06:08:37 +00:00
|
|
|
glog.Errorf("nodeGetter is nil: assuming iptables proxy")
|
|
|
|
return tryIptablesProxy(iptver)
|
2015-09-21 21:25:57 +00:00
|
|
|
}
|
|
|
|
node, err := client.Get(hostname)
|
|
|
|
if err != nil {
|
2015-10-27 06:08:37 +00:00
|
|
|
glog.Errorf("Can't get Node %q, assuming iptables proxy: %v", hostname, err)
|
|
|
|
return tryIptablesProxy(iptver)
|
2015-09-21 21:25:57 +00:00
|
|
|
}
|
|
|
|
if node == nil {
|
2015-10-27 06:08:37 +00:00
|
|
|
glog.Errorf("Got nil Node %q, assuming iptables proxy: %v", hostname)
|
|
|
|
return tryIptablesProxy(iptver)
|
2015-09-21 21:25:57 +00:00
|
|
|
}
|
2015-10-09 23:52:23 +00:00
|
|
|
proxyMode, found := node.Annotations[betaProxyModeAnnotation]
|
2015-09-21 21:25:57 +00:00
|
|
|
if found {
|
2015-10-09 23:52:23 +00:00
|
|
|
glog.V(1).Infof("Found beta annotation %q = %q", betaProxyModeAnnotation, proxyMode)
|
|
|
|
} else {
|
|
|
|
// We already published some information about this annotation with the "experimental" name, so we will respect it.
|
|
|
|
proxyMode, found = node.Annotations[experimentalProxyModeAnnotation]
|
|
|
|
if found {
|
|
|
|
glog.V(1).Infof("Found experimental annotation %q = %q", experimentalProxyModeAnnotation, proxyMode)
|
|
|
|
}
|
2015-09-21 21:25:57 +00:00
|
|
|
}
|
2015-10-27 06:08:37 +00:00
|
|
|
if proxyMode == proxyModeUserspace {
|
|
|
|
glog.V(1).Infof("Annotation demands userspace proxy")
|
|
|
|
return proxyModeUserspace
|
2015-09-21 21:25:57 +00:00
|
|
|
}
|
2015-10-27 06:08:37 +00:00
|
|
|
return tryIptablesProxy(iptver)
|
|
|
|
}
|
|
|
|
|
|
|
|
func tryIptablesProxy(iptver iptables.IptablesVersioner) string {
|
|
|
|
var err error
|
|
|
|
// guaranteed false on error, error only necessary for debugging
|
|
|
|
useIptablesProxy, err := iptables.CanUseIptablesProxier(iptver)
|
|
|
|
if err != nil {
|
|
|
|
glog.Errorf("Can't determine whether to use iptables proxy, using userspace proxier: %v", err)
|
|
|
|
return proxyModeUserspace
|
|
|
|
}
|
|
|
|
if useIptablesProxy {
|
|
|
|
return proxyModeIptables
|
|
|
|
}
|
|
|
|
// Fallback.
|
|
|
|
glog.V(1).Infof("Can't use iptables proxy, using userspace proxier: %v", err)
|
|
|
|
return proxyModeUserspace
|
2015-09-21 21:25:57 +00:00
|
|
|
}
|
|
|
|
|
2015-08-09 18:07:36 +00:00
|
|
|
func (s *ProxyServer) birthCry() {
|
2015-11-13 22:30:01 +00:00
|
|
|
s.Recorder.Eventf(s.Config.NodeRef, api.EventTypeNormal, "Starting", "Starting kube-proxy.")
|
2015-08-09 18:07:36 +00:00
|
|
|
}
|