一、Docker 基础
Docker是基于Go开发的开源项目--容器虚拟化技术
主要目标: Build , Ship and Run Any App, Anywhere (一次镜像,处处运行)
微服务通过docker打包成镜像
1.1 Docker 与 虚拟机
- 传统虚拟机是虚拟出一套硬件后, 在其上运行一个完整操作系统,在该系统上运行所需应用进程;
- 容器内的应用进程直接运行于宿主的内核,在容器内没有自己的内核也没有进行硬件虚拟。因此容器比传统虚拟机更轻便
- 每个容器之间相互隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能分区计算资源
- 隔离与共享:虚拟机通过添加hypervisor层,虚拟出网卡,内存,CPU等虚拟硬件,再在其上建立客户机,每个客户机都有自己的虚拟内核;容器通过隔离的方式,将文件系统、进程、设备、网络等资源进行隔离,再对权限、CPU等资源进行控制,最终让容器之间互不影响,容器无法影响宿主机,容器与宿主机共享内核、文件系统、硬件等资源
1.2 Docker三要素
- 镜像 image
- 容器 container
- 仓库 repository
//java
Book b1 = new Book();
Book b2 = new Book();
Book b3 = new Bool();
//docker
镜像名
Redis r1 = docker run 镜像;
Redis r2 = docker run 镜像;
Redis r3 = docker run 镜像;
- 从面向对象角度
Docker利用容器独立运行一个或一组应用,应用程序或服务运行在容器里面,容器类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。就像是java中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器为镜像提供了一个标准和隔离的运行环境。他可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的。
- 从镜像容器角度
容器是一个简易版的Linux环境(包括root用户权限,进程空间,用户空间和网络空间等)和运行其中的环境。
- 正确理解仓库/镜像/容器概念
docker本身是一个容器运行载体或称之为管理引擎,我们把应用程序和配置依赖打包好成为一个可交付的环境。这个打包好的运行环境就是image镜像文件,只有通过镜像文件才能生成docker容器实例(就类似new出来一个对象)
image文件是可以看做容器的模板,docker根据image文件生成容器的实例。同一个image文件,可以生成多个同时运行的容器实例。
1.3 docker架构
1.4 Docker Engine
Docker中的一个核心就是Docker Engine
- Server:整个结构最核心的部分,命令的真实执行者,里面住着 docker daemon,简单的说就是一个守护docker守护进程,长期的运行着,常驻于内存中,负责创建和管理dockers 对象,比如:image,containers,network和volume。在Linux 中可以找到一个叫 dockerd 的进程就是它。
- Rest Api: 正如它的名字就是一个对外提供的接口,利用这些接口可以实现对 docker 服务的调用执行,完成和 daemon 通信。
- Client: 最外层的命令行界面(CLI: Command Line Interface)。
1.5 Union FS
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
Docker的最底层是bootfs引导文件系统,包含boootloader(boot加载器)和内核,boot加载完成后整个内核就都在内存中了,此时内存的使用权由bootfs转交给系统内核,此时系统会卸载bootfs
当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常称作“容器层”,“容器层”之下都叫做"镜像层",镜像层是只读的,只有容器是可写的
Docker镜像加载原理:
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
二、Docker 命令
启动docker: systemctl start docker
停止docker: systemctl stop docker
重启docker: systemctl restart docker
查看docker状态: systemctl status docker
开机启动: systemctl enable docker
查看docker概要信息: docker info
查看docker总体帮助文档: docker --help
查看docker命令帮助文档: docker 具体命令 --help
谈谈:
- 虚悬镜像?
仓库名和标签都是的镜像,俗称dangling image,建议删除
docker images #查看本地所有镜像
docker search xxx #查找某个镜像
docker pull nginx #下载最新版镜像
docker pull nginx:1.20.1 #下载指定版本
docker rmi nginx #删除镜像
docker rmi 镜像id
docker rmi -f 镜像id #强制删除
docker rmi -f $(docker images -qa) 删除全部
docker system df #查看镜像/容器/数据卷所占空间
docker run [OPTIONS] IMAGE [COMMAND] [ARG...] #启动容器 []可选参数 OPTIONS设置项
docker run 设置项 镜像名 启动运行的命令(默认有,一般不写)
# -d后台运行(守护式) --restart=always开机自启 -p 88:80将主机的88端口映射到这个容器的80端口 小写p制定端口映射
docker run --name=mynginx -d --restart=always -p 88:80 nginx
#停止后台运行的容器
docker stop CONTAINERID/名字
#再次启动
docker start CONTAINERID/名字
#删除容器
docker rm mynginx #删除已经停止的容器,名字冲突了不能再起新的
docker rm -f mynginx #删除正在运行的容器
#查看正在运行的容器
docker ps
#查看所有的容器,包括已经停止了的
docker ps -a
# 查看容器内运行的进程
docker top 容器id
# 查看容器内部细节
docker inspect 容器id
#直接以交互模式启动容器
docker run -it xxx /bin/bash
#先跑起来一个容器
docker run -d nginx
#进入容器 -it以交互模式 也可以用于ctrl+p+q退出容器后重新进入
docker exec -it 55961(CONTAINERID) /bin/bash
#重新进入已退出的容器也可以用
docker attach 容器id
#上述exec与attach重新进入容器的区别:
exec是在容器中打开新的终端,并且可以启动新的进程,用exit退出时不会导致容器的停止
attach是直接进入容器启动命令的终端,不会启动新的进程,用exit退出时会导致容器的停止
#每个镜像的具体文件在哪儿,做什么,可以去dockerhub上看,都会有说明
#nginx的页面在 /usr/share/nginx/html/ 路径下
cd /usr/share/nginx/html
#退出
exit #退出并停止
ctrl+p+q #退出但不停止
#将我们修改后的镜像提交上去,供以后随时下载使用
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
-a 作者 -m 修改的备注
docker commit -a="tietie" -m="修改了首页" f83911a0c019(CONTAINERID) newNginx:1.0
#镜像保存本地
#镜像打成包 -o 把包打成.tar格式
docker save -o abc.tar newnginx:v1.0
#在其他机器上可以加载(前提是其他机器撒谎给你有abc.tar)
docker load -i abc.tar
#镜像推送远程仓库docker hub
docker tag local-image:tagname new-repo:tagname
docker push new-repo:tagname
=>
docker tag newnginx:v1.0 zhangtieyi/repositoryname:v1.0
docker login
Username: zhangtieyi
Password: zhangtieyi123
docker push zhangtieyi/repositoryname:v1.0
(docker logout)
#从dockerhub下载
pull(完整的从dockerhub上镜像页能找到)
#挂载的数据不能提交镜像
#可以通过挂载数据,在容器的外部修改容器内容 :ro只读,容器内不能修改 :rw可读可写
docker run -v 主机目录:容器目录:ro nginx
## 外边是空的,那里面也是空,所以外部得有文件
docker run -d -v /data/html:/usr/share/nginx/html:rw -v /data/conf/nginx.conf:/etc/nginx/nginx.config:rw --name==mynginx nginx
# 查看日志
docker logs containerid
# 容器数据 -> 主机
docker cp 容器id:容器内路径 主机目的路径
docker cp ddb1:/tmp/a.txt /ztyuse
#导出容器 导出容器内容留作一个tar归档文件
docker export 容器id > xxxx.tar
#导入容器 从tar包中去内容再创建一个新的文件系统再导入为镜像
cat xxx.tar | docker import - 镜像用户(类似包名)/镜像名:镜像版本号
cat xxx.tar | docker import - zty/ubuntu:1.0