2014-06-07 07:40:48 +08:00
/ *
Copyright 2014 Google Inc . All rights reserved .
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 .
* /
2014-06-24 02:32:11 +08:00
2014-06-07 07:40:48 +08:00
package main
import (
"flag"
2014-10-04 12:34:30 +08:00
"net"
2014-11-22 01:06:36 +08:00
"net/http"
"strconv"
2014-08-16 05:14:22 +08:00
"time"
2014-06-07 07:40:48 +08:00
2014-10-22 05:14:35 +08:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
2014-08-16 05:14:22 +08:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
2014-11-22 01:06:36 +08:00
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
2014-06-07 07:40:48 +08:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/proxy"
"github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/config"
2014-06-25 11:51:57 +08:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
2014-09-19 07:03:34 +08:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/iptables"
2014-08-30 14:19:32 +08:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/version/verflag"
2014-06-07 07:40:48 +08:00
"github.com/coreos/go-etcd/etcd"
2014-06-25 11:51:57 +08:00
"github.com/golang/glog"
2014-06-07 07:40:48 +08:00
)
var (
2014-07-20 22:48:47 +08:00
etcdServerList util . StringList
2014-09-26 09:11:01 +08:00
etcdConfigFile = flag . String ( "etcd_config" , "" , "The config file for the etcd client. Mutually exclusive with -etcd_servers" )
2014-10-04 12:34:30 +08:00
bindAddress = util . IP ( net . ParseIP ( "0.0.0.0" ) )
2014-09-30 08:15:00 +08:00
clientConfig = & client . Config { }
2014-11-22 01:06:36 +08:00
healthz_port = flag . Int ( "healthz_port" , 10249 , "The port to bind the health check server. Use 0 to disable." )
2014-06-07 07:40:48 +08:00
)
2014-07-20 22:48:47 +08:00
func init ( ) {
2014-09-30 08:15:00 +08:00
client . BindClientConfigFlags ( flag . CommandLine , clientConfig )
2014-09-26 09:11:01 +08:00
flag . Var ( & etcdServerList , "etcd_servers" , "List of etcd servers to watch (http://ip:port), comma separated (optional). Mutually exclusive with -etcd_config" )
2014-09-19 07:03:34 +08:00
flag . Var ( & bindAddress , "bind_address" , "The IP address for the proxy server to serve on (set to 0.0.0.0 for all interfaces)" )
2014-07-20 22:48:47 +08:00
}
2014-06-07 07:40:48 +08:00
func main ( ) {
flag . Parse ( )
2014-06-25 11:51:57 +08:00
util . InitLogs ( )
defer util . FlushLogs ( )
2014-06-07 07:40:48 +08:00
2014-08-01 13:55:44 +08:00
verflag . PrintAndExitIfRequested ( )
2014-07-31 06:21:34 +08:00
2014-07-09 00:55:11 +08:00
serviceConfig := config . NewServiceConfig ( )
endpointsConfig := config . NewEndpointsConfig ( )
2014-06-07 07:40:48 +08:00
2014-08-16 05:14:22 +08:00
// define api config source
2014-09-30 08:15:00 +08:00
if clientConfig . Host != "" {
glog . Infof ( "Using api calls to get config %v" , clientConfig . Host )
client , err := client . New ( clientConfig )
2014-08-28 21:56:38 +08:00
if err != nil {
2014-09-30 08:15:00 +08:00
glog . Fatalf ( "Invalid API configuration: %v" , err )
2014-08-28 21:56:38 +08:00
}
2014-08-16 05:14:22 +08:00
config . NewSourceAPI (
2014-10-22 05:14:35 +08:00
client . Services ( api . NamespaceAll ) ,
client . Endpoints ( api . NamespaceAll ) ,
2014-08-16 05:14:22 +08:00
30 * time . Second ,
serviceConfig . Channel ( "api" ) ,
endpointsConfig . Channel ( "api" ) ,
)
2014-09-26 09:11:01 +08:00
} else {
var etcdClient * etcd . Client
// Set up etcd client
if len ( etcdServerList ) > 0 {
// Set up logger for etcd client
etcd . SetLogger ( util . NewLogger ( "etcd " ) )
etcdClient = etcd . NewClient ( etcdServerList )
} else if * etcdConfigFile != "" {
// Set up logger for etcd client
etcd . SetLogger ( util . NewLogger ( "etcd " ) )
var err error
etcdClient , err = etcd . NewClientFromFile ( * etcdConfigFile )
if err != nil {
glog . Fatalf ( "Error with etcd config file: %v" , err )
}
}
2014-08-16 05:14:22 +08:00
2014-09-26 09:11:01 +08:00
// Create a configuration source that handles configuration from etcd.
if etcdClient != nil {
glog . Infof ( "Using etcd servers %v" , etcdClient . GetCluster ( ) )
2014-08-16 05:14:22 +08:00
2014-09-26 09:11:01 +08:00
config . NewConfigSourceEtcd ( etcdClient ,
serviceConfig . Channel ( "etcd" ) ,
endpointsConfig . Channel ( "etcd" ) )
}
2014-08-16 05:14:22 +08:00
}
2014-06-07 07:40:48 +08:00
2014-11-22 01:06:36 +08:00
if * healthz_port > 0 {
go util . Forever ( func ( ) {
err := http . ListenAndServe ( bindAddress . String ( ) + ":" + strconv . Itoa ( * healthz_port ) , nil )
if err != nil {
glog . Errorf ( "Starting health server failed: %v" , err )
}
} , 5 * time . Second )
}
2014-11-04 00:04:42 +08:00
protocol := iptables . ProtocolIpv4
if net . IP ( bindAddress ) . To4 ( ) == nil {
protocol = iptables . ProtocolIpv6
}
2014-06-07 07:40:48 +08:00
loadBalancer := proxy . NewLoadBalancerRR ( )
2014-11-04 00:04:42 +08:00
proxier := proxy . NewProxier ( loadBalancer , net . IP ( bindAddress ) , iptables . New ( exec . New ( ) , protocol ) )
2014-06-07 07:40:48 +08:00
// Wire proxier to handle changes to services
2014-07-09 00:55:11 +08:00
serviceConfig . RegisterHandler ( proxier )
2014-06-07 07:40:48 +08:00
// And wire loadBalancer to handle changes to endpoints to services
2014-07-09 00:55:11 +08:00
endpointsConfig . RegisterHandler ( loadBalancer )
2014-06-07 07:40:48 +08:00
// Just loop forever for now...
2014-09-19 07:03:34 +08:00
proxier . SyncLoop ( )
2014-06-07 07:40:48 +08:00
}