借助 Calico,管窥 Kubernetes 网络策略
Kubernetes 提出了一系列 CXI 的标准容器接口,其中的 CNI 以插件方式支持多种网络。新增的 networkpolicy API 对象,提供了对网络策略的支持,本文以 Calico 为例,实际操作一个网络策略的创建和测试。
环境准备
- 一个 Kubernetes 集群
- Kubelet 和 API Server 都开启了
--allow_privileged=true
- Kubelet 指定使用 CNI :
--network-plugin=cni
- 为了避免某些不可描述的网络设施的影响,建议下载几个镜像
- quay.io/calico/node:v1.0.2
- calico/cni:v1.5.6
- calico/kube-policy-controller:v0.5.2
- calico/ctl:v1.0.2
运行 Calico
- 下载
http://docs.projectcalico.org/v2.0/getting-started/kubernetes/installation/hosted/calico.yaml
- 如果用私库镜像,需要修改其中的几个镜像地址
- 修改
data/etcd_endpoints
的数据为可访问的 etcd 的地址。
kubectl create -f calico.yaml
这里在 kube-system 中创建了一个 DaemonSet 和一个 Deployment,分别用于提供 CNI 支持和网络策略支持。
$ kubectl get deployment,daemonset,svc --all-namespaces [9:55:14]
NAMESPACE NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kube-system deploy/calico-policy-controller 1 1 1 1 10h
NAMESPACE NAME DESIRED CURRENT READY NODE-SELECTOR AGE
kube-system ds/calico-node 2 2 2 <none> 10h
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default svc/kubernetes 172.200.0.1 <none> 443/TCP 19h
default svc/nginx 172.200.183.204 <none> 80/TCP 9h
网络策略
为测试效果,我们首先创建一个 Namespace
kubectl create ns policy
然后是 Nginx 部署和服务:
---
kind: ReplicationController
apiVersion: v1
metadata:
name: nginx
labels:
name: nginx
spec:
replicas: 1
selector:
name: nginx
template:
metadata:
labels:
name: nginx
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
protocol: TCP
---
kind: Service
apiVersion: v1
metadata:
name: nginx
labels:
name: nginx
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
name: nginx
然后我们用 alpine 镜像测试一下对这一服务进行访问:
kubectl run alpine --rm -it --image=alpine sh
运行成功后,在 Alpine 的 Shell 中输入:
wget -O - -T 5 http://nginx
会出现 Nginx 的缺省页面的代码。
接下来我们给 Default Namespace 加一个缺省拒绝访问的注解:
$ kubectl annotate ns default "net.beta.kubernetes.io/network-policy={\"ingress\": {\"isolation\": \"DefaultDeny\"}}"
重复测试过程,会发现超时错误。
我们来创建一条策略:
kind: NetworkPolicy
apiVersion: extensions/v1beta1
metadata:
name: access-nginx
spec:
podSelector:
matchLabels:
run: nginx
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
很容易理解,对于符合 “run=nginx” 的 Pod,只有 “access=true” 的 Pod 能够访问
给 Alpine 带上标签重新运行:
kubectl run alp --image=alpine --labels="access=true" --rm -ti sh
重新 wget,会发现访问能力已经恢复。
本文主要线索来自官方示例:https://kubernetes.io/docs/getting-started-guides/network-policy/walkthrough/
安装方法来自 Calico 官网。
这只是一个很入门的介绍,后续会有更多进一步的尝试。