Network policies¶
Policy object¶
-
Pod
calico supports control of Egress/Ingress traffic for Pods via
GlobalNetworkPolicy
andNetworkPolicy
.Pods in a particular Namespace can only communicate with Pods under that Namespace. If the namespace has Label:
`environment == "development
'', Pods under that namespace can only communicate with Pods under the same namespace.apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: restrict-development-access spec: namespaceSelector: 'environment == "development"' ingress: - action: Allow source: namespaceSelector: 'environment == "development"' egress: - action: Allow destination: namespaceSelector: 'environment == "development"'
-
Service
Calico supports control of Kubernetes Service: ``yaml
apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: allow-api-access namespace: my-app spec: selector: all() egress: - action: Allow destination: services: name: kubernetes namespace: default
The Policy herein refers to allowing all Pods to access the Kubernetes service.
-
host
Calico supports control of Kubernetes nodes via
GlobalNetworkPolicy
. -
VMs
-
`ServiceAccount
Calico supports
ServiceAccount
to flexibly control how policies are applied on Pods: 1.-
Use
ServiceAccounts
to restrict the ingress traffic to a Pod.When accessing a Pod with Label:
app == "db"
under namespace: prod-engineering, if the name of theserviceAccounts
used by the visitor Pod isapi-service
oruser-auth-service
, the request passes. -
Use the Label of
ServiceAccount
to restrict the ingress traffic of the workload.When the Label of
ServiceAccounts
bound to the visitor Pod meetsapp == "web-frontend"
, access to Pods under theprod-engineering
namespace that meet Label: 'app == "db"' is allowed. -
The target for filtering Policy using
serviceAccountSelector
.Only Pods whose
serviceAccountSelector` matches
role == "intern"` can access each other.apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: restrict-intern-access namespace: prod-engineering spec: serviceAccountSelector: 'role == "intern"' ingress: - action: Allow source: serviceAccounts: selector: 'role == "intern"' egress: - action: Allow destination: serviceAccounts: selector: 'role == "intern"'
-
Bidirectional control of traffic¶
-
Egress
Support egress traffic control for matching policy Endpoint.
-
Ingress
Support ingress control for Endpoint matching policy.
Support multiple control behaviors¶
-
Allow
Allow packets to pass when they match the defined behavior.
-
Deny
When the packet does not match the defined behavior, it is prohibited to pass.
-
Log
Do not control the packet, just log it, and then continue to process the next rule.
-
Pass
The Pass action skips all remaining rules, jumps to the first Profile assigned to the Calico EndPoint, and then executes the rules defined by the Profile. Calico binds two Profiles for each Endpoint (
kns.<namespace>
andksa.<namespace>.default
). The Profile defines a set of labels and policies (for historical reasons, the Profile includes policy rules, which are deprecated). If the Endpoint is not bound to any Profile, then the policy result is equivalent to Deny.
Policy priority¶
Policy priority is specified by the order field. If not specified, it is executed last by default. The smaller the value, the higher the priority. If the order value is the same, the policy is ordered by the name field of the policy.
Cluster and tenant level control¶
Kubernetes uses a zero-trust model by default, meaning that all Pods and hosts in a cluster can access each other. We can define a global policy or a tenant-level policy to control the ingress and egress traffic of Pods.
-
Global Policy Control
The
GlobalNetworkPolicy
object works on all Pods in the namespace. e.g., the following example prohibits Pods with label:app=client
from accessing Pods with label:app=="server"
.apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: deny-tcp-8080 spec: order: 1 selector: app == 'server' types: - Ingress - Egress ingress: - action: Deny metadata: annotations: from: client to: server protocol: TCP source: selector: app == 'client' destination: ports: - 8080 egress: - action: Allow
selector
: filters which Pods this Policy applies to by tagtypes
: control the direction of traffic,Ingress
means ingress traffic,Egress
means egress trafficingress
: defines the content of the ingress policyaction
: policy action. Optional values are Allow, Deny, Log, Passmetadata
: additional information. Just for clarificationprotocol
: protocol. Options areTCP
,UDP
,ICMP
,ICMPv6
,SCTP
,UDPLite
.source
: filter access source by labeldestination
: filter access destination, here filter destination port is 8080egress
: no other requirements here, allow all bycalicoctl apply -f
, it will take effect.
-
Tenant Level Control
Calico controls Pods under specific namespaces through
NetworkPolicy
objects, unlikeGlobalNetworkPolicy
, which works on specific namespaces. For example.apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: allow-tcp-8080 namespace: production spec: selector: app == 'server' types: - Ingress - Egress ingress: - action: Allow metadata: annotations: from: frontend to: database protocol: TCP source: selector: app == 'client' destination: ports: - 8080 egress: - action: Allow
The difference with the
GlobalNetworkPolicy
above is that themetadata
has an additional namespace field, which specifies the namespace that the policy acts on.
Comparison with Kubernetes policy¶
-
Support for policy priority
-
Support for Deny rules
-
More flexible matching rules
-
Support controlling more policy objects whereas Kubernetes only supports controlling Pods
Performance impact¶
Calico's Policy implementation relies on IPtables
. As the number of policies increases, the number of iptables
on a node increases, which affects performance. The following tests show the performance changes (including CPU overhead, throughput, latency) of different modes such as iptables
, ipset
, tc-bpf
, cilium
, calico
when the policy is increased.
Note
The following test scenario is designed to test the impact of the number of Policies on the traffic inside the cluster accessing the external CIDR egress traffic. Calico uses the GlobalNetworkSet API
to pass a list of CIDR egresses it wants to deny, and then references the GlobalNetworkSet
resource in GlobalNetworkPolicy
via the label selector. In fact, this approach essentially uses IPset
, so see the IPtables
schema for data.
Performance test results (just an FYI):
- The throughput in
IPtables
mode increases dramatically when the number of rules is increased to 1000 or more.
- CPU usage in
IPtables
mode increases significantly when the number of rules increases to 1000 or more.
- The latency in
IPtables
mode increases significantly when the number of rules increases to 1000 or more.