Enable Network Policy in ACK Serverless clusters to control pod-level traffic with the Poseidon component.
Prerequisites
-
An ACK managed cluster or ACK dedicated cluster is created. See Create an ACK managed cluster or Create an ACK dedicated cluster (Discontinued).
ImportantIn ACK managed cluster Pro and ACK Serverless Pro clusters, Network Policy is implemented by different components.
-
In an ACK managed cluster Pro (for nodes that are not elastic container instances), Network Policy is implemented by the Terway network plugin. See Enable Network Policy in ACK clusters.
-
In elastic container instances (ECIs) in ACK Serverless clusters and ACK managed Pro clusters, Network Policy is implemented by the Poseidon component.
-
-
The ACK Virtual Node component is upgraded to v2.10.0 or later. See Manage components.
Limitations
-
Network Policy is supported only in ACK Serverless Pro and ACK managed cluster Pro clusters.
-
Network Policy does not support IPv6 addresses.
-
The
endPortfield in a NetworkPolicy is not supported. -
NetworkPolicy rules use label selectors to match namespaces or pods. Too many NetworkPolicy resources slow rule propagation and complicate management and troubleshooting. Limit NetworkPolicy resources to fewer than 40 per cluster.
Step 1: Enable Network Policy
Install the Poseidon component to enable Network Policy in an ACK Serverless Pro cluster.
-
Install the Poseidon component.
Log on to the ACK console. In the left navigation pane, click Clusters.
On the Clusters page, click the name of your cluster. In the left navigation pane, click Components and Add-ons.
-
On the Add-ons page, click the Networking tab. On the Poseidon card, click Install.
-
In the Install Poseidon dialog box, select Enable NetworkPolicy for ACS/ECI instances and click OK.
After installation, Installed appears on the card.
Step 2: Create and test an nginx application
Use the console
Log on to the ACK console. In the left navigation pane, click Clusters.
On the Clusters page, click the name of the target cluster and in the left navigation pane, choose .
On the Deployments page, click Create from Image. In the Create wizard, create an application named nginx and expose it using a Service. After configuring the application, click Create.
For this example, configure only the following items for the Nginx application and keep the default settings for the other parameters. For more information about the configurations, see Create a stateless workload (Deployment).
Configuration item
Description
Example value
Basic Information
Name
A custom name.
nginx
Replicas
Select as needed.
1
Container
Image Name
The name of the image used to start the container.
nginx:latest
Advanced
Services
To the right of Services, click Create to set the service configuration items.
Name: nginx
Service Type:
Cluster IP
SLB
Node Port
Port Mapping:
Name: nginx
Service Port: 80
Container Port: 80
Protocol: TCP
On the Deployments page, click Create from Image. In the resulting Create wizard, create a client application named busybox to test access to the nginx Service that you created in the previous step.
For this example, configure only the following items for the busybox client application and keep the default settings for the other parameters. For more information about the configurations, see Create a stateless workload (Deployment).
Configuration item
Description
Example value
Basic Information
Name
A custom name.
busybox
Replicas
Set a value as needed.
1
Container
Image Name
The name of the image used to start the container.
busybox:latest
Container Start Parameter
None
Select stdin and tty
Verify that the busybox client application can access the Nginx Service.
On the Deployments page, click the busybox application name.
On the Pods tab, locate the busybox-{hash value} pod and click Terminal in the Actions column.

