Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
596527da
Commit
596527da
authored
Mar 17, 2017
by
Wojciech Tyczynski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify proxy config for Endpoints by removing Mux.
parent
8d7ba2be
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
171 additions
and
239 deletions
+171
-239
server.go
cmd/kube-proxy/app/server.go
+2
-2
hollow-node.go
cmd/kubemark/hollow-node.go
+2
-1
BUILD
pkg/kubemark/BUILD
+1
-0
hollow_proxy.go
pkg/kubemark/hollow_proxy.go
+3
-1
BUILD
pkg/proxy/config/BUILD
+2
-0
api.go
pkg/proxy/config/api.go
+3
-69
api_test.go
pkg/proxy/config/api_test.go
+27
-54
config.go
pkg/proxy/config/config.go
+81
-75
config_test.go
pkg/proxy/config/config_test.go
+50
-37
No files found.
cmd/kube-proxy/app/server.go
View file @
596527da
...
@@ -308,14 +308,14 @@ func NewProxyServerDefault(config *options.ProxyServerConfig) (*ProxyServer, err
...
@@ -308,14 +308,14 @@ func NewProxyServerDefault(config *options.ProxyServerConfig) (*ProxyServer, err
serviceConfig
:=
proxyconfig
.
NewServiceConfig
()
serviceConfig
:=
proxyconfig
.
NewServiceConfig
()
serviceConfig
.
RegisterHandler
(
proxier
)
serviceConfig
.
RegisterHandler
(
proxier
)
endpointsConfig
:=
proxyconfig
.
NewEndpointsConfig
()
endpointsConfig
:=
proxyconfig
.
NewEndpointsConfig
(
client
.
Core
()
.
RESTClient
(),
config
.
ConfigSyncPeriod
)
endpointsConfig
.
RegisterHandler
(
endpointsHandler
)
endpointsConfig
.
RegisterHandler
(
endpointsHandler
)
go
endpointsConfig
.
Run
(
wait
.
NeverStop
)
proxyconfig
.
NewSourceAPI
(
proxyconfig
.
NewSourceAPI
(
client
.
Core
()
.
RESTClient
(),
client
.
Core
()
.
RESTClient
(),
config
.
ConfigSyncPeriod
,
config
.
ConfigSyncPeriod
,
serviceConfig
.
Channel
(
"api"
),
serviceConfig
.
Channel
(
"api"
),
endpointsConfig
.
Channel
(
"api"
),
)
)
config
.
NodeRef
=
&
clientv1
.
ObjectReference
{
config
.
NodeRef
=
&
clientv1
.
ObjectReference
{
...
...
cmd/kubemark/hollow-node.go
View file @
596527da
...
@@ -18,6 +18,7 @@ package main
...
@@ -18,6 +18,7 @@ package main
import
(
import
(
"fmt"
"fmt"
"time"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/util/flag"
"k8s.io/apiserver/pkg/util/flag"
...
@@ -138,7 +139,7 @@ func main() {
...
@@ -138,7 +139,7 @@ func main() {
serviceConfig
:=
proxyconfig
.
NewServiceConfig
()
serviceConfig
:=
proxyconfig
.
NewServiceConfig
()
serviceConfig
.
RegisterHandler
(
&
kubemark
.
FakeProxyHandler
{})
serviceConfig
.
RegisterHandler
(
&
kubemark
.
FakeProxyHandler
{})
endpointsConfig
:=
proxyconfig
.
NewEndpointsConfig
()
endpointsConfig
:=
proxyconfig
.
NewEndpointsConfig
(
internalClientset
.
Core
()
.
RESTClient
(),
15
*
time
.
Minute
)
endpointsConfig
.
RegisterHandler
(
&
kubemark
.
FakeProxyHandler
{})
endpointsConfig
.
RegisterHandler
(
&
kubemark
.
FakeProxyHandler
{})
eventClient
,
err
:=
clientgoclientset
.
NewForConfig
(
clientConfig
)
eventClient
,
err
:=
clientgoclientset
.
NewForConfig
(
clientConfig
)
...
...
pkg/kubemark/BUILD
View file @
596527da
...
@@ -41,6 +41,7 @@ go_library(
...
@@ -41,6 +41,7 @@ go_library(
"//vendor:github.com/golang/glog",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/client-go/kubernetes/typed/core/v1",
"//vendor:k8s.io/client-go/kubernetes/typed/core/v1",
"//vendor:k8s.io/client-go/pkg/api/v1",
"//vendor:k8s.io/client-go/pkg/api/v1",
"//vendor:k8s.io/client-go/tools/record",
"//vendor:k8s.io/client-go/tools/record",
...
...
pkg/kubemark/hollow_proxy.go
View file @
596527da
...
@@ -20,6 +20,7 @@ import (
...
@@ -20,6 +20,7 @@ import (
"time"
"time"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
v1core
"k8s.io/client-go/kubernetes/typed/core/v1"
v1core
"k8s.io/client-go/kubernetes/typed/core/v1"
clientv1
"k8s.io/client-go/pkg/api/v1"
clientv1
"k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/tools/record"
...
@@ -71,11 +72,12 @@ func NewHollowProxyOrDie(
...
@@ -71,11 +72,12 @@ func NewHollowProxyOrDie(
UID
:
types
.
UID
(
nodeName
),
UID
:
types
.
UID
(
nodeName
),
Namespace
:
""
,
Namespace
:
""
,
}
}
go
endpointsConfig
.
Run
(
wait
.
NeverStop
)
proxyconfig
.
NewSourceAPI
(
proxyconfig
.
NewSourceAPI
(
client
.
Core
()
.
RESTClient
(),
client
.
Core
()
.
RESTClient
(),
15
*
time
.
Minute
,
15
*
time
.
Minute
,
serviceConfig
.
Channel
(
"api"
),
serviceConfig
.
Channel
(
"api"
),
endpointsConfig
.
Channel
(
"api"
),
)
)
hollowProxy
,
err
:=
proxyapp
.
NewProxyServer
(
client
,
eventClient
,
config
,
iptInterface
,
&
FakeProxier
{},
broadcaster
,
recorder
,
nil
,
"fake"
)
hollowProxy
,
err
:=
proxyapp
.
NewProxyServer
(
client
,
eventClient
,
config
,
iptInterface
,
&
FakeProxier
{},
broadcaster
,
recorder
,
nil
,
"fake"
)
...
...
pkg/proxy/config/BUILD
View file @
596527da
...
@@ -18,11 +18,13 @@ go_library(
...
@@ -18,11 +18,13 @@ go_library(
tags = ["automanaged"],
tags = ["automanaged"],
deps = [
deps = [
"//pkg/api:go_default_library",
"//pkg/api:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/util/config:go_default_library",
"//pkg/util/config:go_default_library",
"//vendor:github.com/davecgh/go-spew/spew",
"//vendor:github.com/davecgh/go-spew/spew",
"//vendor:github.com/golang/glog",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/fields",
"//vendor:k8s.io/apimachinery/pkg/fields",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
...
...
pkg/proxy/config/api.go
View file @
596527da
...
@@ -29,31 +29,24 @@ import (
...
@@ -29,31 +29,24 @@ import (
)
)
// NewSourceAPI creates config source that watches for changes to the services and endpoints.
// NewSourceAPI creates config source that watches for changes to the services and endpoints.
func
NewSourceAPI
(
c
cache
.
Getter
,
period
time
.
Duration
,
servicesChan
chan
<-
ServiceUpdate
,
endpointsChan
chan
<-
EndpointsUpdate
)
{
func
NewSourceAPI
(
c
cache
.
Getter
,
period
time
.
Duration
,
servicesChan
chan
<-
ServiceUpdate
)
{
servicesLW
:=
cache
.
NewListWatchFromClient
(
c
,
"services"
,
metav1
.
NamespaceAll
,
fields
.
Everything
())
servicesLW
:=
cache
.
NewListWatchFromClient
(
c
,
"services"
,
metav1
.
NamespaceAll
,
fields
.
Everything
())
endpointsLW
:=
cache
.
NewListWatchFromClient
(
c
,
"endpoints"
,
metav1
.
NamespaceAll
,
fields
.
Everything
())
newSourceAPI
(
servicesLW
,
period
,
servicesChan
,
wait
.
NeverStop
)
newSourceAPI
(
servicesLW
,
endpointsLW
,
period
,
servicesChan
,
endpointsChan
,
wait
.
NeverStop
)
}
}
func
newSourceAPI
(
func
newSourceAPI
(
servicesLW
cache
.
ListerWatcher
,
servicesLW
cache
.
ListerWatcher
,
endpointsLW
cache
.
ListerWatcher
,
period
time
.
Duration
,
period
time
.
Duration
,
servicesChan
chan
<-
ServiceUpdate
,
servicesChan
chan
<-
ServiceUpdate
,
endpointsChan
chan
<-
EndpointsUpdate
,
stopCh
<-
chan
struct
{})
{
stopCh
<-
chan
struct
{})
{
serviceController
:=
NewServiceController
(
servicesLW
,
period
,
servicesChan
)
serviceController
:=
NewServiceController
(
servicesLW
,
period
,
servicesChan
)
go
serviceController
.
Run
(
stopCh
)
go
serviceController
.
Run
(
stopCh
)
endpointsController
:=
NewEndpointsController
(
endpointsLW
,
period
,
endpointsChan
)
if
!
cache
.
WaitForCacheSync
(
stopCh
,
serviceController
.
HasSynced
)
{
go
endpointsController
.
Run
(
stopCh
)
if
!
cache
.
WaitForCacheSync
(
stopCh
,
serviceController
.
HasSynced
,
endpointsController
.
HasSynced
)
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"source controllers not synced"
))
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"source controllers not synced"
))
return
return
}
}
servicesChan
<-
ServiceUpdate
{
Op
:
SYNCED
}
servicesChan
<-
ServiceUpdate
{
Op
:
SYNCED
}
endpointsChan
<-
EndpointsUpdate
{
Op
:
SYNCED
}
}
}
func
sendAddService
(
servicesChan
chan
<-
ServiceUpdate
)
func
(
obj
interface
{})
{
func
sendAddService
(
servicesChan
chan
<-
ServiceUpdate
)
func
(
obj
interface
{})
{
...
@@ -99,49 +92,6 @@ func sendDeleteService(servicesChan chan<- ServiceUpdate) func(obj interface{})
...
@@ -99,49 +92,6 @@ func sendDeleteService(servicesChan chan<- ServiceUpdate) func(obj interface{})
}
}
}
}
func
sendAddEndpoints
(
endpointsChan
chan
<-
EndpointsUpdate
)
func
(
obj
interface
{})
{
return
func
(
obj
interface
{})
{
endpoints
,
ok
:=
obj
.
(
*
api
.
Endpoints
)
if
!
ok
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"cannot convert to *api.Endpoints: %v"
,
obj
))
return
}
endpointsChan
<-
EndpointsUpdate
{
Op
:
ADD
,
Endpoints
:
endpoints
}
}
}
func
sendUpdateEndpoints
(
endpointsChan
chan
<-
EndpointsUpdate
)
func
(
oldObj
,
newObj
interface
{})
{
return
func
(
_
,
newObj
interface
{})
{
endpoints
,
ok
:=
newObj
.
(
*
api
.
Endpoints
)
if
!
ok
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"cannot convert to *api.Endpoints: %v"
,
newObj
))
return
}
endpointsChan
<-
EndpointsUpdate
{
Op
:
UPDATE
,
Endpoints
:
endpoints
}
}
}
func
sendDeleteEndpoints
(
endpointsChan
chan
<-
EndpointsUpdate
)
func
(
obj
interface
{})
{
return
func
(
obj
interface
{})
{
var
endpoints
*
api
.
Endpoints
switch
t
:=
obj
.
(
type
)
{
case
*
api
.
Endpoints
:
endpoints
=
t
case
cache
.
DeletedFinalStateUnknown
:
var
ok
bool
endpoints
,
ok
=
t
.
Obj
.
(
*
api
.
Endpoints
)
if
!
ok
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"cannot convert to *api.Endpoints: %v"
,
t
.
Obj
))
return
}
default
:
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"cannot convert to *api.Endpoints: %v"
,
obj
))
return
}
endpointsChan
<-
EndpointsUpdate
{
Op
:
REMOVE
,
Endpoints
:
endpoints
}
}
}
// NewServiceController creates a controller that is watching services and sending
// NewServiceController creates a controller that is watching services and sending
// updates into ServiceUpdate channel.
// updates into ServiceUpdate channel.
func
NewServiceController
(
lw
cache
.
ListerWatcher
,
period
time
.
Duration
,
ch
chan
<-
ServiceUpdate
)
cache
.
Controller
{
func
NewServiceController
(
lw
cache
.
ListerWatcher
,
period
time
.
Duration
,
ch
chan
<-
ServiceUpdate
)
cache
.
Controller
{
...
@@ -157,19 +107,3 @@ func NewServiceController(lw cache.ListerWatcher, period time.Duration, ch chan<
...
@@ -157,19 +107,3 @@ func NewServiceController(lw cache.ListerWatcher, period time.Duration, ch chan<
)
)
return
serviceController
return
serviceController
}
}
// NewEndpointsController creates a controller that is watching endpoints and sending
// updates into EndpointsUpdate channel.
func
NewEndpointsController
(
lw
cache
.
ListerWatcher
,
period
time
.
Duration
,
ch
chan
<-
EndpointsUpdate
)
cache
.
Controller
{
_
,
endpointsController
:=
cache
.
NewInformer
(
lw
,
&
api
.
Endpoints
{},
period
,
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
sendAddEndpoints
(
ch
),
UpdateFunc
:
sendUpdateEndpoints
(
ch
),
DeleteFunc
:
sendDeleteEndpoints
(
ch
),
},
)
return
endpointsController
}
pkg/proxy/config/api_test.go
View file @
596527da
...
@@ -166,68 +166,40 @@ func TestNewEndpointsSourceApi_UpdatesAndMultipleEndpoints(t *testing.T) {
...
@@ -166,68 +166,40 @@ func TestNewEndpointsSourceApi_UpdatesAndMultipleEndpoints(t *testing.T) {
watchResp
:
fakeWatch
,
watchResp
:
fakeWatch
,
}
}
ch
:=
make
(
chan
EndpointsUpdate
)
stopCh
:=
make
(
chan
struct
{})
defer
close
(
stopCh
)
endpointsController
:=
NewEndpointsController
(
lw
,
30
*
time
.
Second
,
ch
)
ch
:=
make
(
chan
struct
{})
go
endpointsController
.
Run
(
wait
.
NeverStop
)
handler
:=
newEpsHandler
(
t
,
nil
,
func
()
{
ch
<-
struct
{}{}
})
endpointsConfig
:=
newEndpointsConfig
(
lw
,
time
.
Minute
)
endpointsConfig
.
RegisterHandler
(
handler
)
go
endpointsConfig
.
Run
(
stopCh
)
// Add the first endpoints
// Add the first endpoints
handler
.
expected
=
[]
*
api
.
Endpoints
{
endpoints1v1
}
fakeWatch
.
Add
(
endpoints1v1
)
fakeWatch
.
Add
(
endpoints1v1
)
got
,
ok
:=
<-
ch
<-
ch
if
!
ok
{
t
.
Errorf
(
"Unable to read from channel when expected"
)
}
expected
:=
EndpointsUpdate
{
Op
:
ADD
,
Endpoints
:
endpoints1v1
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
expected
,
got
)
{
t
.
Errorf
(
"Expected %#v; Got %#v"
,
expected
,
got
)
}
// Add another endpoints
// Add another endpoints
handler
.
expected
=
[]
*
api
.
Endpoints
{
endpoints1v1
,
endpoints2
}
fakeWatch
.
Add
(
endpoints2
)
fakeWatch
.
Add
(
endpoints2
)
got
,
ok
=
<-
ch
<-
ch
if
!
ok
{
t
.
Errorf
(
"Unable to read from channel when expected"
)
}
// Could be sorted either of these two ways:
expected
=
EndpointsUpdate
{
Op
:
ADD
,
Endpoints
:
endpoints2
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
expected
,
got
)
{
t
.
Errorf
(
"Expected %#v, Got %#v"
,
expected
,
got
)
}
// Modify endpoints1
// Modify endpoints1
handler
.
expected
=
[]
*
api
.
Endpoints
{
endpoints1v2
,
endpoints2
}
fakeWatch
.
Modify
(
endpoints1v2
)
fakeWatch
.
Modify
(
endpoints1v2
)
got
,
ok
=
<-
ch
<-
ch
if
!
ok
{
t
.
Errorf
(
"Unable to read from channel when expected"
)
}
expected
=
EndpointsUpdate
{
Op
:
UPDATE
,
Endpoints
:
endpoints1v2
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
expected
,
got
)
{
t
.
Errorf
(
"Expected %#v, Got %#v"
,
expected
,
got
)
}
// Delete endpoints1
// Delete endpoints1
handler
.
expected
=
[]
*
api
.
Endpoints
{
endpoints2
}
fakeWatch
.
Delete
(
endpoints1v2
)
fakeWatch
.
Delete
(
endpoints1v2
)
got
,
ok
=
<-
ch
<-
ch
if
!
ok
{
t
.
Errorf
(
"Unable to read from channel when expected"
)
}
expected
=
EndpointsUpdate
{
Op
:
REMOVE
,
Endpoints
:
endpoints1v2
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
expected
,
got
)
{
t
.
Errorf
(
"Expected %#v, Got %#v"
,
expected
,
got
)
}
// Delete endpoints2
// Delete endpoints2
handler
.
expected
=
[]
*
api
.
Endpoints
{}
fakeWatch
.
Delete
(
endpoints2
)
fakeWatch
.
Delete
(
endpoints2
)
got
,
ok
=
<-
ch
<-
ch
if
!
ok
{
t
.
Errorf
(
"Unable to read from channel when expected"
)
}
expected
=
EndpointsUpdate
{
Op
:
REMOVE
,
Endpoints
:
endpoints2
}
if
!
apiequality
.
Semantic
.
DeepEqual
(
expected
,
got
)
{
t
.
Errorf
(
"Expected %#v, Got %#v"
,
expected
,
got
)
}
}
}
type
svcHandler
struct
{
type
svcHandler
struct
{
...
@@ -286,13 +258,6 @@ func TestInitialSync(t *testing.T) {
...
@@ -286,13 +258,6 @@ func TestInitialSync(t *testing.T) {
// Wait for both services and endpoints handler.
// Wait for both services and endpoints handler.
wg
.
Add
(
2
)
wg
.
Add
(
2
)
svcConfig
:=
NewServiceConfig
()
epsConfig
:=
NewEndpointsConfig
()
svcHandler
:=
newSvcHandler
(
t
,
[]
api
.
Service
{
*
svc2
,
*
svc1
},
wg
.
Done
)
svcConfig
.
RegisterHandler
(
svcHandler
)
epsHandler
:=
newEpsHandler
(
t
,
[]
*
api
.
Endpoints
{
eps2
,
eps1
},
wg
.
Done
)
epsConfig
.
RegisterHandler
(
epsHandler
)
// Setup fake api client.
// Setup fake api client.
fakeSvcWatch
:=
watch
.
NewFake
()
fakeSvcWatch
:=
watch
.
NewFake
()
svcLW
:=
fakeLW
{
svcLW
:=
fakeLW
{
...
@@ -305,8 +270,16 @@ func TestInitialSync(t *testing.T) {
...
@@ -305,8 +270,16 @@ func TestInitialSync(t *testing.T) {
watchResp
:
fakeEpsWatch
,
watchResp
:
fakeEpsWatch
,
}
}
svcConfig
:=
NewServiceConfig
()
epsConfig
:=
newEndpointsConfig
(
epsLW
,
time
.
Minute
)
svcHandler
:=
newSvcHandler
(
t
,
[]
api
.
Service
{
*
svc2
,
*
svc1
},
wg
.
Done
)
svcConfig
.
RegisterHandler
(
svcHandler
)
epsHandler
:=
newEpsHandler
(
t
,
[]
*
api
.
Endpoints
{
eps2
,
eps1
},
wg
.
Done
)
epsConfig
.
RegisterHandler
(
epsHandler
)
stopCh
:=
make
(
chan
struct
{})
stopCh
:=
make
(
chan
struct
{})
defer
close
(
stopCh
)
defer
close
(
stopCh
)
newSourceAPI
(
svcLW
,
epsLW
,
time
.
Minute
,
svcConfig
.
Channel
(
"one"
),
epsConfig
.
Channel
(
"two"
),
stopCh
)
go
epsConfig
.
Run
(
stopCh
)
newSourceAPI
(
svcLW
,
time
.
Minute
,
svcConfig
.
Channel
(
"one"
),
stopCh
)
wg
.
Wait
()
wg
.
Wait
()
}
}
pkg/proxy/config/config.go
View file @
596527da
...
@@ -17,12 +17,20 @@ limitations under the License.
...
@@ -17,12 +17,20 @@ limitations under the License.
package
config
package
config
import
(
import
(
"fmt"
"sync"
"sync"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/davecgh/go-spew/spew"
"github.com/golang/glog"
"github.com/golang/glog"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/types"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
listers
"k8s.io/kubernetes/pkg/client/listers/core/internalversion"
"k8s.io/kubernetes/pkg/util/config"
"k8s.io/kubernetes/pkg/util/config"
)
)
...
@@ -76,102 +84,100 @@ type EndpointsConfigHandler interface {
...
@@ -76,102 +84,100 @@ type EndpointsConfigHandler interface {
// EndpointsConfig tracks a set of endpoints configurations.
// EndpointsConfig tracks a set of endpoints configurations.
// It accepts "set", "add" and "remove" operations of endpoints via channels, and invokes registered handlers on change.
// It accepts "set", "add" and "remove" operations of endpoints via channels, and invokes registered handlers on change.
type
EndpointsConfig
struct
{
type
EndpointsConfig
struct
{
mux
*
config
.
Mux
informer
cache
.
Controller
bcaster
*
config
.
Broadcaster
lister
listers
.
EndpointsLister
store
*
endpointsStore
handlers
[]
EndpointsConfigHandler
// updates channel is used to trigger registered handlers.
updates
chan
struct
{}
}
}
// NewEndpointsConfig creates a new EndpointsConfig.
// NewEndpointsConfig creates a new EndpointsConfig.
// It immediately runs the created EndpointsConfig.
func
NewEndpointsConfig
(
c
cache
.
Getter
,
period
time
.
Duration
)
*
EndpointsConfig
{
func
NewEndpointsConfig
()
*
EndpointsConfig
{
endpointsLW
:=
cache
.
NewListWatchFromClient
(
c
,
"endpoints"
,
metav1
.
NamespaceAll
,
fields
.
Everything
())
// The updates channel is used to send interrupts to the Endpoints handler.
return
newEndpointsConfig
(
endpointsLW
,
period
)
// It's buffered because we never want to block for as long as there is a
}
// pending interrupt, but don't want to drop them if the handler is doing
// work.
func
newEndpointsConfig
(
lw
cache
.
ListerWatcher
,
period
time
.
Duration
)
*
EndpointsConfig
{
updates
:=
make
(
chan
struct
{},
1
)
result
:=
&
EndpointsConfig
{}
store
:=
&
endpointsStore
{
updates
:
updates
,
endpoints
:
make
(
map
[
string
]
map
[
types
.
NamespacedName
]
*
api
.
Endpoints
)}
mux
:=
config
.
NewMux
(
store
)
store
,
informer
:=
cache
.
NewIndexerInformer
(
bcaster
:=
config
.
NewBroadcaster
()
lw
,
go
watchForUpdates
(
bcaster
,
store
,
updates
)
&
api
.
Endpoints
{},
return
&
EndpointsConfig
{
mux
,
bcaster
,
store
}
period
,
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
result
.
handleAddEndpoints
,
UpdateFunc
:
result
.
handleUpdateEndpoints
,
DeleteFunc
:
result
.
handleDeleteEndpoints
,
},
cache
.
Indexers
{},
)
result
.
informer
=
informer
result
.
lister
=
listers
.
NewEndpointsLister
(
store
)
return
result
}
}
// RegisterHandler registers a handler which is called on every endpoints change.
// RegisterHandler registers a handler which is called on every endpoints change.
func
(
c
*
EndpointsConfig
)
RegisterHandler
(
handler
EndpointsConfigHandler
)
{
func
(
c
*
EndpointsConfig
)
RegisterHandler
(
handler
EndpointsConfigHandler
)
{
c
.
bcaster
.
Add
(
config
.
ListenerFunc
(
func
(
instance
interface
{})
{
c
.
handlers
=
append
(
c
.
handlers
,
handler
)
glog
.
V
(
3
)
.
Infof
(
"Calling handler.OnEndpointsUpdate()"
)
handler
.
OnEndpointsUpdate
(
instance
.
([]
*
api
.
Endpoints
))
}))
}
}
// Channel returns a channel to which endpoints updates should be delivered.
func
(
c
*
EndpointsConfig
)
Run
(
stopCh
<-
chan
struct
{})
{
func
(
c
*
EndpointsConfig
)
Channel
(
source
string
)
chan
EndpointsUpdate
{
// The updates channel is used to send interrupts to the Endpoints handler.
ch
:=
c
.
mux
.
Channel
(
source
)
// It's buffered because we never want to block for as long as there is a
endpointsCh
:=
make
(
chan
EndpointsUpdate
)
// pending interrupt, but don't want to drop them if the handler is doing
// work.
c
.
updates
=
make
(
chan
struct
{},
1
)
go
c
.
informer
.
Run
(
stopCh
)
if
!
cache
.
WaitForCacheSync
(
stopCh
,
c
.
informer
.
HasSynced
)
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"endpoint controller not synced"
))
return
}
// We have synced informers. Now we can start delivering updates
// to the registered handler.
go
func
()
{
go
func
()
{
for
update
:=
range
endpointsCh
{
for
range
c
.
updates
{
ch
<-
update
endpoints
,
err
:=
c
.
lister
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
glog
.
Errorf
(
"Error while listing endpoints from cache: %v"
,
err
)
// This will cause a retry (if there isn't any other trigger in-flight).
c
.
dispatchUpdate
()
continue
}
if
endpoints
==
nil
{
endpoints
=
[]
*
api
.
Endpoints
{}
}
for
i
:=
range
c
.
handlers
{
glog
.
V
(
3
)
.
Infof
(
"Calling handler.OnEndpointsUpdate()"
)
c
.
handlers
[
i
]
.
OnEndpointsUpdate
(
endpoints
)
}
}
}
}()
}()
return
endpointsCh
// Close updates channel when stopCh is closed.
go
func
()
{
<-
stopCh
close
(
c
.
updates
)
}()
}
}
// Config returns list of all endpoints from underlying store.
func
(
c
*
EndpointsConfig
)
handleAddEndpoints
(
_
interface
{})
{
func
(
c
*
EndpointsConfig
)
Config
()
[]
api
.
Endpoints
{
c
.
dispatchUpdate
()
return
c
.
store
.
MergedState
()
.
([]
api
.
Endpoints
)
}
}
type
endpointsStore
struct
{
func
(
c
*
EndpointsConfig
)
handleUpdateEndpoints
(
_
,
_
interface
{})
{
endpointLock
sync
.
RWMutex
c
.
dispatchUpdate
()
endpoints
map
[
string
]
map
[
types
.
NamespacedName
]
*
api
.
Endpoints
synced
bool
updates
chan
<-
struct
{}
}
}
func
(
s
*
endpointsStore
)
Merge
(
source
string
,
change
interface
{})
error
{
func
(
c
*
EndpointsConfig
)
handleDeleteEndpoints
(
_
interface
{})
{
s
.
endpointLock
.
Lock
()
c
.
dispatchUpdate
()
endpoints
:=
s
.
endpoints
[
source
]
if
endpoints
==
nil
{
endpoints
=
make
(
map
[
types
.
NamespacedName
]
*
api
.
Endpoints
)
}
update
:=
change
.
(
EndpointsUpdate
)
switch
update
.
Op
{
case
ADD
,
UPDATE
:
glog
.
V
(
5
)
.
Infof
(
"Adding new endpoint from source %s : %s"
,
source
,
spew
.
Sdump
(
update
.
Endpoints
))
name
:=
types
.
NamespacedName
{
Namespace
:
update
.
Endpoints
.
Namespace
,
Name
:
update
.
Endpoints
.
Name
}
endpoints
[
name
]
=
update
.
Endpoints
case
REMOVE
:
glog
.
V
(
5
)
.
Infof
(
"Removing an endpoint %s"
,
spew
.
Sdump
(
update
.
Endpoints
))
name
:=
types
.
NamespacedName
{
Namespace
:
update
.
Endpoints
.
Namespace
,
Name
:
update
.
Endpoints
.
Name
}
delete
(
endpoints
,
name
)
case
SYNCED
:
s
.
synced
=
true
default
:
glog
.
V
(
4
)
.
Infof
(
"Received invalid update type: %s"
,
spew
.
Sdump
(
update
))
}
s
.
endpoints
[
source
]
=
endpoints
synced
:=
s
.
synced
s
.
endpointLock
.
Unlock
()
if
s
.
updates
!=
nil
&&
synced
{
select
{
case
s
.
updates
<-
struct
{}{}
:
default
:
glog
.
V
(
4
)
.
Infof
(
"Endpoints handler already has a pending interrupt."
)
}
}
return
nil
}
}
func
(
s
*
endpointsStore
)
MergedState
()
interface
{}
{
func
(
c
*
EndpointsConfig
)
dispatchUpdate
()
{
s
.
endpointLock
.
RLock
()
select
{
defer
s
.
endpointLock
.
RUnlock
()
case
c
.
updates
<-
struct
{}{}
:
endpoints
:=
make
([]
*
api
.
Endpoints
,
0
)
default
:
for
_
,
sourceEndpoints
:=
range
s
.
endpoints
{
glog
.
V
(
4
)
.
Infof
(
"Endpoints handler already has a pending interrupt."
)
for
_
,
value
:=
range
sourceEndpoints
{
endpoints
=
append
(
endpoints
,
value
)
}
}
}
return
endpoints
}
}
// ServiceConfig tracks a set of service configurations.
// ServiceConfig tracks a set of service configurations.
...
...
pkg/proxy/config/config_test.go
View file @
596527da
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
)
)
...
@@ -228,98 +229,110 @@ func TestNewMultipleSourcesServicesMultipleHandlersAddedAndNotified(t *testing.T
...
@@ -228,98 +229,110 @@ func TestNewMultipleSourcesServicesMultipleHandlersAddedAndNotified(t *testing.T
handler2
.
ValidateServices
(
t
,
services
)
handler2
.
ValidateServices
(
t
,
services
)
}
}
func
TestNewMultipleSourcesEndpointsMultipleHandlersAddedAndNotified
(
t
*
testing
.
T
)
{
func
TestNewEndpointsMultipleHandlersAddedAndNotified
(
t
*
testing
.
T
)
{
config
:=
NewEndpointsConfig
()
fakeWatch
:=
watch
.
NewFake
()
config
.
store
.
synced
=
true
lw
:=
fakeLW
{
channelOne
:=
config
.
Channel
(
"one"
)
listResp
:
&
api
.
EndpointsList
{
Items
:
[]
api
.
Endpoints
{}},
channelTwo
:=
config
.
Channel
(
"two"
)
watchResp
:
fakeWatch
,
}
stopCh
:=
make
(
chan
struct
{})
defer
close
(
stopCh
)
config
:=
newEndpointsConfig
(
lw
,
time
.
Minute
)
handler
:=
NewEndpointsHandlerMock
()
handler
:=
NewEndpointsHandlerMock
()
handler2
:=
NewEndpointsHandlerMock
()
handler2
:=
NewEndpointsHandlerMock
()
config
.
RegisterHandler
(
handler
)
config
.
RegisterHandler
(
handler
)
config
.
RegisterHandler
(
handler2
)
config
.
RegisterHandler
(
handler2
)
endpointsUpdate1
:=
CreateEndpointsUpdate
(
ADD
,
&
api
.
Endpoints
{
go
config
.
Run
(
stopCh
)
endpoints1
:=
&
api
.
Endpoints
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"foo"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"foo"
},
Subsets
:
[]
api
.
EndpointSubset
{{
Subsets
:
[]
api
.
EndpointSubset
{{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"1.1.1.1"
},
{
IP
:
"2.2.2.2"
}},
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"1.1.1.1"
},
{
IP
:
"2.2.2.2"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
}},
}},
}
)
}
endpoints
Update2
:=
CreateEndpointsUpdate
(
ADD
,
&
api
.
Endpoints
{
endpoints
2
:=
&
api
.
Endpoints
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"bar"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"bar"
},
Subsets
:
[]
api
.
EndpointSubset
{{
Subsets
:
[]
api
.
EndpointSubset
{{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"3.3.3.3"
},
{
IP
:
"4.4.4.4"
}},
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"3.3.3.3"
},
{
IP
:
"4.4.4.4"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
}},
}},
}
)
}
channelOne
<-
endpointsUpdate1
fakeWatch
.
Add
(
endpoints1
)
channelTwo
<-
endpointsUpdate2
fakeWatch
.
Add
(
endpoints2
)
endpoints
:=
[]
*
api
.
Endpoints
{
endpoints
Update2
.
Endpoints
,
endpointsUpdate1
.
Endpoints
}
endpoints
:=
[]
*
api
.
Endpoints
{
endpoints
2
,
endpoints1
}
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
}
}
func
TestNewMultipleSourcesEndpointsMultipleHandlersAddRemoveSetAndNotified
(
t
*
testing
.
T
)
{
func
TestNewEndpointsMultipleHandlersAddRemoveSetAndNotified
(
t
*
testing
.
T
)
{
config
:=
NewEndpointsConfig
()
fakeWatch
:=
watch
.
NewFake
()
config
.
store
.
synced
=
true
lw
:=
fakeLW
{
channelOne
:=
config
.
Channel
(
"one"
)
listResp
:
&
api
.
EndpointsList
{
Items
:
[]
api
.
Endpoints
{}},
channelTwo
:=
config
.
Channel
(
"two"
)
watchResp
:
fakeWatch
,
}
stopCh
:=
make
(
chan
struct
{})
defer
close
(
stopCh
)
config
:=
newEndpointsConfig
(
lw
,
time
.
Minute
)
handler
:=
NewEndpointsHandlerMock
()
handler
:=
NewEndpointsHandlerMock
()
handler2
:=
NewEndpointsHandlerMock
()
handler2
:=
NewEndpointsHandlerMock
()
config
.
RegisterHandler
(
handler
)
config
.
RegisterHandler
(
handler
)
config
.
RegisterHandler
(
handler2
)
config
.
RegisterHandler
(
handler2
)
endpointsUpdate1
:=
CreateEndpointsUpdate
(
ADD
,
&
api
.
Endpoints
{
go
config
.
Run
(
stopCh
)
endpoints1
:=
&
api
.
Endpoints
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"foo"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"foo"
},
Subsets
:
[]
api
.
EndpointSubset
{{
Subsets
:
[]
api
.
EndpointSubset
{{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"1.1.1.1"
},
{
IP
:
"2.2.2.2"
}},
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"1.1.1.1"
},
{
IP
:
"2.2.2.2"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
}},
}},
}
)
}
endpoints
Update2
:=
CreateEndpointsUpdate
(
ADD
,
&
api
.
Endpoints
{
endpoints
2
:=
&
api
.
Endpoints
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"bar"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"bar"
},
Subsets
:
[]
api
.
EndpointSubset
{{
Subsets
:
[]
api
.
EndpointSubset
{{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"3.3.3.3"
},
{
IP
:
"4.4.4.4"
}},
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"3.3.3.3"
},
{
IP
:
"4.4.4.4"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
}},
}},
}
)
}
channelOne
<-
endpointsUpdate1
fakeWatch
.
Add
(
endpoints1
)
channelTwo
<-
endpointsUpdate2
fakeWatch
.
Add
(
endpoints2
)
endpoints
:=
[]
*
api
.
Endpoints
{
endpoints
Update2
.
Endpoints
,
endpointsUpdate1
.
Endpoints
}
endpoints
:=
[]
*
api
.
Endpoints
{
endpoints
2
,
endpoints1
}
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
// Add one more
// Add one more
endpoints
Update3
:=
CreateEndpointsUpdate
(
ADD
,
&
api
.
Endpoints
{
endpoints
3
:=
&
api
.
Endpoints
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"foobar"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"foobar"
},
Subsets
:
[]
api
.
EndpointSubset
{{
Subsets
:
[]
api
.
EndpointSubset
{{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"5.5.5.5"
},
{
IP
:
"6.6.6.6"
}},
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"5.5.5.5"
},
{
IP
:
"6.6.6.6"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
}},
}},
}
)
}
channelTwo
<-
endpointsUpdate3
fakeWatch
.
Add
(
endpoints3
)
endpoints
=
[]
*
api
.
Endpoints
{
endpoints
Update2
.
Endpoints
,
endpointsUpdate1
.
Endpoints
,
endpointsUpdate3
.
Endpoints
}
endpoints
=
[]
*
api
.
Endpoints
{
endpoints
2
,
endpoints1
,
endpoints3
}
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
// Update the "foo" service with new endpoints
// Update the "foo" service with new endpoints
endpoints
Update1
=
CreateEndpointsUpdate
(
ADD
,
&
api
.
Endpoints
{
endpoints
1v2
:=
&
api
.
Endpoints
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"foo"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"foo"
},
Subsets
:
[]
api
.
EndpointSubset
{{
Subsets
:
[]
api
.
EndpointSubset
{{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"7.7.7.7"
}},
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"7.7.7.7"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
80
}},
}},
}},
}
)
}
channelOne
<-
endpointsUpdate1
fakeWatch
.
Modify
(
endpoints1v2
)
endpoints
=
[]
*
api
.
Endpoints
{
endpoints
Update2
.
Endpoints
,
endpointsUpdate1
.
Endpoints
,
endpointsUpdate3
.
Endpoints
}
endpoints
=
[]
*
api
.
Endpoints
{
endpoints
2
,
endpoints1v2
,
endpoints3
}
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
// Remove "bar" service
// Remove "bar" endpoints
endpointsUpdate2
=
CreateEndpointsUpdate
(
REMOVE
,
&
api
.
Endpoints
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
"testnamespace"
,
Name
:
"bar"
}})
fakeWatch
.
Delete
(
endpoints2
)
channelTwo
<-
endpointsUpdate2
endpoints
=
[]
*
api
.
Endpoints
{
endpoints1v2
,
endpoints3
}
endpoints
=
[]
*
api
.
Endpoints
{
endpointsUpdate1
.
Endpoints
,
endpointsUpdate3
.
Endpoints
}
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
handler2
.
ValidateEndpoints
(
t
,
endpoints
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment