Docker遇到的一些问题和感想

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475
Docker 是“不可变”架构。

当你希望改变一个服务的时候(比如更新版本、修改配置、开放端口),不允许直接登录到服务器上改变某个文件,而是应该把这个服务整个删掉,然后替换成新的版本。你不能改变它,只能替换它,这就是 Docker 的优点。

在服务规模大的时候,这种维护方式能够保持每个服务版本、配置的一致性。Docker 禁止对容器内部做任何修改,所以只要查看镜像版本和调度参数,就能判断服务的一致性。系统运行在软件定义的基础架构上,这样就可以使用版本管理工具(比如 Git)管理基础架构的变化,像管理软件版本一样管理整个环境。这是他的优势。

Docker “还不够好”。

  1. 不少同事或者朋友,吐槽了Docker的很多麻烦事儿,简单说就是抛弃了传统的操作系统环境,很多原来的东西都要用新的容器工具链。Docker的隔离性也没有虚拟机级别的好。这些都是客观存在的。Docker是一套新的承载环境,相对于传统的虚拟机需要非常多的新的工具链,但远没有成熟。带来的好处,在传统的模式下也不是没有方案。所以Docker仍然缺少决定性的优势。并不能说服大家大规模的迁移和适应。
  2. 目前docker 镜像,没有统一标准,体现在一下几个方面。在使用过程中会遇到过各种本班的 OS。包括 alpine, debian, ubuntu, centos, oraclelinux, redhat 等等。即使是镜像采用 CentOS 母版,很多镜像制作者会给操作系统减肥。经过优化后,已经不是官方版本,在使用过程中你会遇到各种麻烦。例如调试的时候需要 curl,wget,telnet,nslookup 等工具在镜像中没有。甚至 ps, top, free, find, netstat, ifconfig 命令都没有。很多容器都不带 iptables 所以,即使带有iptables 在容器中修改规则也很麻烦。
  3. 传统OS 以 CentOS为例,有严格的安装规范,例如:
/etc/example 配置文件
/bin/sbin 二进制文件
/var/lib/example 数据文件
/var/log/example 日志文件
/var/run/example PID 文件/etc/sysconfig/example 启动参数文件
/etc/system.d/example  启动脚本

或者被安装在:

/usr/local/etc 配置文件
/usr/local/bin 可执行文件
/usr/local/share 文档

