代码开发完之后,要经过构建,把产物部署到服务器上跑起来,这样才能被用户访问到。
不同的代码需要不同的环境,比如 JS 代码的构建需要 node 环境,Java 代码 需要 JVM 环境,一般我们会把它们隔离开来单独部署。
现在一台物理主机的性能是很高的,完全可以同时跑很多个服务,而我们又有环境隔离的需求,所以会用虚拟化技术把一台物理主机变为多台虚拟主机来用。
现在主流的虚拟化技术就是 docker 了,它是基于容器的虚拟化技术。
它可以在一台机器上跑多个容器,每个容器都有独立的操作系统环境,比如文件系统、网络端口等。
这也是为什么它的 logo 是这样的:
那它是怎么实现的这种隔离的容器呢?
这就依赖操作系统的机制了:
linix 提供了一种叫 namespace 的机制,可以给进程、用户、网络等分配一个命名空间,这个命名空间下的资源都是独立命名的。
比如 PID namespace,也就是进程的命名空间,它会使命名空间内的这个进程 id 变为 1,而 linux 的初始进程的 id 就是 1,所以这个命名空间内它就是所有进程的父进程了。
而 IPC namespace 能限制只有这个 namespace 内的进程可以相互通信,不能和 namespace 外的进程通信。
Mount namespace 会创建一个新的文件系统,namespace 内的文件访问都是在这个文件系统之上。
类似这样的 namespace 一共有 6 种:
通过这 6 种命名空间,Docker 就实现了资源的隔离。
但是只有命名空间的隔离还不够,这样还是有问题的,比如如果一个容器占用了太多的资源,那就会导致别的容器受影响。
怎么能限制容器的资源访问呢?
这就需要 linux 操作系统的另一种机制:Control Group。
创建一个 Control Group 可以给它指定参数,比如 cpu 用多少、内存用多少、磁盘用多少,然后加到这个组里的进程就会受到这个限制。
这样,创建容器的时候先创建一个 Control Group,指定资源的限制,然后把容器进程加到这个 Control Group 里,就不会有容器占用过多资源的问题了。
那这样就完美了么?
其实还有一个问题:每个容器都是独立的文件系统,相互独立,而这些文件系统之间可能很大部分都是一样的,同样的内容占据了很大的磁盘空间,会导致浪费。
那怎么解决这个问题呢?
Docker 设计了一种分层机制:
每一层都是不可修改的,也叫做镜像。那要修改怎么办呢?
会创建一个新的层,在这一层做修改
然后通过一种叫做 UnionFS 的机制把这些层合并起来,变成一个文件系统:
这样如果有多个容器内做了文件修改,只要创建不同的层即可,底层的基础镜像是一样的。
Docker 通过这种分层的镜像存储,写时复制的机制,极大的减少了文件系统的磁盘占用。
而且这种镜像是可以复用的,上传到镜像仓库,别人拉下来也可以直接用。
比如下面这张 Docker 架构图:
docker 文件系统的内容是通过镜像的方式存储的,可以上传到 registry 仓库。docker pull 拉下来之后经过 docker run 就可以跑起来。
回顾一下 Docker 实现原理的三大基础技术:
都是缺一不可的。
上图中还有个 docker build 是干啥的呢?
一般我们生成镜像都是通过 dockerfile 来描述的。
比如这样:
FROM node:10
WORKDIR /app
COPY . /app
EXPOSE 8080
RUN npm install http-server -g
RUN npm install && npm run build
CMD http-server ./dist
Dokcer 是分层存储的,修改的时候会创建一个新的层,所以这里的每一行都会创建一个新的层。
这些指令的含义如下:
上面这个 dockerfile 的作用不难看出来,就是在 node 环境下,把项目复制过去,执行依赖安装和构建。
我们通过 docker build 就可以根据这个 dockerfile 来生成镜像。
然后执行 docker run 把这个镜像跑起来,这时候就会执行 http-server ./dist 来启动服务。
这个就是一个 docker 跑 node 静态服务的例子。
但其实这个例子不是很好,从上面流程的描述我们可以看出来,构建的过程只是为了拿到产物,容器运行的时候就不再需要了。
那能不能把构建分到一个镜像里,然后把产物赋值到另一个镜像,这样单独跑产物呢?
确实可以,而且这也是推荐的用法。
那岂不是要 build 写一个 dockerfile,run 写一个 dockerfile 吗?
也不用,docker 支持多阶段构建,比如这样:
# build stage
FROM node:10 AS build_image
WORKDIR /app
COPY . /app
EXPOSE 8080
RUN npm install && npm run build
# production stage
FROM node:10
WORKDIR /app
COPY --from=build_image /app/dist ./dist
RUN npm i -g http-server
CMD http-server ./dist
我们把两个镜像的生成过程写到了一个 dockerfile 里,这是 docker 支持的多阶段构建。
第一个 FROM 里我们写了 as build_image,这是把第一个镜像命名为 build_image。
后面第二个镜像 COPY 的时候就可以指定 --from=build_image 来从那个镜像复制内容了。
这样,最终只会留下第二个镜像,这个镜像里只有生产环境需要的依赖,体积更小。传输速度、运行速度也会更快。
构建镜像和运行镜像分离,这个算是一种最佳实践了。
一般我们都是在 jenkins 里跑,push 代码的时候,通过 web hooks 触发 jenkins 构建,最终产生运行时的镜像,上传到 registry。
部署的时候把这个镜像 docker pull 下来,然后 docker run 就完成了部署。
node 项目的 dockerfile 大概怎么写我们知道了,那前端项目呢?
大概是这样的:
# build stage
FROM node:14.15.0 as build-stage
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-perl as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY --from=build-stage /app/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
也是 build 阶段通过一个镜像做构建,然后再制作一个镜像把产物复制过去,然后用 nginx 跑一个静态服务。
一般公司内部署前端项目都是这样的。
不过也不一定。
因为公司部署前端代码的服务是作为 CDN 的源站服务器的,CDN 会从这里取文件,然后在各地区的缓存服务器缓存下来。
而阿里云这种云服务厂商都提供了对象存储服务,可以直接把静态文件上传到 oss,根本不用自己部署:
但是,如果是内部的网站,或者私有部署之类的,还是要用 docker 部署的。
Docker 是一种虚拟化技术,通过容器的方式,它的实现原理依赖 linux 的 Namespace、Control Group、UnionFS 这三种机制。
Namespace 做资源隔离,Control Group 做容器的资源限制,UnionFS 做文件系统的镜像存储、写时复制、镜像合并。
一般我们是通过 dockerfile 描述镜像构建的过程,然后通过 docker build 构建出镜像,上传到 registry。
镜像通过 docker run 就可以跑起来,对外提供服务。
用 dockerfile 做部署的最佳实践是分阶段构建,build 阶段单独生成一个镜像,然后把产物复制到另一个镜像,把这个镜像上传 registry。
这样镜像是最小的,传输速度、运行速度都比较快。
前端、node 的代码都可以用 docker 部署,前端代码的静态服务还要作为 CDN 的源站服务器,不过我们也不一定要自己部署,很可能直接用阿里云的 OSS 对象存储服务了。
理解了 Docker 的实现原理,知道了怎么写 dockerfile 还有 dockerfile 的分阶段构建,就可以应付大多数前端部署需求了。
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/DbCyFkKRd2WCiJRtXlZ2kw
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。