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 容器名
- 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
- 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 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