最后一种是独立安装在:/usr/local/example 下。容器镜像那可是五花八门,没有统一标准,如果不看 Dockerfile 根本不知道作者将文件安装到了哪里。常常存储目录被放置在根目录。例如 /data
4. 在我的执业生涯中是遇到过 Linux 系统有BUG的,如果你采用的镜像有BUG,你想过怎么去debug 吗?
5. 在Linux是一般是采用守护进程方式启动。启动后进入后台,启动采用 systemd 。
1. 容器中启动通常是直接运行,这样的运行方式,相当于你在linux的Shell 终端直接运行一样,是在前台运行,随时 CTRL + C 或者关闭终端窗口,程序就会退出。容器采用这种方式启动,就是为了让 docker 管理容器,docker 能够感知到容器的当前状态,如果程序退出,docker 将会重新启动这个容器。
2. 守护进程方式需要记录 pid 即父进程ID,用于后面管理该进程,例如可以实现 HUP 信号处理。也就是 reload 操作,不用退出当前程序实现配置文件刷新。处理 HUP 信号,无需关闭 Socker 端口,也不会关闭线程或进程,
3. 用户体验更好。容器是直接运行(前台运行),所以没有 PID 也不能实现 reload 操作。 配置文件更新需要重新启动容器,容器启动瞬间TCP Socker 端口关闭,此时用户会 timeout。甚至该服务可能会引起集群系统的雪崩效应。
4. 很多镜像制作者更趋向使用环境变量传递启动参数。当然你也可以在容器中使用 systemd ,这样做容器不能直接感知到容器的运行状态,systemctl stop example 后,容器仍然正常。需要做存活和健康检查。通过健康状态判断容器的工作情况。如果处于非健康状态,将该节点从负载均衡节点池中将它踢出去。
5. Linux 启动一个应用远远比docker 启动一个容器速度要快。因为物理机或者虚拟机的Linux操作系统已经启动,虚拟机也分配了资源,运行可执行文件基本上是瞬间启动。而 docker 启动容器,要分配资源(分配内存和CPU资源,新建文件系统),相当于创建一个虚拟机的过程,最后载入约200MB左右的镜像,并将镜像运行起来,所以启动所需时间较长,有时不可控,尤其是Java应用更为突出。
6. 存储面临的问题。传统 Linux 直接操作本地硬盘,IO性能最大化。私有云还好办公有云处处受限。自建的 Docker 或 Kubrnetes 可以使用宿主主机资源,公有云只能使用网络文件系统和分布式系统。这也是我的架构中 KVM,Docker,Kubernetes,物理机混合使用的原因,根据业务场景的需要来选择哪种方案。
1. 物理机上部署 docker 可以分配宿主主机的所有资源,适合做有状态的服务的存储持久化的需求。
2. 私有云Kubernetes 适合做 CPU密集型运算服务,虽然通过local 卷和 hostPath 可以绑定,但是管理起来不如 Docker 更方便。
3. NFS 基本是做实验用的,不能用在生产环境。我职业生涯遇到过很多奇葩,例如 NFS 卡顿,NFS 用一段时间后访问不了,或者可以访问,文件内容是旧的等等。无论是NFS是更先进的分布式文件系统,如果不是 10G以太网,基本都不能用在生产环境。多年前我用4电口1G网卡做端口聚合勉强可以用于生产环境,不过当年的互联网生态跟当今不同,那时还是以图文为主,确切的说是文字为主,配图还很少。
7. 内部域名DNS。由于在集群环境中容器名称是随机,IP地址是不固定的,甚至端口也是动态的。为了定位到容器的节点,通常集群中带有DNS功能,为每个节点分配一个域名,在其他容器中使用域名即可访问到需要的容器。
1. 看似没有问题,我的职业生涯中就遇到过DNS的问题,bind,dnsmseq 我都用过,都出现过事故。解析卡顿,ping  www.domain.com  后迟迟解析不出IP。最长一次用了几分钟才解析到IP地址。
2. 所以后面就非常谨慎,配置文件中我们仍然使用域名,因为修改配置文件可能需要 reload 应用,或者重新部署等等。域名写入配置,方便IP地址变更。例如 db.host=www.domain.com   同时我们会在 /etc/hosts 中增加 xxx.xxx.xxx.xxx    www.domain.com。这样主要使用 /etc/hosts 做解析,一旦漏掉 /etc/hosts 配置 DNS 还能工作。
3. 故障分析。DNS 使用 UDP 协议 53 端口,UDP 在网络中传输不会返回状态,有无数种可能导致 DNS 解析失败。例如内部的交换机繁忙,背板带宽不够(用户存储转发数据包,你可以理解就是交换机的内存),路由的问题等等……
8. 容器中的网络环境。
1. 相比传统网络,容器中的网络环境是十分复杂的。传统网络中一个数据包仅仅经过路由器,交换机,达到服务器,最多在服务前在增加一些防火墙,负载均衡等设备。
2. 容器网络部分实现方式SDN(软件定义网络)相比物理机(路由器、交换机、无服务)实现相对复杂。容器里面使用了IP转发,端口转发,软路由,lvs,7层负载均衡等等技术…… 调试起来非常复杂。docker 的 iptables 规则很头痛。
3. 例如一个TCP/IP 请求,需要经过多层虚拟网络设备(docker0,bridge0,tun0……)层层转发,再经过4层和7层的各种应用拆包,封包,最终到达容器内部。有兴趣你可以测试一下对比硬件设备,容器的网络延迟和吞吐量。
9. 容器的管理。
1. 传统服务可以通过键盘和显示器本地管理,OpenSSH 远程管理,通过配置还能使用串口。容器的管理让你抓狂 docker exec 和 kubectl exec 进入后与传统Linux差异非常大,这是镜像制作者造成的。
2. 有些镜像没有初始化 shell 只有一个 $ 符号,没有彩色显示,可能不支持 UTF-8,中文乱码,可能不是标准 ANSI/XTerm 终端,键盘定义五花八门,可能不是美式104键盘,国家和时区并不是东八区,HOME 目录也是不是 /root······
3. 想查看端口情况,发现 netstat 和 ss 命令没有。想查看IP地址,发现 ifconfig, ip 命令没有。想测试IP地址是否畅通,发现 ping, traceroute 没有。想测试URL,发现 curl , wget 没有。
4. 有些镜像 dnf,yum,apk,apt 可以使用,有些镜像把包管理也给阉割了,你想安装上述工具都安装不了。然后就自己用 Dockerfile 编译,整出200MB的镜像,卧槽这么大。
10. 容器的安全。
1. 很多容器的镜像中是不包含 iptables 的,所以无法做颗粒度很细的容器内部网络安全设置。即使你制作的镜像带有iptables ,多数容器的策略,IP地址和端口是随机变化的。绑定IP地址又带了容器的复杂性。一旦攻入一个容器,进入容器后,容器与容器间基本是畅通无阻。
2. 在容器中藏一个后门比物理机更容易,如上文所说很多容器中没有调试相关命令,限制了你排查后门的难度。所以Dockerfile 制作镜像,最好使用官方镜像衍生出你的镜像。
11. 容器与CI/CD
1. 在DevOps场景中,使用 docker 或 kubernetes 做 CI/CD 是很扯淡的。当 git 产生提交后,gitlab/jenkins 启动容器,下载代码,编译,打包,测试,产生构建物,编译 Dockerfile ,上传 docker 镜像到 registry,最后部署到容器执行。卧槽!!!速度能急死你。
2. 于是乎,我们做了 Cache。 不用每次都 pull 镜像,缓存 Maven 的 .m2 库,不再清理代码(mvn clean)提速不少,测试环境凑合用吧。 注意不mvn clean 有时会编译出错。至于生产环境,我就不说了,有多少人真用CD部署生产环境。

