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
8a8b5845
Commit
8a8b5845
authored
Jul 23, 2018
by
liangwei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
optimize ipvs get nodeIP
parent
4797c8df
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
39 additions
and
46 deletions
+39
-46
netlink.go
pkg/proxy/ipvs/netlink.go
+3
-3
netlink_linux.go
pkg/proxy/ipvs/netlink_linux.go
+20
-10
netlink_unsupported.go
pkg/proxy/ipvs/netlink_unsupported.go
+1
-1
proxier.go
pkg/proxy/ipvs/proxier.go
+5
-25
fake.go
pkg/proxy/ipvs/testing/fake.go
+6
-3
fake_test.go
pkg/proxy/ipvs/testing/fake_test.go
+4
-4
No files found.
pkg/proxy/ipvs/netlink.go
View file @
8a8b5845
...
@@ -32,7 +32,7 @@ type NetLinkHandle interface {
...
@@ -32,7 +32,7 @@ type NetLinkHandle interface {
DeleteDummyDevice
(
devName
string
)
error
DeleteDummyDevice
(
devName
string
)
error
// ListBindAddress will list all IP addresses which are bound in a given interface
// ListBindAddress will list all IP addresses which are bound in a given interface
ListBindAddress
(
devName
string
)
([]
string
,
error
)
ListBindAddress
(
devName
string
)
([]
string
,
error
)
// GetLocalAddresses returns all unique local type IP addresses based on
filter device interface. If filter device is not given,
// GetLocalAddresses returns all unique local type IP addresses based on
specified device and filter device
//
it will list all unique local type addresses.
//
If device is not specified, it will list all unique local type addresses except filter device addresses
GetLocalAddresses
(
filterDev
string
)
(
sets
.
String
,
error
)
GetLocalAddresses
(
dev
,
filterDev
string
)
(
sets
.
String
,
error
)
}
}
pkg/proxy/ipvs/netlink_linux.go
View file @
8a8b5845
...
@@ -123,7 +123,7 @@ func (h *netlinkHandle) ListBindAddress(devName string) ([]string, error) {
...
@@ -123,7 +123,7 @@ func (h *netlinkHandle) ListBindAddress(devName string) ([]string, error) {
}
}
// GetLocalAddresses lists all LOCAL type IP addresses from host based on filter device.
// GetLocalAddresses lists all LOCAL type IP addresses from host based on filter device.
// If
filter device
is not specified, it's equivalent to exec:
// If
dev
is not specified, it's equivalent to exec:
// $ ip route show table local type local proto kernel
// $ ip route show table local type local proto kernel
// 10.0.0.1 dev kube-ipvs0 scope host src 10.0.0.1
// 10.0.0.1 dev kube-ipvs0 scope host src 10.0.0.1
// 10.0.0.10 dev kube-ipvs0 scope host src 10.0.0.10
// 10.0.0.10 dev kube-ipvs0 scope host src 10.0.0.10
...
@@ -136,20 +136,28 @@ func (h *netlinkHandle) ListBindAddress(devName string) ([]string, error) {
...
@@ -136,20 +136,28 @@ func (h *netlinkHandle) ListBindAddress(devName string) ([]string, error) {
// Then cut the unique src IP fields,
// Then cut the unique src IP fields,
// --> result set: [10.0.0.1, 10.0.0.10, 10.0.0.252, 100.106.89.164, 127.0.0.1, 192.168.122.1]
// --> result set: [10.0.0.1, 10.0.0.10, 10.0.0.252, 100.106.89.164, 127.0.0.1, 192.168.122.1]
// If
filter device
is specified, it's equivalent to exec:
// If
dev
is specified, it's equivalent to exec:
// $ ip route show table local type local proto kernel dev kube-ipvs0
// $ ip route show table local type local proto kernel dev kube-ipvs0
// 10.0.0.1 scope host src 10.0.0.1
// 10.0.0.1 scope host src 10.0.0.1
// 10.0.0.10 scope host src 10.0.0.10
// 10.0.0.10 scope host src 10.0.0.10
// Then cut the unique src IP fields,
// Then cut the unique src IP fields,
// --> result set: [10.0.0.1, 10.0.0.10]
// --> result set: [10.0.0.1, 10.0.0.10]
func
(
h
*
netlinkHandle
)
GetLocalAddresses
(
filterDev
string
)
(
sets
.
String
,
error
)
{
linkIndex
:=
-
1
// If filterDev is specified, the result will discard route of specified device and cut src from other routes.
if
len
(
filterDev
)
!=
0
{
func
(
h
*
netlinkHandle
)
GetLocalAddresses
(
dev
,
filterDev
string
)
(
sets
.
String
,
error
)
{
chosenLinkIndex
,
filterLinkIndex
:=
-
1
,
-
1
if
dev
!=
""
{
link
,
err
:=
h
.
LinkByName
(
dev
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error get device %s, err: %v"
,
filterDev
,
err
)
}
chosenLinkIndex
=
link
.
Attrs
()
.
Index
}
else
if
filterDev
!=
""
{
link
,
err
:=
h
.
LinkByName
(
filterDev
)
link
,
err
:=
h
.
LinkByName
(
filterDev
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error get filter device %s, err: %v"
,
filterDev
,
err
)
return
nil
,
fmt
.
Errorf
(
"error get filter device %s, err: %v"
,
filterDev
,
err
)
}
}
l
inkIndex
=
link
.
Attrs
()
.
Index
filterL
inkIndex
=
link
.
Attrs
()
.
Index
}
}
routeFilter
:=
&
netlink
.
Route
{
routeFilter
:=
&
netlink
.
Route
{
...
@@ -159,18 +167,20 @@ func (h *netlinkHandle) GetLocalAddresses(filterDev string) (sets.String, error)
...
@@ -159,18 +167,20 @@ func (h *netlinkHandle) GetLocalAddresses(filterDev string) (sets.String, error)
}
}
filterMask
:=
netlink
.
RT_FILTER_TABLE
|
netlink
.
RT_FILTER_TYPE
|
netlink
.
RT_FILTER_PROTOCOL
filterMask
:=
netlink
.
RT_FILTER_TABLE
|
netlink
.
RT_FILTER_TYPE
|
netlink
.
RT_FILTER_PROTOCOL
// find
filter
device
// find
chosen
device
if
l
inkIndex
!=
-
1
{
if
chosenL
inkIndex
!=
-
1
{
routeFilter
.
LinkIndex
=
l
inkIndex
routeFilter
.
LinkIndex
=
chosenL
inkIndex
filterMask
|=
netlink
.
RT_FILTER_OIF
filterMask
|=
netlink
.
RT_FILTER_OIF
}
}
routes
,
err
:=
h
.
RouteListFiltered
(
netlink
.
FAMILY_ALL
,
routeFilter
,
filterMask
)
routes
,
err
:=
h
.
RouteListFiltered
(
netlink
.
FAMILY_ALL
,
routeFilter
,
filterMask
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error list route table, err: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"error list route table, err: %v"
,
err
)
}
}
res
:=
sets
.
NewString
()
res
:=
sets
.
NewString
()
for
_
,
route
:=
range
routes
{
for
_
,
route
:=
range
routes
{
if
route
.
LinkIndex
==
filterLinkIndex
{
continue
}
if
route
.
Src
!=
nil
{
if
route
.
Src
!=
nil
{
res
.
Insert
(
route
.
Src
.
String
())
res
.
Insert
(
route
.
Src
.
String
())
}
}
...
...
pkg/proxy/ipvs/netlink_unsupported.go
View file @
8a8b5845
...
@@ -58,6 +58,6 @@ func (h *emptyHandle) ListBindAddress(devName string) ([]string, error) {
...
@@ -58,6 +58,6 @@ func (h *emptyHandle) ListBindAddress(devName string) ([]string, error) {
}
}
// GetLocalAddresses is part of interface.
// GetLocalAddresses is part of interface.
func
(
h
*
emptyHandle
)
GetLocalAddresses
(
filterDev
string
)
(
sets
.
String
,
error
)
{
func
(
h
*
emptyHandle
)
GetLocalAddresses
(
dev
,
filterDev
string
)
(
sets
.
String
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"netlink is not supported in this platform"
)
return
nil
,
fmt
.
Errorf
(
"netlink is not supported in this platform"
)
}
}
pkg/proxy/ipvs/proxier.go
View file @
8a8b5845
...
@@ -241,7 +241,8 @@ type realIPGetter struct {
...
@@ -241,7 +241,8 @@ type realIPGetter struct {
}
}
// NodeIPs returns all LOCAL type IP addresses from host which are taken as the Node IPs of NodePort service.
// NodeIPs returns all LOCAL type IP addresses from host which are taken as the Node IPs of NodePort service.
// Firstly, it will list source IP exists in local route table with `kernel` protocol type. For example,
// It will list source IP exists in local route table with `kernel` protocol type, and filter out IPVS proxier
// created dummy device `kube-ipvs0` For example,
// $ ip route show table local type local proto kernel
// $ ip route show table local type local proto kernel
// 10.0.0.1 dev kube-ipvs0 scope host src 10.0.0.1
// 10.0.0.1 dev kube-ipvs0 scope host src 10.0.0.1
// 10.0.0.10 dev kube-ipvs0 scope host src 10.0.0.10
// 10.0.0.10 dev kube-ipvs0 scope host src 10.0.0.10
...
@@ -251,35 +252,14 @@ type realIPGetter struct {
...
@@ -251,35 +252,14 @@ type realIPGetter struct {
// 127.0.0.1 dev lo scope host src 127.0.0.1
// 127.0.0.1 dev lo scope host src 127.0.0.1
// 172.17.0.1 dev docker0 scope host src 172.17.0.1
// 172.17.0.1 dev docker0 scope host src 172.17.0.1
// 192.168.122.1 dev virbr0 scope host src 192.168.122.1
// 192.168.122.1 dev virbr0 scope host src 192.168.122.1
// Then cut the unique src IP fields,
// Then filter out dev==kube-ipvs0, and cut the unique src IP fields,
// --> result set1: [10.0.0.1, 10.0.0.10, 10.0.0.252, 100.106.89.164, 127.0.0.1, 192.168.122.1]
// Node IP set: [100.106.89.164, 127.0.0.1, 192.168.122.1]
// NOTE: For cases where an LB acts as a VIP (e.g. Google cloud), the VIP IP is considered LOCAL, but the protocol
// of the entry is 66, e.g. `10.128.0.6 dev ens4 proto 66 scope host`. Therefore, the rule mentioned above will
// filter these entries out.
// Secondly, as we bind Cluster IPs to the dummy interface in IPVS proxier, we need to filter the them out so that
// we can eventually get the Node IPs. Fortunately, the dummy interface created by IPVS proxier is known as `kube-ipvs0`,
// so we just need to specify the `dev kube-ipvs0` argument in ip route command, for example,
// $ ip route show table local type local proto kernel dev kube-ipvs0
// 10.0.0.1 scope host src 10.0.0.1
// 10.0.0.10 scope host src 10.0.0.10
// Then cut the unique src IP fields,
// --> result set2: [10.0.0.1, 10.0.0.10]
// Finally, Node IP set = set1 - set2
func
(
r
*
realIPGetter
)
NodeIPs
()
(
ips
[]
net
.
IP
,
err
error
)
{
func
(
r
*
realIPGetter
)
NodeIPs
()
(
ips
[]
net
.
IP
,
err
error
)
{
// Pass in empty filter device name for list all LOCAL type addresses.
// Pass in empty filter device name for list all LOCAL type addresses.
allAddress
,
err
:=
r
.
nl
.
GetLocalAddresses
(
""
)
nodeAddress
,
err
:=
r
.
nl
.
GetLocalAddresses
(
""
,
DefaultDummyDevice
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error listing LOCAL type addresses from host, error: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"error listing LOCAL type addresses from host, error: %v"
,
err
)
}
}
dummyAddress
,
err
:=
r
.
nl
.
GetLocalAddresses
(
DefaultDummyDevice
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error listing LOCAL type addresses from device: %s, error: %v"
,
DefaultDummyDevice
,
err
)
}
// exclude ip address from dummy interface created by IPVS proxier - they are all Cluster IPs.
nodeAddress
:=
allAddress
.
Difference
(
dummyAddress
)
// translate ip string to IP
// translate ip string to IP
for
_
,
ipStr
:=
range
nodeAddress
.
UnsortedList
()
{
for
_
,
ipStr
:=
range
nodeAddress
.
UnsortedList
()
{
ips
=
append
(
ips
,
net
.
ParseIP
(
ipStr
))
ips
=
append
(
ips
,
net
.
ParseIP
(
ipStr
))
...
...
pkg/proxy/ipvs/testing/fake.go
View file @
8a8b5845
...
@@ -63,17 +63,20 @@ func (h *FakeNetlinkHandle) ListBindAddress(devName string) ([]string, error) {
...
@@ -63,17 +63,20 @@ func (h *FakeNetlinkHandle) ListBindAddress(devName string) ([]string, error) {
}
}
// GetLocalAddresses is a mock implementation
// GetLocalAddresses is a mock implementation
func
(
h
*
FakeNetlinkHandle
)
GetLocalAddresses
(
filterDev
string
)
(
sets
.
String
,
error
)
{
func
(
h
*
FakeNetlinkHandle
)
GetLocalAddresses
(
dev
,
filterDev
string
)
(
sets
.
String
,
error
)
{
res
:=
sets
.
NewString
()
res
:=
sets
.
NewString
()
if
len
(
filterD
ev
)
!=
0
{
if
len
(
d
ev
)
!=
0
{
// list all addresses from a given network interface.
// list all addresses from a given network interface.
for
_
,
addr
:=
range
h
.
localAddresses
[
filterD
ev
]
{
for
_
,
addr
:=
range
h
.
localAddresses
[
d
ev
]
{
res
.
Insert
(
addr
)
res
.
Insert
(
addr
)
}
}
return
res
,
nil
return
res
,
nil
}
}
// If filterDev is not given, will list all addresses from all available network interface.
// If filterDev is not given, will list all addresses from all available network interface.
for
linkName
:=
range
h
.
localAddresses
{
for
linkName
:=
range
h
.
localAddresses
{
if
linkName
==
filterDev
{
continue
}
// list all addresses from a given network interface.
// list all addresses from a given network interface.
for
_
,
addr
:=
range
h
.
localAddresses
[
linkName
]
{
for
_
,
addr
:=
range
h
.
localAddresses
[
linkName
]
{
res
.
Insert
(
addr
)
res
.
Insert
(
addr
)
...
...
pkg/proxy/ipvs/testing/fake_test.go
View file @
8a8b5845
...
@@ -27,21 +27,21 @@ func TestSetGetLocalAddresses(t *testing.T) {
...
@@ -27,21 +27,21 @@ func TestSetGetLocalAddresses(t *testing.T) {
fake
:=
NewFakeNetlinkHandle
()
fake
:=
NewFakeNetlinkHandle
()
fake
.
SetLocalAddresses
(
"eth0"
,
"1.2.3.4"
)
fake
.
SetLocalAddresses
(
"eth0"
,
"1.2.3.4"
)
expected
:=
sets
.
NewString
(
"1.2.3.4"
)
expected
:=
sets
.
NewString
(
"1.2.3.4"
)
addr
,
_
:=
fake
.
GetLocalAddresses
(
"eth0"
)
addr
,
_
:=
fake
.
GetLocalAddresses
(
"eth0"
,
""
)
if
!
reflect
.
DeepEqual
(
expected
,
addr
)
{
if
!
reflect
.
DeepEqual
(
expected
,
addr
)
{
t
.
Errorf
(
"Unexpected mismatch, expected: %v, got: %v"
,
expected
,
addr
)
t
.
Errorf
(
"Unexpected mismatch, expected: %v, got: %v"
,
expected
,
addr
)
}
}
list
,
_
:=
fake
.
GetLocalAddresses
(
""
)
list
,
_
:=
fake
.
GetLocalAddresses
(
""
,
""
)
if
!
reflect
.
DeepEqual
(
expected
,
list
)
{
if
!
reflect
.
DeepEqual
(
expected
,
list
)
{
t
.
Errorf
(
"Unexpected mismatch, expected: %v, got: %v"
,
expected
,
list
)
t
.
Errorf
(
"Unexpected mismatch, expected: %v, got: %v"
,
expected
,
list
)
}
}
fake
.
SetLocalAddresses
(
"lo"
,
"127.0.0.1"
)
fake
.
SetLocalAddresses
(
"lo"
,
"127.0.0.1"
)
expected
=
sets
.
NewString
(
"127.0.0.1"
)
expected
=
sets
.
NewString
(
"127.0.0.1"
)
addr
,
_
=
fake
.
GetLocalAddresses
(
"lo"
)
addr
,
_
=
fake
.
GetLocalAddresses
(
"lo"
,
""
)
if
!
reflect
.
DeepEqual
(
expected
,
addr
)
{
if
!
reflect
.
DeepEqual
(
expected
,
addr
)
{
t
.
Errorf
(
"Unexpected mismatch, expected: %v, got: %v"
,
expected
,
addr
)
t
.
Errorf
(
"Unexpected mismatch, expected: %v, got: %v"
,
expected
,
addr
)
}
}
list
,
_
=
fake
.
GetLocalAddresses
(
""
)
list
,
_
=
fake
.
GetLocalAddresses
(
""
,
""
)
expected
=
sets
.
NewString
(
"1.2.3.4"
,
"127.0.0.1"
)
expected
=
sets
.
NewString
(
"1.2.3.4"
,
"127.0.0.1"
)
if
!
reflect
.
DeepEqual
(
expected
,
list
)
{
if
!
reflect
.
DeepEqual
(
expected
,
list
)
{
t
.
Errorf
(
"Unexpected mismatch, expected: %v, got: %v"
,
expected
,
list
)
t
.
Errorf
(
"Unexpected mismatch, expected: %v, got: %v"
,
expected
,
list
)
...
...
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