-
Docker 是什么
Docker 是一个开源的应用容器引擎,基于 Go 语言, 并遵从Apache2.0协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。
本文会引导你实际操作Docker,带你进入Docker的世界。
下面跟随我一起来看个究竟。 -
我们先从简单的docker version说起
从上图可以看到以下几点:
- 安装的docker版本是18.06.3-ce(社区版,免费)
- docker api 版本1.38
- docker是用go语言编写的,当前版本1.10.3
- Experimental:false,表示实验功能特性处于关闭状态,想要深究该功能特性的,可以到https://github.com/docker/cli/tree/master/experimental了解
- docker采用Client–Server(C/S)架构模式
-
docker架构
从上面的信息我们知道docker是采用Client-Server(C/S)的架构,如下图所示:
注:docker作为Client通过Restful与Server端的dockerd通信。这只是我们看到docker架构的冰山一角。下图列出了完整的docker的架构图(蓝色为Server端):
通过上图我们可以看出,我们如果通过docker run 一个容器,要经过以下步骤: -
①docker 客户端 向 dockerd 发送请求
-
②dockerd 从仓库拉取镜像
-
③dockerd 通过gRPC的方式通知 containerd 启动指定容器
-
④containerd 收到请求后,启动shim进程,并将相关配置所在目录作为参数传给shim.
-
⑤shim 按照runtime的标准准备好环境,然后启动runc进程。
-
⑥runc 创建容器,到此我们所要创建的容器外部一切环境就已全部准备就绪,然后runc启动init进程
-
⑦init 在容器中创建进程,这个进程的入口就是我们在dockerfile文件中指定的cmd/entrypoint命令
除了上面步骤中提及的组件还有两个组件没有介绍到:
- ctr组件:主要是containerd的命令行客户端;
- docker-proxy组件:主要是用来做端口映射的。
docker的所有组件我们可以通过如下命令看到:
ls /usr/bin | grep docker
具体每个组件的介绍可以通过对应的命令查看help. 比如要看docker-containerd的帮助可以执行:
docker-containerd -h
掌握了docker的组件及架构,我们实际run一个容器玩玩。
首先我们先从docker hub拉取镜像:
docker pull nginx
如果不加tag,默认拉取latest,dockerd经过对比镜像的摘要,检测到该镜像已存在就不会重复拉取。
接下来我们运行刚才pull下来的镜像
docker run --name test -d -p 8080:80 nginx
说明:
- 执行完docker run 命令,如果容器创建成功,则会输出容器的完整ID
- –name test 指定容器的名称为test
- -d 后台运行
- -p 8080:80 将容器里面应用的端口80映射到主机8080端口
- nginx 使用官方nginx镜像,如果要使用指定仓库的镜像要写全仓库地址;这里镜像不带tag,默认使用latest.
docker ps 查看正在运行的容器。(要查看所有容器使用 docker ps -a)
浏览器通过暴露出来的8080端口访问nginx服务:
查看容器日志:docker logs {containerID} (容器ID不用全部输入,只要能区别开就可以,比如只有一个容器的时候,只写一个5也是可以的)
通过上面的日志,我们看到缺少文件favicon.ico.
我们通过以下命令进入容器看下是不是存在该文件:
注:命令中的 5059 为容器的id,请根据实际情况替换;文中出现的类似命令都以此方法处理
docker exec -it 5059 bash
说明:-it 在容器中开启交互模式的终端
通过上面的操作,进入容器发现目录/usr/share/nginx/html下确实缺少文件favicon.ico
我们通过以下命令往容器里面拷贝文件:
docker cp favicon.ico 5059:/usr/share/nginx/html/
通过在容器里面执行ls,发现文件已经拷贝成功。
我们访问几次服务之后,通过docker logs -f ** (跟踪日志输出)发现再没有报找不到文件的日志 。
我们也可以通过以下命令获取容器的元数据信息:
docker inspect 5059
内容比较多,截图没有截全。如果要获取指定信息,可以通过–format,比如获取容器的IPAddress
停止上面创建的nginx容器:
删除nginx容器:
重新创建一个nginx容器,这次我们使用-v给容器挂载一个外部文件:
我们把nginx的index.html文件替换了,使用外部挂载的,通过暴露的8080端口访问看看:
通过docker stats 命令监控全部或指定容器的资源消耗情况:
有时候我们需要查看容器中运行的进程,但是容器运行时不一定有/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,我们就可以使用docker top来实现查看容器中正在运行的进程信息:
通过docker rename 来重命名容器,比如我把上面的test2容器重命名为test3,执行以下命令:
docker rename test2 test3
通过docker diff 命令来查看容器内文件系统的变更情况:
其中:指定3种事件来比对:
- A - Add
- D - Delete
- C - Change
通过docker update来更新容器的运行时配置,比如我们限制下容器的CPU和Memory
从上面的截图可以看出,刚开始我们的容器cpu和memory的值默认都是0,即没有限制。
我们通过命令, 限制cpu为1,内存为200M:
docker update --cpus 1 --memory 200M fe8b
验证下更新是否生效:
从上图我们看到我们的限制已经生效.
总结:
把上文实操过程中用到的docker命令汇总一下:
- docker pull ** :拉取镜像
- docker run ** : 创建并启动一个容器
- docker ps : 查看正在运行的容器
- docker logs ** : 查看容器日志
- docker exec -it ** : 进入容器,开启交互模式的终端
- docker cp ** :宿主机和容器之间相互拷贝文件(夹)
- docker inspect : 查看容器/镜像元数据
- docker stop ** : 停止容器
- docker rm ** : 删除容器
- docker stats : 监控容器资源消耗
- docker top ** : 查看容器中运行的进程信息
- docker rename **: 重命名容器
- docker diff ** : 查看容器内文件系统的变更
- docker update ** : 更新容器的一些运行时配置
本次的Docker介绍就讲这些,我们下节给大家分享《Docker 镜像详解》