使用物理机,虚拟机,学习成本,试错成本,部署成本远远低于容器技术。Google 官方也曾经说过,未来 kubernetes 重点可能会转向虚拟机。不过Docker的理念和思想还是值得学习的。任何技术都会有平替,只是各种成本的妥协,在你想好怎么处理一些问题的时候,谨慎引入Docker等各类新技术到你的生产环境中。还有一些Docker+微服务遇到的坑和想法,等有空了再更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401255.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hdu 4293 Groups DP

http://acm.hdu.edu.cn/showproblem.php?pid4293 题意: 有n个人分成了若干组走在一条林荫道路上,导游为了能够确定人数,要求每个人喊出自己所在的队伍前边有多少人Ai表示,后边有多少人Bi表示,于是我们得到了n条信息。这里面有错误…

IAR切BANK--命令连接器文件xcl格式说明

IAREWARM中段后缀含义 后缀 段类型 含义 AC CONST 绝对地址定位常数 AN DATA 用关键字__no_init声明的绝对地址定位数据 C CONST 常数 I DATA 初始化值为非0的数据 ID CONST 上述数据的初始式 N DATA 未初始化的数据 Z DATA 初始化值为0的数据 ROM用于…

ARM系列处理器的分类

1.ARM ARM即以英国ARM(Advanced RISC Machines)公司的内核芯片作为CPU,同时附加其他外围功能的嵌入式开发板,用以评估内核芯片的功能和研发各科技类企业的产品. ARM 微处理器目前包括下面几个系列,以及其它厂商基于 AR…

DBA_Oracle Table Partition表分区概念汇总(概念)

2014-06-20 Created By BaoXinjian 一、摘要 有关表分区的一些维护性操作: 注:分区根据具体情况选择。 表分区有以下优点: 1、数据查询:数据被存储到多个文件上,减少了I/O负载,查询速度提高。 2、数据修剪&…

electron打包vue项目

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 创建项目 点击这里 添加electron-builder 1、在项目目录下运行命令:vue add electron-builder 2、electron-…

Hdu 4293 DP

题意: n个人说自己前面有多少人 后面有多少人 求出说真话人数最多的情况 每个样例有 一个 n 表示n个人 接下来 n 行有a b 表示他前面的人数和后面的人数 思路: 如果已经知道了其中一组的人数~ 就往前找..找在这一组之前与这一组的话不矛盾的最多人数 Ti…

