在前面详细讲解了几种网络模式:none,host,bridge,container。他们解决了单个主机间的容器的通信问题,并不能实现多个主机容器之间的通信。

跨主机网络方案包括两大类:

1,docker原生的:overlay和macvlan

2,第三方方案:flannel、weave和calico

overlay

Docker overlay网络需要一个key-value数据库用于保存网络状态信息,包括Network、Endpoint、IP等。

consul、Etcd、Zookeeper都是Docker支持的key-value软件,这里我们使用consul。

在docker主机docker01(10.0.0.11)和docker02(10.0.0.12)上实践各种跨主机网络方案,在10.0.0.11上部署支持的组件,比如consul。

第一步:启动路由转发功能

【两台主机都需开启】

[root@docker01 ~]# echo "1" > /proc/sys/net/ipv4/ip_forward
[root@docker02 ~]# echo "1" > /proc/sys/net/ipv4/ip_forward

第二步:运行consul

以容器的方式运行consul

[root@docker01 ~]# systemctl restart docker
[root@docker01 ~]# systemctl enable docker
[root@docker01 ~]# docker pull progrium/consul
Using default tag: latest
latest: Pulling from progrium/consul [root@docker01 ~]# docker run -d -p 8500:8500 -h consul --name consul --restart=always progrium/consul -server -bootstrap
### 其中 -h 为指定容器内部的主机名;--restart=always 为docker启动时,此容器自动启动;-server -bootstrap 表示当在群集中,加上这两个选项可以使其以master的身份出现 [root@docker01 ~]# netstat -lntp | grep 8500
tcp6 0 0 :::8500 :::* LISTEN 1576/docker-proxy

  

第三步:浏览器访问

通过ip+port的方式访问

第四步:修改docker启动文件

需要修改的是docker01和docker02的docker daemon 的配置文件。

【注】在这里我们使用的是两台。如果是3台,可以为3台都设置:表示这3台准备跨主机;也可以将第一台设置为只存放consul,2,3台修改配置文件即可:表示后两台准备跨主机。

【注】只修改[Service]内容即可

[root@docker01 ~]# cat /usr/lib/systemd/system/docker.service
...
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://10.0.0.11:8500 --cluster-advertise=eth0:2376
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
... ### 各项解释如下
# /var/run/docker.sock 表示Docker的一个编程接口;
# '-H tcp://0.0.0.0:2376' 表示使用本机的2376/tcp端口;
# '--cluster-store=consul://10.0.0.11:8500' 表示运行了consul的服务器IP和端口
# '--cluster-advertise=eth0:2376' 表示从本机的eth0网卡通过2376端口收集网络信息,也有可能是ens33。

  

[root@docker02 ~]# cat /usr/lib/systemd/system/docker.service
...
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://10.0.0.11:8500 --cluster-advertise=eth0:2376
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
...

 

重新加载docker daemon,修改了文件的服务都需要重启

[root@docker01 ~]# systemctl daemon-reload
[root@docker01 ~]# systemctl restart docker

这里注意,如果consul容器没有设置为自启,那么需要手动启动

[root@docker02 ~]# systemctl daemon-reload
[root@docker02 ~]# systemctl restart docker

第五步:浏览器查看

这时发现两个主机已经注册上去了

第六步:创建overlay网络

在docker01上创建网络ov_ken

