Skip to content

Commit 2c92609

Browse files
committed
Merge branch 'master' into isaiahraya/npm-cilium-migration-script
2 parents 6cb46db + 7225b14 commit 2c92609

File tree

11 files changed

+328
-69
lines changed

11 files changed

+328
-69
lines changed

.pipelines/singletenancy/dualstack-overlay/dualstackoverlay-e2e-step-template.yaml

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -113,38 +113,4 @@ steps:
113113
displayName: "Windows DualStack Overlay Datapath Tests"
114114
retryCountOnTaskFailure: 3
115115
116-
- task: AzureCLI@1
117-
inputs:
118-
azureSubscription: $(BUILD_VALIDATIONS_SERVICE_CONNECTION)
119-
scriptLocation: "inlineScript"
120-
scriptType: "bash"
121-
addSpnToEnvironment: true
122-
inlineScript: |
123-
set -e
124-
clusterName=${{ parameters.clusterName }}
125-
echo "Restarting nodes"
126-
for val in $(az vmss list -g MC_${clusterName}_${clusterName}_$(REGION_DUALSTACKOVERLAY_CLUSTER_TEST) --query "[].name" -o tsv); do
127-
make -C ./hack/aks restart-vmss AZCLI=az CLUSTER=${clusterName} REGION=$(REGION_DUALSTACKOVERLAY_CLUSTER_TEST) VMSS_NAME=${val}
128-
done
129-
displayName: "Restart Nodes"
130-
131-
- task: AzureCLI@1
132-
inputs:
133-
azureSubscription: $(BUILD_VALIDATIONS_SERVICE_CONNECTION)
134-
scriptLocation: "inlineScript"
135-
scriptType: "bash"
136-
addSpnToEnvironment: true
137-
inlineScript: |
138-
set -e
139-
cd test/integration/load
140-
141-
# Scale Cluster Up/Down to confirm functioning CNS
142-
ITERATIONS=2 SCALE_UP=${{ parameters.scaleup }} OS_TYPE=windows go test -count 1 -timeout 30m -tags load -run ^TestLoad$
143-
kubectl get pods -owide -A
144-
145-
cd ../../..
146-
echo "Validating Node Restart"
147-
make test-validate-state OS_TYPE=windows RESTART_CASE=true CNI_TYPE=cniv2
148-
kubectl delete ns load-test
149-
displayName: "Validate Node Restart"
150-
retryCountOnTaskFailure: 3
116+
# Windows node restart and validation tests removed due to flakiness

