istio

Форк
0
169 строк · 6.0 Кб
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package serviceentry
16

17
import (
18
	"k8s.io/apimachinery/pkg/types"
19

20
	"istio.io/istio/pilot/pkg/model"
21
	"istio.io/istio/pkg/util/sets"
22
)
23

24
type hostPort struct {
25
	host instancesKey
26
	port int
27
}
28

29
// stores all the service instances from SE, WLE and pods
30
type serviceInstancesStore struct {
31
	ip2instance map[string][]*model.ServiceInstance
32
	// service instances by hostname -> config
33
	instances map[instancesKey]map[configKey][]*model.ServiceInstance
34
	// instances only for serviceentry
35
	instancesBySE map[types.NamespacedName]map[configKey][]*model.ServiceInstance
36
	// instancesByHostAndPort tells whether the host has instances.
37
	// This is used to validate that we only have one instance for DNS_ROUNDROBIN_LB.
38
	instancesByHostAndPort sets.Set[hostPort]
39
}
40

41
func (s *serviceInstancesStore) getByIP(ip string) []*model.ServiceInstance {
42
	return s.ip2instance[ip]
43
}
44

45
func (s *serviceInstancesStore) getAll() []*model.ServiceInstance {
46
	all := []*model.ServiceInstance{}
47
	for _, instances := range s.ip2instance {
48
		all = append(all, instances...)
49
	}
50
	return all
51
}
52

53
func (s *serviceInstancesStore) getByKey(key instancesKey) []*model.ServiceInstance {
54
	all := []*model.ServiceInstance{}
55
	for _, instances := range s.instances[key] {
56
		all = append(all, instances...)
57
	}
58
	return all
59
}
60

61
// deleteInstanceKeys deletes all instances with the given configKey and instanceKey
62
// Note: as a convenience, this takes a []ServiceInstance instead of []instanceKey, as most callers have this format
63
// However, this function only operates on the instance keys
64
func (s *serviceInstancesStore) deleteInstanceKeys(key configKey, instances []*model.ServiceInstance) {
65
	for _, i := range instances {
66
		ikey := makeInstanceKey(i)
67
		s.instancesByHostAndPort.Delete(hostPort{ikey, i.ServicePort.Port})
68
		oldInstances := s.instances[ikey][key]
69
		delete(s.instances[ikey], key)
70
		if len(s.instances[ikey]) == 0 {
71
			delete(s.instances, ikey)
72
		}
73
		delete(s.ip2instance, i.Endpoint.Address)
74
		// Cleanup stale IPs, if the IPs changed
75
		for _, oi := range oldInstances {
76
			s.instancesByHostAndPort.Delete(hostPort{ikey, oi.ServicePort.Port})
77
			delete(s.ip2instance, oi.Endpoint.Address)
78
		}
79
	}
80
}
81

82
// addInstances add the instances to the store.
83
func (s *serviceInstancesStore) addInstances(key configKey, instances []*model.ServiceInstance) {
84
	for _, instance := range instances {
85
		ikey := makeInstanceKey(instance)
86
		hostPort := hostPort{ikey, instance.ServicePort.Port}
87
		// For DNSRoundRobinLB resolution type, check if service instances already exist and do not add
88
		// if it already exist. This can happen if two Service Entries are created with same host name,
89
		// resolution as DNS_ROUND_ROBIN and with same/different endpoints.
90
		if instance.Service.Resolution == model.DNSRoundRobinLB &&
91
			s.instancesByHostAndPort.Contains(hostPort) {
92
			log.Debugf("skipping service %s from service entry %s with DnsRoundRobinLB. A service entry with the same host "+
93
				"already exists. Only one locality lb end point is allowed for DnsRoundRobinLB services.",
94
				ikey.hostname, key.name+"/"+key.namespace)
95
			continue
96
		}
97
		if _, f := s.instances[ikey]; !f {
98
			s.instances[ikey] = map[configKey][]*model.ServiceInstance{}
99
		}
100
		s.instancesByHostAndPort.Insert(hostPort)
101
		s.instances[ikey][key] = append(s.instances[ikey][key], instance)
102
		if instance.Endpoint.Address != "" {
103
			s.ip2instance[instance.Endpoint.Address] = append(s.ip2instance[instance.Endpoint.Address], instance)
104
		}
105
	}
106
}
107

108
func (s *serviceInstancesStore) updateInstances(key configKey, instances []*model.ServiceInstance) {
109
	// first delete
110
	s.deleteInstanceKeys(key, instances)
111

112
	// second add
113
	s.addInstances(key, instances)
114
}
115

116
func (s *serviceInstancesStore) getServiceEntryInstances(key types.NamespacedName) map[configKey][]*model.ServiceInstance {
117
	return s.instancesBySE[key]
118
}
119

120
func (s *serviceInstancesStore) updateServiceEntryInstances(key types.NamespacedName, instances map[configKey][]*model.ServiceInstance) {
121
	s.instancesBySE[key] = instances
122
}
123

124
func (s *serviceInstancesStore) updateServiceEntryInstancesPerConfig(key types.NamespacedName, cKey configKey, instances []*model.ServiceInstance) {
125
	if s.instancesBySE[key] == nil {
126
		s.instancesBySE[key] = map[configKey][]*model.ServiceInstance{}
127
	}
128
	s.instancesBySE[key][cKey] = instances
129
}
130

131
func (s *serviceInstancesStore) deleteServiceEntryInstances(key types.NamespacedName, cKey configKey) {
132
	delete(s.instancesBySE[key], cKey)
133
	if len(s.instancesBySE[key]) == 0 {
134
		delete(s.instancesBySE, key)
135
	}
136
}
137

138
func (s *serviceInstancesStore) deleteAllServiceEntryInstances(key types.NamespacedName) {
139
	delete(s.instancesBySE, key)
140
}
141

142
// stores all the services converted from serviceEntries
143
type serviceStore struct {
144
	// services keeps track of all services - mainly used to return from Services() to avoid reconversion.
145
	servicesBySE   map[types.NamespacedName][]*model.Service
146
	allocateNeeded bool
147
}
148

149
// getAllServices return all the services.
150
func (s *serviceStore) getAllServices() []*model.Service {
151
	var out []*model.Service
152
	for _, svcs := range s.servicesBySE {
153
		out = append(out, svcs...)
154
	}
155
	return model.SortServicesByCreationTime(out)
156
}
157

158
func (s *serviceStore) getServices(key types.NamespacedName) []*model.Service {
159
	return s.servicesBySE[key]
160
}
161

162
func (s *serviceStore) deleteServices(key types.NamespacedName) {
163
	delete(s.servicesBySE, key)
164
}
165

166
func (s *serviceStore) updateServices(key types.NamespacedName, services []*model.Service) {
167
	s.servicesBySE[key] = services
168
	s.allocateNeeded = true
169
}
170

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.