在运输行业,大家在运输货物的时候,需要将货物搬到码头卸货,码头货物再搬到轮船等等。在卸货,搬运的过程中,材料经过了多次的损坏,效益变得非常的差。
后来随着时代发展,吊车等机械的出现,集装箱开始得到使用,让搬运只需要放到集装箱中,而不需要再去对货物的多次拆,装。大大的减少了货物在过程中的损失。
随着计算机的发展,同样出现了软件中的集装箱(容器),Docker。
image-20220126141634070总结自cloudman《每天5分钟玩转Docker容器技术》 公众号搜索cloudman
概述
容器技术鸟瞰
image-20220213193040595核心内容
image-20220125114727699-
容器规范 容器不光是Docker,还有其他容器,比如CoreOS的rkt。为了保证容器生态的健康发展,保证不同容器之间能够兼容,包含Docker、CoreOS、Google在内的若干公司共同成立了一个叫Open Container Initiative(OCI)的组织,其目的是制定开放的容器规范。目前OCI发布了两个规范:
runtime spec
和image format spec
。有了这两个规范,不同组织和厂商开发的容器能够在不同的runtime上运行。这样就保证了容器的可移植性和互操作性。
-
容器runtime
image-20220125115334619容器需要运行在runtime上。
就像java程序需要运行在JVM上一样。
docker之前使用lxc,后来使用自己开发的runc作为runtime,符合oci规范,现在是默认的runtime。
rkt是senOS开发的runtime,也符合oci,docker也同样适用。
-
容器管理工具
image-20220213192851395光有runtime还不够,用户得有工具来管理容器。
就想JVM支持命令来启动java程序,每个runtime也支持命令来操作docker。
runc的管理工具是
docker engine
。docker engine包含后台deamon
和cli
两个部分。我们通常提到Docker,一般就是指的docker engine。rkt的管理工具是rkt cli。
-
容器定义工具
image-20220213192940990容器需要被保存和共享,所以需要工具。
docker image是Docker容器的模板,runtime依据docker image创建容器。
dockerfile是包含若干命令的文本文件,可以通过这些命令创建出docker image。
ACI(App Container Image)与docker image类似,只不过它是由CoreOS开发的rkt容器的image格式。
-
仓库
容器在保存之后,需要存储下来,所以使用仓库。
image-20220125134830014常用:容器是通过image创建的,需要有一个仓库来统一存放image,这个仓库就叫做Registry。企业可以用Docker Registry构建私有的Registry,
如Docker Hub(https://hub.docker.com)是Docker为公众提供的托管Registry,上面有很多现成的image,为Docker用户提供了极大的便利。
Quay.io(https://quay.io/)是另一个公共托管Registry,提供与Docker Hub类似的服务
-
容器OS 专门运行容器的操作系统。
比常规的linux运行容器更快。
容器平台
容器核心技术能够让容器在一台服务器上运行。
容器平台能够统一管理多个服务器上,分布式部署的容器。
image-20220213193200394-
编排引擎
提供容器运行上根据资源自动分配,自动重启容器等等。
docker swarm
是Docker开发的容器编排引擎。kubernetes
是Google领导开发的开源容器编排引擎,同时支持Docker和CoreOS容器。mesos
是一个通用的集群资源调度平台,mesos与marathon一起提供容器编排引擎功能。 -
容器管理平台
方便容器更简单的在可视化界面使用。
容器管理平台是架构在容器编排引擎之上的一个更为通用的平台。通常容器管理平台能够支持多种编排引擎,抽象了编排引擎的底层实现细节,为用户提供更方便的功能,比如application catalog和一键应用部署等。
Rancher
和ContainerShip
是容器管理平台的典型代表 -
基于容器的PaaS
基于容器的PaaS为微服务应用开发人员和公司提供了开发、部署和管理应用的平台,使用户不必关心底层基础设施而专注于应用的开发。Deis、Flynn和Dokku都是开源容器PaaS的代表
容器支持技术
image-20220125142540941-
容器网络
容器的网络和拓扑变得更加复杂。
所以需要容器和容器,容器和其他服务的网络交互解决方案。
docker network
是Docker原生的网络解决方案。除此之外,我们还可以采用第三方开源解决方案,例如fannel、weave和calico。不同方案的设计和实现方式不同,各有优势和特点,应根据实际需要来选型,
-
服务发现
动态变化是微服务应用的一大特点。
当负载增加时,集群会自动创建新的容器
;负载减小,多余的容器会被销毁
。容器也会根据host的资源使用情况在不同host中迁移,容器的IP和端口也会随之发生变化。etcd
、consul
和zookeeper
是服务发现的典型解决方案 -
监控
docker ps/top/stats是Docker原生的命令行监控工具。
除了命令行,Docker也提供了stats API,用户可以通过HTTP请求获取容器的状态信息。
sysdig、cAdvisor/Heapster和Weave Scope是其他开源的容器监控方案。
-
数据管理
容器经常会在不同的host之间迁移,如何保证持久化数据也能够动态迁移,是Rex-Ray这类数据管理工具提供的能力。
-
日志管理
docker logs是Docker原生的日志工具。
而logspout对日志提供了路由功能,它可以收集不同容器的日志并转发给其他工具进行后处理。
-
安全性
OpenSCAP能够对容器镜像进行扫描,发现潜在的漏洞。
容器技术
虚拟机启动内核引导bootfs特别慢 docker 使用操作系统的内核 只需要加载只包含简单的命令rootfs快很多 image-20220126141410654架构
Docker的核心组件包括:
● Docker客户端:Client
● Docker服务器:Docker daemon
● Docker镜像:Image
● Registry
● Docker容器:Container
image-20220126143622424Docker采用的是Client/Server架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器可以运行在同一个Host上,客户端也可以通过socket或REST API与远程的服务器通信。
-
Client
docker客户端提供了丰富api给我们管理使用。
也可以通过restful api使用。
-
Docker host
-
Docker daemon 是真正负责干活的打工人。
负责创建、运行、监控容器,构建、存储镜像。
如果要允许远程客户端请求,需要在配置文件中打开TCP监听。
-
Images 是打好包的模版
可以把自己的集装箱放上去作为模版给人用。
也可以拉下别人的模版自己修改在使用。
-
Docker容器
容器就是真正在跑的实例。
可以通过CLI的api对docker容器进行启动,停止。
-
-
Registry
存放模版的地方。
企业可以搭建自己的参考。
docker run -d -p 80:80 docker/getting-started
#(1)Docker客户端执行docker run命令。
#(2)Docker daemon发现本地没有getting-started镜像。
#(3)daemon从Docker Hub下载镜像。
#(4)下载完成,镜像httpd被保存到本地。
#(5)Docker daemon启动容器。
Docker镜像
内部结构
因为对于一个镜像来说Host的kernel,自己只需要提供rootfs就行。所以能够做到占用存储特别低。
加上新镜像都是在base镜像上不断累加的,非常节省资源。
要注意的是,每个容器中虽然也有/etc这些路径,但是对于在里面修改的东西,只在自己的容器,对底层共享的东西,只读不可写。
image-20220126153323393构造镜像
一般使用镜像有两种场景:
- 常用软件,nginx,mysql这种,直接去网上仓库直接拉取。
- 企业使用的镜像,需要自己拉下来更改然后发布到企业仓库。
docker commit
最直观的是三步:
- 去网上拉取个镜像
- 启动容器,在里面修修改改
- 修改后的容器打成镜像,发布上去
#运行一个容器
docker run -it ubuntu
#测试一下 是不是没有安装vim
vim
#报错 找不到vim
#安装vim
apt-get install -y vim
#如果下载不了 改一下镜像源
cat >/etc/apt/sources.list <<EOF
deb http://deb.debian.org/debian buster main
deb http://security.debian.org/debian-security buster/updates main
deb http://deb.debian.org/debian buster-updates main
EOF
#退出镜像
Ctrl+P+Q 或者exit
#查看新的镜像
docker ps
#提交容器变为新的镜像
docker commit xxx new-with-vim
#查看新的镜像 比旧的内存更大
docker images
#进入新的镜像 发现已经安装了vim
docker run -it new-with-vim
不推荐commit来构建镜像
,因为没有很好的知道镜像到底经历过什么,而且也不知道是不是有恶意程序。但是其他方式的底层,也都是commit,只不过封装得更好
Dockerfile
Dockerfile是一个文本文件,记录了镜像构建的所有步骤。记录了镜像的一生,减少了重复劳动,减少了风险。
基本流程
image-20220213110547580#拉取 ubuntu
FROM ubuntu
#安装vim
RUN apt-get update && apt-get install -y vim
① 当前目录为 /root。
②运行命令的该路径下 Dockerfile准备就绪(也可以去docker hub上搜索复制)。
③ docker build -t ubt-with-vim-dockerfile .
运行docker build命令,-t将新镜像命名为ubuntu-with-vi-dockerfile,命令末尾的.
指明build context为当前目录。Docker默认会从build context中查找Dockerfile文件,然后根据这个文件镜像运行,我们也可以通过-f参数指定Dockerfile的位置。
④ 从这步开始就是镜像真正的构建过程。首先Docker将buildcontext中的所有文件发送给Docker daemon。build context为镜像构建提供所需要的文件或目录。Dockerfile中的ADD、COPY等命令可以将build context中的文件添加到镜像。此例中,build context为当前目录 /root,该目录下的所有文件和子目录都会被发送给Dockerdaemon。所以,使用build context就得小心了,不要将多余文件放到build context,特别不要把 /、/usr作为build context,否则构建过程会相当缓慢甚至失败。
⑤ Step 1:执行FROM,将Ubuntu作为base镜像。Ubuntu镜像ID为f753707788c5。
⑥ Step 2:执行RUN,安装vim,具体步骤为 ⑦ ⑧ ⑨。
⑦ 启动ID为9f4d4166f7e3的临时容器,在容器中通过apt-get安装vim。
⑧ 安装成功后,将容器保存为镜像,其ID为35ca89798937。这一步底层使用的是类似docker commit的命令。
⑨ 删除临时容器9f4d4166f7e3。
⑩ 镜像构建成功。
#查看生成镜像的历史
#能看到在过程中运行了哪些命令安装了些什么
#在构建时 遇到已经构建过的会缓存起来 减少重复劳动
docker history ubuntu
注:missing表示无法获取IMAGE ID,通常从Docker Hub下载的镜像会有这个问题。
构建过程:
- 从base镜像运行一个容器
- 执行指令修改容器
- 执行类似docker commit生成新的镜像
- 基于刚提交的镜像再运行一个容器
- 重复2-4知道所有执行执行完
这样在任何一次2-4失败后,我们能得到前一个镜像,更好的分析问题。
比如构建时,两步中第二步出错了,可以查看日志,修改第二部的dockerfile来调整。
image-20220213113035158常用语法
-
FROM
#base 镜像为nginx FROM nginx
-
MAINTAINER
#镜像作者为xxx MAINTAINER r4441
-
COPY
#src只能指定build context中的文件或者目录(docker build命令执行路径) COPY info.log /var/log/info #写法2 COPY ["info.log","/var/log/info"]
-
ADD
#命令支持添加本地的tar压缩包到容器中指定目录,压缩包(tar、zip、tgz、xz等)会被自动解压为dest目录,也可以自动下载URL并拷贝到镜像,例如: #将目录下的tar文件放入容器的/var/data ADD html.tar /var/data ADD http://www.shiyanlou.com/html.tar /var/www
-
ENV
#容器host name ENV HOSTNAME shiyanloutest #设置环境变了 ENV APACHE_RUN_USER www-data ENV APACHE_RUN_GROUP www-data ENV APACHE_LOG_DIR /var/log/apche2
-
EXPOSE
#容器暴露出端口 EXPOSE 80
-
VOLUME
#文件或者目录声明为xxx #例如:指定输出日志到宿主机的xxx VOLUME ["/var/log"]
-
WORKDIR
#为后面的RUN、CMD、ENTRYPOINT、ADD或COPY指令设置镜像中的当前工作目录。 WORKDIR /var/data/html
-
RUN
#在容器中运行指定命令 #执行命令并创建新的镜像层,RUN经常用于安装软件包。 #更新apt-get 安装vim -yqq自动yes RUN apt-get update && apt-get install -yqq vim #递归创建文件夹 RUN mkdir -vp /var/log/info
-
CMD
#在容器中运行指定命令 #设置容器启动后默认执行的命令及其参数 #Dockerfile中可以有多个CMD指令,但只有最后一个生效。CMD可以被docker run之后的参数替换。默认在/bin/sh中执行 #容器启动 = CMD /usr/sbin/apache2ctl -D FOREGROUND CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
-
ENTRYPOINT
#在容器中运行指定命令 #配置容器启动时运行的命令 #Dockerfile中可以有多个ENTRYPOINT指令,但只有最后一个生效。 #CMD或docker run之后的参数会被当作参数传递给ENTRYPOINT ENTRYPOINT /bin/sh echo $JAVA_HOME #注意 Exec写法需要加上-c $才生效 ENTRYPOINT ["bin/sh","-c","echo $JAVA_HOME"]
使用镜像
这里有几种可用的方法:
(1)用相同的Dockerfile在其他host构建镜像。
(2)将镜像上传到公共Registry(比如Docker Hub), Host直接下载使用。
(3)搭建私有的Registry供本地Host使用。
#docker build -t 镜像名:版本/tag(default:latest)
docker build -t nginx-with-vim(:latest)
#打tag 为版本 1,1.9,1.9.2,latest更新镜像
docker tag myimage-v1.9.2 myimage:1
docker tag myimage-v1.9.2 myimage:1.9
docker tag myimage-v1.9.2 myimage:1.9.2
docker tag myimage-v1.9.2 myimage:latest
Docker Hub
切记自己玩docker的时候不要把公司代码放到docker hub去了
#build 一定要将docker hub的docker-id加在前面
docker build -t docker-id/nginx-with-vim(:latest)
#add tag for image
docker tag my-docker-image-1.0 my-docker-image:1.0
#login docker hub
docker login -u docker-username
#push docker images
docker push my-docker-image:1.0
Registry
#-d 后台启动 down
#-p 映射容器内端口到服务器 port
#-v 将 服务器a端口 映射到容器内部b端口
#获取仓库的镜像 并启动
docker run -d -p 5000:5000 -v /Users/a1234/docker/myregistry:/var/lib/registry registry:2
#host 已经加入127.0.0.1 localhost registry
#给镜像打个tag [registry-host]:[port]/[username]/xxx:[version]
docker tag opop32165455/simple-web:1.0 registry:5000/opop32165455/simple-web:1.0
#push 到本地仓库
docker push registry:5000/opop32165455/simple-web
#查看本地仓库是否有images了
docker images registry:5000/opop32165455/simple-web
Docker命令
#重启docker
systemctl daemon-reload
systeamctl restart docker
#info version
docker version
docker info
container
container
#容器
image
#镜像
exp
#例子
attach
#vt. 使依附;贴上;系上;使依恋
#vi. 附加;附属;伴随
official
#adj. 官方的;正式的;公务的
#n. 官员;公务员;高级职员
#运行容器(自动拉取镜像) 启动并进入
docker run -i -t <iamges name> /bin/bash
exp:docker run -i -t ubuntu /bin/bash
#使用端口
docker run -i -t <iamges name> /bin/bash -p 8080
docker run -i -t <iamges name> /bin/bash -p 8080:8080 #使用并映射端口 主机端口:容器端口
#跑shell脚本
docker run -d <iamges name/id> /bin/sh -c "while true;do echo hello world;sleep1;done"
#所有运行中容器
docker ps
#所有容器
docker ps -a
#附着(进入)容器
docker attach <container id/name>
#进入容器
docker exec -it <container id/name> /bin/bash
#退出并停止容器(在容器内部)
exit
#退出不停止容器
Ctrl+P+Q
#控制容器(外部)
docker start/stop/.. <container id/name>
#后台运行容器 不进入
docker run -d
#查看容器日志
docker logs <container id/name>
#查看容器详细信息
docker inspect <container id/name>
#查看容器运行状态
docker inspect --format='{{ .State.Running}}' <container id/name>
#查看容器的IP的地址
docker inspect --format='{{ .NetworkSettings.IPAddress}}' <container id/name>
#查看容器日志
docker run -tf --tail 100 <iamges name/id>
#查看容器进程
docker top <contain id>
#删除容器
docker rm <container id/name>
images
#拉取镜像
docker pull <images name>
exp:docker pull ubuntu
#查看镜像
docker iamges
#搜索镜像
docker search <images name>
#登录docker
docker login
#镜像创建容器
docker run -i -t <iamges name> /bin/bash
#安装软件(已经在容器中/attach进容器)
apt-get -yqq update //静默安装
apt-get -y install <soft name(exp:apache2)>
#删除容器
docker rmi -f <soft name(exp:apache2)>
网友评论