cns/client/client_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ func TestMain(m *testing.M) {
152152
config := common.ServiceConfig{}
153153

154154
httpRestService, err := restserver.NewHTTPRestService(&config, &fakes.WireserverClientFake{},
155-
&fakes.WireserverProxyFake{}, &fakes.NMAgentClientFake{}, nil, nil, nil,
155+
&fakes.WireserverProxyFake{}, &restserver.IPtablesProvider{}, &fakes.NMAgentClientFake{}, nil, nil, nil,
156156
fakes.NewMockIMDSClient())
157157
svc = httpRestService
158158
httpRestService.Name = "cns-test-server"

cns/fakes/iptablesfake.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package fakes
2+
3+
import (
4+
"errors"
5+
"strings"
6+
7+
"github.com/Azure/azure-container-networking/iptables"
8+
)
9+
10+
var (
11+
errChainExists = errors.New("chain already exists")
12+
errChainNotFound = errors.New("chain not found")
13+
errRuleExists = errors.New("rule already exists")
14+
)
15+
16+
type IPTablesMock struct {
17+
state map[string]map[string][]string
18+
}
19+
20+
func NewIPTablesMock() *IPTablesMock {
21+
return &IPTablesMock{
22+
state: make(map[string]map[string][]string),
23+
}
24+
}
25+
26+
func (c *IPTablesMock) ensureTableExists(table string) {
27+
_, exists := c.state[table]
28+
if !exists {
29+
c.state[table] = make(map[string][]string)
30+
}
31+
}
32+
33+
func (c *IPTablesMock) ChainExists(table, chain string) (bool, error) {
34+
c.ensureTableExists(table)
35+
36+
builtins := []string{iptables.Input, iptables.Output, iptables.Prerouting, iptables.Postrouting, iptables.Forward}
37+
38+
_, exists := c.state[table][chain]
39+
40+
// these chains always exist
41+
for _, val := range builtins {
42+
if chain == val && !exists {
43+
c.state[table][chain] = []string{}
44+
return true, nil
45+
}
46+
}
47+
48+
return exists, nil
49+
}
50+
51+
func (c *IPTablesMock) NewChain(table, chain string) error {
52+
c.ensureTableExists(table)
53+
54+
exists, _ := c.ChainExists(table, chain)
55+
56+
if exists {
57+
return errChainExists
58+
}
59+
60+
c.state[table][chain] = []string{}
61+
return nil
62+
}
63+
64+
func (c *IPTablesMock) Exists(table, chain string, rulespec ...string) (bool, error) {
65+
c.ensureTableExists(table)
66+
67+
chainExists, _ := c.ChainExists(table, chain)
68+
if !chainExists {
69+
return false, nil
70+
}
71+
72+
targetRule := strings.Join(rulespec, " ")
73+
chainRules := c.state[table][chain]
74+
75+
for _, chainRule := range chainRules {
76+
if targetRule == chainRule {
77+
return true, nil
78+
}
79+
}
80+
return false, nil
81+
}
82+
83+
func (c *IPTablesMock) Append(table, chain string, rulespec ...string) error {
84+
c.ensureTableExists(table)
85+
86+
chainExists, _ := c.ChainExists(table, chain)
87+
if !chainExists {
88+
return errChainNotFound
89+
}
90+
91+
ruleExists, _ := c.Exists(table, chain, rulespec...)
92+
if ruleExists {
93+
return errRuleExists
94+
}
95+
96+
targetRule := strings.Join(rulespec, " ")
97+
c.state[table][chain] = append(c.state[table][chain], targetRule)
98+
return nil
99+
}
100+
101+
func (c *IPTablesMock) Insert(table, chain string, _ int, rulespec ...string) error {
102+
return c.Append(table, chain, rulespec...)
103+
}

cns/restserver/api_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1735,7 +1735,7 @@ func startService(serviceConfig common.ServiceConfig, _ configuration.CNSConfig)
17351735
config.Store = fileStore
17361736

17371737
nmagentClient := &fakes.NMAgentClientFake{}
1738-
service, err = NewHTTPRestService(&config, &fakes.WireserverClientFake{}, &fakes.WireserverProxyFake{},
1738+
service, err = NewHTTPRestService(&config, &fakes.WireserverClientFake{}, &fakes.WireserverProxyFake{}, &IPtablesProvider{},
17391739
nmagentClient, nil, nil, nil, fakes.NewMockIMDSClient())
17401740
if err != nil {
17411741
return err

cns/restserver/internalapi_linux.go

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,28 @@ import (
1111
"github.com/Azure/azure-container-networking/iptables"
1212
"github.com/Azure/azure-container-networking/network/networkutils"
1313
goiptables "github.com/coreos/go-iptables/iptables"
14+
"github.com/pkg/errors"
1415
)
1516

1617
const SWIFT = "SWIFT-POSTROUTING"
1718

19+
type IPtablesProvider struct{}
20+
21+
func (c *IPtablesProvider) GetIPTables() (iptablesClient, error) {
22+
client, err := goiptables.New()
23+
return client, errors.Wrap(err, "failed to get iptables client")
24+
}
25+
1826
// nolint
1927
func (service *HTTPRestService) programSNATRules(req *cns.CreateNetworkContainerRequest) (types.ResponseCode, string) {
2028
service.Lock()
2129
defer service.Unlock()
2230

2331
// Parse primary ip and ipnet from nnc
24-
ncPrimaryIP, ncIPNet, _ := net.ParseCIDR(req.IPConfiguration.IPSubnet.IPAddress + "/" + fmt.Sprintf("%d", req.IPConfiguration.IPSubnet.PrefixLength))
25-
ipt, err := goiptables.New()
32+
// in podsubnet case, ncPrimaryIP is the pod subnet's primary ip
33+
// in vnet scale case, ncPrimaryIP is the node's ip
34+
ncPrimaryIP, _, _ := net.ParseCIDR(req.IPConfiguration.IPSubnet.IPAddress + "/" + fmt.Sprintf("%d", req.IPConfiguration.IPSubnet.PrefixLength))
35+
ipt, err := service.iptables.GetIPTables()
2636
if err != nil {
2737
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to create iptables interface : %v", err)
2838
}
@@ -56,41 +66,51 @@ func (service *HTTPRestService) programSNATRules(req *cns.CreateNetworkContainer
5666
}
5767
}
5868

59-
snatUDPRuleexist, err := ipt.Exists(iptables.Nat, SWIFT, "-m", "addrtype", "!", "--dst-type", "local", "-s", ncIPNet.String(), "-d", networkutils.AzureDNS, "-p", iptables.UDP, "--dport", strconv.Itoa(iptables.DNSPort), "-j", iptables.Snat, "--to", ncPrimaryIP.String())
60-
if err != nil {
61-
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to check for existence of SNAT UDP rule : %v", err)
62-
}
63-
if !snatUDPRuleexist {
64-
logger.Printf("[Azure CNS] Inserting SNAT UDP rule ...")
65-
err = ipt.Insert(iptables.Nat, SWIFT, 1, "-m", "addrtype", "!", "--dst-type", "local", "-s", ncIPNet.String(), "-d", networkutils.AzureDNS, "-p", iptables.UDP, "--dport", strconv.Itoa(iptables.DNSPort), "-j", iptables.Snat, "--to", ncPrimaryIP.String())
69+
// use any secondary ip + the nnc prefix length to get an iptables rule to allow dns and imds traffic from the pods
70+
for _, v := range req.SecondaryIPConfigs {
71+
// put the ip address in standard cidr form (where we zero out the parts that are not relevant)
72+
_, podSubnet, _ := net.ParseCIDR(v.IPAddress + "/" + fmt.Sprintf("%d", req.IPConfiguration.IPSubnet.PrefixLength))
73+
74+
snatUDPRuleExists, err := ipt.Exists(iptables.Nat, SWIFT, "-m", "addrtype", "!", "--dst-type", "local", "-s", podSubnet.String(), "-d", networkutils.AzureDNS, "-p", iptables.UDP, "--dport", strconv.Itoa(iptables.DNSPort), "-j", iptables.Snat, "--to", ncPrimaryIP.String())
6675
if err != nil {
67-
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to inset SNAT UDP rule : " + err.Error()
76+
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to check for existence of pod SNAT UDP rule : %v", err)
77+
}
78+
if !snatUDPRuleExists {
79+
logger.Printf("[Azure CNS] Inserting pod SNAT UDP rule ...")
80+
err = ipt.Insert(iptables.Nat, SWIFT, 1, "-m", "addrtype", "!", "--dst-type", "local", "-s", podSubnet.String(), "-d", networkutils.AzureDNS, "-p", iptables.UDP, "--dport", strconv.Itoa(iptables.DNSPort), "-j", iptables.Snat, "--to", ncPrimaryIP.String())
81+
if err != nil {
82+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to insert pod SNAT UDP rule : " + err.Error()
83+
}
6884
}
69-
}
7085

71-
snatTCPRuleexist, err := ipt.Exists(iptables.Nat, SWIFT, "-m", "addrtype", "!", "--dst-type", "local", "-s", ncIPNet.String(), "-d", networkutils.AzureDNS, "-p", iptables.TCP, "--dport", strconv.Itoa(iptables.DNSPort), "-j", iptables.Snat, "--to", ncPrimaryIP.String())
72-
if err != nil {
73-
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to check for existence of SNAT TCP rule : %v", err)
74-
}
75-
if !snatTCPRuleexist {
76-
logger.Printf("[Azure CNS] Inserting SNAT TCP rule ...")
77-
err = ipt.Insert(iptables.Nat, SWIFT, 1, "-m", "addrtype", "!", "--dst-type", "local", "-s", ncIPNet.String(), "-d", networkutils.AzureDNS, "-p", iptables.TCP, "--dport", strconv.Itoa(iptables.DNSPort), "-j", iptables.Snat, "--to", ncPrimaryIP.String())
86+
snatPodTCPRuleExists, err := ipt.Exists(iptables.Nat, SWIFT, "-m", "addrtype", "!", "--dst-type", "local", "-s", podSubnet.String(), "-d", networkutils.AzureDNS, "-p", iptables.TCP, "--dport", strconv.Itoa(iptables.DNSPort), "-j", iptables.Snat, "--to", ncPrimaryIP.String())
7887
if err != nil {
79-
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to insert SNAT TCP rule : " + err.Error()
88+
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to check for existence of pod SNAT TCP rule : %v", err)
89+
}
90+
if !snatPodTCPRuleExists {
91+
logger.Printf("[Azure CNS] Inserting pod SNAT TCP rule ...")
92+
err = ipt.Insert(iptables.Nat, SWIFT, 1, "-m", "addrtype", "!", "--dst-type", "local", "-s", podSubnet.String(), "-d", networkutils.AzureDNS, "-p", iptables.TCP, "--dport", strconv.Itoa(iptables.DNSPort), "-j", iptables.Snat, "--to", ncPrimaryIP.String())
93+
if err != nil {
94+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to insert pod SNAT TCP rule : " + err.Error()
95+
}
8096
}
81-
}
8297

83-
snatIMDSRuleexist, err := ipt.Exists(iptables.Nat, SWIFT, "-m", "addrtype", "!", "--dst-type", "local", "-s", ncIPNet.String(), "-d", networkutils.AzureIMDS, "-p", iptables.TCP, "--dport", strconv.Itoa(iptables.HTTPPort), "-j", iptables.Snat, "--to", req.HostPrimaryIP)
84-
if err != nil {
85-
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to check for existence of SNAT IMDS rule : %v", err)
86-
}
87-
if !snatIMDSRuleexist {
88-
logger.Printf("[Azure CNS] Inserting SNAT IMDS rule ...")
89-
err = ipt.Insert(iptables.Nat, SWIFT, 1, "-m", "addrtype", "!", "--dst-type", "local", "-s", ncIPNet.String(), "-d", networkutils.AzureIMDS, "-p", iptables.TCP, "--dport", strconv.Itoa(iptables.HTTPPort), "-j", iptables.Snat, "--to", req.HostPrimaryIP)
98+
snatIMDSRuleexist, err := ipt.Exists(iptables.Nat, SWIFT, "-m", "addrtype", "!", "--dst-type", "local", "-s", podSubnet.String(), "-d", networkutils.AzureIMDS, "-p", iptables.TCP, "--dport", strconv.Itoa(iptables.HTTPPort), "-j", iptables.Snat, "--to", req.HostPrimaryIP)
9099
if err != nil {
91-
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to insert SNAT IMDS rule : " + err.Error()
100+
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to check for existence of pod SNAT IMDS rule : %v", err)
101+
}
102+
if !snatIMDSRuleexist {
103+
logger.Printf("[Azure CNS] Inserting pod SNAT IMDS rule ...")
104+
err = ipt.Insert(iptables.Nat, SWIFT, 1, "-m", "addrtype", "!", "--dst-type", "local", "-s", podSubnet.String(), "-d", networkutils.AzureIMDS, "-p", iptables.TCP, "--dport", strconv.Itoa(iptables.HTTPPort), "-j", iptables.Snat, "--to", req.HostPrimaryIP)
105+
if err != nil {
106+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to insert pod SNAT IMDS rule : " + err.Error()
107+
}
92108
}
109+
110+
// we only need to run this code once as the iptable rule applies to all secondary ip configs in the same subnet
111+
break
93112
}
113+
94114
return types.Success, ""
95115
}
96116

0 commit comments

Comments
 (0)