Skip to content

Commit 4345b43

Browse files
committed
koordlet: tc plugin for netqos
Signed-off-by: lucming <[email protected]>
1 parent e003d3e commit 4345b43

24 files changed

+2435
-5
lines changed

docker/koordlet.dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ RUN go build -a -o koordlet cmd/koordlet/main.go
3636
FROM --platform=$TARGETPLATFORM nvidia/cuda:11.8.0-base-ubuntu22.04
3737
WORKDIR /
3838
RUN apt-get update && apt-get install -y lvm2 && rm -rf /var/lib/apt/lists/*
39+
RUN apt-get update && apt-get install -y iptables
3940
COPY --from=builder /go/src/github.com/koordinator-sh/koordinator/koordlet .
4041
COPY --from=builder /usr/local/lib /usr/lib
4142
ENTRYPOINT ["/koordlet"]

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/NVIDIA/go-nvml v0.11.6-0.0.20220823120812-7e2082095e82
77
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5
88
github.com/containerd/nri v0.6.1
9+
github.com/coreos/go-iptables v0.5.0
910
github.com/docker/docker v20.10.21+incompatible
1011
github.com/evanphx/json-patch v5.6.0+incompatible
1112
github.com/fsnotify/fsnotify v1.6.0
@@ -196,7 +197,7 @@ require (
196197
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
197198
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
198199
github.com/ugorji/go/codec v1.2.9 // indirect
199-
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 // indirect
200+
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
200201
github.com/vishvananda/netns v0.0.4 // indirect
201202
github.com/vmware/govmomi v0.30.6 // indirect
202203
go.etcd.io/etcd/api/v3 v3.5.9 // indirect

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkE
473473
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
474474
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
475475
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
476+
github.com/coreos/go-iptables v0.5.0 h1:mw6SAibtHKZcNzAsOxjoHIG0gy5YFHhypWSSNc6EjbQ=
476477
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
477478
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
478479
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=

pkg/koordlet/resourceexecutor/reader.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type CgroupReader interface {
4040
ReadCPUProcs(parentDir string) ([]uint32, error)
4141
ReadPSI(parentDir string) (*sysutil.PSIByResource, error)
4242
ReadMemoryColdPageUsage(parentDir string) (uint64, error)
43+
ReadNetClsId(parentDir string) (uint64, error)
4344
}
4445

4546
var _ CgroupReader = &CgroupV1Reader{}
@@ -230,6 +231,14 @@ func (r *CgroupV1Reader) ReadPSI(parentDir string) (*sysutil.PSIByResource, erro
230231
return psi, nil
231232
}
232233

234+
func (r *CgroupV1Reader) ReadNetClsId(parentDir string) (uint64, error) {
235+
resource, ok := sysutil.DefaultRegistry.Get(sysutil.CgroupVersionV1, sysutil.NetClsClassIdName)
236+
if !ok {
237+
return 0, ErrResourceNotRegistered
238+
}
239+
return readCgroupAndParseUint64(parentDir, resource)
240+
}
241+
233242
var _ CgroupReader = &CgroupV2Reader{}
234243

235244
type CgroupV2Reader struct{}
@@ -436,6 +445,14 @@ func (r *CgroupV2Reader) ReadPSI(parentDir string) (*sysutil.PSIByResource, erro
436445
return psi, nil
437446
}
438447

448+
func (r *CgroupV2Reader) ReadNetClsId(parentDir string) (uint64, error) {
449+
resource, ok := sysutil.DefaultRegistry.Get(sysutil.CgroupVersionV2, sysutil.NetClsClassIdName)
450+
if !ok {
451+
return 0, ErrResourceNotRegistered
452+
}
453+
return readCgroupAndParseUint64(parentDir, resource)
454+
}
455+
439456
func NewCgroupReader() CgroupReader {
440457
if sysutil.GetCurrentCgroupVersion() == sysutil.CgroupVersionV2 {
441458
return &CgroupV2Reader{}

pkg/koordlet/resourceexecutor/updater.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func init() {
5555
sysutil.MemoryPriorityName,
5656
sysutil.MemoryUsePriorityOomName,
5757
sysutil.MemoryOomGroupName,
58+
sysutil.NetClsClassIdName,
5859
)
5960
// special cases
6061
DefaultCgroupUpdaterFactory.Register(NewCgroupUpdaterWithUpdateFunc(CgroupUpdateCPUSharesFunc), sysutil.CPUSharesName)

pkg/koordlet/runtimehooks/config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/koordinator-sh/koordinator/pkg/koordlet/runtimehooks/hooks/cpuset"
3333
"github.com/koordinator-sh/koordinator/pkg/koordlet/runtimehooks/hooks/gpu"
3434
"github.com/koordinator-sh/koordinator/pkg/koordlet/runtimehooks/hooks/groupidentity"
35+
"github.com/koordinator-sh/koordinator/pkg/koordlet/runtimehooks/hooks/tc"
3536
"github.com/koordinator-sh/koordinator/pkg/koordlet/runtimehooks/hooks/terwayqos"
3637
"github.com/koordinator-sh/koordinator/pkg/koordlet/util/system"
3738
)
@@ -81,6 +82,11 @@ const (
8182
// owner: @l1b0k
8283
// alpha: v1.5
8384
TerwayQoS featuregate.Feature = "TerwayQoS"
85+
86+
// TCNetworkQoS indicates a network qos implementation based on tc.
87+
// owner: @lucming
88+
// alpha: v1.5
89+
TCNetworkQoS featuregate.Feature = "TCNetworkQoS"
8490
)
8591

8692
var (
@@ -92,6 +98,7 @@ var (
9298
CPUNormalization: {Default: false, PreRelease: featuregate.Alpha},
9399
CoreSched: {Default: false, PreRelease: featuregate.Alpha},
94100
TerwayQoS: {Default: false, PreRelease: featuregate.Alpha},
101+
TCNetworkQoS: {Default: false, PreRelease: featuregate.Alpha},
95102
}
96103

97104
runtimeHookPlugins = map[featuregate.Feature]HookPlugin{
@@ -102,6 +109,7 @@ var (
102109
CPUNormalization: cpunormalization.Object(),
103110
CoreSched: coresched.Object(),
104111
TerwayQoS: terwayqos.Object(),
112+
TCNetworkQoS: tc.Object(),
105113
}
106114
)
107115

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
Copyright 2022 The Koordinator Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package tc
18+
19+
import (
20+
"fmt"
21+
"strconv"
22+
"strings"
23+
24+
"k8s.io/apimachinery/pkg/api/resource"
25+
"k8s.io/apimachinery/pkg/util/intstr"
26+
27+
slov1alpha1 "github.com/koordinator-sh/koordinator/apis/slo/v1alpha1"
28+
)
29+
30+
func loadConfigFromNodeSlo(nodesloSpec *slov1alpha1.NodeSLOSpec) *NetQosGlobalConfig {
31+
res := NetQosGlobalConfig{}
32+
var total uint64 = 0
33+
if nodesloSpec != nil && nodesloSpec.SystemStrategy != nil {
34+
total = uint64(nodesloSpec.SystemStrategy.TotalNetworkBandwidth.Value())
35+
res.HwRxBpsMax = total
36+
res.HwTxBpsMax = total
37+
}
38+
39+
if nodesloSpec.ResourceQOSStrategy == nil {
40+
return &res
41+
}
42+
43+
strategy := nodesloSpec.ResourceQOSStrategy
44+
if strategy.LSClass != nil &&
45+
strategy.LSClass.NetworkQOS != nil &&
46+
*strategy.LSClass.NetworkQOS.Enable {
47+
cur := strategy.LSClass.NetworkQOS
48+
res.L1RxBpsMin = getBandwidthVal(total, cur.IngressRequest)
49+
res.L1RxBpsMax = getBandwidthVal(total, cur.IngressLimit)
50+
res.L1TxBpsMin = getBandwidthVal(total, cur.EgressRequest)
51+
res.L1TxBpsMax = getBandwidthVal(total, cur.EgressLimit)
52+
}
53+
54+
if strategy.BEClass != nil &&
55+
strategy.BEClass.NetworkQOS != nil &&
56+
*strategy.BEClass.NetworkQOS.Enable {
57+
cur := strategy.BEClass.NetworkQOS
58+
res.L2RxBpsMin = getBandwidthVal(total, cur.IngressRequest)
59+
res.L2RxBpsMax = getBandwidthVal(total, cur.IngressLimit)
60+
res.L2TxBpsMin = getBandwidthVal(total, cur.EgressRequest)
61+
res.L2TxBpsMax = getBandwidthVal(total, cur.EgressLimit)
62+
}
63+
64+
return &res
65+
}
66+
67+
func getBandwidthVal(total uint64, intOrPercent *intstr.IntOrString) uint64 {
68+
if intOrPercent == nil {
69+
return 0
70+
}
71+
72+
switch intOrPercent.Type {
73+
case intstr.String:
74+
return getBandwidthByQuantityFormat(intOrPercent.StrVal)
75+
case intstr.Int:
76+
return getBandwidthByPercentageFormat(total, intOrPercent.IntValue())
77+
default:
78+
return 0
79+
}
80+
}
81+
82+
func getBandwidthByQuantityFormat(quanityStr string) uint64 {
83+
val, err := resource.ParseQuantity(quanityStr)
84+
if err != nil {
85+
return 0
86+
}
87+
88+
return uint64(val.Value())
89+
}
90+
91+
func getBandwidthByPercentageFormat(total uint64, percentage int) uint64 {
92+
if percentage < 0 || percentage > 100 {
93+
return 0
94+
}
95+
96+
return total * uint64(percentage) / 100
97+
}
98+
99+
func convertToClassId(major, minor int) string {
100+
return fmt.Sprintf("%d:%d", major, minor)
101+
}
102+
103+
// convertToHexClassId get class id in hex.
104+
func convertToHexClassId(major, minor int) uint32 {
105+
hexVal := fmt.Sprintf("%d%04d", major, minor)
106+
decimalVal, _ := strconv.ParseUint(hexVal, 16, 32)
107+
return uint32(decimalVal)
108+
}
109+
110+
// convertIpToHex convert ip to it's hex format
111+
// 10.211.248.149 => 0ad3f895
112+
func convertIpToHex(ip string) string {
113+
result := ""
114+
elems := strings.Split(ip, ".")
115+
for _, elem := range elems {
116+
cur, _ := strconv.Atoi(elem)
117+
hex := fmt.Sprintf("%x", cur)
118+
// each ip segment takes up two hexadecimal digits, and when it does not take up all the bits,
119+
// it needs to be filled with 0.
120+
for i := 0; i < 2-len(hex); i++ {
121+
hex = "0" + hex
122+
}
123+
result += hex
124+
}
125+
126+
return result
127+
}

0 commit comments

Comments
 (0)