Docker理解

- 安装Docker,相当于安装"VM"

- 拉取镜像,相当于安装'win10.iso'

- 结论: 只要你的系统能把Docker跑起来,那么运行的镜像当然是一模一样的
  实现镜像做好,处处运行
- Linux容器: 可以理解为"精简版的Linux系统",Docker就是一个'Linux容器'
	- 相比'虚拟机',轻量化了很多,运行速度也更加快速!

docker主要构成部分

- 镜像(image): 类,所以一个'镜像'可以创造出很多'容器'

- 容器(container,存放各种镜像,镜像依赖容器才能运行):实例,每个'容器'都是互相隔离的,简易版的'Linux'环境,可以跑'应用程序',可以看成一个个'集装箱'

- 仓库(repository):存放'镜像'的场所.Docker官方的registry称为'Docker Hub',存放各种镜像模板
	- 公开仓
	- 私有仓

Docker的安装

  • 依赖Linux环境: 必须部署在Linux内核的系统上
- 注意事项: 其他系统想部署"Docker"就必须安装一个Linux环境
- Windows安装方法: VM上面运行Linux,然后把Docker跑起来
  • 演示环境
- Linux内核版本为3.8以上,这里选择"Centos7.x"

常用命令

- docker run [option] 镜像名 [向启动容器中传入的命令] # 创建容器,把镜像扔进去并运行起来
- docker container ls

- docker container start tracker # 有镜像的前提下,才能start.若没有镜像,start根本跑不起来
- docker container start storage
- docker container ls

docker架构

- 基于C/S 架构: docker是一个基于c/s的系统
- S端(服务端)运行 images和container
- 用户操作C端(客户端)
	- docker build: 创建镜像
	- docker pull: 拉取镜像(从registry)
	- docker run: 运行docker

  • 守护进程: 客户端与服务端连接的桥梁

配置CentOS环境

- 安装gcc
	yum -y install gcc
	yum -y install gcc-c++
	
- 配置仓库(以阿里云作为镜像仓库)
	sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

- 加速缓存: yum makecache fast

安装Docker

- 安装Docker CE: yum -y install docker-ce docker-ce-cli containerd.io
- 开启Docker引擎: systemctl start docker
- 查询一下: ps -ef|grep docker
- 查询docker版本并运行hello-world
	docker version
	docker run hello-world # 若提示权限问题,请在前面加上 sudo

阿里云镜像加速