[root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c8d69c4c3ffe bridge bridge local
f5d3339712b4 host host local
93359dad0336 none null local [root@docker01 ~]# docker network create -d overlay ov_ken [root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c8d69c4c3ffe bridge bridge local
f5d3339712b4 host host local
93359dad0336 none null local
70c2c8b47ead ov_ken overlay global ### 这个时候docker02上不用添加就会自动添加
[root@docker02 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
7c9560f3b566 bridge bridge local
e76394dcf8f8 host host local
4cdde3f7dce2 none null local
70c2c8b47ead ov_ken overlay global
### 因为创建ov_ken时docker01将overlay网络信息存入了consul,docker02从consul读取了新网络的数据。

 

查看网络信息

[root@docker01 ~]# docker network inspect ov_ken
[
{
"Name": "ov_ken",
"Id": "70c2c8b47ead8af423a6b562aba42f1106454b58577c27cf47143a9eacdb419a",
"Created": "2020-04-13T11:47:08.079686153+08:00",
"Scope": "global",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
### 由此可以看出docker自动为ov_ken分配的ip地址空间为10.0.0.0/24

 

在overlay网络中运行容器

运行一个busybox容器并使用overlay网络

[root@docker01 ~]# docker run -d -it --name busybox --network ov_ken busybox:latest
3492931078a8d2cf2a7e77b7a8518c3f89f64c0b803a79ffc9742965581d96fa
6.1 跨主机连通

在docker02上运行新的容器

[root@docker02 ~]# docker run -it -d --name busybox_02 --network ov_ken busybox:latest
53e708b68a31d5f08bce6f949426e64ce333e4ee9f28396271b2a6eb3daad182

查看容器的网络

[root@docker02 ~]# docker exec busybox_02 ip r
default via 172.18.0.1 dev eth1
10.0.0.0/24 dev eth0 scope link src 10.0.0.3
172.18.0.0/16 dev eth1 scope link src 172.18.0.2

测试使用docker01上的容器ping docker02上的容器

[root@docker01 ~]# docker exec busybox ip r
default via 172.18.0.1 dev eth1
10.0.0.0/24 dev eth0 scope link src 10.0.0.2
172.18.0.0/16 dev eth1 scope link src 172.18.0.2 [root@docker01 ~]# docker exec busybox ping -c 2 10.0.0.3
PING 10.0.0.3 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=3.657 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.351 ms
--- 10.0.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.351/2.004/3.657 ms

 

至此:overlay容器是可以直接通信,同时docker也实现了DNS服务。

6.2 overlay网络隔离

不同的overlay网络是相互隔离的。我们创建第二个overlay网络ov_ken2并运行容器

[root@docker01 ~]# docker network create -d overlay ov_ken2
0dd70337a3f1504c9d24891c9e37d74af35abcad0ce3751ac0efa5ad138cb12c [root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c8d69c4c3ffe bridge bridge local
2436e5e8c848 docker_gwbridge bridge local
f5d3339712b4 host host local
93359dad0336 none null local
70c2c8b47ead ov_ken overlay global
0dd70337a3f1 ov_ken2 overlay global [root@docker01 ~]# docker run -d -it --name busybox_03 --network ov_ken2 busybox:latest
a5963fd6a9b863613269f773069fa99630fc88d7af49a3b355e78c9060858699 [root@docker01 ~]# docker exec busybox_03 ip r
default via 172.18.0.1 dev eth1
10.0.1.0/24 dev eth0 scope link src 10.0.1.2
172.18.0.0/16 dev eth1 scope link src 172.18.0.3
### 在这里我们能看到docker给第二个overlay分配的ip地址为10.0.1.0/24 [root@docker01 ~]# docker exec busybox_03 ping -c 2 10.0.0.3
PING 10.0.0.3 (10.0.0.3): 56 data bytes
--- 10.0.0.3 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
### 在这里我们发现ov_ken和ov_ken2并不互通

  

如果要实现busybox_03和busybox_02的互通,可以将busybox_03也连接到ov_ken网络上

[root@docker01 ~]# docker network connect ov_ken busybox_03
### 意思为,将busybox_03添加到ov_ken网络 [root@docker01 ~]# docker exec busybox_03 ip r
default via 172.18.0.1 dev eth1
10.0.0.0/24 dev eth2 scope link src 10.0.0.4
10.0.1.0/24 dev eth0 scope link src 10.0.1.2
172.18.0.0/16 dev eth1 scope link src 172.18.0.3
### 这个时候会发现busybox_03会被添加一个新的ov_ken的网段IP [root@docker01 ~]# docker exec busybox_03 ping -c 2 10.0.0.3
PING 10.0.0.3 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=6.571 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.411 ms
--- 10.0.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.411/3.491/6.571 ms

weave

weave不依赖分布式数据库(例如etcd和consul)交换网络信息,每个主机上只需要运行weave组件就能建立起跨主机容器网络。接下来在docker01和docker02上部署weave并实践weave的各项特性

一、安装部署weave

weave安装非常简单,在docker01和docker02上执行如下命令:

[root@docker01 ~]# curl -L git.io/weave -o /usr/local/bin/weave
[root@docker01 ~]# chmod a+x /usr/local/bin/weave [root@docker02 ~]# curl -L git.io/weave -o /usr/local/bin/weave
[root@docker02 ~]# chmod a+x /usr/local/bin/weave

在docker01上启动weave

[root@docker01 ~]# weave launch

注:在执行weave launch命令,启动weave相关服务。weave所有的组件都是以容器的方式运行的,会自动从docker hub上获取最新的image并启动容器

查看启动的容器

[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e089485df46f weaveworks/weave:2.6.2 "/home/weave/weaver …" 55 seconds ago Up 54 seconds weave

weave运行了一个容器:

weave是主程序,负责建立weave网络,收发数据,提供DNS服务等

在docker01中启动容器

[root@docker01 ~]# eval $(weave env)
[root@docker01 ~]# docker run -d -it --name busybox_01 --rm busybox:latest
a1a4f0931a65b36067f8d27e6474fee584d003ac302e9c7ac4e517f48b0d46a2

注意:在这里因为是测试,用到了 --rm :关闭即删除,删除,删除 !!

首先执行 eval $(weave env) 很重要,其作用是将后续的docker命令发送给weave proxy处理,如果要恢复之前的环境,可执行eval $(weave env --restore)。

查看当前容器busybox_01的网络配置

[root@docker01 ~]# docker exec busybox_01 ip r
default via 172.17.0.1 dev eth0
10.32.0.0/12 dev ethwe scope link src 10.32.0.1
172.17.0.0/16 dev eth0 scope link src 172.17.0.2
224.0.0.0/4 dev ethwe scope link ### 由此可以看出,docker给其分配的地址为10.32.0.0/12网段,并且IP地址为10.32.0.1
### 而且busybox_01有两个网络接口eth0和ethwe,其中eth0是默认连接的bridge网络,即网桥docker0。分配的IP 10.32.0.1/12 ethwe与weave相关

 

在当前主机上再运行一个容器

[root@docker01 ~]# docker run -d -it --name busybox_02 --rm busybox:latest
88f208a2ca486eccc346ed7239f44836587796ce7898f48b65e162bfebe522e6 [root@docker01 ~]# docker exec busybox_02 ip r
default via 172.17.0.1 dev eth0
10.32.0.0/12 dev ethwe scope link src 10.32.0.2
172.17.0.0/16 dev eth0 scope link src 172.17.0.3
224.0.0.0/4 dev ethwe scope link

测试同一个主机上的busybox_01和busybox_02的连通性

[root@docker01 ~]# docker exec busybox_01 ping -c 2 busybox_02
PING busybox_02 (10.32.0.2): 56 data bytes
64 bytes from 10.32.0.2: seq=0 ttl=64 time=0.051 ms
64 bytes from 10.32.0.2: seq=1 ttl=64 time=0.050 ms --- busybox_02 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.050/0.050/0.051 ms ### 在这里是可以连通的,并且还可以解析
二、weave跨主机通信

第一步:再docker02上执行以下命令

[root@docker02 ~]# weave launch 10.0.0.11
## 格式 weave launch [docker01的ip地址]

这里必须指定docker01的ip地址,这样docker01和docker02才能加入到同一个weave网络。

第二步:开启路由转发功能

[root@docker01 ~]# echo "1">/proc/sys/net/ipv4/ip_forward
[root@docker02 ~]# echo "1">/proc/sys/net/ipv4/ip_forward

第三步:启动容器

[root@docker02 ~]# docker run -d -it --name busybox_03 --rm busybox:latest
82503c97ee984d5a330f635eeca825edc795c7ef96a8fc592da9dc8598764594

第四步:测试连通性

[root@docker02 ~]# docker exec busybox_03 ping -c 2 busybox_02
PING busybox_02 (10.32.0.2): 56 data bytes
64 bytes from 10.32.0.2: seq=0 ttl=64 time=1.477 ms
64 bytes from 10.32.0.2: seq=1 ttl=64 time=1.187 ms --- busybox_02 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 1.187/1.332/1.477 ms ### 可以发现主机docker02上运行的容器可以与docker01上的容器通信,而且可以解析主机名

三、weave网络隔离

默认配置下,weave使用一个大subnet(例如10.32.0.0/12),所有的主机的容器都是从这个地址空间中分配IP,因为同属一个subnet,容器可以直接通信。如果要实现网络隔离,可以通过环境变量WEAVE_CIDR为容器分配不同的subnet的IP,举例如下:

[root@docker02 ~]# docker run -d -it -e WEAVE_CIDR=net:10.32.2.0/24 --name busybox_04 --rm busybox:latest
d3a4430bbc111c9f7eca1ab9c4b6f432f63d9e45d66ea0d0d66b3dfecfa75eb6

在这里WEAVE_CIDR=net:10.32.2.0/24的作用是使容器分配到IP 10.32.2.2。由于10.32.0.0/12 与 10.32.2.0/24位于不同的subnet,所以无法ping到busybox_02。

[root@docker02 ~]# docker exec busybox_04 ping -c 2 busybox_02
PING busybox_02 (10.32.0.2): 56 data bytes
--- busybox_02 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

当然也无法ping同同主机上的busybox_03

除了subnet,我们还可以直接为容器分配特定的ip:

[root@docker02 ~]# docker run -d -it -e WEAVE_CIDR=ip:10.32.6.6/24 --name busybox_05 busybox:latest
b2eccb69e37e5da8558237163103f050a3efc118cf71bf11c62c68b572e2b8a6
[root@docker02 ~]# docker exec busybox_05 ip r
default via 172.17.0.1 dev eth0
10.32.6.0/24 dev ethwe scope link src 10.32.6.6
172.17.0.0/16 dev eth0 scope link src 172.17.0.4
224.0.0.0/4 dev ethwe scope link
四、weave与外网的连通性

weave是一个私有的VLAN网络(容器可以访问外网),默认与外部网络隔离。外部网络如何才能访问到weave中的容器呢?

答案:

  1. 首先将主机加入到weave网络。

  2. 然后把主机当作访问的网关。

第一步:要将主机加入到weave,执行weave expose。

[root@docker02 ~]# weave expose
10.32.2.129

第二步:查看ip

这个10.32.2.129会被配置到host2的weave网桥上。

[root@docker02 ~]# ip a
...
13: weave: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP qlen 1000
link/ether c6:77:0c:f6:e2:29 brd ff:ff:ff:ff:ff:ff
inet 10.32.2.129/12 brd 10.47.255.255 scope global weave
valid_lft forever preferred_lft forever
inet6 fe80::c477:cff:fef6:e229/64 scope link
valid_lft forever preferred_lft forever 

第三步:测试连通性

ping同一主机的busybox_03

[root@docker02 ~]# docker exec busybox_03 ip r
default via 172.17.0.1 dev eth0
10.32.0.0/12 dev ethwe scope link src 10.44.0.0
172.17.0.0/16 dev eth0 scope link src 172.17.0.2
224.0.0.0/4 dev ethwe scope link [root@docker02 ~]# ping -c 2 10.44.0.0
PING 10.44.0.0 (10.44.0.0) 56(84) bytes of data.
64 bytes from 10.44.0.0: icmp_seq=1 ttl=64 time=0.123 ms
64 bytes from 10.44.0.0: icmp_seq=2 ttl=64 time=0.048 ms
--- 10.44.0.0 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.048/0.085/0.123/0.038 ms

ping docker01上的busybox_01

[root@docker01 ~]# docker exec busybox_01 ip r
default via 172.17.0.1 dev eth0
10.32.0.0/12 dev ethwe scope link src 10.32.0.1
172.17.0.0/16 dev eth0 scope link src 172.17.0.2
224.0.0.0/4 dev ethwe scope link [root@docker02 ~]# ping -c 2 10.32.0.1
PING 10.32.0.1 (10.32.0.1) 56(84) bytes of data.
64 bytes from 10.32.0.1: icmp_seq=1 ttl=64 time=2.16 ms
64 bytes from 10.32.0.1: icmp_seq=2 ttl=64 time=0.337 ms --- 10.32.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.337/1.252/2.168/0.916 ms

接下来要让其他非weave主机访问到busybox_01和busybox_03,只需要将网关指向docker01。例如在新的主机docker03上添加如下路由:

[root@docker03 ~]# ip route add 10.32.0.0/12 via 10.0.0.11

[root@docker03 ~]# ping -c 2 10.32.0.1
PING 10.32.0.1 (10.32.0.1) 56(84) bytes of data.
64 bytes from 10.32.0.1: icmp_seq=1 ttl=63 time=1.45 ms
64 bytes from 10.32.0.1: icmp_seq=2 ttl=63 time=2.25 ms
--- 10.32.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 1.450/1.852/2.254/0.402 ms

注意:10.32.0.0/12是weave网络使用的默认subnet,如果此地址空间与现有IP冲突,可以通过 --ipalloc-range 分配特定的subnet。

weave launch --ipalloc-range 10.2.0.0/16

不过需要确保所有的host都使用相同的subnet

【注意】如果出现以下情况

[root@docker02 ~]# docker ps
Cannot connect to the Docker daemon at unix:///var/run/weave/weave.sock. Is the docker daemon running?

需要执行

[root@docker02 ~]# eval $(weave env --restore)

Docker系列04—跨主机网络方案(overlay/weave)的更多相关文章

  1. docker 跨主机网络:overlay 简介

    简介 docker 在早前的时候没有考虑跨主机的容器通信,这个特性直到 docker 1.9 才出现.在此之前,如果希望位于不同主机的容器能够通信,一般有几种方法: 使用端口映射:直接把容器的服务端口 ...

  2. Docker 跨主机网络方案分析

    PS:文章首发公众号,欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 上篇文章介绍了容器网络的单主机网络,本文将进一步介绍多 ...

  3. Docker跨主机网络——overlay

    前言 在Docker网络--单host网络一文中,我为大家总结了Docker的单机网络相关知识和操作,单机网络比较容易.本文我为大家总结Docker跨主机通信相关知识.同样本文大部分内容以CloudM ...

  4. centos7下安装docker(15.2跨主机网络-overlay)

    为支持容器跨主机通信,Docker提供了overlay driver,使用户可以创建基于VxLAN的overlay网络.VxLAN可将二层数据封装到UDP进行传输,VxLAN提供与VLAN相同的以太网 ...

  5. Docker 跨主机网络 overlay(十六)

    目录 一.跨主机网络概述 二.准备 overlay 环境 1.环境描述 2.创建 consul 3.修改 docker 配置文件 4.准备就绪 三.创建 overlay 网络 1.在 host1 中创 ...

  6. 跨主机网络概述 - 每天5分钟玩转 Docker 容器技术(48)

    前面已经学习了 Docker 的几种网络方案:none.host.bridge 和 joined 容器,它们解决了单个 Docker Host 内容器通信的问题.本章的重点则是讨论跨主机容器间通信的方 ...

  7. Docker 跨主机网络

    Docker提供两种原生的跨主机网络: Overlay  和  Macvlan libnetwork & CNM libnetwork 是 docker 容器网络库,最核心的内容是其定义的 C ...

  8. 跨主机网络-overlay(18)

    docker overlay跨主机网络 .环境 docker版本 Docker version -ce, build fc4de44 3台主机 192.168.55.51 host1 192.168. ...

  9. [Kubernetes]谈谈容器跨主机网络

    继上篇文章:[Kubernetes]浅谈容器网络,自己给自己挖的坑,这篇文章来谈谈容器跨主机网络. 要理解容器"跨主通信"的原理,就要来谈谈 Flannel 这个项目. Flann ...

随机推荐

  1. springboot利用redis做缓存

    首先 配置redis redis: password: 123456 host: 127.0.0.1 port: 6379 #103.249.252.109:10086 expireSeconds: ...

  2. JavaScript实时显示当前时间

    1.HTML部分 <div id="div1">显示当前时间!</div> 2.css部分 #div1 { width: 700px; height: 50 ...

  3. shell-的变量-局部变量

    1. 定义本地变量 本地变量在用户当前的shell生产期的脚本中使用.例如,本地变量OLDBOY取值为ett098,这个值只在用户当前shell生存期中有意义.如果在shell中启动另一个进程或退出, ...

  4. NB 的开源项目遍地开花——GitHub 热点速览 Vol.41

    作者:HelloGitHub-小鱼干 本周的 GitHub 热点速览的关键词便是 nb,也是本周特推之一的项目名字,这个功能如名字一般 nb 的项目是一个脚本,帮你处理笔记.书签.归档和知识库应用程序 ...

  5. JS中实现Trim(),TrimStart(),TrimEnd() 的方法

    //去除字符串头尾空格或指定字符 String.prototype.Trim = function (c) { if (c == null || c == "") { var st ...

  6. 【折半枚举+二分】POJ 3977 Subset

    题目内容 Vjudge链接 给你\(n\)个数,求出这\(n\)个数的一个非空子集,使子集中的数加和的绝对值最小,在此基础上子集中元素的个数应最小. 输入格式 输入含多组数据,每组数据有两行,第一行是 ...

  7. BOOST库 消息队列

    直接贴实验代码: /******* boost 消息队列 **********/ #if 1 #include <boost/thread/thread.hpp> #include < ...

  8. python爬虫 -掘金

    import json from time import sleep import requests url = "https://web-api.juejin.im/query" ...

  9. 【Azure Redis 缓存 Azure Cache For Redis】当使用Jedis客户端连接Redis时候,遇见JedisConnectionException: Could not get a resource from the pool / Redis connection lost

    问题情形 当在执行Redis一直指令时,有可能会遇见如下几种错误: 1) redis.clients.jedis.exceptions.JedisConnectionException: Could ...

  10. Chimm.Excel —— 使用Java 操作 excel 模板文件生成 excel 文档

    Chimm.Excel -- 设置模板,填充数据,就完事儿了~ _____ _ _ _____ _ / __ \ | (_) | ___| | | | / \/ |__ _ _ __ ___ _ __ ...