Skip to content

Commit 5e20a6d

Browse files
committed
tg-node-annotation-patch
Signed-off-by: Ilya Lisitsyn <ilya.lisitsyn@flant.com>
1 parent d9f4b29 commit 5e20a6d

5 files changed

Lines changed: 53 additions & 21 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.DS_Store
12
# Program binaries
23
*.exe
34
*.exe~

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ Due to API limitations, only one subnet from each zone must be present in each N
129129
* `yandex.cpi.flant.com/listener-subnet-id` – default SubnetID to use for Listeners in created NetworkLoadBalancers. NetworkLoadBalancers will be INTERNAL.
130130
* `yandex.cpi.flant.com/listener-address-ipv4` – select pre-defined IPv4 address. Works both on internal and external NetworkLoadBalancers.
131131
* `yandex.cpi.flant.com/loadbalancer-external` – override `YANDEX_CLOUD_DEFAULT_LB_LISTENER_SUBNET_ID` per-service.
132+
* `yandex.cpi.flant.com/target-group-name-prefix` - set target group for LB to target group with name `yandex.cpi.flant.com/target-group-name-prefix` annotation value + yandex cluster name + `YANDEX_CLOUD_DEFAULT_LB_TARGET_GROUP_NETWORK_ID`.
133+
134+
##### Node annotations
135+
136+
* `yandex.cpi.flant.com/target-group-name-prefix` - set node to the non-default target group add this annotation to the node. Yandex CCM creates new target groups with name `yandex.cpi.flant.com/target-group-name-prefix` annotation value + yandex cluster name + network id of instance interfaces.
132137

133138
## Warning
134139

pkg/cloudprovider/yandex/load_balancer.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ import (
1313
)
1414

1515
const (
16-
targetGroupNetworkIdAnnotation = "yandex.cpi.flant.com/target-group-network-id"
17-
externalLoadBalancerAnnotation = "yandex.cpi.flant.com/loadbalancer-external"
18-
listenerSubnetIdAnnotation = "yandex.cpi.flant.com/listener-subnet-id"
19-
listenerAddressIPv4 = "yandex.cpi.flant.com/listener-address-ipv4"
16+
// node annotation to put node to the specific target group
17+
customTargetGroupNamePrefixAnnotation = "yandex.cpi.flant.com/target-group-name-prefix"
18+
targetGroupNetworkIdAnnotation = "yandex.cpi.flant.com/target-group-network-id"
19+
externalLoadBalancerAnnotation = "yandex.cpi.flant.com/loadbalancer-external"
20+
listenerSubnetIdAnnotation = "yandex.cpi.flant.com/listener-subnet-id"
21+
listenerAddressIPv4 = "yandex.cpi.flant.com/listener-address-ipv4"
2022

2123
nodesHealthCheckPath = "/healthz"
2224
// NOTE: Please keep the following port in sync with ProxyHealthzPort in pkg/cluster/ports/ports.go
@@ -178,7 +180,8 @@ func (yc *Cloud) ensureLB(ctx context.Context, service *v1.Service, nodes []*v1.
178180
},
179181
}
180182