- 登录阿里云账户(容器镜像服务)
- 获取加速器地址连接
- 粘贴脚本直接执行

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["urURL"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

- 重启服务器

Docker常用命令

  • 帮助启动类命令
- 启动docker
	systemctl start docker
- 停止docker
	systemctl stop docker
- 重启docker
	systemctl restart docker
- 查看docker状态
	systemctl status docker
- 开机启动
	systemctl enable docker
- 查看docker概要信息
	docker info
- 帮助命令
	docker --help
	docker 具体命令 --help
  • 镜像命令
- docker images: 列出本地主机上的所有镜像
- docker search 某个镜像名字: 搜索远程仓库镜像
	- 示例: docker search redis
- docker pull 某个镜像名字: 拉取镜像(默认最新版)
	- docker puu 某个镜像名字[:TAG](拉取某个特定版本)
- docker systemdf 查看镜像/容器/数据卷所占的空间
- docker rmi某个镜像名字ID
  • 以交互式模式运行docker镜像(拉取最新的ubuntu镜像作为演示)
- docker pull ubuntu
- dokcer run ubuntu # 成功跑起来,但没用(因为没有交互式终端)
- 改正: docker run -it ubuntu /bin/bash(出现伪终端,可以与ubuntu交互了)
- 退出伪终端命令: exit
- docker ps # 列出所有正在运行的容器信息
- 类似的命令: docker images ls
  • 同一个镜像,运行在两个容器上面演示
- docker run ubuntu

- docker run -it ubuntu /bin/bash
  • 容器退出命令
- run以后进去容器,exit退出,容器也随之停止
- run以后进去容器,ctrl+p+q退出,退回到本机,但容器不会停止
  • 容器的启动,重启,停止,强行停止
- docker start 容器ID/容器名
- docker restart 容器ID/容器名
- docker stop 容器ID/容器名
- docker kill 容器ID/容器名
  • 删除容器命令(是删除容器,不是删除镜像)
- docker rm 容器ID/容器名
- 注意事项: 删除之前,请先停止容器的运行,否则删除失败

- 一次性删除多个容器实例
	- docker rm -f$(docker ps -a -q)
	- docker ps -a -q | xargs docker rm # 前面的结果当参数传进来,赋值给xargs

启动守护式容器(容器后台默默运行,不至于显示出来,容易被误关闭)

- docker run -d 容器名
  • 演示实例注意事项: 以启动ubuntu为例
- docker run -d ubuntu # 运行以后,容器马上退出(docker ps -a)
- 重要说明: docker容器后台运行,就必须有一个前台进程;如果不是'一直挂起的命令'(例如 top,tail),就会自动退出
  这是docker的机制问题
- 最佳解决方式: 将你要运行的程序,以前台进程的形式运行(常见就是命令行模式,表示我还有交互式操作,别中断)

- 前台交互式启动: docker run -it redis
- 后台守护式启动: docker run -d redis
- 此时: docker ps 会发现运行了两个redis容器实例
- 注意事项: 这里要开三个独立终端才能演示出效果

其他命令

  • docker top xxxx: 查看容器在Linux进程中的运行情况
[root@localhost ~]# docker run -d redis # 跑起来
3e15de8754913ca519497119600aebe2271093f099beec0da2c660a0b2824320
[root@localhost ~]# docker ps # 查看是否在运行
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS          PORTS      NAMES
3e15de875491   redis     "docker-entrypoint.s…"   16 seconds ago   Up 15 seconds   6379/tcp   awesome_hofstadter
[root@localhost ~]# docker top 3e15de875491 # 查看在进程中的情况
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
polkitd             3478                3457                0                   11:34               ?                   00:00:00            redis-server *:6379

  • docker exec -it xxx bashShell: 进入已经在运行的容器,退出后,容器不会停止运行
  • docker attach xxx:进入已经在运行的容器,退出后,容器停止运行(不推荐使用,简单了解)
- 注意事项:推荐使用个命令进入已经在运行中的容器(ctrl+p+q退出的时候,容器不会被停止)
	- 原理: exec是在容器中打开新的终端,并且可以启动新的进程;使用exec退出,不会导致容器停止

[root@localhost ~]# docker exec -it 3e15de875491 /bin/bash # 进入已经在运行中的容器
root@3e15de875491:/# ls
bin   data  etc   lib	 lib64	 media	opt   root  sbin  sys  usr
boot  dev   home  lib32  libx32  mnt	proc  run   srv   tmp  var
root@3e15de875491:/# read escape sequence # ctrl+p+q退出容器,但容器不会停止
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS      NAMES
3e15de875491   redis     "docker-entrypoint.s…"   7 minutes ago   Up 7 minutes   6379/tcp   awesome_hofstadter

- 另一个示例

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS          PORTS      NAMES
3e15de875491   redis     "docker-entrypoint.s…"   17 minutes ago   Up 17 minutes   6379/tcp   awesome_hofstadter
[root@localhost ~]# docker exec -it 3e15de875491 /bin/bash
root@3e15de875491:/data# redis-cli -p 6379 # 运行redis
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> 

  • 在主机上,从容器内拷贝文件到主机
- docker cp 容器ID:容器内路径 目的主机路径

- 演示:

# 启动ubuntu镜像
[root@localhost ~]# docker run -it ubuntu
# 查看ubuntu镜像ID
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
41afe642a0f0   ubuntu    "/bin/bash"   7 seconds ago   Up 6 seconds  
# 进入容器,在bin目录下创建'b.txt'文件
root@667b12084ade:/# touch a.txt
# 主机上,拷贝容器文件b.txt到主机的/bin目录下
[root@localhost ~]# docker cp 41afe642a0f0:/bin/b.txt /bin
  • exportimport命令
- export: 导出容器的内容,并压缩为一个tar文件
- import: 读取tar包的内容并创建成一个新的文件系统再导入为镜像

docker export 容器ID>文件名.tar
cat 文件名.tar|docker import - 镜像用户/镜像名:镜像版本号

- 演示:

# 根目录下创建demo目录,进入该目录,打包ubuntu容器并导出
[root@localhost demo]# docker export 41afe642a0f0 > ubuntuDemo.tar
# 查询已经打包好的ubuntu文件
[root@localhost demo]# ls
ubuntuDemo.tar

# 导入刚刚打包好的ubuntu文件,并创建为docker镜像
[root@localhost demo]# cat ubuntuDemo.tar | docker import - ubuntu_version:1.0
sha256:0df56bd059a615aee06f395a2fac308400c600213d521e9298b4536cccf25f2a
# 查询刚刚创建好的docker镜像
[root@localhost demo]# docker images
REPOSITORY       TAG       IMAGE ID       CREATED          SIZE
ubuntu_version   1.0       0df56bd059a6   38 seconds ago   77.9MB
redis            latest    bdff4838c172   3 months ago     138MB
ubuntu           latest    174c8c134b2a   4 months ago     77.9MB
hello-world      latest    d2c94e258dcb   12 months ago    13.3kB
# 运行刚刚创建的docker镜像(进入容器正常)
[root@localhost demo]# docker run -it 0df56bd059a6 /bin/bash

  • 镜像: 可以理解为一个运行环境
- 只有通过镜像文件,才能生成Docker实例(先有'类',然后才能生成'类实例')
  • Docker镜像分层下载
- docker pull tomcat: 开始分层下载
- 镜像分层的好处: 共享资源(为了复用)
  • UnionFS(联合文件系统): 是一种分层,轻量级并且高性能的文件系统
- 特点: 对文件系统的修改作为一次提交来一层层的叠加,同时将不同目录挂载到同一个虚拟文件系统下
- 说明: Union是Docker镜像的基础,镜像可以通过分层来进行继承,基于"基础镜像",可以制作各种具体的"应用镜像"
- 特性: 一次性加载多个文件系统,但从外面看来,只能看到一个文件系统
       联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有的底层文件和目录
  • Docker镜像层: 都是'只读'的,而"容器层"是可写的
- 当容器启动时,一个新的'可写层'被加载到镜像的顶部(该层就称为'容器层','容器层'之下的都称为'镜像层')
	- 所有对'容器'的增删改查,都只会发生在'容器层'中(因为'容器层'可写,而'镜像层'只读)

Docker commit

  • 定义: 提交容器副本,使之成为一个新的镜像
- 语法: docker commit -m="提交的描述信息" -a="作者" 容器ID 新镜像名称:[标签名]
  • 实际应用案例: 给极简版ubuntu系统新增vim命令并重新打包成镜像
- 进入极简版ubuntu系统,发现不支持vim命令

[root@localhost ~]# docker images
REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
ubuntu_version   1.0       0df56bd059a6   10 days ago     77.9MB
......
[root@localhost ~]# docker run -it ubuntu /bin/bash
root@254994c25f58:/# ls
......
root@254994c25f58:/# vim a.txt
bash: vim: command not found

- 先安装vim
	- 首先更新本地包数据库
		- apt-get update: 这句命令只是更新本地的包数据库,并不会实际安装或升级任何软件包
	- 然后安装vim
		- apt-get -y install vim

root@254994c25f58:/# apt-get update
......                                    
Reading package lists... Done
root@254994c25f58:/# apt-get -y install vim
......

- 验证vim命令创建文件并编辑

root@254994c25f58:/# vim a.txt
'''
- 按'i'进入编辑模式,输入想要的信息
- 按'esc'退出编辑模式
- 按':wq'保存并退出
'''
# 查询刚刚编辑的内容
root@254994c25f58:/# cat a.txt

- 现在把这个容器打包成镜像

# 这里有个失误,把这个镜像取名为'home/demo'了
[root@localhost /]# docker commit -m="vim cmd add ok" -a="anning" 254994c25f58 home/demo
sha256:028cd906ab5d86e1976b771475644617ae3feb6de883aabd05f0a5a98d5f421a
[root@localhost /]# docker images
REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
home/demo        latest    028cd906ab5d   8 seconds ago   188MB
ubuntu           latest    174c8c134b2a   4 months ago    77.9MB
......
# 运行刚刚创建的镜像,验证vim是否可以直接用
[root@localhost /]# docker run -it home/demo /bin/bash
root@8e52b4b6852c:/# ls
a.txt  boot  etc   lib    lib64   media  opt   root  sbin  sys  usr
bin    dev   home  lib32  libx32  mnt    proc  run   srv   tmp  var
root@8e52b4b6852c:/# vim b.txt
root@8e52b4b6852c:/# cat b.txt
1111
222
333
root@8e52b4b6852c:/# 



  • 底层原理分析
- 基于Docker的'镜像分层',新镜像从base镜像一层一层叠加上去
  每安装一个软件,就从现有镜像的基础上增加一层

本地镜像发布到阿里云

- 登录阿里云,使用阿里云的'容器镜像服务'-创建仓库
- 根据仓库文档提供的指令,一步一步操作即可

# 密码是镜像服务的密码(不是阿里云账户的密码)
docker login --username=your_account registry.cn-hangzhou.aliyuncs.com