Skip to content

Commit eedcd38

Browse files
committed
CORS-3431: CAPI: Add firewall rule for worker nodes
Add firewall rules for worker to master communication.
1 parent 4d9a76f commit eedcd38

File tree

2 files changed

+197
-0
lines changed

2 files changed

+197
-0
lines changed

pkg/infrastructure/gcp/clusterapi/clusterapi.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ func (p Provider) InfraReady(ctx context.Context, in clusterapi.InfraReadyInput)
137137
return fmt.Errorf("failed to create internal load balancer address: %w", err)
138138
}
139139

140+
// The firewall for masters, aka control-plane, is created by CAPG
141+
// Create the ones needed for worker to master communication
142+
if err = createFirewallRules(ctx, in, *gcpCluster.Status.Network.SelfLink); err != nil {
143+
return fmt.Errorf("failed to add firewall rules: %w", err)
144+
}
145+
140146
if in.InstallConfig.Config.GCP.UserProvisionedDNS != gcptypes.UserProvisionedDNSEnabled {
141147
// Get the network from the GCP Cluster. The network is used to create the private managed zone.
142148
if gcpCluster.Status.Network.SelfLink == nil {
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
package clusterapi
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"google.golang.org/api/compute/v1"
9+
10+
"github.com/openshift/installer/pkg/infrastructure/clusterapi"
11+
)
12+
13+
func getControlPlanePorts() []*compute.FirewallAllowed {
14+
return []*compute.FirewallAllowed{
15+
{
16+
IPProtocol: "tcp",
17+
Ports: []string{
18+
"22623", // Ignition
19+
},
20+
},
21+
{
22+
IPProtocol: "tcp",
23+
Ports: []string{
24+
"10257", // Kube manager
25+
},
26+
},
27+
{
28+
IPProtocol: "tcp",
29+
Ports: []string{
30+
"10259", // Kube scheduler
31+
},
32+
},
33+
}
34+
}
35+
36+
func getInternalClusterPorts() []*compute.FirewallAllowed {
37+
return []*compute.FirewallAllowed{
38+
{
39+
IPProtocol: "tcp",
40+
Ports: []string{
41+
"30000-32767", // k8s NodePorts
42+
},
43+
},
44+
{
45+
IPProtocol: "udp",
46+
Ports: []string{
47+
"30000-32767", // k8s NodePorts
48+
},
49+
},
50+
{
51+
IPProtocol: "tcp",
52+
Ports: []string{
53+
"9000-9999", // host-level services
54+
},
55+
},
56+
{
57+
IPProtocol: "udp",
58+
Ports: []string{
59+
"9000-9999", // host-level services
60+
},
61+
},
62+
{
63+
IPProtocol: "udp",
64+
Ports: []string{
65+
"4789", "6081", // VXLAN and GENEVE
66+
},
67+
},
68+
{
69+
IPProtocol: "udp",
70+
Ports: []string{
71+
"500", "4500", // IKE and IKE(NAT-T)
72+
},
73+
},
74+
{
75+
IPProtocol: "tcp",
76+
Ports: []string{
77+
"10250", // kubelet secure
78+
},
79+
},
80+
{
81+
IPProtocol: "esp",
82+
},
83+
}
84+
}
85+
86+
func getAPIPorts() []*compute.FirewallAllowed {
87+
return []*compute.FirewallAllowed{
88+
{
89+
IPProtocol: "tcp",
90+
Ports: []string{
91+
"6443", // kube-apiserver
92+
},
93+
},
94+
}
95+
}
96+
97+
func getInternalNetworkPorts() []*compute.FirewallAllowed {
98+
return []*compute.FirewallAllowed{
99+
{
100+
IPProtocol: "tcp",
101+
Ports: []string{
102+
"22", // SSH
103+
},
104+
},
105+
{
106+
IPProtocol: "icmp",
107+
},
108+
}
109+
}
110+
111+
// addFirewallRule creates the firewall rule and adds it the compute's firewalls.
112+
func addFirewallRule(ctx context.Context, name, network, projectID string, ports []*compute.FirewallAllowed, srcTags, targetTags, srcRanges []string) error {
113+
service, err := NewComputeService()
114+
if err != nil {
115+
return err
116+
}
117+
118+
ctx, cancel := context.WithTimeout(ctx, time.Minute*3)
119+
defer cancel()
120+
121+
firewallRule := &compute.Firewall{
122+
Name: name,
123+
Description: resourceDescription,
124+
Direction: "INGRESS",
125+
Network: network,
126+
Allowed: ports,
127+
SourceTags: srcTags,
128+
TargetTags: targetTags,
129+
}
130+
if len(srcTags) > 0 {
131+
firewallRule.SourceTags = srcTags
132+
}
133+
if len(srcRanges) > 0 {
134+
firewallRule.SourceRanges = srcRanges
135+
}
136+
137+
op, err := service.Firewalls.Insert(projectID, firewallRule).Context(ctx).Do()
138+
if err != nil {
139+
return fmt.Errorf("failed to create %s firewall rule: %w", name, err)
140+
}
141+
142+
if err := WaitForOperationGlobal(ctx, projectID, op); err != nil {
143+
return fmt.Errorf("failed to wait for inserting %s firewall rule: %w", name, err)
144+
}
145+
146+
return nil
147+
}
148+
149+
// createFirewallRules creates the rules needed between tthe worker and master nodes.
150+
func createFirewallRules(ctx context.Context, in clusterapi.InfraReadyInput, network string) error {
151+
projectID := in.InstallConfig.Config.Platform.GCP.ProjectID
152+
workerTag := fmt.Sprintf("%s-worker", in.InfraID)
153+
masterTag := fmt.Sprintf("%s-control-plane", in.InfraID)
154+
155+
// control-plane rules are needed for worker<->master communication for worker provisioning
156+
firewallName := fmt.Sprintf("%s-control-plane", in.InfraID)
157+
srcTags := []string{workerTag, masterTag}
158+
targetTags := []string{masterTag}
159+
srcRanges := []string{}
160+
if err := addFirewallRule(ctx, firewallName, network, projectID, getControlPlanePorts(), srcTags, targetTags, srcRanges); err != nil {
161+
return err
162+
}
163+
164+
// internal-cluster rules are needed for worker<->master communication for k8s nodes
165+
firewallName = fmt.Sprintf("%s-internal-cluster", in.InfraID)
166+
srcTags = []string{workerTag, masterTag}
167+
targetTags = []string{workerTag, masterTag}
168+
srcRanges = []string{}
169+
if err := addFirewallRule(ctx, firewallName, network, projectID, getInternalClusterPorts(), srcTags, targetTags, srcRanges); err != nil {
170+
return err
171+
}
172+
173+
// api rules are needed to access the kube-apiserver on master nodes
174+
firewallName = fmt.Sprintf("%s-api", in.InfraID)
175+
srcTags = []string{}
176+
targetTags = []string{masterTag}
177+
srcRanges = []string{}
178+
if err := addFirewallRule(ctx, firewallName, network, projectID, getAPIPorts(), srcTags, targetTags, srcRanges); err != nil {
179+
return err
180+
}
181+
182+
// internal-network rules are used to access ssh and icmp over the machine network
183+
firewallName = fmt.Sprintf("%s-internal-network", in.InfraID)
184+
srcTags = []string{}
185+
targetTags = []string{workerTag, masterTag}
186+
machineCIDR := in.InstallConfig.Config.Networking.MachineNetwork[0].CIDR.String()
187+
srcRanges = []string{machineCIDR}
188+
err := addFirewallRule(ctx, firewallName, network, projectID, getInternalNetworkPorts(), srcTags, targetTags, srcRanges)
189+
190+
return err
191+
}

0 commit comments

Comments
 (0)