Skip to content

Commit

Permalink
Refactor(instance): Refactor the way instance metadata is retrieved
Browse files Browse the repository at this point in the history
- Modify the logic for retrieving instance metadata, optimizing with interfaces and caching
- Refactor the way EFLO instance metadata is retrieved
- Update relevant unit tests

Signed-off-by: l1b0k <[email protected]>
  • Loading branch information
l1b0k committed Feb 20, 2025
1 parent 2f8cb10 commit 367e9b0
Show file tree
Hide file tree
Showing 44 changed files with 1,376 additions and 528 deletions.
56 changes: 53 additions & 3 deletions cmd/terway-cli/cni_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package main
import (
"errors"
"fmt"
"strconv"
"strings"
"syscall"

"github.com/docker/docker/pkg/parsers/kernel"
"github.com/vishvananda/netlink"
utilfeature "k8s.io/apiserver/pkg/util/feature"

Expand Down Expand Up @@ -60,6 +62,54 @@ func allowEBPFNetworkPolicy(require bool) (bool, error) {
return require, nil
}

func checkKernelVersion(k, major, minor int) bool {
return kernel.CheckKernelVersion(k, major, minor)
func checkKernelVersion(iMajor, iMinor, iPatch int) bool {
var un syscall.Utsname
syscall.Uname(&un)
var sb strings.Builder
for _, b := range un.Release[:] {
if b == 0 {
break

Check warning on line 71 in cmd/terway-cli/cni_linux.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-cli/cni_linux.go#L65-L71

Added lines #L65 - L71 were not covered by tests
}
sb.WriteByte(byte(b))

Check warning on line 73 in cmd/terway-cli/cni_linux.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-cli/cni_linux.go#L73

Added line #L73 was not covered by tests
}
major, minor, patch, ok := parseRelease(sb.String())
return ok && (major > iMajor ||
major == iMajor && minor > iMinor ||
major == iMajor && minor == iMinor && iPatch >= patch)

Check warning on line 78 in cmd/terway-cli/cni_linux.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-cli/cni_linux.go#L75-L78

Added lines #L75 - L78 were not covered by tests
}

// parseRelease parses a dot-separated version number. It follows the semver
// syntax, but allows the minor and patch versions to be elided.
//
// This is a copy of the Go runtime's parseRelease from
// https://golang.org/cl/209597.
func parseRelease(rel string) (major, minor, patch int, ok bool) {
// Strip anything after a dash or plus.
for i := 0; i < len(rel); i++ {
if rel[i] == '-' || rel[i] == '+' {
rel = rel[:i]
break

Check warning on line 91 in cmd/terway-cli/cni_linux.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-cli/cni_linux.go#L86-L91

Added lines #L86 - L91 were not covered by tests
}
}

next := func() (int, bool) {
for i := 0; i < len(rel); i++ {
if rel[i] == '.' {
ver, err := strconv.Atoi(rel[:i])
rel = rel[i+1:]
return ver, err == nil
}

Check warning on line 101 in cmd/terway-cli/cni_linux.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-cli/cni_linux.go#L95-L101

Added lines #L95 - L101 were not covered by tests
}
ver, err := strconv.Atoi(rel)
rel = ""
return ver, err == nil

Check warning on line 105 in cmd/terway-cli/cni_linux.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-cli/cni_linux.go#L103-L105

Added lines #L103 - L105 were not covered by tests
}
if major, ok = next(); !ok || rel == "" {
return
}
if minor, ok = next(); !ok || rel == "" {
return
}
patch, ok = next()
return

Check warning on line 114 in cmd/terway-cli/cni_linux.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-cli/cni_linux.go#L107-L114

Added lines #L107 - L114 were not covered by tests
}
12 changes: 12 additions & 0 deletions cmd/terway-controlplane/terway-controlplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"math/rand"
"net"
"os"
"strings"
"time"

"github.com/samber/lo"
Expand All @@ -41,7 +42,9 @@ import (
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog/v2/textlogger"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
Expand Down Expand Up @@ -92,9 +95,12 @@ func main() {
var (
configFilePath string
credentialFilePath string
featureGates map[string]bool

Check warning on line 98 in cmd/terway-controlplane/terway-controlplane.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-controlplane/terway-controlplane.go#L98

Added line #L98 was not covered by tests
)
flag.StringVar(&configFilePath, "config", "/etc/config/ctrl-config.yaml", "config file for controlplane")
flag.StringVar(&credentialFilePath, "credential", "/etc/credential/ctrl-secret.yaml", "secret file for controlplane")
flag.Var(cliflag.NewMapStringBool(&featureGates), "feature-gates", "A set of key=value pairs that describe feature gates for alpha/experimental features. "+
"Options are:\n"+strings.Join(utilfeature.DefaultFeatureGate.KnownFeatures(), "\n"))

Check warning on line 103 in cmd/terway-controlplane/terway-controlplane.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-controlplane/terway-controlplane.go#L102-L103

Added lines #L102 - L103 were not covered by tests

logCfg := textlogger.NewConfig()
logCfg.AddFlags(flag.CommandLine)
Expand All @@ -104,6 +110,12 @@ func main() {
ctrl.SetLogger(textlogger.NewLogger(textlogger.NewConfig()))
log.Info(version.Version)

err := utilfeature.DefaultMutableFeatureGate.SetFromMap(featureGates)
if err != nil {
log.Error(err, "unable to set feature gates")
os.Exit(1)
}

Check warning on line 117 in cmd/terway-controlplane/terway-controlplane.go

View check run for this annotation

Codecov / codecov/patch

cmd/terway-controlplane/terway-controlplane.go#L113-L117

Added lines #L113 - L117 were not covered by tests

ctx := ctrl.SetupSignalHandler()

cfg, err := controlplane.ParseAndValidate(configFilePath, credentialFilePath)
Expand Down
74 changes: 62 additions & 12 deletions daemon/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ type NetworkServiceBuilder struct {

limit *client.Limits

err error
eflo bool
err error
}

func NewNetworkServiceBuilder(ctx context.Context) *NetworkServiceBuilder {
Expand Down Expand Up @@ -120,6 +121,10 @@ func (b *NetworkServiceBuilder) InitK8S() *NetworkServiceBuilder {
b.service.daemonMode = daemon.ModeENIOnly
}

if utils.ISLinJunNode(b.service.k8s.Node().Labels) {
b.eflo = true
instance.Init(&instance.EFLO{})
}

Check warning on line 127 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L124-L127

Added lines #L124 - L127 were not covered by tests
return b
}

Expand Down Expand Up @@ -152,10 +157,10 @@ func (b *NetworkServiceBuilder) LoadDynamicConfig() *NetworkServiceBuilder {
}

func (b *NetworkServiceBuilder) setupAliyunClient() error {
if os.Getenv("TERWAY_DEPLOY_ENV") == envEFLO {
instance.SetPopulateFunc(instance.EfloPopulate)
regionID, err := instance.GetInstanceMeta().GetRegionID()
if err != nil {
return err

Check warning on line 162 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L160-L162

Added lines #L160 - L162 were not covered by tests
}
meta := instance.GetInstanceMeta()

var providers []credential.Interface
if string(b.config.AccessID) != "" && string(b.config.AccessSecret) != "" {
Expand All @@ -164,7 +169,7 @@ func (b *NetworkServiceBuilder) setupAliyunClient() error {
providers = append(providers, credential.NewEncryptedCredentialProvider(utils.NormalizePath(b.config.CredentialPath)))
providers = append(providers, credential.NewMetadataProvider())

clientSet, err := credential.NewClientMgr(meta.RegionID, providers...)
clientSet, err := credential.NewClientMgr(regionID, providers...)

Check warning on line 172 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L172

Added line #L172 was not covered by tests
if err != nil {
return err
}
Expand All @@ -184,14 +189,18 @@ func (b *NetworkServiceBuilder) initInstanceLimit() error {
return fmt.Errorf("k8s node not found")
}
provider := client.LimitProviders["ecs"]
if os.Getenv("TERWAY_DEPLOY_ENV") == envEFLO {
if b.eflo {

Check warning on line 192 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L192

Added line #L192 was not covered by tests
provider = client.LimitProviders["eflo"]
limit, err := provider.GetLimitFromAnno(node.Annotations)
if err != nil {
return err
}
if limit == nil {
limit, err = provider.GetLimit(b.aliyunClient, instance.GetInstanceMeta().InstanceID)
instanceID, err := instance.GetInstanceMeta().GetInstanceID()
if err != nil {
return err
}
limit, err = provider.GetLimit(b.aliyunClient, instanceID)

Check warning on line 203 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L199-L203

Added lines #L199 - L203 were not covered by tests
if err != nil {
return fmt.Errorf("upable get instance limit, %w", err)
}
Expand All @@ -202,10 +211,28 @@ func (b *NetworkServiceBuilder) initInstanceLimit() error {
if err != nil {
return err
}
if limit == nil || instance.GetInstanceMeta().InstanceType != limit.InstanceTypeID {
limit, err = provider.GetLimit(b.aliyunClient, instance.GetInstanceMeta().InstanceType)

if limit != nil {
instanceType, err := instance.GetInstanceMeta().GetInstanceType()

Check warning on line 216 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L215-L216

Added lines #L215 - L216 were not covered by tests
if err != nil {
return fmt.Errorf("upable get instance limit, %w", err)
return err
}
if limit.InstanceTypeID != instanceType {
limit = nil
}

Check warning on line 222 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L218-L222

Added lines #L218 - L222 were not covered by tests
}

if limit == nil {
instanceType, err := instance.GetInstanceMeta().GetInstanceType()
if err != nil {
return err
}

Check warning on line 229 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L225-L229

Added lines #L225 - L229 were not covered by tests

if instanceType != limit.InstanceTypeID {
limit, err = provider.GetLimit(b.aliyunClient, instanceType)
if err != nil {
return fmt.Errorf("upable get instance limit, %w", err)
}

Check warning on line 235 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L231-L235

Added lines #L231 - L235 were not covered by tests
}
}
b.limit = limit
Expand All @@ -227,6 +254,29 @@ func (b *NetworkServiceBuilder) setupENIManager() error {
eniConfig.EnableIPv4 = enableIPv4
eniConfig.EnableIPv6 = enableIPv6

zoneID, err := instance.GetInstanceMeta().GetZoneID()
if err != nil {
return err
}
instanceID, err := instance.GetInstanceMeta().GetInstanceID()
if err != nil {
return err
}
vswitchID, err := instance.GetInstanceMeta().GetVSwitchID()
if err != nil {
return err
}

Check warning on line 268 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L257-L268

Added lines #L257 - L268 were not covered by tests

if eniConfig.ZoneID == "" {
eniConfig.ZoneID = zoneID
}
if eniConfig.InstanceID == "" {
eniConfig.InstanceID = instanceID
}
if len(eniConfig.VSwitchOptions) == 0 {
eniConfig.VSwitchOptions = []string{vswitchID}
}

Check warning on line 278 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L270-L278

Added lines #L270 - L278 were not covered by tests

// fall back to use primary eni's sg
if len(eniConfig.SecurityGroupIDs) == 0 {
enis, err := b.aliyunClient.DescribeNetworkInterface(b.ctx, "", nil, eniConfig.InstanceID, "Primary", "", nil)
Expand Down Expand Up @@ -361,7 +411,7 @@ func (b *NetworkServiceBuilder) setupENIManager() error {
eniList = append(eniList, eni.NewLocal(nil, "secondary", factory, poolConfig))
}

eniManager := eni.NewManager(poolConfig.MinPoolSize, poolConfig.MaxPoolSize, poolConfig.Capacity, 30*time.Second, eniList, types.EniSelectionPolicy(b.config.EniSelectionPolicy), b.service.k8s)
eniManager := eni.NewManager(poolConfig.MinPoolSize, poolConfig.MaxPoolSize, poolConfig.Capacity, 30*time.Second, eniList, daemon.EniSelectionPolicy(b.config.EniSelectionPolicy), b.service.k8s)

Check warning on line 414 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L414

Added line #L414 was not covered by tests
b.service.eniMgr = eniManager
err = eniManager.Run(b.ctx, &b.service.wg, podResources)
if err != nil {
Expand Down Expand Up @@ -405,7 +455,7 @@ func (b *NetworkServiceBuilder) PostInitForCRDV2() *NetworkServiceBuilder {
return b
}
crdv2 := eni.NewCRDV2(b.service.k8s.NodeName(), b.namespace)
mgr := eni.NewManager(0, 0, 0, 0, []eni.NetworkInterface{crdv2}, types.EniSelectionPolicy(b.config.EniSelectionPolicy), nil)
mgr := eni.NewManager(0, 0, 0, 0, []eni.NetworkInterface{crdv2}, daemon.EniSelectionPolicy(b.config.EniSelectionPolicy), nil)

Check warning on line 458 in daemon/builder.go

View check run for this annotation

Codecov / codecov/patch

daemon/builder.go#L458

Added line #L458 was not covered by tests

svc := b.RunENIMgr(b.ctx, mgr)
go b.service.startGarbageCollectionLoop(b.ctx)
Expand Down
23 changes: 8 additions & 15 deletions daemon/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/AliyunContainerService/terway/pkg/aliyun/client"
"github.com/AliyunContainerService/terway/pkg/aliyun/instance"
"github.com/AliyunContainerService/terway/pkg/k8s"
"github.com/AliyunContainerService/terway/pkg/utils"
"github.com/AliyunContainerService/terway/pkg/vswitch"
Expand All @@ -25,26 +24,24 @@ func getDynamicConfig(ctx context.Context, k8s k8s.Kubernetes) (string, string,
return cfg, label, err
}

func getENIConfig(cfg *daemon.Config) *types.ENIConfig {
func getENIConfig(cfg *daemon.Config) *daemon.ENIConfig {
vswitchSelectionPolicy := vswitch.VSwitchSelectionPolicyRandom
switch cfg.VSwitchSelectionPolicy {
case "ordered":
// keep the previous behave
vswitchSelectionPolicy = vswitch.VSwitchSelectionPolicyMost
}

eniSelectionPolicy := types.EniSelectionPolicyMostIPs
eniSelectionPolicy := daemon.EniSelectionPolicyMostIPs
switch cfg.EniSelectionPolicy {
case "least_ips":
eniSelectionPolicy = types.EniSelectionPolicyLeastIPs
eniSelectionPolicy = daemon.EniSelectionPolicyLeastIPs

Check warning on line 38 in daemon/config.go

View check run for this annotation

Codecov / codecov/patch

daemon/config.go#L38

Added line #L38 was not covered by tests
}

eniConfig := &types.ENIConfig{
ZoneID: instance.GetInstanceMeta().ZoneID,
eniConfig := &daemon.ENIConfig{
VSwitchOptions: nil,
ENITags: cfg.ENITags,
SecurityGroupIDs: cfg.GetSecurityGroups(),
InstanceID: instance.GetInstanceMeta().InstanceID,
VSwitchSelectionPolicy: vswitchSelectionPolicy,
EniSelectionPolicy: eniSelectionPolicy,
ResourceGroupID: cfg.ResourceGroupID,
Expand All @@ -59,24 +56,20 @@ func getENIConfig(cfg *daemon.Config) *types.ENIConfig {
}
}

if len(eniConfig.VSwitchOptions) == 0 {
eniConfig.VSwitchOptions = []string{instance.GetInstanceMeta().VSwitchID}
}

if cfg.EnableENITrunking {
types.EnableFeature(&eniConfig.EniTypeAttr, types.FeatTrunk)
daemon.EnableFeature(&eniConfig.EniTypeAttr, daemon.FeatTrunk)
}
if cfg.EnableERDMA {
types.EnableFeature(&eniConfig.EniTypeAttr, types.FeatERDMA)
daemon.EnableFeature(&eniConfig.EniTypeAttr, daemon.FeatERDMA)
}

return eniConfig
}

// the actual size for pool is minIdle and maxIdle
func getPoolConfig(cfg *daemon.Config, daemonMode string, limit *client.Limits) (*types.PoolConfig, error) {
func getPoolConfig(cfg *daemon.Config, daemonMode string, limit *client.Limits) (*daemon.PoolConfig, error) {

poolConfig := &types.PoolConfig{
poolConfig := &daemon.PoolConfig{
BatchSize: 10,
}

Expand Down
Loading

0 comments on commit 367e9b0

Please sign in to comment.