Docker是什么?
如官网所述,Docker是一个平台。可以在这个平台上开发、迁移和运行app应用。Docker它能够将你的应用从你的基础设施(硬件、操作系统)中分离,从而让你可以更加快速的部署、安装软件。
是不是有点抽象?来个对比就比较清晰了,首先介绍下VM(虚拟机),典型的就是在Windows系统上通过安装VMware虚拟出来的虚拟机(它可以是Linux虚拟机或Windows虚拟机)。当然也可以不依托操作系统,直接在硬件上安装VMware ESXi,在其上虚拟机器也可以,而且性能更高。虚拟机的结构图如下:

Hypervisor,又称虚拟机监视器(英语:virtual machine monitor,缩写为 VMM)
通俗的讲,虚拟机,就是在你的操作系统里面,装一个软件,然后通过这个软件,再模拟一台甚至多台“子电脑”出来。在“子电脑”里,你可以和正常电脑一样运行程序,例如开QQ。如果你愿意,你可以变出好几个“子电脑”,里面都开上QQ。“子电脑”和“子电脑”之间,是相互隔离的,互不影响。
虚拟机的应用还可以用来游戏的多开和挂机,我之前在打LOL的时候,曾经在淘宝上购买过挂金币的脚本,它是通过模拟键盘和鼠标来实现挂机。所以,如果直接用你的主操作系统挂机,那么挂机的时候你的鼠标和键盘就会被脚本控制,就不能用了,所以我当时用vmware搞了很多台虚拟机,然后在每个虚拟机上装一个LOL客户端,就这样挂了很多小号,打了很多金币。搞好后虚拟机就挂在后台运行,我的主操作系统想干点别的事还是可以干的。
但由于一般情况下,虚拟出一台机器,需要安装某个操作系统的镜像,就相当于你装一台全新的Windows机器,比较费时费力。所以为了更轻便的进行项目部署,Docker出现了,它直接在操作系统上封装一层,可以直接在操作系统上拉取已经安装好MySQL或JDK的Docker、甚至已经部署好你的应用的Docker下来,免去再次安装部署的麻烦。Docker包含如下:

Docker的结构和组成
Docker使用的是CS的架构。它包括Docker client客户端、Docker daemon进程、Docker registries仓库、Docker objects对象(包括镜像、容器、服务)。客户端和进程之间使用REST API, over UNIX sockets or a network interface进行通讯。

