Docker容器操作
我们通过一个镜像可以轻松的创建一个容器,一个镜像可以有多个容器,在运行容器的时候,实际上是在容器内部创建了这个文件系统的读写副本,如下图所示
![[Docker系列]4 Docker操作_推送](https://file.cfanz.cn/uploads/png/2022/03/30/8/dbLDcO9A2c.png)
容器的生命周期是怎么样的?
容器的生命周期一共有五个状态分别为
- created 初建状态
 - running 运行状态
 - stopped 停止状态
 - opaused 暂停状态
 - deleted 删除状态
 
通过 docker cretate 进入容器的初建状态,然后通过 docker start 进入运行状态,通过 docker stop 进入停止状态,运行状态的容器可以通过 docker pause 让其变为暂停状态,为了详细的查看这些过程,我们实操一下
- 创建并启动容器
 
![[Docker系列]4 Docker操作_docker_02](https://file.cfanz.cn/uploads/png/2022/03/30/8/8a7eO53KA9.png)
通过 docker create 创建的容器处于停止的状态,使用 docker start busybox 进入启动状态
![[Docker系列]4 Docker操作_docker_03](https://file.cfanz.cn/uploads/png/2022/03/30/8/O09WKR45EI.png)
当使用 docker run 创建并启动容器的时候,docker 后台的执行逻辑为
- 首先检查本地是否有busybox镜像,不存在则取dockerhub中拉取
 - 使用busybox镜像启动一个容器
 - 分配文件系统,并在镜像的只读层外创建一个读写层
 - 从docker ip池分配个ip给容器
 - 运行镜像
 
可以进入交互模式么
同时使用 -it 参数可以让我们进入交互模式,容器内部和主机是完全隔离的。另外由于此时的 sh 为 1 号进程,所以如果通过 exit 退出 sh,那么容器也就退出,所以对于容器而言,杀死容器中的主进程,那么容器也就会被杀死
通过 docker stop 停止容器,其原理是给运行中的容器给 sigterm 信号,如果容器为 1 号进程接受并处理sigterm,则等待 1 号进程处理完毕后就退出,如果等待一段时间后还是没有处理,则会通过发送 sigkill 命令强制终止容器
如何进入容器?
想要进入容器,有三种方案,分别是 docker attach,docker exec,nsenter 等
- 使用 docker attach 方式进入容器
 
![[Docker系列]4 Docker操作_docker_04](https://file.cfanz.cn/uploads/png/2022/03/30/8/b4DB8AZ4K5.png)
通过 docker ps -a 查看当前的进程信息
![[Docker系列]4 Docker操作_推送_05](https://file.cfanz.cn/uploads/png/2022/03/30/8/aRNI2188dH.png)
可是当我们在进行窗口进行 docker attach 的时候,这个命令就不好用了,所以使用 docker exec 的方式
- 使用
docker exec进入容器 
![[Docker系列]4 Docker操作_docker_06](https://file.cfanz.cn/uploads/png/2022/03/30/8/5F101S3981.png)
奇怪的发现居然是两个 sh 进程,主要是因为,当我们使用 docker exec 方式进入容器的时候,会单独启动一个 sh 进程,此时的多个窗口都是独立且不受干扰,也是非常常用的方式
- 删除容器
 
现在基本上知道了如何创建,启动容器,那么怎么删除容器呢
使用docker rm的方式删除容器
![[Docker系列]4 Docker操作_服务器_07](https://file.cfanz.cn/uploads/png/2022/03/30/8/9b2214F7a0.png)
如果此时,容器正在运行,那么需要添加 -f 的方式停止正在运行的容器
如果想要导出容器怎么操作呢
这简单,不过在导出之前先进入容器创建一个文件
![[Docker系列]4 Docker操作_推送_08](https://file.cfanz.cn/uploads/png/2022/03/30/8/0R0V906785.png)
然后导出为文件
![[Docker系列]4 Docker操作_推送_09](https://file.cfanz.cn/uploads/png/2022/03/30/8/1W0112T2RZ.png)
此时会在当前目录生成一个 busybox.tar 文件,此时就可以将其拷贝到其他的机器上使用
那如何导入容器呢
通过 docker import 的方式导入,然后使用 docker  run 启动就完成了容器的迁移
![[Docker系列]4 Docker操作_推送_10](https://file.cfanz.cn/uploads/png/2022/03/30/8/5JW7O4U486.png)
此时容器名称为 busybox:test,然后我们使用 docker run 启动并进入容器
![[Docker系列]4 Docker操作_docker_11](https://file.cfanz.cn/uploads/png/2022/03/30/8/5EVf918dcH.png)
此时发现之前在 /tmp 创建的目录也被迁移了过来
仓库
容器的基本操作应该都会了,那么我们应该如何去存储和分发这些镜像,这就需要介绍下仓库;
我们可以使用共有镜像仓库分发,也可以搭建私有的仓库
仓库是啥玩意
钱钱仓库放钱,这个仓库放镜像。Github 放代码,我们理解镜像的仓库可以联想 Github 仓库。
在学习的过程中,不太能区分注册服务器和仓库的关系。注册服务器其实是用来存放仓库的实际机器,而仓库我们可以将其理解为具体的项目或者目录。一个注册服务器可以存放多个仓库,每个仓库可以存放多个镜像
公有仓库
Docker hub 是当前全球最大的镜像市场,差不多超过 10w 个容器镜像,大部分操作系统镜像都来自于此。
![[Docker系列]4 Docker操作_服务器_12](https://file.cfanz.cn/uploads/png/2022/03/30/8/380e95N3Jb.png)
如何使用公共镜像仓库和存储镜像
- 注册 Docker hub
 
![[Docker系列]4 Docker操作_docker_13](https://file.cfanz.cn/uploads/png/2022/03/30/8/Wf425HR41Y.png)
- 创建仓库
 
![[Docker系列]4 Docker操作_docker_14](https://file.cfanz.cn/uploads/png/2022/03/30/8/d9eT4GT026.png)
- 实战镜像推送到仓库
 
此时假设我的账户是 xiaolantest,创建一个 busybox 的仓库,随后将镜像推送到仓库中。
第一步:拉取 busybox 镜像
![[Docker系列]4 Docker操作_推送_15](https://file.cfanz.cn/uploads/png/2022/03/30/8/OOad8G2GC1.png)
第二步:推送镜像之前先登录镜像服务器(注意用户名密码哦),出现 login Succeeded表示登录成功
![[Docker系列]4 Docker操作_服务器_16](https://file.cfanz.cn/uploads/png/2022/03/30/8/1841VJ67C7.png)
第三步:推送之前还要做一件事,重新对镜像命名,这样测能正确的推动到自己创建的仓库中
![[Docker系列]4 Docker操作_服务器_17](https://file.cfanz.cn/uploads/png/2022/03/30/8/GB174e8982.png)
第四步:docker push 到仓库中
![[Docker系列]4 Docker操作_docker_18](https://file.cfanz.cn/uploads/png/2022/03/30/8/4VCdS22dM4.png)
私有仓库
Docker 官方提供了开源的镜像仓库 Distribution,镜像存放于 Docker hub 的 Registry中
- 启动本地镜像仓库
 
![[Docker系列]4 Docker操作_docker_19](https://file.cfanz.cn/uploads/png/2022/03/30/8/4VCdS22dM4.png)
- 使用 docker ps查看启动的容器
 
![[Docker系列]4 Docker操作_docker_20](https://file.cfanz.cn/uploads/png/2022/03/30/8/4b3G9TGbMN.png)
- 重命名镜像
 
此时 Docker 为busybox镜像创建了一个别名localhost:5000/busybox,localhost:5000为主机名和端口,Docker 将会把镜像推送到这个地址。
![[Docker系列]4 Docker操作_服务器_21](https://file.cfanz.cn/uploads/png/2022/03/30/8/1J53d6714E.png)
- 推送镜像到本地仓库
 
![[Docker系列]4 Docker操作_推送_22](https://file.cfanz.cn/uploads/png/2022/03/30/8/83RD3N9SK6.png)
- 删除之前存在的镜像
 
此时,我们验证一下从本地镜像仓库拉取镜像。首先,我们删除本地的busybox和localhost:5000/busybox镜像。
![[Docker系列]4 Docker操作_docker_23](https://file.cfanz.cn/uploads/png/2022/03/30/8/84a7G6PWR1.png)
- 查看当前本地镜像
 
![[Docker系列]4 Docker操作_docker_24](https://file.cfanz.cn/uploads/png/2022/03/30/8/71fW9212SV.png)
可以看到此时本地已经没有busybox这个镜像了。下面,我们从本地镜像仓库拉取busybox镜像:
![[Docker系列]4 Docker操作_推送_25](https://file.cfanz.cn/uploads/png/2022/03/30/8/daeLC18M03.png)
随后再使用 docker image ls busybox 命令,这时可以看到我们已经成功从私有镜像仓库拉取 busybox 镜像到本地了
总结
不知不觉,每周下班开始写,做实验,截图,至此也就告一段落了,开篇思维导图由于完整版太大,我计划一共分为四篇文章,分别为 Docker基本认识,Docker实战,Docker底层原理以及Docker集群安全四个方面来分享,后续精简后再给大家。本篇文章从 Docker容器圈到基本使用,写的应该蛮清楚了,另外说明一下,由于直接使用代码很可能导致格式排版混乱,所以全部采用截图的方式,更加直观和清晰,当然如有不妥之处也望大家指正。点赞,转发,收藏,感谢!我们下期见!
Docker学习网站 
- Docker官方主页(http://www.docker.com)
 - Docker Hub(http://hub.docker.com)
 - Docker官方文档(http://docs.docker.com)
 - Docker的StackOverflow问答主页
 - Docker的Github源代码(http://github.com/docker/docker)
 









