flannel
Docker跨主机容器间网络通信实现的工具有Pipework、Flannel、Weave、Open vSwitch(虚拟交换机)、Calico实现跨主机容器间的通信。其中Pipework、Weave、Flannel,三者的区别是:
Weave的思路
1
2
|
在每个宿主机上布置一个特殊的route的容器,不同宿主机的route容器连接起来。 route拦截所有普通容器的ip请求,并通过udp包发送到其他宿主机上的普通容器。 这样在跨机的多个容器端看到的就是同一个扁平网络。 weave解决了网络问题,不过部署依然是单机的。 |
flannel的思路
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。 但在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址。并使 这些容器之间能够之间通过IP地址相互找到,也就是相互 ping 通。 Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得 "同属一个内网" 且 "不重复的" IP地址,并让属于不同节 点上的容器能够直接通过内网IP通信。 Flannel实质上是一种 "覆盖网络(overlay network)" ,即表示运行在一个网上的网(应用层网络),并不依靠ip地址来传递消息,而是采用一种映射机制,把ip地址和 identifiers做映射来资源定位。也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发方式。 原理是每个主机配置一个ip段和子网个数。例如,可以配置一个覆盖网络使用 10.100.0.0 /16 段,每个主机 /24 个子网。因此主机a可以接受10.100.5.0 /24 ,主机B可以 接受10.100.18.0 /24 的包。flannel使用etcd来维护分配的子网到实际的ip地址之间的映射。对于数据路径,flannel 使用udp来封装ip数据报,转发到远程主机。选择 UDP作为转发协议是因为他能穿透防火墙。例如,AWS Classic无法转发IPoIP or GRE 网络包,是因为它的安全组仅仅支持TCP /UDP/ICMP 。 flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。 etcd也存储这个每个主机对应的ip。flannel 使用etcd的 watch 机制监视 /coreos .com /network/subnets 下面所有元素的变化信息,并且根据它来维护一个路由表。为了 提高性能,flannel优化了Universal TAP /TUN 设备,对TUN和UDP之间的ip分片做了代理。 |
默认的节点间数据通信方式是UDP转发.在Flannel的GitHub页面有如下的一张原理图:
对上图的简单解释:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
1)数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。 2)Flannel通过Etcd服务维护了一张节点间的路由表,在稍后的配置部分我们会介绍其中的内容。 3)源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡, 然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一下的有docker0路由到达目标容器。 这样整个数据包的传递就完成了,这里需要解释三个问题: 1)UDP封装是怎么回事? 在UDP的数据内容部分其实是另一个ICMP(也就是 ping 命令)的数据包。原始数据是在起始节点的Flannel服务上进行UDP封装的,投递到目的节点后就被另一端的Flannel服务 还原成了原始的数据包,两边的Docker服务都感觉不到这个过程的存在。 2)为什么每个节点上的Docker会使用不同的IP地址段? 这个事情看起来很诡异,但真相十分简单。其实只是单纯的因为Flannel通过Etcd分配了每个节点可用的IP地址段后,偷偷的修改了Docker的启动参数。 在运行了Flannel服务的节点上可以查看到Docker服务进程运行参数( ps aux| grep docker| grep "bip" ),例如“--bip=182.48.25.1 /24 ”这个参数,它限制了所在节 点容器获得的IP范围。这个IP范围是由Flannel自动分配的,由Flannel通过保存在Etcd服务中的记录确保它们不会重复。 3)为什么在发送节点上的数据会从docker0路由到flannel0虚拟网卡,在目的节点会从flannel0路由到docker0虚拟网卡? 例如现在有一个数据包要从IP为172.17.18.2的容器发到IP为172.17.46.2的容器。根据数据发送节点的路由表,它只与172.17.0.0 /16 匹配这条记录匹配,因此数据从docker0 出来以后就被投递到了flannel0。同理在目标节点,由于投递的地址是一个容器,因此目的地址一定会落在docker0对于的172.17.46.0 /24 这个记录上,自然的被投递到了docker0网卡。 |
pipework的思路
pipework是一个单机的工具,组合了brctl等工具,可以认为pipework解决的是宿主机上的设置容器的虚拟网卡、网桥、ip等,可以配合其他网络使用。
如果容器数量不多,想简单的组一个大的3层网络,可以考虑weave
如果容器数量很多,而且你们的环境复杂,需要多个子网,可以考虑open vswitch或者fannel
weave的总体网络性能表现欠佳, flannel VXLAN 能满足要求,一般推荐用flannel
Flannel环境部署记录
1)机器环境(centos7系统)
1
2
|
182.48.115.233 部署etcd,flannel,docker 主机名:node-1 主控端(通过etcd) 182.48.115.235 部署flannel,docker 主机名:node-2 被控端 |
2)node-1(182.48.115.233)机器操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
设置主机名及绑定hosts [root@node-1 ~] # hostnamectl --static set-hostname node-1 [root@node-1 ~] # vim /etc/hosts 182.48.115.233 node-1 182.48.115.233 etcd 182.48.115.235 node-2 关闭防火墙,如果开启防火墙,则最好打开2379和4001端口 [root@node-1 ~] # systemctl disable firewalld.service [root@node-1 ~] # systemctl stop firewalld.service 先安装docker环境 [root@node-1 ~] # yum install -y docker 安装etcd k8s运行依赖etcd,需要先部署etcd,下面采用yum方式安装: [root@node-1 ~] # yum install etcd -y yum安装的etcd默认配置文件在 /etc/etcd/etcd .conf,编辑配置文件: [root@node-1 ~] # cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf.bak [root@node-1 ~] # cat /etc/etcd/etcd.conf #[member] ETCD_NAME=master #节点名称 ETCD_DATA_DIR= "/var/lib/etcd/default.etcd" #数据存放位置 #ETCD_WAL_DIR="" #ETCD_SNAPSHOT_COUNT="10000" #ETCD_HEARTBEAT_INTERVAL="100" #ETCD_ELECTION_TIMEOUT="1000" #ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380" ETCD_LISTEN_CLIENT_URLS= "http://0.0.0.0:2379,http://0.0.0.0:4001" #监听客户端地址 #ETCD_MAX_SNAPSHOTS="5" #ETCD_MAX_WALS="5" #ETCD_CORS="" # #[cluster] #ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380" # if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..." #ETCD_INITIAL_CLUSTER="default=http://localhost:2380" #ETCD_INITIAL_CLUSTER_STATE="new" #ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_ADVERTISE_CLIENT_URLS= "http://etcd:2379,http://etcd:4001" #通知客户端地址 #ETCD_DISCOVERY="" #ETCD_DISCOVERY_SRV="" #ETCD_DISCOVERY_FALLBACK="proxy" #ETCD_DISCOVERY_PROXY="" 启动etcd并验证状态 [root@node-1 ~] # systemctl start etcd [root@node-1 ~] # ps -ef|grep etcd etcd 28145 1 1 14:38 ? 00:00:00 /usr/bin/etcd --name=master --data- dir = /var/lib/etcd/default .etcd --listen-client-urls=http: //0 .0.0.0:2379,http: //0 .0.0.0:4001 root 28185 24819 0 14:38 pts /1 00:00:00 grep --color=auto etcd [root@node-1 ~] # lsof -i:2379 COMMAND PID USER FD TYPE DEVICE SIZE /OFF NODE NAME etcd 28145 etcd 6u IPv6 1283822 0t0 TCP *:2379 (LISTEN) etcd 28145 etcd 18u IPv6 1284133 0t0 TCP localhost:53203->localhost:2379 (ESTABLISHED) ........ [root@node-1 ~] # etcdctl set testdir/testkey0 0 0 [root@node-1 ~] # etcdctl get testdir/testkey0 0 [root@node-1 ~] # etcdctl -C http://etcd:4001 cluster-health member 8e9e05c52164694d is healthy: got healthy result from http: //etcd :2379 cluster is healthy [root@node-1 ~] # etcdctl -C http://etcd:2379 cluster-health member 8e9e05c52164694d is healthy: got healthy result from http: //etcd :2379 cluster is healthy 安装覆盖网络Flannel [root@node-1 ~] # yum install flannel 配置Flannel [root@node-1 ~] # cp /etc/sysconfig/flanneld /etc/sysconfig/flanneld.bak [root@node-1 ~] # vim /etc/sysconfig/flanneld # Flanneld configuration options # etcd url location. Point this to the server where etcd runs FLANNEL_ETCD_ENDPOINTS= "http://etcd:2379" # etcd config key. This is the configuration key that flannel queries # For address range assignment FLANNEL_ETCD_PREFIX= "/atomic.io/network" # Any additional options that you want to pass #FLANNEL_OPTIONS="" 配置etcd中关于flannel的key(这个只在安装了etcd的机器上操作) Flannel使用Etcd进行配置,来保证多个Flannel实例之间的配置一致性,所以需要在etcd上进行如下配置( '/atomic.io/network/config' 这个key与上文 /etc/sysconfig/flannel 中的配置项FLANNEL_ETCD_PREFIX是相对应的,错误的话启动就会出错): [root@node-1 ~] # etcdctl mk /atomic.io/network/config '{ "Network": "182.48.0.0/16" }' { "Network" : "182.48.0.0/16" } 温馨提示:上面flannel设置的ip网段可以任意设定,随便设定一个网段都可以。容器的ip就是根据这个网段进行自动分配的,ip分配后,容器一般是可以对外联网的(网桥模式,只要宿主机能上网就可以) 启动Flannel [root@node-1 ~] # systemctl enable flanneld.service [root@node-1 ~] # systemctl start flanneld.service [root@node-1 ~] # ps -ef|grep flannel root 9305 9085 0 09:12 pts /2 00:00:00 grep --color=auto flannel root 28876 1 0 May15 ? 00:00:07 /usr/bin/flanneld -etcd-endpoints=http: //etcd :2379 -etcd-prefix= /atomic .io /network 启动Flannel后,一定要记得重启docker,这样Flannel配置分配的ip才能生效,即docker0虚拟网卡的ip会变成上面flannel设定的ip段 [root@node-1 ~] # systemctl restart docker |
3)node-2(182.48.115.235)机器操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
设置主机名及绑定hosts [root@node-2 ~] # hostnamectl --static set-hostname node-2 [root@node-2 ~] # vim /etc/hosts 182.48.115.233 node-1 182.48.115.233 etcd 182.48.115.235 node-2 关闭防火墙,如果开启防火墙,则最好打开2379和4001端口 [root@node-2 ~] # systemctl disable firewalld.service [root@node-2 ~] # systemctl stop firewalld.service 先安装docker环境 [root@node-2 ~] # yum install -y docker 安装覆盖网络Flannel [root@node-2 ~] # yum install flannel 配置Flannel [root@node-2 ~] # cp /etc/sysconfig/flanneld /etc/sysconfig/flanneld.bak [root@node-2 ~] # vim /etc/sysconfig/flanneld # Flanneld configuration options # etcd url location. Point this to the server where etcd runs FLANNEL_ETCD_ENDPOINTS= "http://etcd:2379" # etcd config key. This is the configuration key that flannel queries # For address range assignment FLANNEL_ETCD_PREFIX= "/atomic.io/network" # Any additional options that you want to pass #FLANNEL_OPTIONS="" 启动Flannel [root@node-2 ~] # systemctl enable flanneld.service [root@node-2 ~] # systemctl start flanneld.service [root@node-2 ~] # ps -ef|grep flannel root 3841 9649 0 09:11 pts /0 00:00:00 grep --color=auto flannel root 28995 1 0 May15 ? 00:00:07 /usr/bin/flanneld -etcd-endpoints=http: //etcd :2379 -etcd-prefix= /atomic .io /network 启动Flannel后,一定要记得重启docker,这样Flannel配置分配的ip才能生效,即docker0虚拟网卡的ip会变成上面flannel设定的ip段 [root@node-2 ~] # systemctl restart docker |
4)创建容器,验证跨主机容器之间的网络联通性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
首先在node-1(182.48.115.233)上容器容器,如下,登陆容器发现已经按照上面flannel配置的分配了一个ip段(每个宿主机都会分配一个182.48.0.0 /16 的网段) [root@node-1 ~] # docker run -ti -d --name=node-1.test docker.io/nginx /bin/bash 5e403bf93857fa28b42c9e2abaa5781be4e2bc118ba0c25cb6355b9793dd107e [root@node-1 ~] # docker exec -ti node-1.test /bin/bash root@5e403bf93857:/ # ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1 /8 scope host lo valid_lft forever preferred_lft forever inet6 ::1 /128 scope host valid_lft forever preferred_lft forever 2953: eth0@if2954: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP group default link /ether 02:42:b6:30:19:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 182.48.25.4 /24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:b6ff:fe30:1904 /64 scope link valid_lft forever preferred_lft forever 接着在node-2(182.48.115.233)上容器容器 [root@node-2 ~] # docker exec -ti node-2.test /bin/bash root@052a6a2a4a19:/ # ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1 /8 scope host lo valid_lft forever preferred_lft forever inet6 ::1 /128 scope host valid_lft forever preferred_lft forever 10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP group default link /ether 02:42:b6:30:43:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 182.48.67.3 /24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:b6ff:fe30:4303 /64 scope link valid_lft forever preferred_lft forever root@052a6a2a4a19:/ # ping 182.48.25.4 PING 182.48.25.4 (182.48.25.4): 56 data bytes 64 bytes from 182.48.25.4: icmp_seq=0 ttl=60 time =2.463 ms 64 bytes from 182.48.25.4: icmp_seq=1 ttl=60 time =1.211 ms ....... root@052a6a2a4a19:/ # ping www.baidu.com PING www.a.shifen.com (14.215.177.37): 56 data bytes 64 bytes from 14.215.177.37: icmp_seq=0 ttl=51 time =39.404 ms 64 bytes from 14.215.177.37: icmp_seq=1 ttl=51 time =39.437 ms ....... 发现,在两个宿主机的容器内,互相 ping 对方容器的ip,是可以 ping 通的!也可以直接连接外网(桥接模式) 查看两台宿主机的网卡信息,发现docker0虚拟网卡的ip(相当于容器的网关)也已经变成了flannel配置的ip段,并且多了flannel0的虚拟网卡信息 [root@node-1 ~] # ifconfig docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1472 inet 182.48.25.1 netmask 255.255.255.0 broadcast 0.0.0.0 inet6 fe80::42:31ff:fe0f:cf0f prefixlen 64 scopeid 0x20<link> ether 02:42:31:0f:cf:0f txqueuelen 0 (Ethernet) RX packets 48 bytes 2952 (2.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 31 bytes 2286 (2.2 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 182.48.115.233 netmask 255.255.255.224 broadcast 182.48.115.255 inet6 fe80::5054:ff:fe34:782 prefixlen 64 scopeid 0x20<link> ether 52:54:00:34:07:82 txqueuelen 1000 (Ethernet) RX packets 10759798 bytes 2286314897 (2.1 GiB) RX errors 0 dropped 40 overruns 0 frame 0 TX packets 21978639 bytes 1889026515 (1.7 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 flannel0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1472 inet 182.48.25.0 netmask 255.255.0.0 destination 182.48.25.0 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC) RX packets 12 bytes 1008 (1008.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 12 bytes 1008 (1008.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 通过下面命令,可以查看到本机的容器的ip所在的范围 [root@node-1 ~] # ps aux|grep docker|grep "bip" root 2080 0.0 1.4 796864 28168 ? Ssl May15 0:18 /usr/bin/dockerd-current --add-runtime docker-runc= /usr/libexec/docker/docker-runc-current --default-runtime=docker-runc -- exec -opt native.cgroupdriver=systemd --userland-proxy-path= /usr/libexec/docker/docker-proxy-current --insecure-registry registry:5000 --bip=182.48.25.1 /24 --ip-masq= true --mtu=1472 这里面的“--bip=182.48.25.1 /24 ”这个参数,它限制了所在节点容器获得的IP范围。 这个IP范围是由Flannel自动分配的,由Flannel通过保存在Etcd服务中的记录确保它们不会重复。 |
==========================================================================
温馨提示:
如上面操作后,发现各容器内分配的ip之间相互ping不通,基本就是由于防火墙问题引起的!
可是明明已经在前面部署的时候,通过"systemctl stop firewalld.service"关闭了防火墙,为什么还有防火墙问题??
这是因为linux还有底层的iptables,所以解决办法是在各节点上执行下面操作:
1
2
3
4
5
6
|
[root@node-1 ~] # iptables -P INPUT ACCEPT [root@node-1 ~] # iptables -P FORWARD ACCEPT [root@node-1 ~] # iptables -F [root@node-1 ~] # iptables -L -n 执行上面操作后,基本各容器间就能相互 ping 通了。 |
docker通过Flannel可以实现各容器间的相互通信,即宿主机和容器,容器和容器之间都能相互通信。
flannel的更多相关文章
- 【Network】Calico, Flannel, Weave and Docker Overlay Network 各种网络模型之间的区别
From the previous posts, I have analysed 4 different Docker multi-host network solutions - Calico, F ...
- 【Network】golang 容器项目 flannel/UDP相关资料
参考资料: flannel_百度搜索 Flannel首页.文档和下载 - 容器集群子网 - 开源中国社区 docker下基于flannel的overlay网络分析 - OPEN 开发经验库 flann ...
- 【Networking】flannel,pipework,weave,udp,vxlan,ovs等资料
Add Open vSwitch-based multitenant backend for use with OpenShift / Kubernetes: https://github.com/ ...
- 浅析flannel与docker结合的机制和原理
flannel flannel可以为容器提供网络服务. 其模型为全部的容器使用一个network,然后在每个host上从network中划分一个子网subnet. 为host上的容器创建网络时,从su ...
- Docker 网络 Flannel
flannel 安装 sudo yum install kernel-headers golang gccyum install flannel flannel 配置 在etcd中设置变量 etcdc ...
- docker k8s 1.3.8 + flannel
docker k8s + flannel kubernetes 是谷歌开源的 docker 集群管理解决方案. 项目地址: http://kubernetes.io/ 测试环境: node-1: 10 ...
- Docker - 用Flannel跨主机
试了下比较流行的几种SDN,感觉flannel还是比较好用,这里简单记录一下. 用的是virtualbox,3个机器,分别为: genesis : inet 192.168.99.103/24 brd ...
- flannel 概述 - 每天5分钟玩转 Docker 容器技术(58)
flannel 是 CoreOS 开发的容器网络解决方案.flannel 为每个 host 分配一个 subnet,容器从此 subnet 中分配 IP,这些 IP 可以在 host 间路由,容器间无 ...
- 安装配置 flannel - 每天5分钟玩转 Docker 容器技术(59)
上一节我们部署了 etcd,本节安装和配置 flannel. build flannel flannel 没有现成的执行文件可用,必须自己 build,最可靠的方法是在 Docker 容器中 buil ...
- 在 Docker 中使用 flannel - 每天5分钟玩转 Docker 容器技术(60)
上一节我们安装和配置了 flannel,本节在 Docker 中使用 flannel. 配置 Docker 连接 flannel 编辑 host1 的 Docker 配置文件 /etc/systemd ...
随机推荐
- CountDownLatch、CyclicBarrier及Semaphore的用法示例
一.参考blog https://www.cnblogs.com/dolphin0520/p/3920397.html 二.CountDownLatch 个人把它类比于一个持有计数的闸门,每到达这个闸 ...
- 解决百度云推送通知,不显示默认Notification
问题:百度云推送通知,不显示默认Notification 描述:采用推送消息的方式,可以在onMessage方法里面获取到推送的消息.另外推送通知也有获取到内容,后台日志也有show private ...
- 常见Python爬虫工具总结
常见Python爬虫工具总结 前言 以前写爬虫都是用requests包,虽然很好用,不过还是要封装一些header啊什么的,也没有用过无头浏览器,今天偶然接触了一下. 原因是在处理一个错误的时候,用到 ...
- idea 导入 android项目
1. 2. 主要是勾选上面选项. next next 导入即可
- haproxy配置详解
先看一个ha的配置文件: # # Global settings # global # to have these messages end up in /var/log/haproxy.log yo ...
- 使用apktool.jar工具反编译和回编译Android APK 终端命令模式
1.工具准备 工具可以网上搜索下载新版本,也可以从这里Download:https://github.com/FlymeOS/tools/blob/lollipop-5.1/reverses/apkt ...
- 图像处理滤波应用(Halcon)
1.增强对比度:halcon算子 equ_histo_image (GrayImage, ImageEquHisto) 2.空间滤波基础 滤波指接受或拒绝一定的频率分量.低通滤波器的最终效果是模糊(平 ...
- Java知多少(70)面向字节流的应用
文件输入输出流 文件输入输出流 FileInputStream 和 FileOutputStream 负责完成对本地磁盘文件的顺序输入输出操作. [例 10-5]通过程序创建一个文件,从键盘输入字符, ...
- 解决Django-1.8.2应用部署到Apache后无法显示admin应用的CSS
在将Django-1.8.2应用部署到Apache后,无法显示admin应用的静态内容,而在“manage.py runserver”命令下可以正常显示,主要是Apache没有找到Django静态内容 ...
- “failed to excute script xxx” PyInstaller 打包python程序为exe文件过程错误
在使用PyInstaller打包python程序,打包命令为: pyinstaller -F -w -i manage.ico yourpyfile.py 顺便说一下几个参数的作用 -F:是直接生成单 ...