mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #4032 from ddysher/remove-ip-cache
Remove ip cache, use node status cache instead.
This commit is contained in:
commit
2ac6bbb7eb
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package master
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewIPCache makes a new ip caching layer, which will get IP addresses from cp,
|
|
||||||
// and use clock for deciding when to re-get an IP address.
|
|
||||||
// Thread-safe.
|
|
||||||
//
|
|
||||||
// TODO: when we switch to go1.4, this class would be a good candidate for something
|
|
||||||
// that could be produced from a template and a type via `go generate`.
|
|
||||||
func NewIPCache(cp cloudprovider.Interface, clock util.Clock, ttl time.Duration) *ipCache {
|
|
||||||
return &ipCache{
|
|
||||||
cache: util.NewTimeCache(
|
|
||||||
clock,
|
|
||||||
ttl,
|
|
||||||
func(host string) util.T {
|
|
||||||
return getInstanceIPFromCloud(cp, host)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ipCache struct {
|
|
||||||
cache util.TimeCache
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInstanceIP returns the IP address of host, from the cache
|
|
||||||
// if possible, otherwise it asks the cloud provider.
|
|
||||||
func (c *ipCache) GetInstanceIP(host string) string {
|
|
||||||
return c.cache.Get(host).(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getInstanceIPFromCloud(cloud cloudprovider.Interface, host string) string {
|
|
||||||
if cloud == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
instances, ok := cloud.Instances()
|
|
||||||
if instances == nil || !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
addr, err := instances.IPAddress(host)
|
|
||||||
if err != nil {
|
|
||||||
glog.Errorf("Error getting instance IP for %q: %v", host, err)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return addr.String()
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package master
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
fake_cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake"
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCacheExpire(t *testing.T) {
|
|
||||||
fakeCloud := &fake_cloud.FakeCloud{}
|
|
||||||
clock := &util.FakeClock{time.Now()}
|
|
||||||
|
|
||||||
c := NewIPCache(fakeCloud, clock, 60*time.Second)
|
|
||||||
|
|
||||||
_ = c.GetInstanceIP("foo")
|
|
||||||
// This call should hit the cache, so we expect no additional calls to the cloud
|
|
||||||
_ = c.GetInstanceIP("foo")
|
|
||||||
// Advance the clock, this call should miss the cache, so expect one more call.
|
|
||||||
clock.Time = clock.Time.Add(61 * time.Second)
|
|
||||||
_ = c.GetInstanceIP("foo")
|
|
||||||
|
|
||||||
if len(fakeCloud.Calls) != 2 || fakeCloud.Calls[1] != "ip-address" || fakeCloud.Calls[0] != "ip-address" {
|
|
||||||
t.Errorf("Unexpected calls: %+v", fakeCloud.Calls)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCacheNotExpire(t *testing.T) {
|
|
||||||
fakeCloud := &fake_cloud.FakeCloud{}
|
|
||||||
clock := &util.FakeClock{time.Now()}
|
|
||||||
|
|
||||||
c := NewIPCache(fakeCloud, clock, 60*time.Second)
|
|
||||||
|
|
||||||
_ = c.GetInstanceIP("foo")
|
|
||||||
// This call should hit the cache, so we expect no additional calls to the cloud
|
|
||||||
clock.Time = clock.Time.Add(60 * time.Second)
|
|
||||||
_ = c.GetInstanceIP("foo")
|
|
||||||
|
|
||||||
if len(fakeCloud.Calls) != 1 || fakeCloud.Calls[0] != "ip-address" {
|
|
||||||
t.Errorf("Unexpected calls: %+v", fakeCloud.Calls)
|
|
||||||
}
|
|
||||||
}
|
|
@ -141,7 +141,6 @@ type Master struct {
|
|||||||
admissionControl admission.Interface
|
admissionControl admission.Interface
|
||||||
masterCount int
|
masterCount int
|
||||||
v1beta3 bool
|
v1beta3 bool
|
||||||
nodeIPCache IPGetter
|
|
||||||
|
|
||||||
publicIP net.IP
|
publicIP net.IP
|
||||||
publicReadOnlyPort int
|
publicReadOnlyPort int
|
||||||
@ -295,7 +294,6 @@ func New(c *Config) *Master {
|
|||||||
authorizer: c.Authorizer,
|
authorizer: c.Authorizer,
|
||||||
admissionControl: c.AdmissionControl,
|
admissionControl: c.AdmissionControl,
|
||||||
v1beta3: c.EnableV1Beta3,
|
v1beta3: c.EnableV1Beta3,
|
||||||
nodeIPCache: NewIPCache(c.Cloud, util.RealClock{}, c.CacheTimeout),
|
|
||||||
|
|
||||||
cacheTimeout: c.CacheTimeout,
|
cacheTimeout: c.CacheTimeout,
|
||||||
|
|
||||||
@ -374,7 +372,6 @@ func (m *Master) init(c *Config) {
|
|||||||
|
|
||||||
nodeRESTStorage := minion.NewREST(m.minionRegistry)
|
nodeRESTStorage := minion.NewREST(m.minionRegistry)
|
||||||
podCache := NewPodCache(
|
podCache := NewPodCache(
|
||||||
m.nodeIPCache,
|
|
||||||
c.KubeletClient,
|
c.KubeletClient,
|
||||||
RESTStorageToNodes(nodeRESTStorage).Nodes(),
|
RESTStorageToNodes(nodeRESTStorage).Nodes(),
|
||||||
m.podRegistry,
|
m.podRegistry,
|
||||||
|
@ -28,14 +28,9 @@ import (
|
|||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IPGetter interface {
|
|
||||||
GetInstanceIP(host string) (ip string)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PodCache contains both a cache of container information, as well as the mechanism for keeping
|
// PodCache contains both a cache of container information, as well as the mechanism for keeping
|
||||||
// that cache up to date.
|
// that cache up to date.
|
||||||
type PodCache struct {
|
type PodCache struct {
|
||||||
ipCache IPGetter
|
|
||||||
containerInfo client.PodInfoGetter
|
containerInfo client.PodInfoGetter
|
||||||
pods pod.Registry
|
pods pod.Registry
|
||||||
// For confirming existance of a node
|
// For confirming existance of a node
|
||||||
@ -57,9 +52,8 @@ type objKey struct {
|
|||||||
// NewPodCache returns a new PodCache which watches container information
|
// NewPodCache returns a new PodCache which watches container information
|
||||||
// registered in the given PodRegistry.
|
// registered in the given PodRegistry.
|
||||||
// TODO(lavalamp): pods should be a client.PodInterface.
|
// TODO(lavalamp): pods should be a client.PodInterface.
|
||||||
func NewPodCache(ipCache IPGetter, info client.PodInfoGetter, nodes client.NodeInterface, pods pod.Registry) *PodCache {
|
func NewPodCache(info client.PodInfoGetter, nodes client.NodeInterface, pods pod.Registry) *PodCache {
|
||||||
return &PodCache{
|
return &PodCache{
|
||||||
ipCache: ipCache,
|
|
||||||
containerInfo: info,
|
containerInfo: info,
|
||||||
pods: pods,
|
pods: pods,
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
@ -187,7 +181,7 @@ func (p *PodCache) computePodStatus(pod *api.Pod) (api.PodStatus, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result, err := p.containerInfo.GetPodStatus(pod.Status.Host, pod.Namespace, pod.Name)
|
result, err := p.containerInfo.GetPodStatus(pod.Status.Host, pod.Namespace, pod.Name)
|
||||||
newStatus.HostIP = p.ipCache.GetInstanceIP(pod.Status.Host)
|
newStatus.HostIP = nodeStatus.HostIP
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newStatus.Phase = api.PodUnknown
|
newStatus.Phase = api.PodUnknown
|
||||||
|
@ -74,7 +74,7 @@ func (f *FakePodInfoGetter) GetPodStatus(host, namespace, name string) (api.PodS
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPodCacheGetDifferentNamespace(t *testing.T) {
|
func TestPodCacheGetDifferentNamespace(t *testing.T) {
|
||||||
cache := NewPodCache(nil, nil, nil, nil)
|
cache := NewPodCache(nil, nil, nil)
|
||||||
|
|
||||||
expectedDefault := api.PodStatus{
|
expectedDefault := api.PodStatus{
|
||||||
Info: api.PodInfo{
|
Info: api.PodInfo{
|
||||||
@ -108,7 +108,7 @@ func TestPodCacheGetDifferentNamespace(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPodCacheGet(t *testing.T) {
|
func TestPodCacheGet(t *testing.T) {
|
||||||
cache := NewPodCache(nil, nil, nil, nil)
|
cache := NewPodCache(nil, nil, nil)
|
||||||
|
|
||||||
expected := api.PodStatus{
|
expected := api.PodStatus{
|
||||||
Info: api.PodInfo{
|
Info: api.PodInfo{
|
||||||
@ -156,21 +156,14 @@ func TestPodCacheDelete(t *testing.T) {
|
|||||||
if err != client.ErrPodInfoNotAvailable {
|
if err != client.ErrPodInfoNotAvailable {
|
||||||
t.Errorf("Unexpected error: %v, expecting: %v", err, client.ErrPodInfoNotAvailable)
|
t.Errorf("Unexpected error: %v, expecting: %v", err, client.ErrPodInfoNotAvailable)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPodCacheGetMissing(t *testing.T) {
|
func TestPodCacheGetMissing(t *testing.T) {
|
||||||
pod1 := makePod(api.NamespaceDefault, "foo", "machine", "bar")
|
pod1 := makePod(api.NamespaceDefault, "foo", "machine", "bar")
|
||||||
config := podCacheTestConfig{
|
config := podCacheTestConfig{
|
||||||
ipFunc: func(host string) string {
|
|
||||||
if host == "machine" {
|
|
||||||
return "1.2.3.5"
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
},
|
|
||||||
kubeletContainerInfo: api.PodStatus{
|
kubeletContainerInfo: api.PodStatus{
|
||||||
Info: api.PodInfo{"bar": api.ContainerStatus{}}},
|
Info: api.PodInfo{"bar": api.ContainerStatus{}}},
|
||||||
nodes: []api.Node{*makeHealthyNode("machine")},
|
nodes: []api.Node{*makeHealthyNode("machine", "1.2.3.5")},
|
||||||
pod: pod1,
|
pod: pod1,
|
||||||
}
|
}
|
||||||
cache := config.Construct()
|
cache := config.Construct()
|
||||||
@ -195,14 +188,7 @@ func TestPodCacheGetMissing(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeIPCache func(string) string
|
|
||||||
|
|
||||||
func (f fakeIPCache) GetInstanceIP(host string) (ip string) {
|
|
||||||
return f(host)
|
|
||||||
}
|
|
||||||
|
|
||||||
type podCacheTestConfig struct {
|
type podCacheTestConfig struct {
|
||||||
ipFunc func(string) string // Construct will set a default if nil
|
|
||||||
nodes []api.Node
|
nodes []api.Node
|
||||||
pods []api.Pod
|
pods []api.Pod
|
||||||
pod *api.Pod
|
pod *api.Pod
|
||||||
@ -216,11 +202,6 @@ type podCacheTestConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *podCacheTestConfig) Construct() *PodCache {
|
func (c *podCacheTestConfig) Construct() *PodCache {
|
||||||
if c.ipFunc == nil {
|
|
||||||
c.ipFunc = func(host string) string {
|
|
||||||
return "ip of " + host
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.fakePodInfo = &FakePodInfoGetter{
|
c.fakePodInfo = &FakePodInfoGetter{
|
||||||
data: api.PodStatusResult{
|
data: api.PodStatusResult{
|
||||||
Status: c.kubeletContainerInfo,
|
Status: c.kubeletContainerInfo,
|
||||||
@ -235,7 +216,6 @@ func (c *podCacheTestConfig) Construct() *PodCache {
|
|||||||
c.fakePods.Pod = c.pod
|
c.fakePods.Pod = c.pod
|
||||||
c.fakePods.Err = c.err
|
c.fakePods.Err = c.err
|
||||||
return NewPodCache(
|
return NewPodCache(
|
||||||
fakeIPCache(c.ipFunc),
|
|
||||||
c.fakePodInfo,
|
c.fakePodInfo,
|
||||||
c.fakeNodes.Nodes(),
|
c.fakeNodes.Nodes(),
|
||||||
c.fakePods,
|
c.fakePods,
|
||||||
@ -253,12 +233,15 @@ func makePod(namespace, name, host string, containers ...string) *api.Pod {
|
|||||||
return pod
|
return pod
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHealthyNode(name string) *api.Node {
|
func makeHealthyNode(name string, ip string) *api.Node {
|
||||||
return &api.Node{
|
return &api.Node{
|
||||||
ObjectMeta: api.ObjectMeta{Name: name},
|
ObjectMeta: api.ObjectMeta{Name: name},
|
||||||
Status: api.NodeStatus{Conditions: []api.NodeCondition{
|
Status: api.NodeStatus{
|
||||||
{Kind: api.NodeReady, Status: api.ConditionFull},
|
HostIP: ip,
|
||||||
}},
|
Conditions: []api.NodeCondition{
|
||||||
|
{Kind: api.NodeReady, Status: api.ConditionFull},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,15 +258,9 @@ func TestPodUpdateAllContainers(t *testing.T) {
|
|||||||
pod1 := makePod(api.NamespaceDefault, "foo", "machine", "bar")
|
pod1 := makePod(api.NamespaceDefault, "foo", "machine", "bar")
|
||||||
pod2 := makePod(api.NamespaceDefault, "baz", "machine", "qux")
|
pod2 := makePod(api.NamespaceDefault, "baz", "machine", "qux")
|
||||||
config := podCacheTestConfig{
|
config := podCacheTestConfig{
|
||||||
ipFunc: func(host string) string {
|
|
||||||
if host == "machine" {
|
|
||||||
return "1.2.3.5"
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
},
|
|
||||||
kubeletContainerInfo: api.PodStatus{
|
kubeletContainerInfo: api.PodStatus{
|
||||||
Info: api.PodInfo{"bar": api.ContainerStatus{}}},
|
Info: api.PodInfo{"bar": api.ContainerStatus{}}},
|
||||||
nodes: []api.Node{*makeHealthyNode("machine")},
|
nodes: []api.Node{*makeHealthyNode("machine", "1.2.3.5")},
|
||||||
pods: []api.Pod{*pod1, *pod2},
|
pods: []api.Pod{*pod1, *pod2},
|
||||||
}
|
}
|
||||||
cache := config.Construct()
|
cache := config.Construct()
|
||||||
@ -326,7 +303,7 @@ func TestFillPodStatusNoHost(t *testing.T) {
|
|||||||
pod := makePod(api.NamespaceDefault, "foo", "", "bar")
|
pod := makePod(api.NamespaceDefault, "foo", "", "bar")
|
||||||
config := podCacheTestConfig{
|
config := podCacheTestConfig{
|
||||||
kubeletContainerInfo: api.PodStatus{},
|
kubeletContainerInfo: api.PodStatus{},
|
||||||
nodes: []api.Node{*makeHealthyNode("machine")},
|
nodes: []api.Node{*makeHealthyNode("machine", "")},
|
||||||
pods: []api.Pod{*pod},
|
pods: []api.Pod{*pod},
|
||||||
}
|
}
|
||||||
cache := config.Construct()
|
cache := config.Construct()
|
||||||
@ -382,7 +359,7 @@ func TestFillPodStatus(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nodes: []api.Node{*makeHealthyNode("machine")},
|
nodes: []api.Node{*makeHealthyNode("machine", "ip of machine")},
|
||||||
pods: []api.Pod{*pod},
|
pods: []api.Pod{*pod},
|
||||||
}
|
}
|
||||||
cache := config.Construct()
|
cache := config.Construct()
|
||||||
@ -409,7 +386,7 @@ func TestFillPodInfoNoData(t *testing.T) {
|
|||||||
leaky.PodInfraContainerName: {},
|
leaky.PodInfraContainerName: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nodes: []api.Node{*makeHealthyNode("machine")},
|
nodes: []api.Node{*makeHealthyNode("machine", "ip of machine")},
|
||||||
pods: []api.Pod{*pod},
|
pods: []api.Pod{*pod},
|
||||||
}
|
}
|
||||||
cache := config.Construct()
|
cache := config.Construct()
|
||||||
|
Loading…
Reference in New Issue
Block a user