In the busybox command-line terminal, run the
wget nginxcommand to test access to Nginx.
The output indicates that busybox can access the Nginx Service.
Use the CLI
Run the following commands to create an Nginx application and expose it using a Service named nginx.
Create an Nginx application:
kubectl run nginx --image=nginxExpected output:
pod/nginx createdCheck whether the pod is started:
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 12sRun the following command to create a pod named busybox and access the Service named nginx.
kubectl run busybox --rm -ti --image=busybox /bin/shExpected output:
If you don't see a command prompt, try pressing enter. / # / #Access 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
Apply NetworkPolicy resources to restrict pod traffic by label, CIDR block, egress destination, or public network access.
Scenario 1: Restrict service access to applications with specific labels using a network policy
Run the
vim policy.yamlcommand to create a file named policy.yaml, and populate it with the following YAML template.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"Run the following command to create a network policy from the policy.yaml file.
kubectl apply -f policy.yamlExpected output:
networkpolicy.networking.k8s.io/access-nginx createdRun the following commands to test access to the nginx Service. Because no access label is defined, the request times out.
kubectl run busybox --rm -ti --image=busybox /bin/shTest access to the nginx Service:
wget nginxExpected output:
Connecting to nginx (172.19.XX.XX:80) wget: can't connect to remote host (172.19.XX.XX): Connection timed outRun the following commands to define the access label.
kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/shTest access to 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' savedThe output indicates that the connection progress is 100%. This means that the request is successful and the Nginx service can be accessed.
Scenario 2: Restrict the source CIDR blocks that can access an Internet-facing service using a network policy
Run the following command to create an Alibaba Cloud SLB instance for the nginx application. Specify
type=LoadBalancerto expose the nginx service to the Internet.vim nginx-service.yamlThe following is the template 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: LoadBalancerRun the following command to create a network policy from the nginx-service.yaml file.
kubectl apply -f nginx-service.yamlExpected output:
service/nginx-slb createdCheck whether 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 8mRun the following command to access the IP address of the newly created SLB instance, 47.110.xxx.xxx. Access 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.NoteAccess fails for the following reasons:
The configured nginx Service can only be accessed by applications with the specific label
access=true.Accessing the IP address of the SLB instance is considered external access to Kubernetes. This is different from the scenario of restricting service access to applications with specific labels.
Solution: Modify the network policy to add the allowed source CIDR block.
Run the following command to view your local IP address.
curl myip.ipip.netExpected output:
Current IP: 10.0.x.x From: China Beijing Beijing # This is an example. Use the actual device information.Run the following command to modify the policy.yaml file.
vim policy.yamlModify the policy.yaml file to include the following content:
# 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 # Local IP address. This is an example. Use the actual device information.Run the following command to create a network policy from the policy.yaml file.
kubectl apply -f policy.yamlExpected output:
networkpolicy.networking.k8s.io/access-nginx unchangedNoteSome networks have multiple egress IP addresses. We recommend that you use a /24 address range.
The SLB health check addresses are in the
100.64.0.0/10CIDR block. Therefore, you must add100.64.0.0/10to the allowed list.
Run the following command to access the Nginx service.
kubectl run busybox --rm -ti --labels="access=true" --image=busybox /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 ETAThe output indicates that the connection progress is 100%. This means that you have successfully accessed the Nginx service.
Scenario 3: Restrict a pod to access only a specified address using a network policy
Run the following command to obtain the list of IP addresses to which the www.aliyun.com domain name resolves.
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.3Create a file named busybox-policy.yaml.
vim busybox-policy.yamlUse the following template for the busybox-policy.yaml file:
# 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: 53NoteIn the busybox-policy.yaml file, egress rules are configured to restrict the application's outbound access. You must configure the rules to allow UDP requests. Otherwise, DNS resolution fails.
Run the following command to create a network policy from the busybox-policy.yaml file.
kubectl apply -f busybox-policy.yamlExpected output:
networkpolicy.networking.k8s.io/busybox-policy createdRun the following command to create a busybox pod and test access.
kubectl run busybox --rm -ti --image=busybox /bin/shAccess a website other than www.aliyun.com, such as 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 can't connect to remote host message indicates that access failed.
Run the following command 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 output indicates that the connection progress is 100%. This means that the service was accessed successfully.
Scenario 4: Control public network access for pods in a namespace using a network policy
This operation may affect online services that are accessing the public network. We recommend that you perform the following operations in an empty namespace.
Run the following command to create a test namespace.
Create a namespace named test-np.
kubectl create ns test-npExpected output:
namespace/test-np createdRun the following command to create a default network policy for the namespace that allows only outbound access to private networks.
vim default-deny.yamlThe following is an example template for the default-deny.yaml file:
# 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/8Verify that the default-deny.yaml file has been created.
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> 1mRun the following command to create a network policy that allows pods with a specific label to access the public network.
vim allow-specify-label.yamlIn this example, the 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-system # Allows pods to access key services in kube-system (such as CoreDNS). This is an example. Configure as needed.Run 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> 3mRun the following commands to verify that a pod without the special label cannot access the public network.
kubectl run -it --namespace test-np --rm --image registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/busybox:1.28 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 0 packets received message indicates that access failed.
NoteAccess failed because the deny-public-net network policy restricts public network access for pods in the test-np namespace by default. Therefore, pods that are started in this namespace with default labels cannot access the public network.
Run the following command to verify that a pod with the public-network=true label can access the public network.
kubectl run -it --namespace test-np --labels public-network=true --rm --image registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/busybox:1.28 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 0% packet loss message indicates that the service was accessed successfully.
NoteAccess is successful because the allow-public-network-for-labels network policy allows public network access for pods with the public-network=true label. Therefore, the busybox-internet pod, which has this label, can access the public network.