istio
156 строк · 4.8 Кб
1// Copyright Istio Authors. All Rights Reserved.
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
15package controller
16
17import (
18v1 "k8s.io/api/core/v1"
19
20"istio.io/api/label"
21"istio.io/istio/pilot/pkg/model"
22"istio.io/istio/pilot/pkg/networking/util"
23"istio.io/istio/pilot/pkg/serviceregistry/kube"
24labelutil "istio.io/istio/pilot/pkg/serviceregistry/util/label"
25"istio.io/istio/pkg/config/labels"
26kubeUtil "istio.io/istio/pkg/kube"
27"istio.io/istio/pkg/network"
28)
29
30// EndpointBuilder is a stateful IstioEndpoint builder with metadata used to build IstioEndpoint
31type EndpointBuilder struct {
32controller controllerInterface
33
34labels labels.Instance
35metaNetwork network.ID
36serviceAccount string
37locality model.Locality
38tlsMode string
39workloadName string
40namespace string
41
42// Values used to build dns name tables per pod.
43// The hostname of the Pod, by default equals to pod name.
44hostname string
45// If specified, the fully qualified Pod hostname will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>".
46subDomain string
47// If in k8s, the node where the pod resides
48nodeName string
49}
50
51func NewEndpointBuilder(c controllerInterface, pod *v1.Pod) *EndpointBuilder {
52var locality, sa, namespace, hostname, subdomain, ip, node string
53var podLabels labels.Instance
54if pod != nil {
55locality = c.getPodLocality(pod)
56sa = kube.SecureNamingSAN(pod)
57podLabels = pod.Labels
58namespace = pod.Namespace
59subdomain = pod.Spec.Subdomain
60if subdomain != "" {
61hostname = pod.Spec.Hostname
62if hostname == "" {
63hostname = pod.Name
64}
65}
66ip = pod.Status.PodIP
67node = pod.Spec.NodeName
68}
69dm, _ := kubeUtil.GetDeployMetaFromPod(pod)
70out := &EndpointBuilder{
71controller: c,
72serviceAccount: sa,
73locality: model.Locality{
74Label: locality,
75ClusterID: c.Cluster(),
76},
77tlsMode: kube.PodTLSMode(pod),
78workloadName: dm.Name,
79namespace: namespace,
80hostname: hostname,
81subDomain: subdomain,
82labels: podLabels,
83nodeName: node,
84}
85networkID := out.endpointNetwork(ip)
86out.labels = labelutil.AugmentLabels(podLabels, c.Cluster(), locality, node, networkID)
87return out
88}
89
90func NewEndpointBuilderFromMetadata(c controllerInterface, proxy *model.Proxy) *EndpointBuilder {
91locality := util.LocalityToString(proxy.Locality)
92out := &EndpointBuilder{
93controller: c,
94metaNetwork: proxy.Metadata.Network,
95serviceAccount: proxy.Metadata.ServiceAccount,
96locality: model.Locality{
97Label: locality,
98ClusterID: c.Cluster(),
99},
100tlsMode: model.GetTLSModeFromEndpointLabels(proxy.Labels),
101nodeName: proxy.GetNodeName(),
102}
103var networkID network.ID
104if len(proxy.IPAddresses) > 0 {
105networkID = out.endpointNetwork(proxy.IPAddresses[0])
106}
107out.labels = labelutil.AugmentLabels(proxy.Labels, c.Cluster(), locality, out.nodeName, networkID)
108return out
109}
110
111func (b *EndpointBuilder) buildIstioEndpoint(
112endpointAddress string,
113endpointPort int32,
114svcPortName string,
115discoverabilityPolicy model.EndpointDiscoverabilityPolicy,
116healthStatus model.HealthStatus,
117) *model.IstioEndpoint {
118if b == nil {
119return nil
120}
121
122// in case pod is not found when init EndpointBuilder.
123networkID := network.ID(b.labels[label.TopologyNetwork.Name])
124if networkID == "" {
125networkID = b.endpointNetwork(endpointAddress)
126b.labels[label.TopologyNetwork.Name] = string(networkID)
127}
128
129return &model.IstioEndpoint{
130Labels: b.labels,
131ServiceAccount: b.serviceAccount,
132Locality: b.locality,
133TLSMode: b.tlsMode,
134Address: endpointAddress,
135EndpointPort: uint32(endpointPort),
136ServicePortName: svcPortName,
137Network: networkID,
138WorkloadName: b.workloadName,
139Namespace: b.namespace,
140HostName: b.hostname,
141SubDomain: b.subDomain,
142DiscoverabilityPolicy: discoverabilityPolicy,
143HealthStatus: healthStatus,
144NodeName: b.nodeName,
145}
146}
147
148// return the mesh network for the endpoint IP. Empty string if not found.
149func (b *EndpointBuilder) endpointNetwork(endpointIP string) network.ID {
150// If we're building the endpoint based on proxy meta, prefer the injected ISTIO_META_NETWORK value.
151if b.metaNetwork != "" {
152return b.metaNetwork
153}
154
155return b.controller.Network(endpointIP, b.labels)
156}
157