k8s集群Canal的网络控制 原
1 简介
直接上干货
public class DispatcherServlet extends HttpServlet {
private Properties contextConfigProperties = new Properties();
private List<String> classNames = new ArrayList<>();
private Map<String, Object> ioc = new HashMap<String, Object>();
private Map<String, Method> handlerMappings = new HashMap<>();
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
dispatcher(req,resp);
} catch (Exception e) {
resp.getWriter().write("500 Server has an error"+Arrays.toString(e.getStackTrace()));
}
}
private void dispatcher(HttpServletRequest req, HttpServletResponse resp) throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (this.handlerMappings.isEmpty()) {
return;
}
String url = req.getRequestURI();
String contextPath = req.getContextPath();
url.replace(contextPath, "").replaceAll("/+", "/");
if (!this.handlerMappings.containsKey(url)) {
resp.getWriter().write("404 Page Not Found! ");
return;
}
Method method = this.handlerMappings.get(url);
Map<String,String[]> parameterMap = req.getParameterMap();
String beanName = this.lowerFirstLetter(method.getDeclaringClass().getSimpleName());
Object obj = this.ioc.get(beanName);
if (!parameterMap.containsKey("name")) {
resp.getWriter().write("handerMapping Not Found!");
return;
}
method.invoke(obj, new Object[] {req,resp,parameterMap.get("name")[0]});
}
@Override
public void init(ServletConfig config) throws ServletException {
//加载配置
loadConfig(config.getInitParameter("contextConfigLocation"));
//扫描指定包下的所有类
scannerClass(this.contextConfigProperties.getProperty("scanPackage"));
//初始化容器
initIoc();
//自动注入
autoWiredInstance();
//初始化处理映射
initHanderMapping();
System.out.println("mvc init over...");
}
private void initHanderMapping() {
if (this.ioc.isEmpty()) {
return;
}
try {
for (Map.Entry<String, Object> en : this.ioc.entrySet()) {
boolean present = en.getValue().getClass().isAnnotationPresent(Controller.class);
if (present) {
StringBuffer baseUrl = new StringBuffer();
RequestMapping requestMapping = en.getValue().getClass().getAnnotation(RequestMapping.class);
baseUrl.append(requestMapping.value());
Method[] methods = en.getValue().getClass().getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(RequestMapping.class)) {
RequestMapping mapping = method.getAnnotation(RequestMapping.class);
String fullUrl = ("/"+baseUrl.append("/").append(mapping.value().trim()).toString()).replaceAll("/+", "/");
this.handlerMappings.put(fullUrl, method);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void autoWiredInstance() {
if (this.ioc.isEmpty()) {
return;
}
try {
for (Map.Entry<String, Object> en : this.ioc.entrySet()) {
Field[] fields = en.getValue().getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class)) {
Autowired autowired = field.getAnnotation(Autowired.class);
String beanName = autowired.value();
if ("".equals(beanName)) {
beanName = field.getType().getName();
}
field.setAccessible(true);
field.set(en.getValue(), this.ioc.get(beanName));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void initIoc() {
if (this.classNames.isEmpty()) {
return;
}
try {
for (String className : classNames) {
Class<?> clazz = Class.forName(className);
if (clazz.isAnnotationPresent(Controller.class)||clazz.isAnnotationPresent(Service.class)) {
Object newInstance = clazz.newInstance();
String simpleName = lowerFirstLetter(clazz.getSimpleName());
if (clazz.getAnnotation(Controller.class)!=null) {
String value = clazz.getAnnotation(Controller.class).value();
if ("".equals(value.trim())) {
this.ioc.put(simpleName, newInstance);
}else {
this.ioc.put(value, newInstance);
}
}else if (clazz.getAnnotation(Service.class)!=null) {
String value = clazz.getAnnotation(Service.class).value();
handleAnnotation(clazz,value, newInstance);
}else if (clazz.getAnnotation(Dao.class)!=null) {
String value = clazz.getAnnotation(Dao.class).value();
handleAnnotation(clazz,value, newInstance);
}else {
this.ioc.put(simpleName, clazz.newInstance());
}
}else {
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void handleAnnotation(Class<?> clazz,String annotationValue, Object newInstance) throws Exception {
if ("".equals(annotationValue.trim())) {
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> i : interfaces) {
if (this.ioc.containsKey(i.getName())) {
throw new Exception("the beanName:"+i.getName()+",has samed");
}
this.ioc.put(i.getName(), newInstance);
}
}else {
this.ioc.put(annotationValue, newInstance);
}
}
private void scannerClass(String scanPackage) {
URL url = this.getClass().getClassLoader().getResource(File.separator+scanPackage.replaceAll(".", File.separator));
File dir = new File(url.getFile());
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
scannerClass(scanPackage+"."+file.getName());
}else {
if (!file.getName().contains(".class")) {
continue;
}
String className = (scanPackage+"."+file.getName().replaceAll("class", "")).trim();
this.classNames.add(className);
Canal 是calico和flannel的结合,我们因为Calico不仅能够提供很好的网络性能,还能有网络规则控制,但是我们很多时候使用的Flannel网络,他的缺点就是没有网络控制只能提供网络服务,所以Canal诞生了,为Falanel提供了网络控制。
网络策略 控制出站: egress 控制进站: ingress 可以以ip地址块定义规则,也可以基于命名空间规则定义,还可以对pod定义规则
2 部署Canal
curl \
https://docs.projectcalico.org/v3.6/getting-started/kubernetes/installation/hosted/canal/canal.yaml \
-O
kubectl apply -f canal.yaml
1)canal默认控制的是10.244.0.0/16 ,如果你在安装k8s集群是设置的pod网络不是此段网络,则你需要修改配置文件
2)我们采用的和k8s集群公用etcd的方式创建
查看创建的pod
# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
canal-9lmw8 2/2 Running 0 4m50s
canal-ln6kg 2/2 Running 0 4m50s
canal-mx6tn 2/2 Running 0 4m50s
coredns-fb8b8dccf-lfbkh 1/1 Running 2 10d
coredns-fb8b8dccf-t2kdz 1/1 Running 2 10d
etcd-master-1 1/1 Running 2 10d
kube-apiserver-master-1 1/1 Running 2 10d
kube-controller-manager-master-1 1/1 Running 2 10d
kube-flannel-ds-amd64-df7gk 1/1 Running 3 9d
kube-flannel-ds-amd64-dzxfd 1/1 Running 3 9d
kube-flannel-ds-amd64-mgw2m 1/1 Running 2 9d
kube-proxy-47d6q 1/1 Running 2 10d
kube-proxy-jztrs 1/1 Running 3 10d
kube-proxy-rt4xx 1/1 Running 3 10d
kube-scheduler-master-1 1/1 Running 2 10d
kubernetes-dashboard-5f7b999d65-8h79h 1/1 Running 0 21h
3 创建两个实验的空间
kubectl create namespace shengchan
kubectl create namespace test
4 创建网络规则测试
默认ingress 和 engress可以一起使用,当这两规则同时存在那么将使用policyTypes做具体的规则指向
例如:创建一个policy默认拒绝所有在空间shengchan的入站规则
# cat ingress-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: shengchan
spec:
podSelector: {}
policyTypes:
- Ingress
kubectl apply ingress-deny.yaml
创建一组属于shengchan空间的pod
# cat pod-networkpolicy1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-test
spec:
containers:
- name: pod-test-policy
image: nginx:1.10
kubectl apply -f pod-networkpolicy1.yaml -n shengchan
创建一组属于test空间的pod
kubectl apply -f pod-networkpolicy1.yaml -n test
分别查看两组pod的IP地址
# kubectl get pods -o wide -n shengchan
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-test 1/1 Running 0 16s 10.244.1.2 node2 <none> <none>
[root@master-1 ~]# kubectl get pods -o www.mmingyLgw.com wide -n test
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-test 1/1 Running 0 9s 10.244.2.2 node1 <none> <none>
在宿主机上面分别ping这两个ip
# ping 10.244.1.2 -c 1
PING 10.244.1.2 (10.244.1.2) 56(84) bytes of data.
^C
--- 10.244.1.2 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
# ping 10.244.2.2 -c 1
PING 10.244.2.2 (10.244.2.2) 56(84) bytes of data.
64 bytes from 10.244.2.2: icmp_seq=1 ttl=63 time=0.660 ms
--- 10.244.2.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.660/0.660/0.660/0.000 ms
此时发现属于shengchan空间的pod是被拒绝访问的,属于test空间的pod正常访问
此时我们是基于名称空间级别的入站网络访问策略
5 将上面的默认拒绝策略放行
修改配置文件
apiVersion: networking.www.tianscpt.com k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: shengchan
spec:
podSelector: {www.yunsengyule.com}
ingress:
- {}
policyTypes:
- Ingress
kubectl apply -f ingress-deny.yaml
再次测试10.244.1.2
[root@master-1 ~]# curl -I 10.244.1.2
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Sat, 27 Apr 2019 16:58:04 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
Connection: keep-alive
ETag: "5890a6b7-264"
Accept-Ranges: bytes
[root@master-1 ~]# curl yunshenggw.cn/-I 10.244.2.2
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Sat, 27 Apr 2019 16:58:07 GMT
Content-Type:www.douniu2.cc text/html
Content-Length: 612
Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
Connection: keep-alive
ETag: "5890a6b7-264"
Accept-Ranges: bytes
说明我们的网络策略放行成功
6 放行特定的入站
以标签的形式进行划分pod入站规则是否被放行
1)回复默认拒绝所有
[root@master-1 ~]# cat ingress-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: shengchan
spec:
podSelector: {www.baihuiyulep.cn}
policyTypes:
- Ingress
kubectl apply www.mumingyue.cn-f ingress-deny.yaml
2)给shengchan pod打一个标签
kubectl label pods pod-test app=www.dayuzaixianyL.cn hello -n shengchan
3)创建一个新的规则
# vim ingress-allow.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-hello-ingress
namespace: shengchan
spec:
podSelector:
matchLabels:
app: hello
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16
except:
- 10.244.2.2/32
ports:
- protocol: TCP
port: 80
解释: 我们重新定义了一个policy,通过标签匹配到我们已有的pod(我们一已有的pod是拒绝所有访问的),定义ingres规则,如果不通过from方式定义默认是所有网段都可以访问到拥有这个标签的pod为了测试我们使用from方式去拒绝10.244.0.0但是会放行10.244.2.2因为我们有这个ip的pod创建万郴更可以进行测试ports就是指定特定开放的端口
4)创建之前进行访问测试
# kubectl get pods -n shengchan -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-test 1/1 Running 0 62m 10.244.1.2 node2 <none> <none>
# curl 10.244.1.2
说明无法访问
5)创建之后测试
kubectl apply -f ingress-allow.yml
[root@master-1 ~]# curl -I 10.244.1.2
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Sat, 27 Apr 2019 17:32:15 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
Connection: keep-alive
ETag: "5890a6b7-264"
Accept-Ranges: bytes
说明已经放行
至于对于10.244.0.0网段的限制有兴趣可以测试一下
6 egress出站规则
1)设置一个拒绝所有出站policy
cat egress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: test
spec:
podSelector: {}
policyTypes:
- Egress
kubectl apply -f egress.yml
2)创建一个test命名空间下的pods
kubectl apply -f pod-networkpolicy1.yaml -n test
3)查看podIP并进去容器去测试ping一个正常的podip
[root@master-1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
net-test-5764c456cb-2c9df 1/1 Running 24 24h 10.244.2.22 node1 <none> <none>
net-test-5764c456cb-ng6vh 1/1 Running 46 6d5h 10.244.1.21 node2 <none> <none>
[root@master-1 www.mhylpt.com/~]# kubectl get pods -o wide -n test
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-test 1/1 Running 0 86m 10.244.2.2 node1 <none> <none>
kubectl exec -it pod-test -n test -- /bin/bash
root@pod-test:/# ping 10.244.1.21
PING 10.244.1.21 (10.244.1.21): 56 data bytes
^C--- 10.244.1.21 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
说明此时已经应用策略
4)修改配置文件放行所有出站
# cat egress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: test
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
kubectl apply -f egress.yml
测试:
root@pod-test:/# ping 10.244.1.21 -c 1
PING 10.244.1.21 (10.244.1.21): 56 data bytes
64 bytes from 10.244.1.21: icmp_seq=0 ttl=62 time=0.939 ms
--- 10.244.1.21 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.939/0.939/0.939/0.000 ms
此时说明已经放行成功
7 更加复杂的policy规则需要根据不同的环境规划进行深入探究,其所有都规则都体现在配置文件中
k8s集群Canal的网络控制 原的更多相关文章
- Kubernetes全栈架构师(二进制高可用安装k8s集群扩展篇)--学习笔记
目录 二进制Metrics&Dashboard安装 二进制高可用集群可用性验证 生产环境k8s集群关键性配置 Bootstrapping: Kubelet启动过程 Bootstrapping: ...
- k8s集群搭建过程详解
准备工作 安装CentOS7虚拟机 略 安装Docker 略 关闭CentOS7自带的防火墙服务 systemctl disable firewalld systemctl stop firewall ...
- 基于 kubeadm 部署单控制平面的 k8s 集群
单控制平面不符合 HA 要求,但用于开发/测试环境不会有任何问题,如果资源足够的话(10台以上服务器,3台用于APIserver.3台用于 etcd 存储.至少3台用于工作节点.1台作为负载均衡),可 ...
- Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之flanneld网络介绍及部署(三)
0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.flanneld介绍 ...
- K8s二进制部署单节点 etcd集群,flannel网络配置 ——锥刺股
K8s 二进制部署单节点 master --锥刺股 k8s集群搭建: etcd集群 flannel网络插件 搭建master组件 搭建node组件 1.部署etcd集群 2.Flannel 网络 ...
- k8s集群StatefulSets的Pod调度查询丢失问题?
k8s集群StatefulSets的Pod调度查询丢失问题? 考点之简单介绍下StatefulSets 和 Deployment 之间有什么本质区别?特定场景该如何做出选择呢? 考点之你能辩证的说说看 ...
- 1.还不会部署高可用的kubernetes集群?看我手把手教你使用二进制部署v1.23.6的K8S集群实践(上)
公众号关注「WeiyiGeek」 设为「特别关注」,每天带你玩转网络安全运维.应用开发.物联网IOT学习! 本章目录: 0x00 前言简述 0x01 环境准备 主机规划 软件版本 网络规划 0x02 ...
- Centos7 安装部署Kubernetes(k8s)集群
目录 一.系统环境 二.前言 三.Kubernetes 3.1 概述 3.2 Kubernetes 组件 3.2.1 控制平面组件 3.2.2 Node组件 四.安装部署Kubernetes集群 4. ...
- k8s重要概念及部署k8s集群(一)--技术流ken
重要概念 1. cluster cluster是 计算.存储和网络资源的集合,k8s利用这些资源运行各种基于容器的应用. 2.master master是cluster的大脑,他的主要职责是调度,即决 ...
随机推荐
- 使用curl制作简易百度搜索
这几天研究了一下php中的curl类库,做了一个简单的百度搜索,先上代码 <div style="width:200px;height:100px;"> <div ...
- 2018-07-10 为Chrome和火狐浏览器编写扩展
由于扩展标准的逐渐一致, 现在同一扩展代码库已经有可能同时用于Chrome和火狐. 下面是一个简单的工具栏按钮和弹窗(尚无任何实际功能): 代码库地址: nobodxbodon/suan1 所有代码: ...
- 小程序应用的Python服务器部署高配,依然是腾讯云秒杀阿里云!
上一篇文章,“小程序创业最低配置部署,腾讯云折扣秒杀阿里云!”介绍了小程序项目启动时的最低配置服务器选择,但当项目良好发展时,还是要把服务器配置调整到标准水平,承受住日益增长的流量访问. 随着Pyth ...
- 小米平板6.0以上系统如何不用Root激活Xposed框架的步骤
在异常多公司的引流,或业务操作中,大多数需要使用安卓的神一般的Xposed框架,几天前我们公司买来了一批新的小米平板6.0以上系统,大多数都是基于7.0以上版本,大多数不能够获取Root超级权限,虽然 ...
- Android 使用TextView实现跑马灯效果
前言 我们在开发中经常会遇到一个小问题.比如下面一个小例子: 这个文字太长,单行中导致无法全部显示出来,这就是今天要实现的功能. 当然,百度中也有很多这种解决方案. 其中有一种,例如: <Tex ...
- Android Studio教程07-Fragment的使用
目录 1. Fragment是什么 1.1. 设计原理和实例 2. 创建fragment 2.1. fragment的生命周期 2.2 添加用户界面:融入到Activity中 3. 管理fragmen ...
- ElasticSearch、Logstash、Kibana 搭建高效率日志管理系统
ELK (ElasticSearch.LogStash以及Kibana)三者组合是一个非常强大的工具,这里我们来实现监控日志文件并且收到日志到ElasticSearch搜索引擎,利用Kibana可视化 ...
- 使用 phpstudy 搭建本地测试环境
最近在为另一个部门配置一个多语言的网站,因为之前他们已经做过 英文和中文两种语言,这次帮他们添加其它几种语言,从GitLab 上拉下来的代码,是php环境做的,需要在本地跑起来,做完测试通过后再一次性 ...
- Docker-镜像源加速配置
Docker官网镜像服务在境外,拉取速度很比较慢,所以我们安装完Docker后一般会切换镜像源,将镜像源切换到国内以此达到加速的目的. 国内比较常用的Docker Hub镜像服务:1.阿里云2.Dao ...
- 一:SqlServer中的 CEILING函数和 FLOOR函数以及ROUND()
例如 1.ROUND() 格式为ROUND(y1,y2,y3) y1:要被四舍五入的数字y2:保留的小数位数 y3:为0,可以不写,y1进行四舍五入,不为0则y1不进入四舍五入,如果y1有值就直接根据 ...