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 的地址。
<code><span class="pln">kubectl create </span><span class="pun">-</span><span class="pln">f calico</span><span class="pun">.</span><span class="pln">yaml</span></code>
www#gaodaima.com来源gaodaimacom搞#代%码网搞代码
这里在 kube-system 中创建了一个 DaemonSet 和一个 Deployment,分别用于提供 CNI 支持和网络策略支持。
<code class="console"><span class="pln">$ kubectl </span><span class="kwd">get</span><span class="pln"> deployment</span><span class="pun">,</span><span class="pln">daemonset</span><span class="pun">,</span><span class="pln">svc </span><span class="pun">--</span><span class="pln">all</span><span class="pun">-</span><span class="pln">namespaces </span><span class="pun">[</span><span class="lit">9</span><span class="pun">:</span><span class="lit">55</span><span class="pun">:</span><span class="lit">14</span><span class="pun">]</span><span class="pln"> NAMESPACE NAME DESIRED CURRENT UP</span><span class="pun">-</span><span class="pln">TO</span><span class="pun">-</span><span class="pln">DATE AVAILABLE AGE kube</span><span class="pun">-</span><span class="pln">system deploy</span><span class="pun">/</span><span class="pln">calico</span><span class="pun">-</span><span class="pln">policy</span><span class="pun">-</span><span class="pln">controller </span><span class="lit">1</span> <span class="lit">1</span> <span class="lit">1</span> <span class="lit">1</span> <span class="lit">10h</span><span class="pln"> NAMESPACE NAME DESIRED CURRENT READY NODE</span><span class="pun">-</span><span class="pln">SELECTOR AGE kube</span><span class="pun">-</span><span class="pln">system ds</span><span class="pun">/</span><span class="pln">calico</span><span class="pun">-</span><span class="pln">node </span><span class="lit">2</span> <span class="lit">2</span> <span class="lit">2</span> <span class="str"><none></span> <span class="lit">10h</span><span class="pln"> NAMESPACE NAME CLUSTER</span><span class="pun">-</span><span class="pln">IP EXTERNAL</span><span class="pun">-</span><span class="pln">IP PORT</span><span class="pun">(</span><span class="pln">S</span><span class="pun">)</span><span class="pln"> AGE </span><span class="kwd">default</span><span class="pln"> svc</span><span class="pun">/</span><span class="pln">kubernetes </span><span class="lit">172.200</span><span class="pun">.</span><span class="lit">0.1</span> <span class="str"><none></span> <span class="lit">443</span><span class="pun">/</span><span class="pln">TCP </span><span class="lit">19h</span> <span class="kwd">default</span><span class="pln"> svc</span><span class="pun">/</span><span class="pln">nginx </span><span class="lit">172.200</span><span class="pun">.</span><span class="lit">183.204</span> <span class="str"><none></span> <span class="lit">80</span><span class="pun">/</span><span class="pln">TCP </span><span class="lit">9h</span></code>
网络策略
为测试效果,我们首先创建一个 Namespace
<code><span class="pln">kubectl create ns policy</span></code>
然后是 Nginx 部署和服务:
<code class="yaml"><span class="pun">---</span><span class="pln"> kind</span><span class="pun">:</span> <span class="typ">ReplicationController</span><span class="pln"> apiVersion</span><span class="pun">:</span><span class="pln"> v1 metadata</span><span class="pun">:</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> nginx labels</span><span class="pun">:</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> nginx spec</span><span class="pun">:</span><span class="pln"> replicas</span><span class="pun">:</span> <span class="lit">1</span><span class="pln"> selector</span><span class="pun">:</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> nginx </span><span class="kwd">template</span><span class="pun">:</span><span class="pln"> metadata</span><span class="pun">:</span><span class="pln"> labels</span><span class="pun">:</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> nginx app</span><span class="pun">:</span><span class="pln"> nginx spec</span><span class="pun">:</span><span class="pln"> containers</span><span class="pun">:</span> <span class="pun">-</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> nginx image</span><span class="pun">:</span><span class="pln"> nginx ports</span><span class="pun">:</span> <span class="pun">-</span><span class="pln"> containerPort</span><span class="pun">:</span> <span class="lit">80</span><span class="pln"> protocol</span><span class="pun">:</span><span class="pln"> TCP </span><span class="pun">---</span><span class="pln"> kind</span><span class="pun">:</span> <span class="typ">Service</span><span class="pln"> apiVersion</span><span class="pun">:</span><span class="pln"> v1 metadata</span><span class="pun">:</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> nginx labels</span><span class="pun">:</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> nginx spec</span><span class="pun">:</span><span class="pln"> ports</span><span class="pun">:</span> <span class="pun">-</span><span class="pln"> protocol</span><span class="pun">:</span><span class="pln"> TCP port</span><span class="pun">:</span> <span class="lit">80</span><span class="pln"> targetPort</span><span class="pun">:</span> <span class="lit">80</span><span class="pln"> selector</span><span class="pun">:</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> nginx</span></code>
然后我们用 alpine 镜像测试一下对这一服务进行访问:
<code><span class="pln">kubectl run alpine </span><span class="pun">--</span><span class="pln">rm </span><span class="pun">-</span><span class="pln">it </span><span class="pun">--</span><span class="pln">image</span><span class="pun">=</span><span class="pln">alpine sh</span></code>
运行成功后,在 Alpine 的 Shell 中输入:
<code><span class="pln">wget </span><span class="pun">-</span><span class="pln">O </span><span class="pun">-</span> <span class="pun">-</span><span class="pln">T </span><span class="lit">5</span><span class="pln"> http</span><span class="pun">:</span><span class="com">//nginx </span></code>
会出现 Nginx 的缺省页面的代码。
接下来我们给 Default Namespace 加一个缺省拒绝访问的注解:
<code><span class="pln">$ kubectl annotate ns </span><span class="kwd">default</span> <span class="str">"net.beta.kubernetes.io/network-policy={"ingress": {"isolation": "DefaultDeny"}}"</span></code>
重复测试过程,会发现超时错误。
我们来创建一条策略:
<code class="yaml"><span class="pln">kind</span><span class="pun">:</span> <span class="typ">NetworkPolicy</span><span class="pln"> apiVersion</span><span class="pun">:</span><span class="pln"> extensions</span><span class="pun">/</span><span class="pln">v1beta1 metadata</span><span class="pun">:</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> access</span><span class="pun">-</span><span class="pln">nginx spec</span><span class="pun">:</span><span class="pln"> podSelector</span><span class="pun">:</span><span class="pln"> matchLabels</span><span class="pun">:</span><span class="pln"> run</span><span class="pun">:</span><span class="pln"> nginx ingress</span><span class="pun">:</span> <span class="pun">-</span> <span class="kwd">from</span><span class="pun">:</span> <span class="pun">-</span><span class="pln"> podSelector</span><span class="pun">:</span><span class="pln"> matchLabels</span><span class="pun">:</span><span class="pln"> access</span><span class="pun">:</span> <span class="str">"true"</span></code>
很容易理解,对于符合 “run=nginx” 的 Pod,只有 “access=true” 的 Pod 能够访问
给 Alpine 带上标签重新运行:
<code><span class="pln">kubectl run alp </span><span class="pun">--</span><span class="pln">image</span><span class="pun">=</span><span class="pln">alpine </span><span class="pun">--</span><span class="pln">labels</span><span class="pun">=</span><span class="str">"access=true"</span> <span class="pun">--</span><span class="pln">rm </span><span class="pun">-</span><span class="pln">ti sh</span></code>
重新 wget,会发现访问能力已经恢复。
本文主要线索来自官方示例:https://kubernetes.io/docs/getting-started-guides/network-policy/walkthrough/
安装方法来自 Calico 官网。
这只是一个很入门的介绍,后续会有更多进一步的尝试。