04月07, 2020

Docker介绍和常用指令

Docker是什么?

官网所述,Docker是一个平台。可以在这个平台上开发、迁移和运行app应用。Docker它能够将你的应用从你的基础设施(硬件、操作系统)中分离,从而让你可以更加快速的部署、安装软件。

是不是有点抽象?来个对比就比较清晰了,首先介绍下VM(虚拟机),典型的就是在Windows系统上通过安装VMware虚拟出来的虚拟机(它可以是Linux虚拟机或Windows虚拟机)。当然也可以不依托操作系统,直接在硬件上安装VMware ESXi,在其上虚拟机器也可以,而且性能更高。虚拟机的结构图如下:

*.png

Hypervisor,又称虚拟机监视器(英语:virtual machine monitor,缩写为 VMM)

通俗的讲,虚拟机,就是在你的操作系统里面,装一个软件,然后通过这个软件,再模拟一台甚至多台“子电脑”出来。在“子电脑”里,你可以和正常电脑一样运行程序,例如开QQ。如果你愿意,你可以变出好几个“子电脑”,里面都开上QQ。“子电脑”和“子电脑”之间,是相互隔离的,互不影响。

虚拟机的应用还可以用来游戏的多开和挂机,我之前在打LOL的时候,曾经在淘宝上购买过挂金币的脚本,它是通过模拟键盘和鼠标来实现挂机。所以,如果直接用你的主操作系统挂机,那么挂机的时候你的鼠标和键盘就会被脚本控制,就不能用了,所以我当时用vmware搞了很多台虚拟机,然后在每个虚拟机上装一个LOL客户端,就这样挂了很多小号,打了很多金币。搞好后虚拟机就挂在后台运行,我的主操作系统想干点别的事还是可以干的。

但由于一般情况下,虚拟出一台机器,需要安装某个操作系统的镜像,就相当于你装一台全新的Windows机器,比较费时费力。所以为了更轻便的进行项目部署,Docker出现了,它直接在操作系统上封装一层,可以直接在操作系统上拉取已经安装好MySQL或JDK的Docker、甚至已经部署好你的应用的Docker下来,免去再次安装部署的麻烦。Docker包含如下:

*.png

Docker的结构和组成

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

*.png

Client和Docker daemon交互,Images是静态的,运行时要成为Containers。

Docker的安装

Windows和Mac都是用客户端的,Linux可以参照官方文档进行安装。

*.png

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                                       
#拉取镜像
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.
    ...
#查看容器
$ docker ps --all

    CONTAINER ID     IMAGE           COMMAND      CREATED            STATUS
    54f4984ed6a8     hello-world     "/hello"     20 seconds ago     Exited (0) 19 seconds ago
#删除镜像
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
# 暂停容器
docker pause 8492b
docker unpause 8492b
# 杀死容器
docker kill 35
# 启动容器
docker start 35
# 重启容器
docker restart 35
#进入容器方式1
docker attach 54f4984ed6a8
#不关闭退出容器
ctrl+p+q
# 进入容器方式2
docker exec -it 69d1 bash

docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。

只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。

当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。

容器可以直接打包成tar文件,也可以先转成镜像,再打包成tar文件。如下图的容器状态转换示意图所示:

*.png
#镜像打包成tar文件
docker save b3_9a>box.tar
#将tar文件加载成镜像
docker load <box.tar
#镜像改名
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
#将容器提交成镜像(可以将任意状态的容器提交,保留对容器的操作)
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
#容器内外文件的拷入拷出
[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 ./
*.png
#事件监控,操作记录展示
docker events

# 堵塞住容器直到容器停止
docker wait 74

#获取容器/镜像的元数据
docker inspect node

# 查看镜像的历史
docker history 54

# 返回docker对象的底层信息(容器和镜像适用)
docker inspect 54
#容器操作日志查询
[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
# docker update可以对容器进行设置,包括内存等
#设置容器内存限制大小
docker update -m 1024m --memory-swap -1 node-test
#监控性能参数状态
docker stats
# 查看容器的运行状况和修改状态
docker top 74
docker diff 74
#运行容器,并且映射端口,从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

如果有docker-compose.yml,可以通过该文件指定docker容器配置:

# 停止
docker-compose down

# 启动
docker-compose up -d

实际业务中,我用到了如下的容易构建语句:

#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

如果我想更改代码,我该如何让docker的此容器服务生效呢?

image.png

之后再重新启动容器:

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

本文链接:https://www.daguanren.cc/post/docker-jie-shao.html

-- EOF --

Comments