Alibaba Cloud Container Compute Service (ACS) lets you implement policy-based network control with Kubernetes NetworkPolicy. Use network policies to control network traffic at the IP address or port level for specific applications in your cluster. This topic explains how to use network policies in an ACS cluster and provides common use cases.
Applicability
-
Only general-purpose and compute-optimized CPU pods are supported.
-
Only IPv4 is supported.
Notes
-
NetworkPolicy rules allow you to select namespaces or pods using a LabelSelector. However, applying more NetworkPolicies to a pod increases the time it takes for the rules to take effect. Many NetworkPolicy rules can also complicate cluster management and troubleshooting. Therefore, keep the number of NetworkPolicies in your cluster under 40.
Step 1: Enable NetworkPolicy
-
Install the Poseidon component.
-
Log on to the ACS console. In the left navigation pane, click Clusters.
-
On the Clusters page, click the name of the target cluster. In the left navigation pane, click Add-ons.
-
On the Component management page, click the Network tab. On the Poseidon card, click Install.
-
On the Install Component Poseidon page, select Enable NetworkPolicy, and then click Confirm.
After the component is installed, Installed appears in the upper-right corner of the card.
-
-
Enable NetworkPolicy in the Pod annotation.
To enable NetworkPolicy for a Pod, add the following annotation to its metadata:
network.alibabacloud.com/enable-network-policy-agent: "true".apiVersion: v1 kind: Pod metadata: annotations: network.alibabacloud.com/enable-network-policy-agent: "true" name: example namespace: default spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: example
Step 2: Create an Nginx test application
kubectl
-
Obtain the kubeconfig file of the cluster and use kubectl to connect to the cluster.
-
Create an Nginx application and communicate with it through a Service named nginx.
Create the Nginx application:
kubectl run nginx --image=nginxExpected output:
pod/nginx createdCheck the pod status:
kubectl get podExpected output:
NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 45sCreate a Service named nginx:
kubectl expose pod nginx --port=80Expected output:
service/nginx exposedView the Service:
kubectl get serviceExpected output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 172.XX.XX.1 <none> 443/TCP 30m nginx ClusterIP 172.XX.XX.48 <none> 80/TCP 12s -
Create a Pod named busybox and access a Service named nginx.
kubectl run busybox --rm -ti --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shExpected output:
If you don't see a command prompt, try pressing enter. / # / #Test access to Nginx:
If you don't see a command prompt, try pressing enter. / # / # wget nginx # Enter wget nginx here.Expected output:
Connecting to nginx (172.XX.XX.48:80) saving to 'index.html' index.html 100% |****************************************************************************************************************************************************| 612 0:00:00 ETA 'index.html' saved
Step 3: Use a network policy
You can use network policies in the following scenarios as needed.
Scenario 1: Allow access by label
kubectl
-
Use the following YAML template and run the command
vim policy.yamlto create thepolicy.yaml file.vim policy.yamlThe following is the content of the YAML file.
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-nginx spec: podSelector: matchLabels: run: nginx ingress: - from: - podSelector: matchLabels: access: "true" -
Create a network policy from the policy.yaml file.
kubectl apply -f policy.yamlExpected output:
networkpolicy.networking.k8s.io/access-nginx created -
When no access labels are defined, requests to the Service named nginx will time out and fail.
kubectl run busybox --rm -ti --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shTest access to the Service named nginx:
wget nginxExpected output:
Connecting to nginx (172.19.XX.XX:80) wget: can't connect to remote host (172.19.XX.XX): Connection timed out -
Define access labels.
kubectl run busybox --rm -ti --labels="access=true" --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shTest the Nginx Service:
wget nginxExpected output:
Connecting to nginx (172.21.XX.XX:80) saving to 'index.html' index.html 100% |****************************************************************************************************************************************************| 612 0:00:00 ETA 'index.html' savedA 100% progress indicates a successful connection to the Nginx service.
Scenario 2: Restrict access by source CIDR block
kubectl
-
Create an Alibaba Cloud SLB service for the Nginx application and set
type=LoadBalancerto expose the Nginx service to the internet.vim nginx-service.yamlThe following is the content for the nginx-service.yaml file.
# Paste the following YAML content into nginx-service.yaml. apiVersion: v1 kind: Service metadata: labels: run: nginx name: nginx-slb spec: externalTrafficPolicy: Local ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx type: LoadBalancerCreate the service from the nginx-service.yaml file.
kubectl apply -f nginx-service.yamlExpected output:
service/nginx-slb createdCheck if the application exposes the Nginx service:
kubectl get service nginx-slbExpected output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-slb LoadBalancer 172.19.xx.xxx 47.110.xxx.xxx 80:32240/TCP 8m -
Access the SLB instance's IP address, 47.110.xxx.xxx. The connection fails.
wget 47.110.xxx.xxxExpected output:
--2018-11-21 11:46:05-- http://47.110.xx.xxx/ Connecting to 47.110.XX.XX:80... failed: Connection refused.NoteThe connection fails for the following reasons:
-
The network policy only allows access from applications with the label
access=true. -
Traffic from the SLB IP address originates outside the cluster. The current network policy only allows traffic from pods with a specific label, not external traffic.
Solution: Modify the network policy to add the allowed source CIDR block.
-
-
Check the IP address of your local machine.
curl myip.ipip.netExpected output:
Current IP: 10.0.x.x From: China Beijing Beijing # This is an example. The actual output from your device may vary. -
Modify the policy.yaml file that you created.
vim policy.yamlModify the policy.yaml file as follows:
# The following is the content of the YAML file. kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-nginx spec: podSelector: matchLabels: run: nginx ingress: - from: - podSelector: matchLabels: access: "true" - ipBlock: cidr: 100.64.0.0/10 - ipBlock: cidr: 10.0.0.1/24 # Your local IP address. This is an example. Your actual address may vary.Apply the updated policy:
kubectl apply -f policy.yamlExpected output:
networkpolicy.networking.k8s.io/access-nginx unchangedNote-
Some networks have multiple egress IP addresses. Use a /24 address range in this case.
-
SLB health check addresses are in the
100.64.0.0/10address block. Therefore, you must configure100.64.0.0/10.
-
-
Run a test pod to access the Nginx service.
kubectl run busybox --rm -ti --labels="access=true" --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shAccess the Nginx service:
wget 47.110.XX.XXExpected output:
Connecting to 47.110.XX.XX (47.110.XX.XX:80) index.html 100% |***********************************************************| 612 0:00:00 ETAA progress of 100% indicates a successful connection to the Nginx service.
Scenario 3: Restrict pod access to specific addresses
Kubectl
-
Resolve the www.aliyun.com domain.
dig +short www.aliyun.comExpected output:
www-jp-de-intl-adns.aliyun.com. www-jp-de-intl-adns.aliyun.com.gds.alibabadns.com. v6wagbridge.aliyun.com. v6wagbridge.aliyun.com.gds.alibabadns.com. 106.XX.XX.21 140.XX.XX.4 140.XX.XX.13 140.XX.XX.3 -
Create the busybox-policy file.
vim busybox-policy.yamlThe
busybox-policy.yamlfile contains the following:# The following is the content of the YAML file. kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: busybox-policy spec: podSelector: matchLabels: run: busybox egress: - to: - ipBlock: cidr: 106.XX.XX.21/32 - ipBlock: cidr: 140.XX.XX.4/32 - ipBlock: cidr: 140.XX.XX.13/32 - ipBlock: cidr: 140.XX.XX.3/32 - to: - ipBlock: cidr: 0.0.0.0/0 - namespaceSelector: {} ports: - protocol: UDP port: 53NoteThe
egressrule in thebusybox-policy.yamlfile restricts the application's outbound access. To ensure DNS resolution works, the policy must also allow UDP requests on port 53. -
Create a network policy from the
busybox-policy.yamlfile.kubectl apply -f busybox-policy.yamlExpected output:
networkpolicy.networking.k8s.io/busybox-policy created -
Create a
busyboxpod to test the policy.kubectl run busybox --rm -ti --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shTry to access a website other than www.aliyun.com, for example, www.taobao.com:
wget www.taobao.comExpected output:
Connecting to www.taobao.com (64.13.XX.XX:80) wget: can't connect to remote host (64.13.XX.XX): Connection timed outThe message
can't connect to remote hostindicates that access to the service was denied. -
Try to access www.aliyun.com.
wget www.aliyun.comExpected output:
Connecting to www.aliyun.com (140.205.XX.XX:80) Connecting to www.aliyun.com (140.205.XX.XX:443) wget: note: TLS certificate validation not implemented index.html 100% |***********************************************************| 462k 0:00:00 ETAThe 100% completion status indicates a successful connection.
Use case 4: Control public network access for Pods
This operation might affect online services that are accessing the public network. We recommend that you perform the following steps in an empty namespace.
kubectl
-
Create a test namespace to verify the restriction.
Create a namespace named
test-np.kubectl create ns test-npExpected output:
namespace/test-np created -
Set a default network policy for this namespace that only allows outbound traffic to the private network.
vim default-deny.yamlCreate a file named
default-deny.yamlwith the following content:# The following is the content of the YAML file. kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: namespace: test-np name: deny-public-net spec: podSelector: {} ingress: - from: - ipBlock: cidr: 0.0.0.0/0 egress: - to: - ipBlock: cidr: 192.168.0.0/16 - ipBlock: cidr: 172.16.0.0/12 - ipBlock: cidr: 10.0.0.0/8Create the network policy from the
default-deny.yamlfile.kubectl apply -f default-deny.yamlExpected output:
networkpolicy.networking.k8s.io/deny-public-net createdView the network policy:
kubectl get networkpolicy -n test-npExpected output:
NAME POD-SELECTOR AGE deny-public-net <none> 1m -
Allow Pods with a specific label to access the public network.
vim allow-specify-label.yamlAn example label is
public-network=true.# The following is the content of the YAML file. kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-public-network-for-labels namespace: test-np spec: podSelector: matchLabels: public-network: "true" ingress: - from: - ipBlock: cidr: 0.0.0.0/0 egress: - to: - ipBlock: cidr: 0.0.0.0/0 - namespaceSelector: matchLabels: ns: kube-systemRun the following command to create the network policy:
kubectl apply -f allow-specify-label.yamlExpected output:
networkpolicy.networking.k8s.io/allow-public-network-for-labels createdView the network policy:
kubectl get networkpolicy -n test-npExpected output:
NAME POD-SELECTOR AGE allow-public-network-for-labels public-network=true 1m deny-public-net <none> 3m -
Verify that a Pod without the specific label cannot access the public network.
kubectl run -it --namespace test-np --rm --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 busybox-intranetping aliyun.comExpected output:
PING aliyun.com (106.11.2xx.xxx): 56 data bytes ^C --- aliyun.com ping statistics --- 9 packets transmitted, 0 packets received, 100% packet lossThe message
0 packets receivedindicates that access failed.NoteAccess fails because the
deny-public-netnetwork policy blocks public network access by default for all Pods in thetest-npnamespace. -
Verify that a Pod with the
public-network=truelabel can access the public network.kubectl run -it --namespace test-np --labels public-network=true --rm --image registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 busybox-internetping aliyun.comExpected output:
PING aliyun.com (106.11.1xx.xx): 56 data bytes 64 bytes from 106.11.1xx.xx: seq=0 ttl=47 time=4.235 ms 64 bytes from 106.11.1xx.xx: seq=1 ttl=47 time=4.200 ms 64 bytes from 106.11.1xx.xx: seq=2 ttl=47 time=4.182 ms ^C --- aliyun.com ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 4.182/4.205/4.235 msThe message
0% packet lossindicates successful access to the public network.NoteAccess is successful because the
allow-public-network-for-labelsnetwork policy grants public network access to Pods with thepublic-network=truelabel, such as thebusybox-internetPod.