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
6edcf02d
Commit
6edcf02d
authored
Dec 10, 2017
by
m1093782566
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
proxy endpoints part changes
parent
9e85b526
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
244 additions
and
0 deletions
+244
-0
endpoints.go
pkg/proxy/endpoints.go
+243
-0
endpoints_test.go
pkg/proxy/endpoints_test.go
+0
-0
endpoints.go
pkg/proxy/util/endpoints.go
+1
-0
No files found.
pkg/proxy/endpoints.go
0 → 100644
View file @
6edcf02d
/*
Copyright 2017 The Kubernetes Authors.
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.
*/
package
proxy
import
(
"reflect"
"sync"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
api
"k8s.io/kubernetes/pkg/apis/core"
)
// EndpointChangeTracker carries state about uncommitted changes to an arbitrary number of
// Endpoints, keyed by their namespace and name.
type
EndpointChangeTracker
struct
{
// lock protects items.
lock
sync
.
Mutex
// hostname is the host where kube-proxy is running.
hostname
string
// items maps a service to is endpointsChange.
items
map
[
types
.
NamespacedName
]
*
endpointsChange
}
// NewEndpointChangeTracker initializes an EndpointsChangeMap
func
NewEndpointChangeTracker
(
hostname
string
)
*
EndpointChangeTracker
{
return
&
EndpointChangeTracker
{
hostname
:
hostname
,
items
:
make
(
map
[
types
.
NamespacedName
]
*
endpointsChange
),
}
}
// Update updates given service's endpoints change map based on the <previous, current> endpoints pair. It returns true
// if items changed, otherwise return false. Update can be used to add/update/delete items of EndpointsChangeMap. For example,
// Add item
// - pass <nil, endpoints> as the <previous, current> pair.
// Update item
// - pass <oldEndpoints, endpoints> as the <previous, current> pair.
// Delete item
// - pass <endpoints, nil> as the <previous, current> pair.
func
(
ect
*
EndpointChangeTracker
)
Update
(
previous
,
current
*
api
.
Endpoints
,
makeEndpoints
func
(
IP
string
,
port
int
,
isLocal
bool
)
Endpoint
)
bool
{
endpoints
:=
current
if
endpoints
==
nil
{
endpoints
=
previous
}
// previous == nil && current == nil is unexpected, we should return false directly.
if
endpoints
==
nil
{
return
false
}
namespacedName
:=
types
.
NamespacedName
{
Namespace
:
endpoints
.
Namespace
,
Name
:
endpoints
.
Name
}
ect
.
lock
.
Lock
()
defer
ect
.
lock
.
Unlock
()
change
,
exists
:=
ect
.
items
[
namespacedName
]
if
!
exists
{
change
=
&
endpointsChange
{}
change
.
previous
=
endpointsToEndpointsMap
(
previous
,
ect
.
hostname
,
makeEndpoints
)
ect
.
items
[
namespacedName
]
=
change
}
change
.
current
=
endpointsToEndpointsMap
(
current
,
ect
.
hostname
,
makeEndpoints
)
// if change.previous equal to change.current, it means no change
if
reflect
.
DeepEqual
(
change
.
previous
,
change
.
current
)
{
delete
(
ect
.
items
,
namespacedName
)
}
return
len
(
ect
.
items
)
>
0
}
// endpointsChange contains all changes to endpoints that happened since proxy rules were synced. For a single object,
// changes are accumulated, i.e. previous is state from before applying the changes,
// current is state after applying the changes.
type
endpointsChange
struct
{
previous
EndpointsMap
current
EndpointsMap
}
// UpdateEndpointMapResult is the updated results after applying endpoints changes.
type
UpdateEndpointMapResult
struct
{
// HCEndpointsLocalIPSize maps an endpoints name to the length of its local IPs.
HCEndpointsLocalIPSize
map
[
types
.
NamespacedName
]
int
// StaleEndpoints identifies if an endpoints service pair is stale.
StaleEndpoints
[]
ServiceEndpoint
// StaleServiceNames identifies if a service is stale.
StaleServiceNames
[]
ServicePortName
}
// UpdateEndpointsMap updates endpointsMap base on the given changes.
func
UpdateEndpointsMap
(
endpointsMap
EndpointsMap
,
changes
*
EndpointChangeTracker
)
(
result
UpdateEndpointMapResult
)
{
result
.
StaleEndpoints
=
make
([]
ServiceEndpoint
,
0
)
result
.
StaleServiceNames
=
make
([]
ServicePortName
,
0
)
endpointsMap
.
apply
(
changes
,
&
result
.
StaleEndpoints
,
&
result
.
StaleServiceNames
)
// TODO: If this will appear to be computationally expensive, consider
// computing this incrementally similarly to endpointsMap.
result
.
HCEndpointsLocalIPSize
=
make
(
map
[
types
.
NamespacedName
]
int
)
localIPs
:=
GetLocalEndpointIPs
(
endpointsMap
)
for
nsn
,
ips
:=
range
localIPs
{
result
.
HCEndpointsLocalIPSize
[
nsn
]
=
len
(
ips
)
}
return
result
}
// EndpointsMap maps a service to one of its endpoint.
type
EndpointsMap
map
[
ServicePortName
][]
Endpoint
// endpointsToEndpointsMap translates single Endpoints object to EndpointsMap.
// This function is used for incremental updated of endpointsMap.
//
// NOTE: endpoints object should NOT be modified.
func
endpointsToEndpointsMap
(
endpoints
*
api
.
Endpoints
,
hostname
string
,
makeEndpoints
func
(
IP
string
,
port
int
,
isLocal
bool
)
Endpoint
)
EndpointsMap
{
if
endpoints
==
nil
{
return
nil
}
endpointsMap
:=
make
(
EndpointsMap
)
// We need to build a map of portname -> all ip:ports for that
// portname. Explode Endpoints.Subsets[*] into this structure.
for
i
:=
range
endpoints
.
Subsets
{
ss
:=
&
endpoints
.
Subsets
[
i
]
for
i
:=
range
ss
.
Ports
{
port
:=
&
ss
.
Ports
[
i
]
if
port
.
Port
==
0
{
glog
.
Warningf
(
"ignoring invalid endpoint port %s"
,
port
.
Name
)
continue
}
svcPortName
:=
ServicePortName
{
NamespacedName
:
types
.
NamespacedName
{
Namespace
:
endpoints
.
Namespace
,
Name
:
endpoints
.
Name
},
Port
:
port
.
Name
,
}
for
i
:=
range
ss
.
Addresses
{
addr
:=
&
ss
.
Addresses
[
i
]
if
addr
.
IP
==
""
{
glog
.
Warningf
(
"ignoring invalid endpoint port %s with empty host"
,
port
.
Name
)
continue
}
isLocal
:=
addr
.
NodeName
!=
nil
&&
*
addr
.
NodeName
==
hostname
epInfo
:=
makeEndpoints
(
addr
.
IP
,
int
(
port
.
Port
),
isLocal
)
endpointsMap
[
svcPortName
]
=
append
(
endpointsMap
[
svcPortName
],
epInfo
)
}
if
glog
.
V
(
3
)
{
newEPList
:=
[]
string
{}
for
_
,
ep
:=
range
endpointsMap
[
svcPortName
]
{
newEPList
=
append
(
newEPList
,
ep
.
String
())
}
glog
.
Infof
(
"Setting endpoints for %q to %+v"
,
svcPortName
,
newEPList
)
}
}
}
return
endpointsMap
}
// apply the changes to EndpointsMap and updates stale endpoints and service-endpoints pair. The `staleEndpoints` argument
// is passed in to store the stale udp endpoints and `staleServiceNames` argument is passed in to store the stale udp service.
// The changes map is cleared after applying them.
func
(
endpointsMap
EndpointsMap
)
apply
(
changes
*
EndpointChangeTracker
,
staleEndpoints
*
[]
ServiceEndpoint
,
staleServiceNames
*
[]
ServicePortName
)
{
if
changes
==
nil
{
return
}
changes
.
lock
.
Lock
()
defer
changes
.
lock
.
Unlock
()
for
_
,
change
:=
range
changes
.
items
{
endpointsMap
.
Unmerge
(
change
.
previous
)
endpointsMap
.
Merge
(
change
.
current
)
detectStaleConnections
(
change
.
previous
,
change
.
current
,
staleEndpoints
,
staleServiceNames
)
}
changes
.
items
=
make
(
map
[
types
.
NamespacedName
]
*
endpointsChange
)
}
// Merge ensures that the current EndpointsMap contains all <service, endpoints> pairs from the EndpointsMap passed in.
func
(
em
EndpointsMap
)
Merge
(
other
EndpointsMap
)
{
for
svcPortName
:=
range
other
{
em
[
svcPortName
]
=
other
[
svcPortName
]
}
}
// Unmerge removes the <service, endpoints> pairs from the current EndpointsMap which are contained in the EndpointsMap passed in.
func
(
em
EndpointsMap
)
Unmerge
(
other
EndpointsMap
)
{
for
svcPortName
:=
range
other
{
delete
(
em
,
svcPortName
)
}
}
// GetLocalEndpointIPs returns endpoints IPs if given endpoint is local - local means the endpoint is running in same host as kube-proxy.
func
GetLocalEndpointIPs
(
endpointsMap
EndpointsMap
)
map
[
types
.
NamespacedName
]
sets
.
String
{
localIPs
:=
make
(
map
[
types
.
NamespacedName
]
sets
.
String
)
for
svcPortName
,
epList
:=
range
endpointsMap
{
for
_
,
ep
:=
range
epList
{
if
ep
.
IsLocal
()
{
nsn
:=
svcPortName
.
NamespacedName
if
localIPs
[
nsn
]
==
nil
{
localIPs
[
nsn
]
=
sets
.
NewString
()
}
localIPs
[
nsn
]
.
Insert
(
ep
.
IP
())
}
}
}
return
localIPs
}
// detectStaleConnections modifies <staleEndpoints> and <staleServices> with detected stale connections. <staleServiceNames>
// is used to store stale udp service in order to clear udp conntrack later.
func
detectStaleConnections
(
oldEndpointsMap
,
newEndpointsMap
EndpointsMap
,
staleEndpoints
*
[]
ServiceEndpoint
,
staleServiceNames
*
[]
ServicePortName
)
{
for
svcPortName
,
epList
:=
range
oldEndpointsMap
{
for
_
,
ep
:=
range
epList
{
stale
:=
true
for
i
:=
range
newEndpointsMap
[
svcPortName
]
{
if
newEndpointsMap
[
svcPortName
][
i
]
.
Equal
(
ep
)
{
stale
=
false
break
}
}
if
stale
{
glog
.
V
(
4
)
.
Infof
(
"Stale endpoint %v -> %v"
,
svcPortName
,
ep
.
String
())
*
staleEndpoints
=
append
(
*
staleEndpoints
,
ServiceEndpoint
{
Endpoint
:
ep
.
String
(),
ServicePortName
:
svcPortName
})
}
}
}
for
svcPortName
,
epList
:=
range
newEndpointsMap
{
// For udp service, if its backend changes from 0 to non-0. There may exist a conntrack entry that could blackhole traffic to the service.
if
len
(
epList
)
>
0
&&
len
(
oldEndpointsMap
[
svcPortName
])
==
0
{
*
staleServiceNames
=
append
(
*
staleServiceNames
,
svcPortName
)
}
}
}
pkg/proxy/endpoints_test.go
0 → 100644
View file @
6edcf02d
This diff is collapsed.
Click to expand it.
pkg/proxy/util/endpoints.go
View file @
6edcf02d
...
...
@@ -47,6 +47,7 @@ func IPPart(s string) string {
return
""
}
// PortPart returns just the port part of an endpoint string.
func
PortPart
(
s
string
)
(
int
,
error
)
{
// Must be IP:port
_
,
port
,
err
:=
net
.
SplitHostPort
(
s
)
...
...
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