181-
tgName := yc.config.ClusterName + lbParams.targetGroupNetworkID
183+
tgName := lbParams.targetGroupNamePrefix + yc.config.ClusterName + lbParams.targetGroupNetworkID
184+
182185
tg, err := yc.yandexService.LbSvc.GetTgByName(ctx, tgName)
183186
if err != nil {
184187
return nil, err
@@ -201,10 +204,11 @@ func (yc *Cloud) ensureLB(ctx context.Context, service *v1.Service, nodes []*v1.
201204
}
202205

203206
type loadBalancerParameters struct {
204-
targetGroupNetworkID string
205-
listenerSubnetID string
206-
listenerAddressIPv4 string
207-
internal bool
207+
targetGroupNetworkID string
208+
targetGroupNamePrefix string
209+
listenerSubnetID string
210+
listenerAddressIPv4 string
211+
internal bool
208212
}
209213

210214
func (yc *Cloud) getLoadBalancerParameters(svc *v1.Service) (lbParams loadBalancerParameters) {
@@ -227,5 +231,9 @@ func (yc *Cloud) getLoadBalancerParameters(svc *v1.Service) (lbParams loadBalanc
227231
lbParams.listenerAddressIPv4 = value
228232
}
229233

234+
if value, ok := svc.ObjectMeta.Annotations[customTargetGroupNamePrefixAnnotation]; ok {
235+
lbParams.targetGroupNamePrefix = value
236+
}
237+
230238
return
231239
}

pkg/cloudprovider/yandex/load_balancer_tg_controller.go

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (ntgs *NodeTargetGroupSyncer) SyncTGs(ctx context.Context, nodes []*corev1.
6464
return nil
6565
}
6666

67-
type networkIdToTargetMap map[string][]*loadbalancer.Target
67+
type tgNameToTargetMap map[string][]*loadbalancer.Target
6868

6969
func fromNodeToInterfaceSlice(nodes []*corev1.Node) (ret []interface{}) {
7070
for _, node := range nodes {
@@ -97,6 +97,11 @@ func (ntgs *NodeTargetGroupSyncer) cleanUpTargetGroups(ctx context.Context) erro
9797
return nil
9898
}
9999

100+
type instanceWithNodeInfo struct {
101+
Instance *compute.Instance
102+
Node *corev1.Node
103+
}
104+
100105
func (ntgs *NodeTargetGroupSyncer) synchronizeNodesWithTargetGroups(ctx context.Context, nodes []*corev1.Node) error {
101106
if len(nodes) == 0 {
102107
klog.Info("no nodes to synchronize TGs with, skipping...")
@@ -109,7 +114,7 @@ func (ntgs *NodeTargetGroupSyncer) synchronizeNodesWithTargetGroups(ctx context.
109114
}
110115

111116
// TODO: speed up by not performing individual lookups
112-
var instances []*compute.Instance
117+
var instances []*instanceWithNodeInfo
113118
for _, node := range nodes {
114119
nodeName := MapNodeNameToInstanceName(types.NodeName(node.Name))
115120
log.Printf("Finding Instance by Folder %q and Name %q", ntgs.cloud.config.FolderID, nodeName)
@@ -118,16 +123,16 @@ func (ntgs *NodeTargetGroupSyncer) synchronizeNodesWithTargetGroups(ctx context.
118123
return fmt.Errorf("failed to find Instance by its name: %s", err)
119124
}
120125

121-
instances = append(instances, instance)
126+
instances = append(instances, &instanceWithNodeInfo{Instance: instance, Node: node})
122127
}
123128

124-
mapping, err := ntgs.constructNetworkIdToTargetMap(ctx, instances)
129+
mapping, err := ntgs.constructTgNameToTargetMap(ctx, instances)
125130
if err != nil {
126-
return fmt.Errorf("failed to construct NetworkIdToTargetMap: %s", err)
131+
return fmt.Errorf("failed to construct tgNameToTargetMap: %s", err)
127132
}
128133

129-
for networkID, targets := range mapping {
130-
_, err := ntgs.cloud.yandexService.LbSvc.CreateOrUpdateTG(ctx, ntgs.cloud.config.ClusterName+networkID, targets)
134+
for tgName, targets := range mapping {
135+
_, err := ntgs.cloud.yandexService.LbSvc.CreateOrUpdateTG(ctx, tgName, targets)
131136
if err != nil {
132137
return err
133138
}
@@ -138,18 +143,22 @@ func (ntgs *NodeTargetGroupSyncer) synchronizeNodesWithTargetGroups(ctx context.
138143
return nil
139144
}
140145

141-
func (ntgs *NodeTargetGroupSyncer) constructNetworkIdToTargetMap(ctx context.Context, instances []*compute.Instance) (networkIdToTargetMap, error) {
142-
mapping := make(networkIdToTargetMap)
146+
func (ntgs *NodeTargetGroupSyncer) constructTgNameToTargetMap(ctx context.Context, instances []*instanceWithNodeInfo) (tgNameToTargetMap, error) {
147+
mapping := make(tgNameToTargetMap)
143148

144149
// TODO: Implement simple caching mechanism for subnet-VPC membership lookups
145150
for _, instance := range instances {
146-
for _, iface := range instance.NetworkInterfaces {
151+
for _, iface := range instance.Instance.NetworkInterfaces {
147152
subnetInfo, err := ntgs.cloud.yandexService.VPCSvc.SubnetSvc.Get(ctx, &vpc.GetSubnetRequest{SubnetId: iface.SubnetId})
148153
if err != nil {
149154
return nil, errors.WithStack(err)
150155
}
151156

152-
mapping[subnetInfo.NetworkId] = append(mapping[subnetInfo.NetworkId], &loadbalancer.Target{
157+
key := ntgs.cloud.config.ClusterName + subnetInfo.NetworkId
158+
if v, ok := instance.Node.Annotations[customTargetGroupNamePrefixAnnotation]; ok {
159+
key = truncateAnnotationValue(v) + key
160+
}
161+
mapping[key] = append(mapping[key], &loadbalancer.Target{
153162
SubnetId: iface.SubnetId,
154163
Address: iface.PrimaryV4Address.Address,
155164
})
@@ -162,3 +171,12 @@ func (ntgs *NodeTargetGroupSyncer) constructNetworkIdToTargetMap(ctx context.Con
162171

163172
return mapping, nil
164173
}
174+
175+
func truncateAnnotationValue(value string) string {
176+
// maximum length of annotation values should not exceed 63 - length of cluster uuid(26 symbols) - length of network id(21)
177+
if len(value) > 36 {
178+
log.Printf("annotation '%s' length should be less than 36 characters, truncate it", value)
179+
value = value[:36]
180+
}
181+
return value
182+
}

pkg/yapi/loadbalancer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func (ySvc *LoadBalancerService) GetTGsByClusterName(ctx context.Context, cluste
197197
}
198198

199199
for _, tg := range result.TargetGroups {
200-
if strings.HasPrefix(tg.Name, clusterName) {
200+
if strings.Contains(tg.Name, clusterName) {
201201
ret = append(ret, tg)
202202
}
203203
}

0 commit comments

Comments
 (0)