遇到容器的shipyard 部署容器问题,该怎么办

&*&@author&vma
// 自定义一个类加载器
public&class&DynamicClassLoader&extends&ClassLoader&{
&&&&public&Class&?&&findClass(byte[]&b)&throws&ClassNotFoundException&{
&&&&&&&&return&defineClass(null,&b,&0,&b.length);
import&java.io.F
import&java.io.FileInputS
import&java.io.IOE
&*&@author&vma
public&class&ManageClassLoader&{
&&&&DynamicClassLoader&dc&=null;
&&&&Long&lastModified&=&0l;
&&&&Class&c&=&null;
&&& //加载类, 如果类文件修改过加载,如果没有修改,返回当前的
&&&&public&Class&loadClass(String&name)&throws&ClassNotFoundException,&IOException{
&&&&&if&(isClassModified(name)){
&&&&&&&&dc&=&&new&DynamicClassLoader();
&&&&&&return&c&=&dc.findClass(getBytes(name));
&&&&&return&c;
&&& //判断是否被修改过
&&&&private&boolean&isClassModified(String&filename)&{
&&&&&&&&boolean&returnValue&=&false;
&&&&&&&&File&file&=&new&File(filename);
&&&&&&&&if&(file.lastModified()&&&lastModified)&{
&&&&&&&&&&&&returnValue&=&true;
&&&&&&&&return&returnV
&&&&&& // 从本地读取文件
&&&&&&&private&byte[]&getBytes(String&filename)&throws&IOException&{
&&&&&&&&File&file&=&new&File(filename);
&&&&&&&&long&len&=&file.length();
&&&&&&&&lastModified&=&file.lastModified();
&&&&&&&&byte&raw[]&=&new&byte[(int)&len];
&&&&&&&&FileInputStream&fin&=&new&FileInputStream(file);
&&&&&&&&int&r&=&fin.read(raw);
&&&&&&&&if&(r&!=&len)&{
&&&&&&&&&&&&throw&new&IOException("Can't&read&all,&"&+&r&+&"&!=&"&+&len);
&&&&&&&&fin.close();
&&&&&&&&return&
测试类;Main 每隔 5s 加载一次
import&java.io.IOE
import&java.lang.reflect.InvocationTargetE
import&java.lang.reflect.M
&*&@author&vma
public&class&Main&{
&&&&&*&@param&args&the&command&line&arguments
&&&&public&static&void&main(String[]&args)&throws&ClassNotFoundException,&IOException,&NoSuchMethodException,&IllegalAccessException,&IllegalArgumentException,&InvocationTargetException,&InstantiationException,&InterruptedException&{
&&&&&&&&String&path&=&"D:\\deploy\\JDBC\\ClassLoader\\build\\classes\\classloader\\LocalClass.class";
&&&&&&&&ManageClassLoader&mc&=&new&ManageClassLoader();
&&&&&&&&while(true){
&&&&&&&Class&c&=&mc.loadClass(path);
&&&&&&&&Object&o&=&c.newInstance();
&&&&&&&Method&m&=&c.getMethod("getName");
&&&&&&&&m.invoke(o);
&&&&&&&&System.out.println(c.getClassLoader());
&&&&&&&&Thread.sleep(5000);
被加载的类
&*&@author&vma
public&class&LocalClass&{
&&&&public&void&getName()&{
&&&&&&System.out.println("hahaha&");
运行时,每隔5s 输出:
classloader.DynamicClassLoader@61de33
当我们修改 System.out.println("hahaha&"); ---& System.out.println("changed& "); 编译LocalClass后
输出变为:
classloader.DynamicClassLoader@173a10f
在loadClass中, 我们必须重新初始化一个ClassLoader,负责就会违背同一个ClassLoader是不允许多次加载一个类的。
&&& public&Class&loadClass(String&name)&throws&ClassNotFoundException,&IOException{
&&&&&if&(isClassModified(name)){
&&&&&&&&dc&=&&new&DynamicClassLoader();
&&&&&&return&c&=&dc.findClass(getBytes(name));
&&&&&return&c;
当然,容器的实现机制肯定及其完善,不可能周期性的加载,可能回通过监听机制,动态加载修改过的类。但它的实现机制肯定也是重新
实例化一个ClassLoder,加载需要加载的类。
2728293031123456789101112131415161718192021222526282931123456
随笔 - 184
评论 - 226
留言簿(12)
随笔分类(71)
随笔档案(179)
文章档案(13)
IT人的英语学习网站
优秀个人博客链接
官网学习站点
生活工作站点
积分与排名
阅读排行榜
评论排行榜中国领先的IT技术网站
51CTO旗下网站
Docker容器网络下UDP协议的一个问题
最近在工作中遇到一个docker容器下UDP协议网络不通的问题,困扰了很久,也比较有意思,所以想写下来和大家分享。
作者:佚名来源:| 08:09
最近在工作中遇到一个 docker 容器下 UDP 协议网络不通的问题,困扰了很久,也比较有意思,所以想写下来和大家分享。
我们有个应用是 UDP 协议的,部署上去发现无法工作,但是换成 TCP 协议是可以的(应用同时支持 UDP、TCP 协议,切换成 TCP
模式发现一切正常)。虽然换成 TCP 能解决问题,但是我们还是想知道到底 UDP 协议在网络模式下为什么会出现这个问题,以防止后面其他 UDP
应用会有异常。
这个问题抽象出来是这样的:如果有 UDP 服务运行在主机上(或者运行在网络模型为 Host 的容器里),并且监听在 0.0.0.0 地址(也就是所有的
ip 地址),从运行在 docker bridge 网络的容器运行客户端访问服务,两者通信有问题。
注意以上的的限制条件,通过测试,我们发现下来几种情况都是正常的:
使用 TCP 协议没有这个问题,这个已经说过了
如果 UDP 服务器监听在 eth0 IP 地址上也不会出现这个问题
并不是所有的应用都有这个问题,我们的 DNS(dnsmasq + kubeDNS) 也是同样的部署方式,但是功能都正常
这个问题在 docker 上也有 issue
记录:/moby/moby/issues/15127,但是目前并没有合理的解决方案。
这篇文章就分析一下出现这个问题的原因,希望给同样遇到这个问题的读者提供些帮助。
这个问题很容易重现,我的实验是在 ubuntu16.04 下用 netcat 命令完成的,其他系统应该类似。在主机上通过 nc 监听 56789
端口,然后在容器里使用 nc 发数据。第一个报文是能发送出去的,但是以后的报文虽然在网络上能看到,但是对方无法接收。
在主机上运行 nc UDP 服务器( -u 表示 UDP 协议, -l 表示监听的端口)
$&nc&-ul&56789&
然后启动一个容器,运行客户端:
$&docker&run&-it&apline&sh&/&#&nc&-u&172.16.13.13&56789&
nc 的通信是双方的,不管对方输入什么字符,回车后对方就能立即收到。但是在这个模式下,客户端第一次输入对方能够收到,后续的报文对方都收不到。
在这个实验中,容器使用的是 docker 的默认网络,容器的 ip 是 172.17.0.3,通过 veth pair(图中没有显示)连接到虚拟网桥
docker0(ip 地址为 172.17.0.1),主机本身的网络为 eth0,其 ip 地址为 172.16.13.13。
172.17.0.3&+&|&&&eth0&&&|&+&&&&&&|&&&&&&|&&&&&&|&&&&&&|&+&|&docker0&&|&&&&&&&&&&|&&eth0&&&&|&+&172.17.0.1&&&&&&&&&&&&172.16.13.13&
tcpdump 抓包
遇到这种疑难杂症,第一个想到的抓包,我们需要在 docker0 上抓包,因为这是报文必经过的地方。通过过滤容器的 ip
地址,很容器找到感兴趣的报文:
$&tcpdump&-i&docker0&-nn&host&172.17.0.3&
为了模拟多数应用一问一答的通信方式,我们一共发送三个报文,并用 tcpdump 抓取 docker0 接口上的报文:
客户端先向服务器端发送 hello 字符串
服务器端回复 world
客户端继续发送 hi 消息
抓包的结果如下,可以发现第一个报文发送出去没有任何问题(因为 UDP 是没有 ACK
报文的,所以客户端无法知道对方有没有收到,这里说的没有问题是值没有对应的 ICMP 报文),但是第二个报文从服务端发送的报文,对方会返回一个 ICMP 告诉端口
38908 不可达;第三个报文从客户端发送的报文也是如此。以后的报文情况类似,双方再也无法进行通信了。
11:20:43.973286&IP&172.17.0.3.38908&&&172.16.13.13.56789:&UDP,&length&6&11:20:50.102018&IP&172.17.0.1.56789&&&172.17.0.3.38908:&UDP,&length&6&11:20:50.102129&IP&172.17.0.3&&&172.17.0.1:&ICMP&172.17.0.3&udp&port&38908&unreachable,&length&42&11:20:54.503198&IP&172.17.0.3.38908&&&172.16.13.13.56789:&UDP,&length&3&11:20:54.503242&IP&172.16.13.13&&&172.17.0.3:&ICMP&172.16.13.13&udp&port&56789&unreachable,&length&39&
而此时主机上 UDP nc 服务器并没有退出,使用 lsof -i :56789 可能看到它仍然在监听着该端口。
从网络报文的分析中可以看到服务端返回的报文源地址不是我们预想的 eth0 地址,而是 docker0 的地址,而客户端直接认为该报文是非法的,返回了
ICMP 的报文给对方。
那么问题的原因也可以分为两个部分:
为什么应答报文源地址是 错误的 ?
既然 UDP 是无状态的,内核怎么判断源地址不正确呢?
主机多网络接口 UDP 源地址选择问题
第一个问题的关键词是:UDP 和多网络接口。因为如果主机上只有一个网络接口,发出去的报文源地址一定不会有错;而我们也测试过 TCP
协议是能够处理这个问题的。
通过搜索,发现这确实是个已知的问题。在 UNP() 这本书中,已经描述过这个问题,下面是对应的内容:
这个问题可以归结为一句话:UDP 在多网卡的情况下,可能会发生服务器端源地址不对的情况,这是内核选路的结果。 为什么 UDP 和 TCP
有不同的选路逻辑呢?因为 UDP 是无状态的协议,内核不会保存连接双方的信息,因此每次发送的报文都认为是独立的,socket
层每次发送报文默认情况不会指明要使用的源地址,只是说明对方地址。因此,内核会为要发出去的报文选择一个 ip,这通常都是报文路由要经过的设备 ip 地址。
有了这个原因,还要解释一下问题: 为什么 dnsmasq 服务没有这个问题呢 ?因此我使用 strace 工具抓取了 dnsmasq 和出问题应用的网络
socket 系统调用,来查看它们两个到底有什么区别。
dnsmasq 在启动阶段监听了 UDP 和 TCP 的 54 端口(因为是在本地机器上测试的,为了防止和本地 DNS 监听的 DNS端口冲突,我选择了
54 而不是标准的 53 端口):
socket(PF_INET,&SOCK_DGRAM,&IPPROTO_IP)&=&4&setsockopt(4,&SOL_SOCKET,&SO_REUSEADDR,&[1],&4)&=&0&bind(4,&{sa_family=AF_INET,&sin_port=htons(54),&sin_addr=inet_addr(&0.0.0.0&)},&16)&=&0&setsockopt(4,&SOL_IP,&IP_PKTINFO,&[1],&4)&=&0&&socket(PF_INET,&SOCK_STREAM,&IPPROTO_IP)&=&5&setsockopt(5,&SOL_SOCKET,&SO_REUSEADDR,&[1],&4)&=&0&bind(5,&{sa_family=AF_INET,&sin_port=htons(54),&sin_addr=inet_addr(&0.0.0.0&)},&16)&=&0&listen(5,&5)&&&&&&&&&&&&&&&&&&&&&&&&&&&&=&0&
比起 TCP,UDP 部分少了 listen ,但是多个 setsockopt(4, SOL_IP, IP_PKTINFO, [1], 4)
这句。到底这两点和我们的问题是否有关,先暂时放着,继续看传输报文的部分。
dnsmasq 收包和发包的系统调用,直接使用 recvmsg 和 sendmsg 系统调用:
recvmsg(4,&{msg_name(16)={sa_family=AF_INET,&sin_port=htons(52072),&sin_addr=inet_addr(&10.111.59.4&)},&msg_iov(1)=[{&\315\n\1&\0\1\0\0\0\0\0\1\fterminal19-0\5u5016\3&...,&4096}],&msg_controllen=32,&{cmsg_len=28,&cmsg_level=SOL_IP,&cmsg_type=,&...},&msg_flags=0},&0)&=&67&&sendmsg(4,&{msg_name(16)={sa_family=AF_INET,&sin_port=htons(52072),&sin_addr=inet_addr(&10.111.59.4&)},&msg_iov(1)=[{&\315\n\201\200\0\1\0\1\0\0\0\1\fterminal19-0\5u5016\3&...,&83}],&msg_controllen=28,&{cmsg_len=28,&cmsg_level=SOL_IP,&cmsg_type=,&...},&msg_flags=0},&0)&=&83&
而出问题的应用 strace 结果如下:
[pid&&&477]&socket(PF_INET6,&SOCK_DGRAM,&IPPROTO_IP)&=&124&[pid&&&477]&setsockopt(124,&SOL_IPV6,&IPV6_V6ONLY,&[0],&4)&=&0&[pid&&&477]&setsockopt(124,&SOL_IPV6,&IPV6_MULTICAST_HOPS,&[1],&4)&=&0&[pid&&&477]&bind(124,&{sa_family=AF_INET6,&sin6_port=htons(6088),&inet_pton(AF_INET6,&&::&,&&sin6_addr),&sin6_flowinfo=0,&sin6_scope_id=0},&28)&=&0&&[pid&&&477]&getsockname(124,&{sa_family=AF_INET6,&sin6_port=htons(6088),&inet_pton(AF_INET6,&&::&,&&sin6_addr),&sin6_flowinfo=0,&sin6_scope_id=0},&[28])&=&0&[pid&&&477]&getsockname(124,&{sa_family=AF_INET6,&sin6_port=htons(6088),&inet_pton(AF_INET6,&&::&,&&sin6_addr),&sin6_flowinfo=0,&sin6_scope_id=0},&[28])&=&0&&[pid&&&477]&recvfrom(124,&&j\201\\241\3\2\1\5\242\3\2\1\n\243\0160\f0\n\241\4\2\2\0\225\242\2\4\0&...,&2048,&0,&{sa_family=AF_INET6,&sin6_port=htons(38790),&inet_pton(AF_INET6,&&::ffff:172.17.0.3&,&&sin6_addr),&sin6_flowinfo=0,&sin6_scope_id=0},&[28])&=&168&&[pid&&&477]&sendto(124,&&k\202\2\\r\240\3\2\1\5\241\3\2\1\v\243\5\33\3TDH\244\\3\2&...,&533,&0,&{sa_family=AF_INET6,&sin6_port=htons(38790),&inet_pton(AF_INET6,&&::ffff:172.17.0.3&,&&sin6_addr),&sin6_flowinfo=0,&sin6_scope_id=0},&28)&=&533&
其对应的逻辑是这样的:使用 ipv6 绑定在 0.0.0.0 和 6088 端口,调用 getsockname 获取当前 socket
绑定的端口信息,数据传输过程使用的是 recvfrom 和 sendto 。
对比下来,两者的不同有几点:
后者使用的是 ipv6,而前者是 ipv4
后者使用 recvfrom 和 sendto 传输数据,而前者是 sendmsg 和 recvmsg
前者有调用 setsockopt 设置 IP_PKTINFO 的值,而后者没有
因为是在传输数据的时候出错的,因此第一个疑点是 sendmsg 和 sendto 的某些区别导致选择源地址有不同,通过 man sendto 可以知道
sendmsg 包含了更多的控制信息在 msghdr 。一个合理的猜测是 msghdr 中包含了内核选择源地址的信息!
通过查找,发现 IP_PKTINFO 这个选项就是让内核在 socket 中保存 IP 报文的信息,当然也包括了报文的源地址和目的地址。
IP_PKTINFO 和 msghdr 的关系可以在这个 stackoverflow
中找到:/questions/3062205/setting-the-source-ip-for-a-udp-socket。
而 man 7 ip 文档中也说明了 IP_PKTINFO 是怎么控制源地址选择的:
IP_PKTINFO&(since&Linux&2.2)&&&&&&&&&&&&&&&Pass&&an&&IP_PKTINFO&&ancillary&message&that&contains&a&pktinfo&structure&that&supplies&some&information&about&the&incoming&packet.&&This&only&works&for&datagram&ori\&&&&&&&&&&&&&&&ented&sockets.&&The&argument&is&a&flag&that&tells&the&socket&whether&the&IP_PKTINFO&message&should&be&passed&or&not.&&The&message&itself&can&only&be&sent/retrieved&as&&&&&&&&&&&&&&&control&message&with&a&packet&using&recvmsg(2)&or&sendmsg(2).&&&&&&&&&&&&&&&&&&&&struct&in_pktinfo&{&&&&&&&&&&&&&&&&&&&&&&&unsigned&int&&&ipi_&&/*&Interface&index&*/&&&&&&&&&&&&&&&&&&&&&&&struct&in_addr&ipi_spec_&/*&Local&address&*/&&&&&&&&&&&&&&&&&&&&&&&struct&in_addr&ipi_&&&&&/*&Header&Destination&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&address&*/&&&&&&&&&&&&&&&&&&&};&&&&&&&&&&&&&&&&ipi_ifindex&&is&the&unique&index&of&the&interface&the&packet&was&received&on.&&ipi_spec_dst&is&the&local&address&of&the&packet&and&ipi_addr&is&the&destination&address&&&&&&&&&&&&&&&in&the&packet&header.&&If&IP_PKTINFO&is&passed&to&sendmsg(2)&and&ipi_spec_dst&is&not&zero,&then&it&is&used&as&the&local&source&address&for&the&&routing&&table&&lookup&&&&&&&&&&&&&&&and&&for&&setting&up&IP&source&route&options.&&When&ipi_ifindex&is&not&zero,&the&primary&local&address&of&the&interface&specified&by&the&index&overwrites&ipi_spec_dst&&&&&&&&&&&&&&&for&the&routing&table&lookup.&
如果 ipi_spec_dst 和 ipi_ifindex 不为空,它们都能作为源地址选择的依据,而不是让内核通过路由决定。
也就是说,通过设置 IP_PKTINFO socket 选项为 1,然后使用 recvmsg 和 sendmsg
传输数据就能保证源地址选择符合我们的期望。这也是 dnsmasq 使用的方案,而出问题的应用是因为使用了默认的 recvfrom 和 sendto 。
关于 UDP 连接的疑惑
另外一个疑惑是:为什么内核会把源地址和之前不同的报文丢弃?认为它是非法的?因为我们前面已经说过,UDP 协议是无连接的,默认情况下 socket
也不会保存双方连接的信息。即使服务端发送报文的源地址有误,只要对方能正常接收并处理,也不会导致网络不通。
因为 conntrack,内核的 netfilter 模块会保存连接的状态,并作为防火墙设置的依据。它保存的 UDP 连接,只是简单记录了主机上本地 ip
和端口,和对端 ip 和端口,并不会保存更多的内容。
可以参考 intables info
网站的文章:/en/connection-state.html#UDPCONNECTIONS。
在找到根源之前,我们曾经尝试过用 SNAT 来修改服务端应答报文的源地址,期望能够修复该问题。但是却发现这种方法行不通,为什么呢?
因为 SNAT 是在 netfilter 最后做的,在之前 netfilter 的 conntrack 因为不认识该
connection,直接丢弃了,所以即使添加了 SNAT 也是无法工作的。
那能不能把 conntrack 功能去掉呢?比如解决方案:
iptables&-I&OUTPUT&-t&raw&-p&udp&&iptables&-I&PREROUTING&-t&raw&-p&udp&&
答案也是否定的,因为 NAT 需要 conntrack 来做翻译工作,如果去掉 conntrack 等于 SNAT 完全没用。
知道了问题的原因,解决方案也就很容易找到。
使用 TCP 协议
如果服务端和客户端使用 TCP 协议进行通信,它们之间的网络是正常的。
$&nc&-l&56789&
监听在特定端口
使用 nc 启动一个 udp 服务器,监听在 eth0 上:
➜&~&nc&-ul&172.16.13.13&56789&
nc 可以跟两个参数,分别代表 ip 和 端口,表示服务端监听在某个特定 ip 上。如果接收到的报文目的地址不是
172.16.13.13,也会被内核直接丢弃。
这种情况下,服务端和客户端也能正常通信。
改动应用程序实现
修改应用程序的逻辑,在 UDP socket 上设置 IP_PKTIFO ,并通过 recvmsg 和 sendmsg 函数传输数据。【编辑推荐】【责任编辑: TEL:(010)】
大家都在看猜你喜欢
头条头条头条头条头条
24H热文一周话题本月最赞
讲师:33220人学习过
讲师:207789人学习过
讲师:16318人学习过
精选博文论坛热帖下载排行
本书是一本优秀的C++教材,内容包括:基础类型、操作符和简单变量,循环和决策,命名空间和C++标准库,用C++编写函数,行为、序列点和求值...
订阅51CTO邮刊休闲娱乐生活服务其他类别
容器集群部署 选好编排工具是关键【IT168 评论】容器技术提供了组件化的环境,可以帮助业务应用在云之间轻松迁移而无需显著的返工。随着容器在企业持续获得发展,厂商将增加新的功能让用户可以创建可扩展的基于容器的环境。然而,大范围控制容器部署也会有一些并发症。容器肯定是跟资源相匹配的。这些挑战会导致集群管理和编排的并发需求。集群管理工具是一个通过图形界面或者通过命令行来帮助你管理一组集群的软件程序。有了这个工具,你就可以监控集群里的节点,配置services,管理整个集群服务器。集群管理可以从像发送工作到集群的低投入活动,到像负载均衡和可得性的高介入工作。当前主流的容器集群管理技术,包括了 Docker 官方的 Docker Swarm、Twitter 背书的 Mesos 和 Google 背书的 Kubernetes。这些可选的编排工具有一些共同的特征,如容器配置、发布和发现、系统监控和故障恢复、声明式系统配置以及有关容器布置和性能的规则和约束定义机制。除此之外,有些工具还提供了处理特定需求的特性。其中,由于Apache Mesos 只是一个分布式内核,目前的发展方向是数据中心操作系统,它同时支持 Marathon、Kubernetes 和 Swarm 等多种框架,连 Mesosphere 也是 Kubernetes 生态的一员,从编排的角度,讨论 Mesos 意义不大,故而只对比 Docker Swarm 和 Kubernetes。来自Docker的原生解决方案Docker Swarm的优点之一在于,它是一种原生解决方案――你可以使用Docker命令,实施Docker网络、插件和卷。Swarm管理器创建几个主节点,并为领导选举创建特定规则。万一首要的主节点出现故障,就可以实施这些管理机制。Swarm调度器拥有诸多过滤器,包括亲和标签和节点标签。过滤器可以将容器与底层节点联系起来,提高资源利用率、提升性能。Swarm对用户来说,之前使用Docker的经验可以继承过来。非常容易上手,学习成本和二次开发成本都比较低。同时Swarm本身专注于Docker集群管理,非常轻量,占用资源也非常少。简单说,就是插件化机制,Swarm中的各个模块都抽象出了API,可以根据自己一些特点进行定制实现。与所有的开源项目一样,Swarm项目也成立了自己的社区,参与社区的方法基本上和其他社区一致。当遇到问题时,可以在社区创建issue,然后描述问题,最好能上环境信息以及问题重现的步骤,这样有利于问题的定位。当然也可也直接通过IRC或者邮件直接交流。经验老道的Kubernetes另外一个非常重要的编排技术就是Kubernetes,前身是Borg,是Google 内部使用的集群管理工具,迄今已在 Google 生产环境中运行15年,说久经考验并不过分。Kubernetes的开发者致力于保持它一直处于可访问、轻量级状态,并且易于使用。它可以在很多云环境中使用,包括私有云,公有云,多云端和混合云。Kubernetes可以在fly上进行自我修复,它以自动复制,自动再启动,自动定位为特色。它可以被不断扩展,它的特点是hookable,可插拔和模块化。Kubernetes对计算资源进行了更高层次的抽象,通过将容器进行细致的组合,将最终的应用服务交给用户。Kubernetes在模型建立之初就考虑了容器跨机连接的要求,支持多种网络解决方案,同时在Service层次构建集群范围的SDN网络。其目的是将服务发现和负载均衡放置到容器可达的范围,这种透明的方式便利了各个服务间的通信,并为微服务架构的实践提供了平台基础。而在Pod层次上,作为Kubernetes可操作的最小对象,其特征更是对微服务架构的原生支持。
上一页&1共2页热门新闻更多
热门游戏相关新闻热门视频发现好货
阅读下一篇视频推荐开源的应用容器引擎能够让开发者打包其应用以及依赖包到一个可移植的容器中,然后发布到任意Linux发行版,也可实现虚拟化。容器全使用了沙箱机制,相互之间不会有任何接口(类似iPhone的app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包依赖。
钢琴、大米、西瓜、自行车这些常见物品外形尺寸及重量各不相同,如果让你来做物流,如何才能方便运输呢?为了解决各种型号规格尺寸的货物在各种运输工具上进行运输的问题,我们发明了集装箱。Docker的初衷也就是将各种应用程序和他们所依赖的运行环境打包成标准的container/image,进而发布到不同的平台上运行。如今,从互联网用户到电信再到金融,越来越多的行业用户开始应用容器,让应用部署比买菜还简单已经成为了现实!
软件企业:容器助金融行业迎接新挑战
如果说2013年就是容器诞生大爆炸的话,那么现在已经进入了一个标准化的阶段。包括提出或者建立了开放容器项目(OPEN CONTAINER INITIATIVE)这样一个机构,它的目的主要是使容器的技术在各大公司之间实现标准化。
&&&&2016年红帽在容器方面做出了巨大的贡献,就是推出了OpenShift 3,它是首个把Docker和Kubernetes结合起来的一个私有云平台。现在或是今后几年的时间,企业会处于转型或者是变革的时期。各个企业对于容器技术提出了不少要求,有很多大的公司参与到容器技术的市场上来,而且容器本身也已经得到了广泛的采用
硬件企业:必须支持!构建100%兼容容器标准集群
Gartner预测,到2018年,将会有超过50%的新应用部署到容器中,且至少涵盖应用生命周期中一环。在互联网时代,传统IT正向互联网转型,云计算将成为基石,企业软件需要快速开发、迭代、部署和运维。
&&&&开发者也需要标准化且流畅的开发交付平台,而容器技术正好解决了以往技术的难点。目前,DaoCloud已拥有数以千计的开发者、合作伙伴和客户。客户中有互联网公司,也有金融、能源等传统行业的企业
国美在线:分布式存储与容器技术已经成为电商首选
在行业应用层面主要是采用分布式,一旦遇到问题,可能就是影响一小部分的用户。分布式存储在互联网行业应用的优势更加明显,同时依靠强大的存储性能也可以获得不错的IO表现。
&&&&目前国美在线已经开始使用容器技术部署应用。那广也认为容器将会成为一个主流,因为虚拟化还是有一定的局限性。所以,容器技术是未来发展一个方向
猪八戒网:运用容器等创新技术提升研发效能和技术驱动
容器的重要意义不仅仅在于落地微服务,更是能够重构整个研发流程。而标准化的研发流程有着极大的优势,可以使得研发效能的巨大提升,预计可以达到10倍的提升,并且会比原来的质量好。
&&&&原来需要一个月,三个月完成的项目,现在可能只需要一个周的时间。除此之外,容器技术的运用,需要在实施层面发现和解决缺陷,并能够突破在网络方面和服务治理方面新的瓶颈。通过智能化的,低成本的质量保障的方案,实现高覆盖率的,从工程的层面解决缺陷,保证到质量
正在高速前进中的容器技术
伴随着这些分布式系统的出现,也对容器的集群化功能提出了更高的要求和挑战。如今, 以CNCF(Cloud Native Computing Foundation)、Docker和DC/OS为代表的三大集群编排调度系统并驾齐驱,他们都在围绕自己的解决方案构建监控、安全、部署等能力,力争在容器技术面向容器云的下一波发展中抢占先机。从目前的情况来看,整个容器产业还没有完全成熟,而以互联网、金融为首的“先驱”行业正在不断的拓展和探索中,相信未来的容器市场会更加精彩!

我要回帖

更多关于 openstack容器化部署 的文章

 

随机推荐