Client和Docker daemon交互,Images是静态的,运行时要成为Containers。
Docker的安装
Windows和Mac都是用客户端的,Linux可以参照官方文档进行安装。
Docker指令
- #查看docker版本
- docker --version
- #搜索镜像
- [root@daguanren ~]# docker search hello-world
- NAME DESCRIPTION STARS OFFICIAL AUTOMATED
- hello-world Hello World! (an example of minimal Dockeriz… 1162 [OK]
- kitematic/hello-world-nginx A light-weight nginx container that demonstr… 141
- tutum/hello-world Image to test docker deployments. Has Apache… 70 [OK]
- dockercloud/hello-world Hello World! 19 [OK]
- crccheck/hello-world Hello World web server in under 2.5 MB 12 [OK]
- vad1mo/hello-world-rest A simple REST Service that echoes back all t… 4 [OK]
- ppc64le/hello-world Hello World! (an example of minimal Dockeriz… 2
routeros
- #拉取镜像
- docker pull hello-world
- #运行镜像(如果没有,会从库中拉取后运行)
- $ docker run hello-world
- Unable to find image 'hello-world:latest' locally
- latest: Pulling from library/hello-world
- ca4f61b1923c: Pull complete
- Digest: sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7
- Status: Downloaded newer image for hello-world:latest
- Hello from Docker!
- This message shows that your installation appears to be working correctly.
- ...
routeros
- #查看容器
- $ docker ps --all
- CONTAINER ID IMAGE COMMAND CREATED STATUS
- 54f4984ed6a8 hello-world "/hello" 20 seconds ago Exited (0) 19 seconds ago
livecodeserver
- #删除镜像
- docker rmi hello-world
- #删除容器
- docker rm 8492b
- #停止容器
- docker stop 8492b
- #批量停止容器
- docker stop $(docker ps -a -q)
- #批量删除容器
- docker rm $(docker ps -a -q)
- #强制删除容器
- docker rm -f 8492b
properties
- # 暂停容器
- docker pause 8492b
- docker unpause 8492b
- # 杀死容器
- docker kill 35
- # 启动容器
- docker start 35
- # 重启容器
- docker restart 35
properties
- #进入容器方式1
- docker attach 54f4984ed6a8
- #不关闭退出容器
- ctrl+p+q
- # 进入容器方式2
- docker exec -it 69d1 bash
docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。
只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。
当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。
容器可以直接打包成tar文件,也可以先转成镜像,再打包成tar文件。如下图的容器状态转换示意图所示:

- #镜像打包成tar文件
- docker save b3_9a>box.tar
- #将tar文件加载成镜像
- docker load <box.tar
gauss
- #镜像改名
- docker tag b3_9a haodalong/test:0.2
- # 将container直接export导出成tar包
- docker export 6b > 6b.tar
- # 将归档文件导入image
- cat 6b.tar | docker import - 6b:0.1
- # 启动容器
- docker run -itd --name b2 6b:0.1 /bin/sh
angelscript
- #将容器提交成镜像(可以将任意状态的容器提交,保留对容器的操作)
- docker commit -a dalong node-test haodalong/nodetest:0.1
- #将镜像推送到仓库
- docker push haodalong/test:0.2
- [root@daguanren ~]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- haodalong/nodetest 0.1 c6770438af9a 19 hours ago 943MB
- haodalong/test 0.2 07f237e268b1 21 hours ago 1.22MB
- b3_9a latest 07f237e268b1 21 hours ago 1.22MB
- hello-world latest fce289e99eb9 15 months ago 1.84kB
- [root@daguanren ~]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- #长久运行容器
- [root@daguanren ~]# docker run -itd --name new b3_9a
- 0739fb3d8c2964a2c5229c0f2a476d470dea9f81099261fd3c4ac49b5cdb4d12
- [root@daguanren ~]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 0739fb3d8c29 b3_9a "sh" About a minute ago Up About a minute new
angelscript
- #容器内外文件的拷入拷出
- [root@daguanren ~]# docker cp --help
- Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
- docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
- docker cp a.out node-test:/
- docker cp node-test:/214.txt ./
crmsh

- #事件监控,操作记录展示
- docker events
- # 堵塞住容器直到容器停止
- docker wait 74
- #获取容器/镜像的元数据
- docker inspect node
- # 查看镜像的历史
- docker history 54
- # 返回docker对象的底层信息(容器和镜像适用)
- docker inspect 54
properties
- #容器操作日志查询
- [root@daguanren ~]# docker logs -t node-test
- 2020-04-07T06:53:13.531765725Z Welcome to Node.js v13.10.1.
- 2020-04-07T06:53:13.531810036Z Type ".help" for more information.
- > ls
- 2020-04-07T06:53:26.528358471Z Uncaught ReferenceError: ls is not defined
- > pwd
- 2020-04-07T06:53:35.336256305Z Uncaught ReferenceError: pwd is not defined
- > node -v
- 2020-04-07T06:53:37.664385134Z Uncaught ReferenceError: node is not defined
- > console
- > console
- > console.log(123);
- 2020-04-07T06:54:12.821895518Z 123
- 2020-04-07T06:54:12.821901133Z undefined
- > npm
- 2020-04-07T06:54:17.972029856Z Uncaught ReferenceError: npm is not defined
angelscript
- # docker update可以对容器进行设置,包括内存等
- #设置容器内存限制大小
- docker update -m 1024m --memory-swap -1 node-test
- #监控性能参数状态
- docker stats
- # 查看容器的运行状况和修改状态
- docker top 74
- docker diff 74
properties
- #运行容器,并且映射端口,从8888映射到外部的1126
- docker run -itd -p 1126:8888 --name nodetest2 c6
docker build 和 dockerfile,请参照官方文档。
docker build -t haodalong/nodetest:0.1 www.daguanren.cc/dockerfile
- #通过cli远程连接docker进行管理
- docker -H 192.168.1.23:1126 ps -a
- #查看docker日志
- docker logs 94665cc5552e --tail=100
- # 实时查看日志
- docker logs -f -t 74
properties
如果有docker-compose.yml,可以通过该文件指定docker容器配置:
- # 停止
- docker-compose down
- # 启动
- docker-compose up -d
vala
实际业务中,我用到了如下的容易构建语句:
- #qaqc_calc
- #buildqaqc_calc项目docker镜像
- docker build -t qaqc-calc-image -f /home/services/release/qaqc_calc/Dockerfile /home/services/release/qaqc_calc
- #启动qaqc-calc-container容器,容器内818端口映射系统905端口
- docker run -d --name qaqc-calc-container -p 905:818 -e TZ=Asia/Shanghai qaqc-calc-image
arduino
如果我想更改代码,我该如何让docker的此容器服务生效呢?
之后再重新启动容器:
- docker run -d --name qaqc-calc-container -p 9005:8184 -e TZ=Asia/Shanghai qaqc-calc-image
在某些情况下,你可能希望在不重新构建镜像的情况下修改运行中的容器的代码。这通常可以通过将你的代码作为数据卷(volume)或绑定挂载(bind mount)到容器中来实现。然而,请注意这种做法可能会使你的容器的行为依赖于你的主机的文件系统,可能会增加复杂性和错误的风险。此外,这种做法也可能不适用于所有的应用,取决于你的应用如何加载和执行代码。
参考文档:
https://docs.docker.com/engine/docker-overview/
https://www.runoob.com/docker/docker-exec-command.html
https://www.runoob.com/nodejs/nodejs-http-server.html
https://zhuanlan.zhihu.com/p/53260098
https://beginor.github.io/2017/06/08/use-compose-instead-of-run.html
Comments