Alibaba Cloud Container Compute Service (ACS) permite implementar controle de rede baseado em políticas com o Kubernetes NetworkPolicy. Use políticas de rede para controlar o tráfego no nível de endereço IP ou porta para aplicações específicas no cluster. Este tópico explica como usar políticas de rede em um cluster ACS e apresenta casos de uso comuns.
Aplicabilidade
Há suporte apenas para pods de uso geral e otimizados para computação com CPU.
Há suporte apenas para IPv4.
Observações
As regras de NetworkPolicy permitem selecionar namespaces ou pods usando um LabelSelector. No entanto, aplicar muitas NetworkPolicies a um pod aumenta o tempo para as regras entrarem em vigor. O excesso de regras também pode complicar o gerenciamento e a solução de problemas do cluster. Portanto, mantenha o número de NetworkPolicies no cluster abaixo de 40.
Etapa 1: Ativar NetworkPolicy
-
Instale o componente Poseidon.
Faça login no console do ACS. No painel de navegação à esquerda, clique em Clusters.
Na página Clusters, clique no nome do cluster desejado. No painel de navegação à esquerda, clique em Add-ons.
Na página Component management, clique na aba Network. No cartão Poseidon, clique em Install.
-
Na página Install Component Poseidon, selecione Enable NetworkPolicy e clique em Confirm.
Após a instalação do componente, Installed aparece no canto superior direito do cartão.
-
Ative a NetworkPolicy na anotação do Pod.
Para ativar a NetworkPolicy em um Pod, adicione a seguinte anotação aos metadados dele:
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
Etapa 2: Criar uma aplicação de teste Nginx
kubectl
Obtenha o arquivo kubeconfig do cluster e use kubectl para conectar-se ao cluster.
-
Crie uma aplicação Nginx e comunique-se com ela por meio de um Service chamado nginx.
Crie a aplicação Nginx:
kubectl run nginx --image=nginxSaída esperada:
pod/nginx createdVerifique o status do pod:
kubectl get podSaída esperada:
NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 45sCrie um Service chamado nginx:
kubectl expose pod nginx --port=80Saída esperada:
service/nginx exposedVisualize o Service:
kubectl get serviceSaída esperada:
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 -
Crie um Pod chamado busybox e acesse um Service chamado nginx.
kubectl run busybox --rm -ti --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shSaída esperada:
If you don't see a command prompt, try pressing enter. / # / #Teste o acesso ao Nginx:
If you don't see a command prompt, try pressing enter. / # / # wget nginx # Enter wget nginx here.Saída esperada:
Connecting to nginx (172.XX.XX.48:80) saving to 'index.html' index.html 100% |****************************************************************************************************************************************************| 612 0:00:00 ETA 'index.html' saved
Etapa 3: Usar uma política de rede
Use políticas de rede nos seguintes cenários conforme necessário.
Cenário 1: Permitir acesso por rótulo
kubectl
-
Use o modelo YAML abaixo e execute o comando
vim policy.yamlpara criar o arquivo policy.yaml.vim policy.yamlO conteúdo do arquivo YAML é o seguinte.
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-nginx spec: podSelector: matchLabels: run: nginx ingress: - from: - podSelector: matchLabels: access: "true" -
Crie uma política de rede a partir do arquivo policy.yaml.
kubectl apply -f policy.yamlSaída esperada:
networkpolicy.networking.k8s.io/access-nginx created -
Quando nenhum rótulo de acesso estiver definido, as solicitações ao Service chamado nginx expirarão e falharão.
kubectl run busybox --rm -ti --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shTeste o acesso ao Service chamado nginx:
wget nginxSaída esperada:
Connecting to nginx (172.19.XX.XX:80) wget: can't connect to remote host (172.19.XX.XX): Connection timed out -
Defina rótulos de acesso.
kubectl run busybox --rm -ti --labels="access=true" --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shTeste o Service Nginx:
wget nginxSaída esperada:
Connecting to nginx (172.21.XX.XX:80) saving to 'index.html' index.html 100% |****************************************************************************************************************************************************| 612 0:00:00 ETA 'index.html' savedUm progresso de 100% indica uma conexão bem-sucedida ao serviço Nginx.
Cenário 2: Restringir acesso por bloco CIDR de origem
kubectl
-
Crie um serviço Alibaba Cloud SLB para a aplicação Nginx e defina
type=LoadBalancerpara expor o serviço Nginx à internet.vim nginx-service.yamlO conteúdo do arquivo nginx-service.yaml é o seguinte.
# 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: LoadBalancerCrie o serviço a partir do arquivo nginx-service.yaml.
kubectl apply -f nginx-service.yamlSaída esperada:
service/nginx-slb createdVerifique se a aplicação expõe o serviço Nginx:
kubectl get service nginx-slbSaída esperada:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-slb LoadBalancer 172.19.xx.xxx 47.110.xxx.xxx 80:32240/TCP 8m -
Acesse o endereço IP da instância SLB, 47.110.xxx.xxx. A conexão falha.
wget 47.110.xxx.xxxSaída esperada:
--2018-11-21 11:46:05-- http://47.110.xx.xxx/ Connecting to 47.110.XX.XX:80... failed: Connection refused.NotaA conexão falha pelos seguintes motivos:
A política de rede permite acesso apenas de aplicações com o rótulo
access=true.O tráfego proveniente do endereço IP do SLB tem origem fora do cluster. A política de rede atual permite apenas tráfego de pods com um rótulo específico, não tráfego externo.
Solução: Modifique a política de rede para adicionar o bloco CIDR de origem permitido.
-
Verifique o endereço IP da sua máquina local.
curl myip.ipip.netSaída esperada:
Current IP: 10.0.x.x From: China Beijing Beijing # This is an example. The actual output from your device may vary. -
Modifique o arquivo policy.yaml que você criou.
vim policy.yamlModifique o arquivo policy.yaml da seguinte forma:
# 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.Aplique a política atualizada:
kubectl apply -f policy.yamlSaída esperada:
networkpolicy.networking.k8s.io/access-nginx unchangedNotaAlgumas redes possuem múltiplos endereços IP de saída. Nesse caso, use um intervalo de endereços /24.
Os endereços de verificação de integridade do SLB estão no bloco de endereços
100.64.0.0/10. Portanto, configure100.64.0.0/10.
-
Execute um pod de teste para acessar o serviço Nginx.
kubectl run busybox --rm -ti --labels="access=true" --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shAcesse o serviço Nginx:
wget 47.110.XX.XXSaída esperada:
Connecting to 47.110.XX.XX (47.110.XX.XX:80) index.html 100% |***********************************************************| 612 0:00:00 ETAUm progresso de 100% indica uma conexão bem-sucedida ao serviço Nginx.
Cenário 3: Restringir acesso de pods a endereços específicos
Kubectl
-
Resolva o domínio www.aliyun.com.
dig +short www.aliyun.comSaída esperada:
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 -
Crie o arquivo busybox-policy.
vim busybox-policy.yamlO arquivo
busybox-policy.yamlcontém o seguinte:# 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: 53NotaA regra
egressno arquivobusybox-policy.yamlrestringe o acesso de saída da aplicação. Para garantir que a resolução de DNS funcione, a política também deve permitir solicitações UDP na porta 53. -
Crie uma política de rede a partir do arquivo
busybox-policy.yaml.kubectl apply -f busybox-policy.yamlSaída esperada:
networkpolicy.networking.k8s.io/busybox-policy created -
Crie um pod
busyboxpara testar a política.kubectl run busybox --rm -ti --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 /bin/shTente acessar um site diferente de www.aliyun.com, por exemplo, www.taobao.com:
wget www.taobao.comSaída esperada:
Connecting to www.taobao.com (64.13.XX.XX:80) wget: can't connect to remote host (64.13.XX.XX): Connection timed outA mensagem
can't connect to remote hostindica que o acesso ao serviço foi negado. -
Tente acessar www.aliyun.com.
wget www.aliyun.comSaída esperada:
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 ETAO status de conclusão de 100% indica uma conexão bem-sucedida.
Caso de uso 4: Controlar acesso à rede pública para Pods
Esta operação pode afetar serviços online que acessam a rede pública. Recomendamos executar as etapas a seguir em um namespace vazio.
kubectl
-
Crie um namespace de teste para verificar a restrição.
Crie um namespace chamado
test-np.kubectl create ns test-npSaída esperada:
namespace/test-np created -
Defina uma política de rede padrão para este namespace que permita apenas tráfego de saída para a rede privada.
vim default-deny.yamlCrie um arquivo chamado
default-deny.yamlcom o seguinte conteúdo:# 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/8Crie a política de rede a partir do arquivo
default-deny.yaml.kubectl apply -f default-deny.yamlSaída esperada:
networkpolicy.networking.k8s.io/deny-public-net createdVisualize a política de rede:
kubectl get networkpolicy -n test-npSaída esperada:
NAME POD-SELECTOR AGE deny-public-net <none> 1m -
Permita que Pods com um rótulo específico acessem a rede pública.
vim allow-specify-label.yamlUm rótulo de exemplo é
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-systemExecute o seguinte comando para criar a política de rede:
kubectl apply -f allow-specify-label.yamlSaída esperada:
networkpolicy.networking.k8s.io/allow-public-network-for-labels createdVisualize a política de rede:
kubectl get networkpolicy -n test-npSaída esperada:
NAME POD-SELECTOR AGE allow-public-network-for-labels public-network=true 1m deny-public-net <none> 3m -
Verifique se um Pod sem o rótulo específico não consegue acessar a rede pública.
kubectl run -it --namespace test-np --rm --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 busybox-intranetping aliyun.comSaída esperada:
PING aliyun.com (106.11.2xx.xxx): 56 data bytes ^C --- aliyun.com ping statistics --- 9 packets transmitted, 0 packets received, 100% packet lossA mensagem
0 packets receivedindica que o acesso falhou.NotaO acesso falha porque a política de rede
deny-public-netbloqueia o acesso à rede pública por padrão para todos os Pods no namespacetest-np. -
Verifique se um Pod com o rótulo
public-network=trueconsegue acessar a rede pública.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.comSaída esperada:
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 msA mensagem
0% packet lossindica acesso bem-sucedido à rede pública.NotaO acesso é bem-sucedido porque a política de rede
allow-public-network-for-labelsconcede acesso à rede pública para Pods com o rótulopublic-network=true, como o Podbusybox-internet.