-
#化鲲为鹏,我有话说#检查本机是否安装旧版本rpm -qa|grep docker卸载yum remove docker docker-common docker-selinux docker-engine更新yum包yum update设置yum源yum -y install yum-utilsyum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo安装dockeryum install docker-ce #由于repo中默认只开启stable仓库,故这里安装的是最新稳定版17.12.0启动并加入开机启动systemctl start dockersystemctl enable docker============================检索源docker search elk拉取elkdocker pull sebp/elkdocker images启动docker run -d --privileged -p 5601:5601 -p 9200:9200 -p 5044:5044 --name elk sebp/elk
-
2019入门级云主机选型测试报告★★★史上最全Python字符串操作指南如何优雅的上传对象到OBS鲲鹏初学者开始指南★★★如何避免DevOps变革的六大“焦油坑”★★★如何查看jsplumb.js的API文档(YUIdoc的基本使用)当Python遇见Andriod手机 万物皆可盘模拟真实AI开发场景,构建图像分类应用ubuntu18.04部署CUDA10.0+cuDNN+tensorflow-gpu+dockerGO富集分析示例用Anaconda3搭建自己的TensorFlow环境摄像机SDK对接第三方平台一人脸检测场景开发流程【最佳实践】如何设置视频封面?云享专家姚冬:9种DevOps团队结构适用类型与7种反型★★华为云MVP许舟平:来自工业制造领域的微服务与云平台实践★★云享专家方志朋:如何搭建自己的个人博客使用华为云数据库复制服务,实现阿里云MySQL数据库迁移到华为云0x2 Docker系列:Docker入门与实践0x2 Docker系列:Docker官方文档翻译20x2 Docker系列:Docker官方文档翻译30x2 Docker系列:Docker官方文档翻译40x2 Docker系列:Docker官方文档翻译50x2 Docker系列:Docker怎么修改hosts0x2 Docker系列:Docker 核心技术与实现原理Kuernetebs系列一:使用Kubespray部署Kubernetes集群Kubernetes系列二:Kubernetes对象模型Kubernetes系列三:Kubernetes基础与架构Kubernetes系列四:谈 Kubernetes 的架构设计与实现原理【Hello,鲲鹏】第一期:什么是华为云鲲鹏?【Hello,鲲鹏】第二期:创造一个属于自己的鲲鹏开发者环境【Hello,鲲鹏】第三期:在鲲鹏上使用编程语言——C语言【Hello,鲲鹏】第四期:在鲲鹏上使用编程语言——Java、Python玩转小熊派BearPi(一)使用STM32CubeMX + HAL点亮一个LED【演讲资料】ArchSummit全球架构师峰会·2019华为云技术专场【课程资料】5天玩转OCR【资料合集】7天玩转容器之基础入门课【版本资料】Atlas 200 DK 【演讲资料】华为IoT云服务助力行业数字化转型【华为云大咖分享】发掘系统弱点,带你一节课搞懂混沌工程!“如何利用GPU云资源训练自己的TensorFlow模型?敏捷的本质到底是什么?你们还提供免费的SSL证书吗?代金券激活找不到激活码在香港的服务器华为不支持SSL证书,有什么办法安装证书么买了模版298元,怎样升级到398元网站解析与备案弹性云服务器用户组devcloud的api文档怎么没有提供,查询一个仓库中的tag列表关于消息推送求大神指导批处理Batch service和MRS啥区别消息&短信 返回码E200037代表什么意思?任务栏在哪里订阅接口请求不成功无法验证签名手机版卡顿问题Agent Lite SDK集成开发指导 >初始化Agent Lite相关资源
-
1、简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架包括系统。 官方链接:https://www.docker.com/ 类别:虚拟化2、基础环境类别子项版本获取地址(方法)华为云虚拟机RC3(916)--OSCentOS7.5 Kernel4.14 软件包Docker1.13.1 3、依赖安装无4、组件编译安装清理 yum 缓存yum clean all下载服务器包到本地缓存yum makecache更新yum 包yum -y update安装dockeryum -y install docker5、系统配置无6、测试测试内容:docker命令是否可正常使用测试结果:正常 7、参考信息官方文档:https://docs.docker.com/部署:https://docs.docker.com/install/linux/docker-ce/centos/ https://get.docker.com/8、FAQA: 运行命令提示“Is the docker daemon running?”Q: docker服务未正常启动,运行systemctl start docker 或 service docker start
-
发现现在华为云还没有 docker-ce 软件源,建议新增 docker-ce 软件源。https://download.docker.com/
-
本期【云享专家·微话题】由云享专家Tsjsdbd与大家一起讨论“容器与虚机,谁将主宰云世界”,希望大家能够畅所欲言。如果大家有其他任何与PaaS相关的问题,也可以在本帖回复直接咨询云享专家Tsjsdbd。 =======【云享专家·微话题】容器与虚机,谁将主宰云世界?=======如今Docker容器技术已经比较普及,在各个领域都开始发挥出价值。并且容器与虚拟机十分和谐的共存,两者各自具有不同的特征和相应适合的应用场景。然而,渐渐地你会发现在各个云基础设所涉及的领地,容器正在以它的角度重建这个世界,容器存储,容器网络,容器调度都全部长出自己的枝干。在实际的领域,容器也开始崭露头角,HPC,基因测序,边缘云,微服务等等。相信有一天,容器会与虚机平起平坐,然后在那之后,迅速超越,成为云计算的中流砥柱。Container will Rebuild the World。每个人对“容器与虚机”都有不一样的理解,今天我们就“容器与虚机”一起来讨论,希望看到大家精彩的评论:1、讲讲你在容器使用过程中存在的问题?2、讲讲容器技术如何在各个技术领域渐露头角?3、容器一直被诟病的薄弱点安全相关进展?4、你觉得容器是否和虚机的各自发展前景?微话题活动:参与本次微话题讨论,有机会获得优质评论奖活动时间:2018年7月16日-7月27日参与方式:直接在本帖回复你关于以上4个问题的理解或评论获奖方式:活动结束后,将由云享专家Tsjsdbd选取出3名优质评论奖,各送出《Docker 容器与容器云》书籍1本。优质评论:建赟:1、讲讲你在容器使用过程中存在的问题? 在容器使用过程中存在的问题有:a、安装非常缓慢,而且经常安装失败。b、Docker所有的镜像都依赖于基础镜像,而这些基础镜像都在国外的docker hub上,镜像pull非常慢。c、默认的dockerhub所有镜像都是公开的,私有仓库价格是非常贵的,而且速度还很慢。d、要在VM上使用docker,需要对网络、存储等做一些特殊的处理。e、使用docker的出发点是降低运维成本,提升效率,但是管理上的成本相反却会上升,需要专业的公司来处理。f、容器的性能。 g、容器的安全。 h、网络的问题。i、容器型运维人员短缺2、讲讲容器技术如何在各个技术领域渐露头角? 容器带来了之前技术所没有的几个新特点。a、与之前的方法相比,Docker让容器部署和使用起来更容易、更安全。b、由于Docker与其他容器领域的巨擘进行了合作,包括Canonical、谷歌、红帽和Parallels,共同开发其关键的开源组件libcontainer,它为容器带来了迫切需要的标准化。c、容器易于部署到云端。3、容器一直被诟病的薄弱点安全相关进展? 对docker容器安全质疑最大的一点就是其隔离的彻底性,将docker生命周期拆为两个大阶段,非生产环境阶段和生产环境阶段,这两个阶段安全控制的目标如下:非生产环境中保证镜像安全可信,生产环境中保证镜像正确的运行。4、你觉得容器是否和虚机的各自发展前景? 说docker代替vm来说还为时过早,长期来看docker会在更多的场景上逐步替代vm的功能,vm技术也会在很长的时间内继续发挥着重要的作用,也许将来两种技术会进行融合,vm技术拥有docker的一些特性,同时docker也会克服自身的一些缺点,变得更加易用。ecstatic:1、讲讲你在容器使用过程中存在的问题? a.项目中docker容器中生成的日志文件名称乱码 b.怎样才能在容器中使用iptables呢 c.容易安装失败 d.kubernetes,mesos框架用不明白2、讲讲容器技术如何在各个技术领域渐露头角? 容器技术最早可以追溯到1979年UNIX系统中的chroot,最初是为了方便切换root目录,为每个进程提供了文件系统资源的隔离,这也是OS虚拟化思想的起源。 2013年Docker诞生,Docker最早是dotCloud(Docker公司的前身,是一家PaaS公司)内部的项目,和Warden类似,Docker最初也用了LXC,后来才自己写了 libcontainer 替换了 LXC。和其它容器技术不同的是,Docker 围绕容器构建了一套完整的生态,包括容器镜像标准、容器Registry、REST API、CLI、容器集群管理工具Docker Swarm等; 2016年微软公司发布基于Windows 的容器技术Hyper-V Container,Hyper-V Container原理和Linux下的容器技术类似,可以保证在某个容器里运行的进程与外界是隔离的,兼顾虚拟机的安全性和容器的轻量级。 为什么要关注Docker或者容器技术呢?容器可以提供隔离性,可以为各种测试提供一个良好的沙盒环境。并且,容器本身就是具有“标准性”的特征,非常适合为服务创建构建块。加速本地开发和构建流程,使其更加高效、更加轻量化。本地开发人员可以构建运行并分享Docker容器。容器可以在开发环境中构建,然后轻松的提交到测试环境,最终 进入生产环境。能够让独立服务或者应用程序在不同的环境中,得到相同的运行结果。用Docker创建隔离的环境来进行测试。eg :JenkinsCIDocker可以让开发者在本机上构建一个复杂的程序或者架构来进行测试,而不是一开始就在生产环境部署、测试。构建一个多用户的平台及服务基础设施。为开发、测试提供一个轻量级的独立沙盒环境,或者将独立的沙盒环境用于技术教学,eg:unix shell 的使用。提供软件及服务应用程序高性能、超大规模的宿主机部署。3、容器一直被诟病的薄弱点安全相关进展? Docker中可能会出现的安全问题 内核漏洞(Kernel exploits) 容器是基于内核的虚拟化,主机(host)和主机上的所有容器共享一套内核。如果某个容器的操作造成了内核崩溃,那么反过来整台机器上的容器都会受到影响。 拒绝服务攻击(Denial-of-service attacks) 所有的容器都共享了内核资源,如果一个容器独占了某一个资源(内存、CPU、各种ID),可能会造成其他容器因为资源匮乏无法工作(形成DoS攻击)。 容器突破(Container breakouts) Linux的namespace机制是容器的核心之一,它允许容器内部拥有一个PID=1的进程而在容器外部这个进程号又是不一样的(比如1234)。现在问题在于如果一个PID=1的进程突破了namespace的限制,那么他将会在主机上获得root权限。 有毒镜像(Poisoned images) 主要是考虑到镜像本身的安全性,没太多好说的。 密钥获取(Compromising secrets) 容器中的应用可能会获取一些容器外部的服务,这些服务之间可能会有密钥(secret key)等,如果因为密钥保存不当,那么这些服务对于攻击者来说就是可获取的了,这就会造成很多隐患。特别的,这样的问题如果出现在微服务架构中就特别严重。 安全方案 主机级别的隔离 主机级别的隔离(Segregate Containers by Host)即将不同用户的容器放在不同的机器上、将那些存放了敏感数据的容器 和普通的容器隔离开来、将哪些直接暴露给终端用户的容器(web容器)隔离开来。 主机级别的隔离的好处是可以防止容器突破攻击、DoS攻击,但是这样的隔离会付出成本甚至性能的代价的。 限制容器的网络 容器应向外暴露尽可能少的端口,此外,对于容器之间的通信,最好是需要通信的容器才是连通的。 移除SUID和SGID的二进制位 限制内存 限制CPU 限制重启 限制文件系统4、你觉得容器是否和虚机的各自发展前景? 随着容器生态圈的继续扩大,容器技术正在与越来越多的行业搭界,不论是过去八竿子打不着的大数据、物联网领域,还是已经闹得沸沸腾腾的微服务、虚拟化,一个更加广阔的后容器技术时代正在到来,他们都将会有更大的发展前景。小修:1、讲讲你在容器使用过程中存在的问题?1. 在docker容器中vi指令找不到2.docker容器启动后没有ifconfig和ping3.Docker客户端和服务器端版本不一致,在某些操作过中会出现错误4.对于基于busybox, alpine等镜像的容器,在执行命令时可能会出现错误5.容器启动后自动退出、或进入“restarting”状态2、讲讲容器技术如何在各个技术领域渐露头角?容器技术已经引起了业内的广泛关注,有充分的证据表明,容器技术能够大大提升工作效率。 现在,虚拟化技术已经成为一种被大家广泛认可的服务器资源共享方式,它可以在按需构建操作系统实例的过程当中为系统管理员提供极大的灵活性。由于hypervisor虚拟化技术仍然存在一些性能和资源使用效率方面的问题,因此出现了一种称为容器(Container)的新型虚拟化技术来帮助解决这些问题。起初,大家普遍认为基于hypervisor的方式可以在最大程度上提供灵活性。所有虚拟机实例都能够运行任何其所支持的操作系统,而不受其他实例的影响。然而,现在越来越多的用户发现hypervisor提供这样一种广泛支持的特性其实是在给自己制造麻烦。对于hypervisor环境来说,每个虚拟机实例都需要运行客户端操作系统的完整副本以及其中包含的大量应用程序。从实际运行的角度来说,由此产生的沉重负载将会影响其工作效率及性能表现。 首先,每种操作系统和应用程序堆栈都需要使用DRAM。对于多个运行简单应用程序的小型虚拟机实例来说,这种方式可能产生很大的系统开销,降低性能表现。加载并卸载这些堆栈镜像需要花费很长时间,并且还会增加容器技术服务器的网络连接数量。对于极端情况来说,如果用户在上午9点同时启动上千台虚拟桌面,还有可能导致网络风暴的发生。部署虚拟服务器的目的之一在于快速创建新的虚拟机实例。然而从网络存储当中复制镜像需要花费大量时间,这些操作会延长启动过程,无疑会限制系统灵活性。 因此我们可以选择使用容器技术。只需要通过简单的观察我们便能够发现容器技术的出现是为了解决多操作系统/应用程序堆栈的问题:在单台服务器当中为所有虚拟机实例使用相同的操作系统对于大部分数据中心来说都不算是真正的限制。流程管理(Orchestration)可以轻松处理这种变化许多应用程序堆栈都是相同的(如LAMP)对于大规模集群来说,在本地硬盘当中存储操作系统副本将会使得更新过程变得更为复杂最为重要的是,容器技术可以同时将操作系统镜像和应用程序加载到内存当中。还可以从网络磁盘进行加载,因为同时启动几十台镜像不会对网络和存储带来很大负载。之后的镜像创建过程只需要指向通用镜像,大大减少了所需内存。 容器技术能够在同一台服务器上创建相比于之前两倍的虚拟机实例数量,因此无疑将会降低系统总投入。但是必须认真进行规划,因为双倍的实例数量同样意味着对于运行这些实例的服务器带来了双倍的I/O负载。 我们需要了解除了避免可能发生的启动风暴之外,容器技术是否还有任何其他性能方面的优势。能否改进IOPS?能够提升网络连接效率并且降低容器间的延迟,解决伴随实例数量增加而产生的问题?美国某传统服务器大厂商的某实验室完成了至今为止大部分权威实验,其研究结果表明容器技术相比于hypervisor,容器技术的许多关键指标都有重大改进。在进行的所有测试当中,容器技术几乎拥有和本地平台一样的运行速度,尽管网络延迟测试还没有完成。 上述厂商的研究表明容器技术在多个领域当中都比hypervisor拥有更好的性能表现。容器技术的运行速度几乎是hypervisor的两倍,在评分当中非常接近于本地操作系统。在和KVM的对比当中,容器技术在硬盘随机读取(84,000 vs 48,000 IOPS)和写入(110,000 vs 60,000 IOPS )方面拥有非常优秀的表现,如果使用本地固态硬盘可以实现更好的SQL性能表现。高性能计算(HPC)社区也在转而使用虚拟化和容器技术。一项由巴西天主教大学进行的研究已经取得了一定成果。“如果可以降低基本的系统开销(比如CPU、内存、硬盘和网络),那么HPC无疑会选择使用虚拟化系统,”研究人员表示。“从这个角度来说,我们发现所有基于容器的系统在CPU、内存、硬盘和网络方面都拥有接近于本地操作系统的性能表现。”美国某虚拟化公司V***re也针对容器技术进行了一系列评测对比。容器技术研究结果印证了容器技术拥有接近本地系统的性能表现,尽管其并没有像IBM实验室那样针对VMware的hypervisor发布非常详细的测试报告。而这项报告的容器技术结果有可能促使VMware做出调整,以降低hypervisor的系统开销。VMware的报告当中没有提及硬盘I/O问题。 为了扩展适用范围,容器技术仍然需要在安全方面不断改进。但是现在,我们可以看到的是这种方式可以解决hypervisor虚拟化当中的大多数性能问题。再加上更加轻松和快捷的部署方式,容器技术将会在不久的将来占据虚拟化市场3、容器一直被诟病的薄弱点安全相关进展?容器安全需要自下而上全面考虑安全风险,从内核,OS ,OS层的网络、软件版本、Selinux策略,Docker版本,Docker的优化配置以及使用方式,image中所依赖的base 以及软件包,容器间的网络隔离。真的是每一处都需要去考虑,任何一个环节的小问题,都有可能造成事故。感觉Docker 安全是个全方位的问题,任何一点疏漏都会带来灾难性后果。有些问题不是Docker本身能解决的,需要多方配合。Docker在这个方面做了哪些工作?4、你觉得容器是否和虚机的各自发展前景?容器实例与主机共享操作系统内核,通过内核提供的运行时隔离能力为服务提供独立的用户域、文件系统、网络以及进程运行空间。虚拟机的每个实例自带操作系统,因而是一种硬件级的虚拟化隔离。容器通常是专用于运行特定服务的,它的镜像通常只包含运行该服务所需的上下文内容,许多广泛使用的镜像都只有几十MB,甚至几MB大小。虚拟机则需要提供包括内核在内的通用进程运行环境,它的镜像偏向于大而完整的全功能集合,即使一个最小精简镜像的体积也有几百MB。容器的使用方式倾向于开箱即用,镜像提供的是一个“不可变的基础设施环境”。虚拟机则倾向于让用户根据所用的系统,自定义初始化操作,使用Ansible、Puppet这样的配置工具来进行基础设施的管理。容器在启动速度和运行性能上更有优势,虚拟机在安全性上更有优势。如果从这些十分清晰的定义来看,近一年来开源界出现的一些虚拟化“边界破坏者”们已经完全无视了这些规则。它们要么是运行在虚拟机中的操作系统,却有着容器一样的使用体验,要么是基于容器技术的运行时隔离,却应该当成虚拟机使用。因此,尽管这些技术的实现细节上差异巨大,但它们都有一个共同特征:携带着容器和虚拟机各一部分的基因,具备两者优势的结合。
-
《直播回看》栏目会将“华为云开发者者联盟”移动端课程平台的精品音视频直播课,定期进行展播,支持各位伙伴进行回看学习本期推荐: 容器-Docker容器和镜像相关技术讨论和解答【主讲人介绍】主讲人:Jarrey Zhou【课程大纲】我们将讨论Docker的基础知识,从Docker的安装到镜像和容器的制作和启动,致力于解决用户使用Docker制作镜像和运行容器遇到的问题,帮大家更快的掌握Docker的原理和学习21天转型云容器课程。【课程链接】可扫描下方二维码进入“华为云开发者联盟“移动端直播间收听课程
-
什么是“容器”和“虚拟机”容器和虚拟机它们的目的很相似:即将应用程序和它的依赖放到一个可以在任何环境运行的自足单元中。此外,容器和虚拟机消除了对物理硬件的需求,从而在能源消耗和成本效益方面能让我们更有效地使用计算资源,容器和虚拟机的主要区别在于它们的架构方式。让我们继续深入了解。虚拟机虚拟机在本质上是对现实中计算机的仿真,它会像真实的计算机一样执行程序。使用 “hypervisor” 可以将虚拟机运行于物理机上。hypervisor 可以在主机运行,也可以在“裸机”上运行。让我们来揭开这些术语的面纱:hypervisor(之后都以虚拟机管理程序称呼)是能让虚拟机在其上运行的软件,固件或者硬件。虚拟机管理程序本身会在物理计算机上运行,称为**“主机”**。主机为虚拟机提供资源,包括 RAM 和 CPU。这些资源在虚拟机之间被划分并且可以根据需要进行分配。所以如果一个虚拟机上运行了资源占用更大的应用程序,相较于其它运行在同一个主机的虚拟机你可以给其分配更多的资源。运行在主机上的虚拟机(再次说明,通过使用虚拟机管理程序)通常也被叫做“访客机”。访客机包含了应用以及运行这个应用所需要的全部依赖(比如:系统二进制文件和库)。它还带有一个自己的完整虚拟化硬件栈,包括虚拟化的网络适配器,储存和 CPU-这意味着它还拥有自己成熟的整个访客操作系统。从虚拟机内部来看,访客机的操作都认为其使用的都是自己的专用资源。从外部来看,我们知道它是一个虚拟机-和其它虚拟机一起共享主机提供的资源。就像前面所提到的,访客机既可以运行在托管的虚拟机管理程序上,也可以运行在裸机虚拟机管理程序上。它们之间存在一些重要的差别。首先,托管的虚拟化管理程序是在主机的操作系统上运行。比如说,可以在一台运行 OSX 操作系统的计算机的系统上安装虚拟机(例如:VirtualBox 或者 VMware Workstation 8)。虚拟机无法直接访问硬件,因此必须通过主机上运行的操作系统访问(在我们的例子中,也就是 Mac 的 OSX 操作系统)。托管虚拟机管理程序的好处是底层硬件并不那么重要。主机的操作系统会负责硬件的驱动而不需要管理程序参与。因此这种方式被认为具备更好的“硬件兼容性”。在另一方面,在硬件和管理程序之间这个额外的附加层会产生更多的资源开销,这会降低虚拟机的性能。裸机虚拟机管理程序通过直接在主机硬件上安装和运行来解决这个性能问题。因为它直接面对底层的硬件,所以并不需要运行在主机的操作系统之上。在这种情况下,安装在主机上第一个作为操作系统运行的就是这个裸机虚拟机管理程序。与托管虚拟机管理程序不同,它有自己的设备驱动直接与每个组件交互,以执行任何 I/O,处理或特定于操作系统的任务。这样可以获得更好的性能,可伸缩性和稳定性。这里的权衡在于其对硬件的兼容性有限,因为裸机虚拟机管理程序内置的设备驱动只有那么多。在讨论了虚拟机管理程序之后,你可能想知道为什么我们需要在虚拟机和主机之间这个额外的“虚拟机管理程序”层。好吧,虚拟机管理程序在其中确实发挥了重要的作用,由于虚拟机拥有自己的虚拟操作系统,管理程序为虚拟机管理和执行访客操作系统提供了一个平台。它允许主机与作为客户端运行的虚拟机之间共享其资源。虚拟机图示正如你可以在图示中所看到的,VMS 会为每个新的虚拟机打包虚拟硬件,一个内核(即操作系统)和用户空间。容器与提供硬件虚拟化的虚拟机不同,容器通过抽象“用户空间”来提供操作系统级别的虚拟化。当我们详解容器这个术语的时候你就会明白我的意思。从所有的意图和目的来看,容器看起来就像一个虚拟机。比如说,它们有执行进程的私有空间,可以使用 root 权限执行命令,具有专有的网络接口和 IP 地址,允许自定义路由和 iptable 规则,可以挂载文件系统等。容器和虚拟机之间的一个重要区别在于容器和其它容器共享主机系统的内核。容器图示这图表明容器只会打包用户空间,而不是像虚拟机那样打包内核或虚拟硬件。每个容器都有自己独立的用户空间从而可以让多个容器在单个主机上运行。我们可以看到所有操作系统级别的体系架构是所有容器共享的。要从头开始创建的部分只有 bins 和 libs 目录。这就是容器如此轻巧的原因。Docker 是从哪来的?Docker 是基于 Linux 容器技术的开源项目。它使用 Luinux 的内核功能(如命名空间和控制组)在操作系统上创建容器。容器已经远远不是一个新技术:Google 已经使用他们自己的容器技术好多年了。其它的容器技术包括 Solaris Zones、BSD jails 和 LXC 也已经存在好多年。那么为啥 Docker 会突然取得成功呢?使用简单:Docker 使得任何人(开发人员,运维,架构师和其他人)都可以更轻松的利用容器的优势来快速构建和测试可移植的应用程序。它可以让任何人在他们的笔记本电脑上打包应用程序,不需要任何修改就可以让应用运行在公有云,私有云甚至裸机上。Docker 的口头禅是:“一次构建,处处运行”。速度:Docker 容器非常轻量级和快速。因为容器只是运行在内核上的沙盒环境,因此它们占用的资源更少。与可能需要更多时间来创建的虚拟机相比,你可以在几秒钟内创建一个 Docker 容器,因为虚拟机每次都必须启动一个完整的操作系统。Docker Hub:Docker 用户也可以从日益丰富的 Docker Hub 生态中受益,你可以把 Docker Hub 看作是 “Docker 镜像的应用商店”。Docker Hub 拥有数万个由社区构建的公共镜像,这些镜像都是随时可用的。在其中搜索符合你需求的镜像非常容易,你只需要准备拉取镜像而且几乎不需要任何修改。模块化和可扩展性:Docker 可以让你轻松地把应用程序按功能拆分为单个独立的容器。比如说,你的 Postgre 数据库可以运行在一个容器中,Redis 服务运行在另一个容器中,而 Node.js 应用运行在另一个容器中。使用 Docker,将这个容器链接在一起以创建你的应用程序将会变得更简单,同时在将来可以很轻松地扩展和更新单独的组件。最后但并不重要的是,有谁不喜欢 Docker 的鲸鱼(Docker 的标志)呢?:)
-
docker官方下载实在是无力吐槽了。前阵子,华为云提供了DockerHub镜像加速。考虑到windows的用户还是有很多,能不能为windows用户提供docker for windows 版本的stable安装包。
-
1 前言前两天有同事发现,通过华为云 ServiceStage 的流水线部署基于模板创建的 CSEJavaSDK demo 服务时,会在容器启动过程中报错。初步排查是由于 JVM 占用的内存超出了 docker 内存配额的上限,导致容器被 kill 掉。于是我们需要排查一下问题出在哪里,为什么以前没有这类问题,而现在却发生了。2 基本定位要确定 docker 容器内存超限问题的直接原因并不难。直接进入docker容器,执行 top 命令,我们发现宿主机是一台8核16G的机器,而且 docker 并不会屏蔽这些信息,也就是 JVM 会认为自己工作于一台 16G 内存的机器上。而查看 demo 服务的 Dockerfile,发现运行服务时并没有对 JVM 的内存进行任何限制,于是 JVM 会根据默认的设置来工作 —— 最大堆内存为物理内存的1/4(这里的描述并不完全准确,因为 JVM 的默认堆内存大小限制比例其实是根据物理内存有所变化的,具体内容请自行搜索资料),而基于模板创建的 ServiceStage 流水线,在部署应用堆栈的时候会把 docker 容器的内存配额默认设置为 512M,于是容器就会在启动的时候内存超限了。至于以前没有碰到过这种问题的原因,只是因为以前没将这么高规格的 ECS 服务器用于流水线部署应用堆栈。在查询过相关资料后,我们找到了两种问题解决方案,一个是直接在 jar 包运行命令里加上 -Xmx 参数来指定最大堆内存,不过这种方式只能将 JVM 堆内存限制为一个固定的值;另一个方法是在执行 jar 包时加上 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap 参数,让 JVM 能够感知到docker容器所设置的 cgroup 限制,相应地调整自身的堆内存大小,不过这个特性是 JDK 8u131 以上的版本才具备的。最终,我们提醒 ServiceStage 流水线的同学将 CSEJavaSDK demo 的创建模板做了改进,在 Dockerfile 中将打包的基础镜像版本由原先的 java:8u111-jre-alpine 升级为了 openjdk:8u181-jdk-alpine,并且在运行服务 jar 包的命令中加上了 -Xmx256m参数。问题至此已经解决了。3 进一步的探究虽然问题已经解决,但是在好奇心的驱使下,我还是打算自己找个 demo 实际去触发一下问题,另外看看从网上搜到的解决方法到底好不好用 : )3.1 准备工作3.1.1 创建云上工程首先需要在华为云 ServiceStage 创建一个云上工程。在 ServiceStage -> 应用开发 -> 微服务开发 -> 工程管理 -> 创建云上工程中,选择“基于模板创建”,语言选择 Java, 框架选择 CSE-Java (SpringMVC),部署系统选择“云容器引擎CCE”,给你的云上工程取一个名字,比如test-memo-consuming,最后选择存放代码的仓库,就可以完成云上工程的创建了。之后云上工程会根据你的选项自动地生成脚手架代码,上传到你指定的代码仓库中,并且为你创建一条流水线,完成代码编译、构建、打包、归档镜像包的操作,并且使用打好的 docker 镜像包在 CCE 集群中部署一个应用堆栈。创建云上工程和流水线不是本文的重点,我就不详细讲操作了 : )。同一个应用堆栈的实例可以部署多个,在这里为了实验方便就按照默认值1个来部署。由于云上工程已经改进了脚手架代码的模板,不会再出现内存超限的问题,所以我们现在能看到 demo 服务已经正常的跑起来,微服务实例已经注册到服务中心了。登录到 demo 服务所部署的容器,使用curl命令可以调用 demo 服务的 helloworld 接口,可以看到此时服务已经可以正常工作。3.1.2 增加实验代码为了能够触发微服务实例消耗更多的内存,我在项目代码中增加了如下接口,当调用/allocateMemory接口时,微服务实例会不停申请内存,直到 JVM 抛出 OOM 错误或者容器内存超限被 kill 掉。private HashMap<String, long[]> cacheMap = new HashMap<>(); @GetMapping(value = "/allocateMemory") public String allocateMemory() { LOGGER.info("allocateMemory() is called"); try { for (long i = 0; true; ++i) { cacheMap.put("key" + i, new long[1024 * 1024]); } } catch (Throwable t) { LOGGER.info("allocateMemory() gets error", t); } return "allocated"; }此时用来打镜像包的基础镜像是openjdk:8u181-jdk-alpine,jar 包启动命令中加上了-Xmx256m参数。执行流水线,应用堆栈部署成功后,调用/allocateMemory接口触发微服务实例消耗内存,直到 JVM 抛出 OOM 错误,可以在 ServiceStage -> 应用上线 -> 应用管理中选择相应的应用,点击进入概览页面,查看应用使用内存的情况。应用使用的内存从 800M+ 陡然下降的时间点就是我重新打包部署的时间,而之后由于调用/allocateMemory接口,内存占用量上升到了接近 400M,并且在这个水平稳定了下来,显示-Xmx256m参数发挥了预期的作用。3.2 复现问题现在将 demo 工程中的 Dockerfile 修改一下,将基础镜像改为 java:8u111-jre-alpine,并且删除启动命令中的-Xmx256m参数,将其提交为noLimit_oldBase分支,推送到代码仓库中。然后编辑流水线,将 source 阶段的任务所使用的代码分支改为noLimit_oldBase分支,保存并重新运行流水线,将新的代码打包部署到应用堆栈中。在微服务实例列表中查询到新的微服务实例的 endpoint IP 后,调用`/allocateMemory`接口,观察内存情况,内存从接近 400M 突然掉下去一下,然后又上升到约 450M 的时间点就是修改代码后的微服务实例部署成功的时间点,之后内存占用量突然下跌就是因为调用`/allocateMemory`接口导致容器内存超限被 kill 掉了。如果你事先使用docker logs -f命令查看容器日志的话,那么日志大概是这个样子的2018-11-23 15:40:04,920 INFO SCBEngine:152 - receive MicroserviceInstanceRegisterTask event, check instance Id... 2018-11-23 15:40:04,920 INFO SCBEngine:154 - instance registry succeeds for the first time, will send AFTER_REGISTRY event. 2018-11-23 15:40:04,925 WARN VertxTLSBuilder:116 - keyStore [server.p12] file not exist, please check! 2018-11-23 15:40:04,925 WARN VertxTLSBuilder:136 - trustStore [trust.jks] file not exist, please check! 2018-11-23 15:40:04,928 INFO DataFactory:62 - Monitor data sender started. Configured data providers is {com.huawei.paas.cse.tcc.upload.TransactionMonitorDataProvider,com.huawei.paas.monitor.HealthMonitorDataProvider,} 2018-11-23 15:40:04,929 INFO ServiceCenterTask:51 - read MicroserviceInstanceRegisterTask status is FINISHED 2018-11-23 15:40:04,939 INFO TestmemoconsumingApplication:57 - Started TestmemoconsumingApplication in 34.81 seconds (JVM running for 38.752) 2018-11-23 15:40:14,943 INFO AbstractServiceRegistry:258 - find instances[1] from service center success. service=default/CseMonitoring/latest, old revision=null, new revision=28475010.1 2018-11-23 15:40:14,943 INFO AbstractServiceRegistry:266 - service id=8b09a7085f4011e89f130255ac10470c, instance id=8b160d485f4011e89f130255ac10470c, endpoints=[rest://100.125.0.198:30109?sslEnabled=true] 2018-11-23 15:40:34,937 INFO ServiceCenterTaskMonitor:39 - sc task interval changed from -1 to 30 2018-11-23 15:47:03,823 INFO SPIServiceUtils:76 - Found SPI service javax.ws.rs.core.Response$StatusType, count=0. 2018-11-23 15:47:04,657 INFO TestmemoconsumingImpl:39 - allocateMemory() is called Killed可以看到allocateMemory方法被调用,然后 JVM 还没来得及抛出 OOM 错误,整个容器就被 kill 掉了。这里也给大家提了一个醒:不要以为自己的服务容器能启动起来就万事大吉了,如果没有特定的限制,JVM 会在运行时继续申请堆内存,也有可能造成内存用量超过 docker 容器的配额!3.3 让 JVM 感知cgroup限制前文提到还有另外一种方法解决 JVM 内存超限的问题,这种方法可以让 JVM 自动感知 docker 容器的 cgroup 限制,从而动态的调整堆内存大小,感觉挺不错的。我们也来试一下这种方法,看看效果如何 ; )回到demo项目代码的master分支,将 Dockerfile 中启动命令参数的-Xmx256m替换为-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap,提交为useCGroupMemoryLimitForHeap分支,推送到代码仓库里。再次运行流水线进行构建部署。等 demo 服务部署成功后,再次调用`/allocateMemory`接口,容器的内存占用情况如上图所示(最右边的那一部分连续曲线),内存上升到一定程度后,JVM 抛出了 OOM 错误,没有继续申请堆内存。看来这种方式也是有效果的。不过,仔细观察容器的内存占用情况,可以发现容器所使用的内存仅为不到 300M,而我们对于这个容器的内存配额限制为 512M,也就是还有 200M+ 是闲置的,并不会被 JVM 利用。这个利用率,比起上文中直接设置-Xmx256m的内存利用率要低 : ( 。推测是因为 JVM 并不会感知到自己是部署在一个 docker 容器里的,所以它把当前的环境当成一个物理内存只有 512M 的物理机,按照比例来限制自己的最大堆内存,另一部分就被闲置了。如此看来,如果想要充分利用自己的服务器资源,还是得多花一点功夫,手动调整好-Xmx参数。4 参考资料Java and Docker, the limitationsJava inside docker: What you must know to not FAIL本文转载自Docker容器内部署Java微服务的内存限制问题
-
本文基于华为云容器镜像服务实践所编写,将一个单体应用进行容器改造为例,展示如何写出可读性更好的Dockerfile,从而提升镜像构建速度,构建层数更少,体积更小的镜像。下面是一个常见企业门户网站架构,由一个Web Server和一个数据库组成,Web Server提供web服务,数据库保存用户数据。通常情况下,这样一个门户网站安装在一台服务器上。如果把应用运行在一个Docker容器中,那么很可能写出下面这样的Dockerfile来。FROM ubuntuADD . /appRUN apt-get update RUN apt-get upgrade -y RUN apt-get install -y nodejs ssh mysql RUN cd /app && npm install# this should start three processes, mysql and ssh# in the background and node app in foreground# isn't it beautifully terrible? <3CMD mysql & sshd & npm start当然这样Dockerfile有很多问题,这里CMD命令是错误的,只是为了说明问题而写。下面的内容中将展示对这个Dockerfile进行改造,说明如何写出更好的Dockerfile,共有如下几种处理方法。一个容器只运行一个进程不要在构建中升级版本将变化频率一样的RUN指令合一使用特定的标签删除多余文件选择合适的基础镜像设置WORKDIR和 CMD使用ENTRYPOINT (可选)在entrypoint脚本中使用exec优先使用COPY合理调整COPY与RUN的顺序设置默认的环境变量,映射端口和数据卷使用EXPOSE暴露端口使用VOLUME管理数据卷使用LABEL设置镜像元数据添加HEALTHCHECK使用USER做权限控制编写.dockerignore文件使用多阶段构建一个容器只运行一个进程从技术角度讲,Docker容器中可以运行多个进程,您可以将数据库,前端,后端,ssh等都运行在同一个Docker容器中。但是,这样跟未使用容器前没有太大区别,且这样容器的构建时间非常长(一处修改就要构建全部)、镜像体积大、横向扩展时非常浪费资源(不同的应用需要运行的容器数并不相同)。通常所说的容器化改造是对应用整体微服务架构改造,再容器化,这样做可以带来如下好处。单独扩展:拆分为微服务后,可单独增加或缩减每个微服务的实例数量。提升开发速度:各微服务之间解耦,某个微服务的代码开发不影响其他微服务。通过隔离确保安全:整体应用中,若存在安全漏洞,会获得所有功能的权限。微服务架构中,若攻击了某个服务,只可获得该服务的访问权限,无法入侵其他服务。隔离崩溃:如果其中一个微服务崩溃,其它微服务还可以持续正常运行。如前面的示例可以改造成下面架构,Web应用和MySQL运行在不同容器中。MySQL运行在单独的镜像中,下面的示例中删掉了MySQL,只安装node.js。FROM ubuntuADD . /appRUN apt-get update RUN apt-get upgrade -yRUN apt-get install -y nodejs RUN cd /app && npm installCMD npm start不要在构建中升级版本为了降低复杂性、减少依赖、减小文件大小、节约构建时间,你应该避免安装任何不必要的包。例如,不要在数据库镜像中包含一个文本编辑器。apt-get upgrade会使得镜像构建非常不确定,在构建时不确定哪些包会被安装,此时可能会产生不一致的镜像,因为你不再有你的应用程序该如何运行以及包含在镜像中依赖的哪种版本的正确源文件。如果基础镜像中的某个包过时了,你应该联系它的维护者。如果你确定某个特定的包,比如 foo,需要升级,使用 apt-get install -y foo 就行,该指令会自动升级 foo 包。删掉apt-get upgrade后,Dockerfile如下:FROM ubuntuADD . /appRUN apt-get updateRUN apt-get install -y nodejsRUN cd /app && npm installCMD npm start将变化频率一样的RUN指令合一Docker镜像是分层的,类似于洋葱,它们都有很多层,为了修改内层,则需要将外面的层都删掉。Docker镜像有如下特性:Dockerfile中的每个指令都会创建一个新的镜像层。镜像层将被缓存和复用。Dockerfile修改后,复制的文件变化了或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效。某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效。镜像层是不可变的,如果我们再某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在Docker容器中不可见。将变化频率一样的指令合并在一起,目的是为了更好的将镜像分层,避免带来不必要的成本。如本例中将node.js安装与npm模块安装放在一起的话,则每次修改源代码,都需要重新安装node.js,这显然不合适。FROM ubuntuADD . /appRUN apt-get update \ && apt-get install -y nodejs \ && cd /app \ && npm install CMD npm start因此,正确的写法是这样的:FROM ubuntuRUN apt-get update && apt-get install -y nodejs ADD . /appRUN cd /app && npm installCMD npm start使用特定的标签当镜像没有指定标签时,将默认使用latest 标签。因此, FROM ubuntu 指令等同于FROM ubuntu:latest。当镜像更新时,latest标签会指向不同的镜像,这时构建镜像有可能失败。如下示例中使用16.04作为标签。FROM ubuntu:16.04RUN apt-get update && apt-get install -y nodejs ADD . /app RUN cd /app && npm installCMD npm start删除多余文件假设我们更新了apt-get源,下载解压并安装了一些软件包,它们都保存在/var/lib/apt/lists/目录中。但是,运行应用时Docker镜像中并不需要这些文件。因此最好将它们删除,因为它会使Docker镜像变大。示例Dockerfile中,删除/var/lib/apt/lists/目录中的文件。FROM ubuntu:16.04RUN apt-get update \ && apt-get install -y nodejs \ && rm -rf /var/lib/apt/lists/* ADD . /app RUN cd /app && npm installCMD npm start选择合适的基础镜像在示例中,我们选择了ubuntu作为基础镜像。但是我们只需要运行node程序,没有必要使用一个通用的基础镜像,node镜像应该是更好的选择。更好的选择是alpine版本的node镜像。alpine是一个极小化的Linux发行版,只有4MB,这让它非常适合作为基础镜像。FROM node:7-alpineADD . /app RUN cd /app && npm installCMD npm start设置WORKDIR和 CMDWORKDIR指令可以设置默认目录,也就是运行RUN / CMD / ENTRYPOINT指令的地方。CMD指令可以设置容器创建是执行的默认命令。另外,您应该将命令写在一个数组中,数组中每个元素为命令的每个单词。FROM node:7-alpineWORKDIR /app ADD . /app RUN npm installCMD ["npm", "start"]使用ENTRYPOINT (可选)ENTRYPOINT指令并不是必须的,因为它会增加复杂度。ENTRYPOINT是一个脚本,它会默认执行,并且将指定的命令作为其参数。它通常用于构建可执行的Docker镜像。FROM node:7-alpineWORKDIR /app ADD . /app RUN npm installENTRYPOINT ["./entrypoint.sh"] CMD ["start"]在entrypoint脚本中使用exec在前文的entrypoint脚本中,我使用了exec命令运行node应用。不使用exec的话,我们则不能顺利地关闭容器,因为SIGTERM信号会被bash脚本进程吞没。exec命令启动的进程可以取代脚本进程,因此所有的信号都会正常工作。优先使用COPYCOPY指令非常简单,仅用于将文件拷贝到镜像中。ADD相对来讲复杂一些,可以用于下载远程文件以及解压压缩包。FROM node:7-alpineWORKDIR /appCOPY . /appRUN npm installENTRYPOINT ["./entrypoint.sh"] CMD ["start"]合理调整COPY与RUN的顺序将变化最少的部分放在Dockerfile的前面,这样可以充分利用镜像缓存。示例中,源代码会经常变化,则每次构建镜像时都需要重新安装NPM模块,这显然不是我们希望看到的。因此我们可以先拷贝package.json,然后安装NPM模块,最后才拷贝其余的源代码。这样的话,即使源代码变化,也不需要重新安装NPM模块。FROM node:7-alpineWORKDIR /appCOPY package.json /app RUN npm install COPY . /appENTRYPOINT ["./entrypoint.sh"] CMD ["start"]设置默认的环境变量,映射端口和数据卷运行Docker容器时很可能需要一些环境变量。在Dockerfile设置默认的环境变量是一种很好的方式。另外,我们应该在Dockerfile中设置映射端口和数据卷。示例如下:FROM node:7-alpineENV PROJECT_DIR=/appWORKDIR $PROJECT_DIRCOPY package.json $PROJECT_DIR RUN npm install COPY . $PROJECT_DIRENTRYPOINT ["./entrypoint.sh"] CMD ["start"]ENV指令指定的环境变量在容器中可以使用。如果你只是需要指定构建镜像时的变量,你可以使用ARG指令。使用EXPOSE暴露端口EXPOSE 指令用于指定容器将要监听的端口。因此,你应该为你的应用程序使用常见的端口。例如,提供 Apache web 服务的镜像应该使用 EXPOSE 80,而提供 MongoDB 服务的镜像使用 EXPOSE 27017。对于外部访问,用户可以在执行 docker run 时使用一个标志来指示如何将指定的端口映射到所选择的端口。FROM node:7-alpineENV PROJECT_DIR=/appWORKDIR $PROJECT_DIRCOPY package.json $PROJECT_DIR RUN npm install COPY . $PROJECT_DIRENV APP_PORT=3000EXPOSE $APP_PORTENTRYPOINT ["./entrypoint.sh"] CMD ["start"]使用VOLUME管理数据卷VOLUME 指令用于暴露任何数据库存储文件,配置文件,或容器创建的文件和目录。强烈建议使用 VOLUME来管理镜像中的可变部分和用户可以改变的部分。下面示例中填写一个媒体目录。FROM node:7-alpineENV PROJECT_DIR=/appWORKDIR $PROJECT_DIRCOPY package.json $PROJECT_DIR RUN npm install COPY . $PROJECT_DIRENV MEDIA_DIR=/media \ APP_PORT=3000VOLUME $MEDIA_DIR EXPOSE $APP_PORTENTRYPOINT ["./entrypoint.sh"] CMD ["start"]使用LABEL设置镜像元数据你可以给镜像添加标签来帮助组织镜像、记录许可信息、辅助自动化构建等。每个标签一行,由 LABEL 开头加上一个或多个标签对。 注意:如果你的字符串中包含空格,必须将字符串放入引号中或者对空格使用转义。如果字符串内容本身就包含引号,必须对引号使用转义。FROM node:7-alpine LABEL com.example.version="0.0.1-beta"添加HEALTHCHECK运行容器时,可以指定--restart always选项。这样的话,容器崩溃时,docker daemon会重启容器。对于需要长时间运行的容器,这个选项非常有用。但是,如果容器的确在运行,但是不可用怎么办?使用HEALTHCHECK指令可以让Docker周期性的检查容器的健康状况。我们只需要指定一个命令,如果一切正常的话返回0,否则返回1。当请求失败时,curl --fail 命令返回非0状态。示例如下:FROM node:7-alpine LABEL com.example.version="0.0.1-beta"ENV PROJECT_DIR=/app WORKDIR $PROJECT_DIRCOPY package.json $PROJECT_DIR RUN npm install COPY . $PROJECT_DIRENV MEDIA_DIR=/media \ APP_PORT=3000VOLUME $MEDIA_DIR EXPOSE $APP_PORT HEALTHCHECK CMD curl --fail http://localhost:$APP_PORT || exit 1ENTRYPOINT ["./entrypoint.sh"] CMD ["start"]使用USER做权限控制如果某个服务不需要特权执行,建议使用 USER 指令切换到非 root 用户。先在 Dockerfile 中使用类似 RUN groupadd -r postgres && useradd -r -g postgres postgres 的指令创建用户和用户组。你应该避免使用 sudo,因为它不可预期的 TTY 和信号转发行为可能造成的问题比它能解决的问题还多。如果你真的需要和 sudo 类似的功能(例如,以 root 权限初始化某个守护进程,以非 root 权限执行它),你可以使用 gosu。最后,为了减少层数和复杂度,避免频繁地使用 USER 来回切换用户。 注意:在镜像中,用户和用户组每次被分配的 UID/GID 都是不确定的,下次重新构建镜像时被分配到的 UID/GID 可能会不一样。如果要依赖确定的 UID/GID,你应该显示的指定一个 UID/GID。编写.dockerignore文件.dockerignore 的作用和语法类似于 .gitignore,可以忽略一些不需要的文件,这样可以有效加快镜像构建时间,同时减少Docker镜像的大小。构建镜像时,Docker需要先准备context ,将所有需要的文件收集到进程中。默认的context包含Dockerfile目录中的所有文件,但是实际上,我们并不需要.git目录等内容。示例如下:.git/使用多阶段构建在 Docker 17.05 以上版本中,你可以使用多阶段构建来减少所构建镜像的大小。
-
本期【云享专家·微话题】由云享专家Tsjsdbd与大家一起讨论“容器与虚机,谁将主宰云世界”,希望大家能够畅所欲言。如果大家有其他任何与PaaS相关的问题,也可以在本帖回复直接咨询云享专家Tsjsdbd。 =======【云享专家·微话题】容器与虚机,谁将主宰云世界?=======如今Docker容器技术已经比较普及,在各个领域都开始发挥出价值。并且容器与虚拟机十分和谐的共存,两者各自具有不同的特征和相应适合的应用场景。然而,渐渐地你会发现在各个云基础设所涉及的领地,容器正在以它的角度重建这个世界,容器存储,容器网络,容器调度都全部长出自己的枝干。在实际的领域,容器也开始崭露头角,HPC,基因测序,边缘云,微服务等等。相信有一天,容器会与虚机平起平坐,然后在那之后,迅速超越,成为云计算的中流砥柱。Container will Rebuild the World。每个人对“容器与虚机”都有不一样的理解,今天我们就“容器与虚机”一起来讨论,希望看到大家精彩的评论:1、讲讲你在容器使用过程中存在的问题?2、讲讲容器技术如何在各个技术领域渐露头角?3、容器一直被诟病的薄弱点安全相关进展?4、你觉得容器是否和虚机的各自发展前景?微话题活动:参与本次微话题讨论,有机会获得优质评论奖活动时间:2018年7月16日-7月27日参与方式:直接在本帖回复你关于以上4个问题的理解或评论获奖方式:活动结束后,将由云享专家Tsjsdbd选取出3名优质评论奖,各送出《Docker 容器与容器云》书籍1本。
-
很多同学在使用镜像构建的时候可能对构建配置选项里的 “Dockerfile目录” 和 “自定义构建路径” 要怎么填感觉有点懵逼,这里给大家分享一点干货帮助大家正确地填写这两个配置项,让大家更好的使用镜像构建功能。 19455 以下图weathermap工程为例,Dockerfile位于工程的 weather/Dockerfile目录下,因此只需要在“Dockerfile目录”中填写weather/Dockerfile即可,记住一定要带上Dockerfile这个文件名哟。所以这里的填写方法就是以工程的跟目录为起始完整地填写Dockerfile的文件路径+文件名即可。 19457 那“自定义构建路径”要怎么填写呢,这里就得说到华为镜像构建一个很人性化的功能,我们平时自己在进行构建时一般会使用如下命令 docker build -t xxx/xxxx:xxx . (这个红色的点不是句号,这个红色的点不是句号,这个红色的点不是句号重要的事情说三遍) 那问题来了这个点到底是什么意思呢,这个点其实就是我们的构建路径,一般我们使用 . 表示在当前目录下进行构建,还是以上面那个工程为例,当你进入到weathermap的根目录的执行上述命令的时候 . 的含义就是 ./ 表示在当前工程的根目录进行构建,当你进入到Dockerfile所在的weather目录执行以上命令的时候 . 的路径其实就是 ./weather 是不是有些明白了,但是又有点糊涂了这个配置项的到底有什么作用呢? 再来举一个栗子···· 我写了一个Dockerfile, 里边有一行COPY run.sh /home/workspace 经常写Dockerfile的同学对这样的命令肯定一点都不陌生,它就是拷贝一个文件到容器的/home/workspace下,那它是从哪里拷呢?就是从我们上面说到的构建目录里去拷,如果我们还是采用上述命令,以 . 作为构建路径,那我们就必须要保证执行构建命令路径下有该文件,否则制作镜像就会失败。 华为的镜像构建默认都是在工程的根目录下进行构建的,但是我就是任性,我就是不一样的花火,我就是要把需要拷贝的文件放到Dockerfile所在的目录下,这个时候要怎么办呢?还是以weathermap工程为例,我们只需要把“自定义构建路径”填写成 /weather 这样就相当于我们进入到了weather 目录再进行构建,这样我们就可以拷贝 weather 目录下的文件了。 辣么...问题来了,华为的镜像构建为啥不直接进入到Dockerfile所在的目录再执行构建呢, 我说了我就是任性,我就是不一样的花火, 我现在就要把Dockerfile放到/weather 目录下,但是我还想要把被拷贝的run.sh 文件放到工程的根目录下,这个时候对华为的镜像构建而言一切也很简单,我们只需要和上面一样继续指定Dockerfile的目录为weather/Dockerfile 然后把 “自定义构建路径”填成 . (亦或 / 亦可不填), 就满足了这样的场景 所以 “自定义构建路径” 提供了一个更灵活的方式让大家去组合Dockerfile 和构建路径的关系。 PS: 有一点要补充的是,Dockerfile文件必须要在个构建路径之下, 这个要怎么解释呢,比如你的Dockerfile是放在 pathA/pathB/pathC/Dockerfile目录下那你的构建路径只能是 / 或 /pathA 或 /pathA/pathB 或 /pathA/pathB/pathC。 至于为什么要这样呢,这个就得去问问Docker了。。。
-
摘要:本文不讲晦涩难懂的概念、不讲实现原理、不讲内核机制,仅仅从搭建一个简单web应用的场景出发,讲讲如何复用docker完成我们开发过程中的一些日常事务,达到提升研发效率的目的。Docker自12年发布,经过几年的蛰伏,15,16年势头猛劲,在大量的企业得到的实施,尤其是在互联网、大数据相关领域更是势不可挡。然而,在一些传统行业、政府、事业机关、小企业中,Docker的使用率还是相对较低的,原因是多方面的,但其中很重要一个原因,源于对这些铺天盖地席卷而来的新技术的“恐惧”。企业发展到一定规模后,其技术架构、组织架构、研发模式基于已经稳定,新技采用势必会对现有组织、业务产生影响,而这种影响的好坏,早期是很难判断的,因此除了少数技术狂热派,一般都会比较谨慎,然而小的初创公司,又很难承担一次技术选型的失败,因此更愿意去采用生态相对成熟、实施过程能有较大容错空间的技术。但是经过这些年的市场的磨练,Docker其实已经成为了云计算领域的一员老将,技术栈、生态各方面已经得到完善。本次以部署一个简单的web应用为例,希望能给还徘徊在Docker门口的开发者、决策者们一些启发,如何利用Docker来简化日常研发工作、提升研发效率。本文所讲解示例如下图,是一个简化的web应用模型,包含了常用的组件,下面将详细讲解如何基于Docker快速完成整个环境的搭建和软件的部署。搭建MySQL数据库一行命令搞定!docker run –dti-e MYSQL_ROOT_PASSWORD=123456 mysql:5.7执行docker ps|grep mysql命令,能看到mysql的容器已经启动,比起下载、安装还有各种配置,够快吧。当然这样运行起来的MySQL,还没有办法供外部服务直接访问,,需要把容器内的服务开个通道,让外部服务通过宿主机的地址找到这个特殊通道,才能实现与外部服务的交互。在宿主机上执行netstat发现3306端口并未对外开放 把容器内的服务映射到宿主机上加上参数 -p 宿主机监听port:容器开放port,建立“通道”,这样当用户访问宿主机的port时,请求会自动发送到容器内对应的端口上docker run -dti -p 3306:3306 -eMYSQL_ROOT_PASSWORD=123456 --namemysql-service mysql:5.7加上端口映射后就可以通过宿主机访问了 对容器运行时产生的数据进行持久化因为每次执行docker run,相当于从指定镜像重新启动一台电脑,镜像是静态不变的,那么意味着,重启后之前运行时产生的数据会全部丢失,一切回归到初始状态,这个对数据库是致命的,如果不能持久化存储数据,也就失去了其意义,Docker也就不可能走到现在。在启动容器时,加上参数 -v 宿主机目录:容器内目录,即可将宿主机的目录mount到容器中,这样容器销毁时,宿主机目录的数据还在,重新启动容器,会继续从宿主机加载数据,借尸还魂,很机智。docker run -dti -p 3306:3306 -eMYSQL_ROOT_PASSWORD=123456 -v /usr1/mysql_data:/var/lib/mysql --name mysql-service mysql:5.7现在运行起来的MySQL就基本上已经能满足日常的需求了。当然,MySQL镜像本身还提供了强大的业务参数(这个是镜像制作者提供的,并非Docker提供),通过dockerrun的 -e 参数指定容器运行的环境变量(等价于Dockerfile里的ENV参数),实现相应的mysql能力,非常有用:MYSQL_ROOT_PASSWORD:指定root用户的密码MYSQL_USER: 新创建一个普通用户MYSQL_PASSWORD:新创建用户的密码MYSQL_DATABASE:新创建一个databaseMYSQL_ALLOW_EMPTY_PASSWORD:是允许无密码登陆想要使用时只需要通过加到命令行里即可,如:docker run -d -p 3306:3306 --namemysql-service -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_USER=visitor -eMYSQL_PASSWORD=visitor -e MYSQL_DATABASE=visitordb -eMYSQL_ALLOW_EMPTY_PASSWORD=true -v /usr1/mysql_data:/var/lib/mysql mysql:5.7这为我们制作业务镜像提供了一些参考,把部署、运行时所需要的变量,通过容器环境变量的方式传递给业务组件,当然业务组件也需要实现从这些约定好的变量里取值。使用定制的MySQL镜像,初始化数据当然,仅仅把MySQL启动起来大部分场景下是不够的,还需要创建业务需要的database、tables,有些时候可能还要导入一些初始的数据。接下来就讲一下,如何通过对官方镜像进行定制,实现在启动容器时,自动执行指定脚本,来创建表、初始化数据。定制镜像,就是基于官方的mysql镜像,加上一些脚本、修改一些权限,再统一打包到新的镜像里,在容器启动后自动执行这些脚本,做一些我们需要的业务操作。首先,我们以mysql:5.7作为基础镜像FROM mysql:5.7(语法:FROM 镜像名称:镜像版本号)然后,把需要在MySQL容器启动后执行的脚本拷贝到目录/docker-entrypoint-initdb.d下。(MySQL镜像启动后会扫描这个目录,然后自动执行里面的shell和sql脚本)COPY ./setup.sh/docker-entrypoint-initdb.d/setup.sh (语法:COPY 文件所在的主机路径:镜像中的绝对路径)接着,把setup.sh会引用到的其它文件,如shell,sql,config等,放到脚本中引用的目录下。(如果有多个脚本需要执行,都放在mysql指定目录下时,mysql并不知道脚本的执行先后顺序,因此一般是在mysql指定目录下放一个执行入口文件,在该文件中去按业务逻辑调用其它文件)COPY ./init.sql /myinfo/init.sql最后,在执行shell脚本时,希望root用户不输入密码就能登陆MySQL,这里需要按MySQL镜像的规范,设置一个环境变量:ENV MYSQL_ALLOW_EMPTY_PASSWORD yes(语法:ENV 环境变量名称 环境变量值)这样就生成了我们需要的Dockerfile文件执行 docker build . -t mysql:cust1就能生成我们自己的镜像了,后面加上参数-t就可以给生成的镜像打上标签,以便进行版本管理。运行该镜像的命令与最开始提到的一样,只是镜像的版本需要使用最新生成的mysql:cust1,这里不再赘述。上面MySQL的示例,涵盖了80%常用的docker制作和运行的指令和参数,这也就是我一直认为,Docker技术也许很高深,但使用确实很简单的原因。搭建tomcat,运行后台服务接下来按照制作MySQL镜像的方式,制作tomcat服务镜像,一个带有VisitorService应用的tomcat定制镜像,这里不再一步步讲解,直接把成品的Dockerfile拿出来给大家分享。FROM tomcat:7-jre8COPY ./VisitorService.war /usr/local/tomcat/webapps就是这么简单,两行搞定,思路和写MySQL的Dockerfile是一样的:1、先选择一个基础镜像:因为程序是基于JDK1.8开发的,所以选择了tomcat:7的jre1.8版本进行定制,具体还有哪些可用的镜像版本,可以在dockerhub官网查到2、然后把自定义的内容塞到镜像里:把编译好的war包拷贝到tomcat的webapps目录下,就像平时在自己测试机上操作一样。如果我们不想每次编译完war包都重新构建镜像,也可以用类似于MySQL目录映射的方法,在运行tomcat镜像时,把本地存放war包的路径,映射到容器的webapps目录下。3、设置环境变量:因为应用中会连接数据库,需要在启动容器时,把数据库信息加入到环境变量中,或在dockerfile中通过EVN参数设置,但因为值是会变的,直接写在dockerfile中,灵活性会差很多,因此我们采用了在启动时通过-e 的方式来设置,代码里已实现从环境变量获取这些信息。最终运行业务软件镜像容器的命令参考如下,命令行完成了目录映射、环境变量设置,并指定要启动的镜像版本:docker run -p 9999:8080 -v 本地目录/war文件:/usr/local/tomcat/webapps/xxx.war-eMYSQL_ADDR=mysql_ip:3306 -e MYSQL_DB=visitordb -e MYSQL_USER=visitor -eMYSQL_PWD=visitor -dti tomcat:7-jre8搭建nginx,运行静态web服务与Tomcat类似,也是有两种方法一种是,把需要部署在Nginx上的文件,以及配置打包到镜像中:FROM nginx:v2COPY ./index.html /usr/visitor/index.htmlCOPY ./visitor.conf/etc/nginx/conf.d/visitor.conf另一种是,从本地目录映射:docker run -p 80:80 -v 本地目录/xx.conf:/etc/nginx/conf.d/xx.conf -v本地目录:容器目录-dti nginx搭建并运行Redis服务因为只是存取一些缓存数据,因此不考虑对容器内的数据做持久化,直接放在容器里,因此这里不对redis镜像做任何改造,直接使用。docker run –p 6379:6379 –dti redis:2.8.23大功告成好了,一套简易的web应用环境就搭好了,下面就是最终效果我们来对比一下Docker帮我们提升了多少效率:环境搭建效率提升明显 说实话,以前搭环境最怕的就是像Nginx这种,下完还要编译之后才能运行的,一旦报错,那真是对耐性的考验。现在好了,一个Dockerfile,加docker build,docker run两个命令,轻轻松松搞定环境的搭建,以前这些困难全没了。最关键的是,日常研发过程中,搭建3至5套环境是最基本的要求了,使用编写好的Dockerfile,可以让我们快速完成各种TEST/QA/STAGE环境、Demo演示环境的搭建与复制,而不需要为拷贝动辄几十G的安装包而苦恼,也不会因为各各环境操作系统版本的差异而痛苦,着实为我们省了不少时间和精力。后记正因为Docker这么火,所有的公有云厂商不约而同的都提供了容器服务,这进一步降低了用户的使用门槛,让企业用户无需关心日常运维、问题处理、版本升级、技术演进等纷繁复杂的事务,使用户更专注于自身业务竞争力的提升。华为云提供的容器服务包括云容器引擎服务(CCE)和云容器实例服务(CCI),围绕着云容器,还提供了镜像管理、应用编排、应用运维管理、微服务管理、云中间件等一系列构建容器化应用生态所需的配套服务,并在兼容社区的基础上,针对游戏、电商、基因等行业,对容器的网络性能、计算性能、存储性能、安全等方面进行了优化,能满足广大用户CI/CD、自动化运维、秒级弹性伸缩、高并发低时延、高性能运算的诉求。赶紧点击下面的链接来体验一下吧:华为云容器引擎:https://console.huaweicloud.com/cce2.0/华为云容器实例:https://console.huaweicloud.com/cci/
-
华为云docker镜像加速何时启用?
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签