IAR切BANK--程序中的使用

一、在IAR的集成开发环境中实现数据变量定位方法如下三种 1、__no_init char alpha 0x0200; 2、#pragma location 0x0202 const int beta; 3、const int gamma 0x0204 3; 或: 1)__no_init int alpha "MYSEGMENT"; //MYSEGMENT段可在…

你需要知道的vue2 jsx render函数

通常开发vue我们使用的是模板语法,其实还有和react相同的语法,那就是render函数,同样支持jsx语法。 Vue 的模板实际是编译成了 render 函数。 0 传统的createElement方法 createElement(anchored-heading, {props: {level: 1}}, [createEleme…

|与||的区别

在众多编程语言中,|与||代表了不同的运算。其中|是按位或运算,||是逻辑或运算。从字面意思来理解,|常可以用于具体数值的计算,结果为数值,而||是用来逻辑运算的没结果只有False或者True。例如int a 2; int b 3; int …

CSS/CSS3语法新特性笔记

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 CSS层叠样式表 三大特性 层叠性:相同的样式会覆盖 继承性:属性可向下继承 优先级:范…

vb 坐标点击

引用 :http://www.vbgood.com/thread-113934-1-1.html 第一步在窗体的通用栏写如下代码:Private Type pointapiX As LongY As LongEnd TypePrivate Declare Function GetCursorPos Lib "user32" (lpPoint As pointapi) As Long第二步在窗体上放…

开始写技术博客

2012年年底掏钱参加的java的培训,13年初找JAVA工作,发现很难找,公司需要的都是有工作经验的,刚刚从培训机构出来的学生不受欢迎,工作很难找,一个月之后打算退而求其次,找了份PHP的工作(那时对ph…

C# winform 自定义皮肤制作

最近要做个软件正在做技术准备,由于WINFORM生成的窗体很丑陋,一个好的软件除了功能性很重要外,UI的体验也是不容忽视的。习惯性的在网上搜素了下,换肤控件也有好几款,但是有些用起来不是很好用,好点的也要花…

Vue 源码解读(10)—— 编译器 之 生成渲染函数

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 前言 这篇文章是 Vue 编译器的最后一部分,前两部分分别是:Vue 源码解读(8)…

蓝牙PROFILE

Bluetooth的一个很重要特性,就是所有的Bluetooth产品都无须实现全部 的Bluetooth规范。为了更容易的保持Bluetooth设备之间的兼容,Bluetooth规范中定义了Profile。Profile定义了设备如何实现一种连接或者应用,你可以把Profile理解为连接层或者…

Laravel Session 遇到的坑

这两天遇到了一个很奇怪的问题,更新session ,session的值不变。经过一番追查,终于找到问题,并搞明白了原理。写这篇博客记录下。 框架版本 Laravel 5.4 问题 先来描述下问题,我在我们项目基础的Middleware中&#xff0…

bootstrap 中这段代码 使bundles 失败

bootstrap 中这段代码 使bundles 失败 _:-ms-fullscreen, :root input[type"date"], _:-ms-fullscreen, :root input[type"time"], _:-ms-fullscreen, :root input[type"datetime-local"], _:-ms-fullscreen, :root input[type"month"…

敏捷结果30天之第十二天:效率角色-你是启动者还是完成者

一.学习1.启动者:善于思考新想法,有太多想法还未开始,喜欢启动一些新事物,但是当事物成型之后就会离开去寻找下一个创新点。2.完成者:喜欢通过从头到尾的做完一件完整的事情来获得成就满足感。知道自己属于那种效率角色…

netty系列之:EventLoop,EventLoopGroup和netty的默认实现

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 目录* 简介 EventLoopGroup和EventLoopEventLoopGroup在netty中的默认实现EventLoop在netty中的默认实现总结 简介 在net…

BZOJ 1444: [Jsoi2009]有趣的游戏 [AC自动机 高斯消元]

1444: [Jsoi2009]有趣的游戏 题意:每种字母出现概率\(p_i\),有一些长度len的字符串,求他们出现的概率 套路DP的话,\(f[i][j]\) i个字符走到节点j的概率,建出转移矩阵来矩乘几十次可以认为是无穷个字符,就得…