1. Docker概述
1.1. Docker安装
1.1.1 Docker的基本组成
镜像(image):
docker镜像就好比是一个目标,可以通过这个目标来创建容器服务,tomcat镜像 => run => 容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。
容器(container):
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的.
启动,停止,删除,基本命令
目前就可以把这个容器理解为就是一个简易的 Linux系统。
仓库(repository):
仓库就是存放镜像的地方!
仓库分为公有仓库和私有仓库。(很类似git)
Docker Hub是国外的。
阿里云…都有容器服务器(配置镜像加速!)
1.1.2 安装Docker
环境查看
➜ ~ uname -r
4.18.0-305.19.1.el8_4.x86_64 # 要求Linux内核3.0以上
➜ ~ cat /etc/os-release # 查看系统配置
NAME="CentOS Linux"
VERSION="8"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
1. 安装:
# 1. 卸载旧版本
➜ ~ yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2. 安装需要的安装包
➜ ~ yum install -y yum-utils
# 3. 设置镜像的仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo # 默认是从国外下载
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # ali云镜像
# 3. 更新软件包索引
yum makecache
# 4. 安装docker相关的Engine docker-ce社区版/docker-ee企业版
yum install docker-ce docker-ce-cli containerd.io
# 5.启动docker
systemctl start docker
# 6. 使用docker version查看是否按照成功
docker version
# 7. 测试
docker run hello-world
# 8.查看已经下载的镜像(从这里可以查看已有镜像的id)
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 4 months ago 13.3kB
2. 卸载
# 1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2. 删除资源
rm -rf /var/lib/docker # /var/lib/docker 是docker的默认工作路径
1.1.3 安装Docker
1.帮助命令
docker version # 显示docker的版本信息。
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令
Docker帮助文档地址:https://docs.docker.com/engine/reference/commandline/build/
2.镜像命令
docker images # 查看所有本地主机上的镜像 可以使用docker image ls代替
docker search # 搜索镜像
docker pull # 下载镜像 docker image pull
docker rmi # 删除镜像 docker image rm
3. docker images命令
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images
# -----------------------------------------------------------------------------------
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 4 months ago 13.3kB
mysql 5.7 b84d68d0a7db 6 days ago 448MB
# -----------------------------------------------------------------------------------
# 解释
# REPOSITORY # 镜像的仓库源
# TAG # 镜像的标签(版本) ---lastest 表示最新版本
# IMAGE ID # 镜像的id
# CREATED # 镜像的创建时间
# SIZE # 镜像的大小
# -----------------------------------------------------------------------------------
# Options(可选项):
-a, --all Show all images (default hides intermediate images) #列出所有镜像
-q, --quiet Only show numeric IDs # 只显示镜像的id
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images -a # 列出所有镜像详细信息
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images -aq # 列出所有镜像的id
4. docker search命令
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker search mysql
# -----------------------------------------------------------------------------------
# Options(可选项):
-f, --filter filter 过滤
# docker search mysql --filter=STARS=3000 # 过滤,搜索出来的镜像收藏STARS数量大于3000的
5. docker pull命令
用法:docker pull 镜像名[:tag]
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker pull tomcat:8
# -----------------------------------------------------------------------------------
8: Pulling from library/tomcat # 如果不写tag,默认就是latest
90fe46dd8199: Already exists # 分层下载: docker image的核心:联合文件系统
35a4f1977689: Already exists
bbc37f14aded: Already exists
74e27dc593d4: Already exists
93a01fbfad7f: Already exists
1478df405869: Pull complete
64f0dd11682b: Pull complete
68ff4e050d11: Pull complete
f576086003cf: Pull complete
3b72593ce10e: Pull complete
Digest: sha256:0c6234e7ec9d10ab32c06423ab829b32e3183ba5bf2620ee66de866df # 签名防伪
Status: Downloaded newer image for tomcat:8
docker.io/library/tomcat:8 # 真实地址
# -----------------------------------------------------------------------------------
# 等价于
docker pull docker.io/library/tomcat:8
docker rmi 删除镜像
用法:docker rmi -f 镜像id
-f :全部删除
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker rmi -f f19c56ce92a8
docker rmi -f $(docker images -aq) # 通过复合查询的方式删除全部的镜像
1.1.4 基本容器命令
镜像下载
docker pull centos # docker中下载centos
新建容器并启动
docker run [可选参数] iamge
# -----------------------------------------------------------------------------------
# Options(可选项):
--name="Name" # 容器名字,用于区分容器
-d # 后台方式运行,问题:当docker容器采用后台运行,就必须要有要一个前台进程,否则会由于docker发现没有应用,而自动停止;例如:nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
-it # 使用交互方式运行,进入容器查看内容
-p # 指定容器的端口 -p 8080:8080
-P # 随机指定端口
# -----------------------------------------------------------------------------------
# 测试,并进入容器
[root@kuanshen/] # docker run -it centos /bin/bash
[root@xxxxxxx /] # ls # 查看容器内的centos,基础版本,很多命令都是不完善的
退出容器
[root@kuanshen/] # exit # 直接停止容器并退出
ctrl + P + Q # 容器不停退出
列出所有运行的容器
# docker ps 命令
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器 + 历史运行的容器
-n=? # 列出最近创建的容器
-q # 只显示容器的编号
删除容器
用法:docker rm 容器id # 删除指定容器,但不能删除正在运行的容器
docker rm -f $(docker ps -aq) # 强制删除所有容器
docker rm -a -q|xarg dicjer rn # 递归删除所有容器
启动和停止容器
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
1.1.5 常用其他命令
查看日志
docker logs -t --tail n 容器id # 查看n行日志
docker logs -ft 容器id # 更新的日志
# -----------------------------------------------------------------------------------
# Options(可选项):
-tf # 显示日志信息(一直更新)
--tail number #需要显示日志条数
查看容器中进程信息
# 用法:docker top 容器id
[root@kuanshen/] # docker top dce7b86171bf
# UID 用户ID
# PID 负ID
# PPID 进程ID
查看镜像的元数据
# 用法:docker inspect 容器id
[root@kuanshen/] # docker inspect dce7b86171bf
进入当前正在运行的容器
# 容器通常都是后台运行的,需要进入容器,需要修改一些配置
# 用法1:docker exec -it 容器id bashshell 进入容器后开启一个新的终端,可以在里面操作(常用)
# 方法2:docker attach 容器id 进入容器正在执行的终端,不会启动新的进程
从容器内拷贝到主机上
docker cp 容器id:容器内路径 主机目的路径
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56a5583b25b4 centos "/bin/bash" 7seconds ago Up 6 seconds
# 1. 进入docker容器内部
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker exec -it 56a5583b25b4 /bin/bash
[root@55321bcae33d /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 2. 在容器内新建一个文件
[root@55321bcae33d /]# echo "hello" > java.java
[root@55321bcae33d /]# cat hello.java
hello
[root@55321bcae33d /]# exit
exit
# 3. 将文件hello.java拷贝到主机home文件加下
[root@iz2zeak7sgj6i7hrb2g862z /]# docker cp 56a5583b25b4:/hello.java /home
[root@iz2zeak7sgj6i7hrb2g862z /]# cd /home
[root@iz2zeak7sgj6i7hrb2g862z home]# ls -l #可以看见java.java存在
total 8
-rw-r--r-- 1 root root 0 May 19 22:09 haust.java
-rw-r--r-- 1 root root 6 May 22 11:12 java.java
drwx------ 3 www www 4096 May 8 12:14 www
# 当前拷贝是一个手动过程,未来我们使用 -v 券的技术,可以实现数据的同步
命令大全
attach Attach local standard input, output, and error streams to a running container # 当前shell下 attach连接指定运行的镜像
build Build an image from a Dockerfile # 通过Dockerfile定制镜像
commit Create a new image from a container's changes # 提交当前容器为新的镜像
cp Copy files/folders between a container and the local filesystem # 拷贝文件
create Create a new container # 创建一个新的容器
diff Inspect changes to files or directories on a container's filesystem # 查看docker容器的变化
events Get real time events from the server # 从服务获取容器实时时间
exec Run a command in a running container # 在运行中的容器上运行命令
export Export a container's filesystem as a tar archive # 导出容器文件系统作为一个tar归档文件[对应import]
history Show the history of an image # 展示一个镜像形成历史
images List images # 列出系统当前的镜像
import Import the contents from a tarball to create a filesystem image # 从tar包中导入内容创建一个文件系统镜像
info Display system-wide information # 显示全系统信息
inspect Return low-level information on Docker objects # 查看容器详细信息
kill Kill one or more running containers # kill指定docker容器
load Load an image from a tar archive or STDIN # 从一个tar包或标准输入中加载一个镜像[对应save]
login Log in to a Docker registry # 登陆到Docker hub
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
1.2 镜像原理
1.2.1 镜像是什么**
镜像是一种轻量级、可执行的独立软件保,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。
如何得到镜像
- 从远程仓库下载
- 别人拷贝给你
- 自己制作一个镜像 DockerFile
1.2.2 Docker镜像加载原理**
- UnionFs(联合文件系统): Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。 - Docker镜像加载原理:
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs (boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots。这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
对于一个精简的OS, rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级! - 分层理解
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。 - 特点
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层
1.2.3 commit镜像
docker commit 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[版本TAG]
实战测试
# 1、启动一个默认的tomcat
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d -p 8080:8080 tomcat
de57d0ace5716d27d0e3a7341503d07ed4695ffc266aef78e0a855b270c4064e
# 2、发现这个默认的tomcat 是没有webapps应用,官方的镜像默认webapps下面是没有文件的!
#docker exec -it 容器id /bin/bash
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker exec -it de57d0ace571 /bin/bash
root@de57d0ace571:/usr/local/tomcat#
# 3、从webapps.dist拷贝文件进去webapp
root@de57d0ace571:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@de57d0ace571:/usr/local/tomcat# cd webapps
root@de57d0ace571:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
# 4、将操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像即可,而不需要每次都重新拷贝webapps.dist下的文件到webapps了,这就是我们自己的一个修改的镜像。
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="kuangshen" -m="add webapps app" 容器id tomcat02:1.0
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker commit -a="csp提交的" -m="add webapps app" de57d0ace571 tomcat02.1.0
sha256:d5f28a0bb0d0b6522fdcb56f100d11298377b2b7c51b9a9e621379b01cf1487e
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02.1.0 latest d5f28a0bb0d0 14 seconds ago 652MB
tomcat latest 1b6b1fe7261e 5 days ago 647MB
nginx latest 9beeba249f3e 5 days ago 127MB
mysql 5.7 b84d68d0a7db 5 days ago 448MB
elasticsearch 7.6.2 f29a1ee41030 8 weeks ago 791MB
portainer/portainer latest 2869fc110bf7 2 months ago 78.6MB
centos latest 470671670cac 4 months ago 237MB
hello-world latest bf756fb1ae65 4 months ago 13.3kB
1.3 容器数据卷
1.3.1 什么是容器数据卷
docker的理念回顾
docker的本质是将应用和环境打成一个镜像
数据?如果数据都在容器中,那么我们容器删除,则数据就会消失;需求:数据可以持久化
例如:Mysql,容器删了,数据没了;需求:Mysql数据可以存储在本地
容器数据卷技术,使得容器之间可以数据共享。使得Docker容器中产生的数据,可以同步到本地;
总结一句话:容器的持久化和同步操作!容器间也可以共享数据!
1.3.2 使用数据卷
方式一:直接使用命令来进行挂载
docker run -it -v
1. Docker安装MySQL实例
# 获取镜像
➜ ~ docker pull mysql:5.7
# 注意:1. 运行容器,需要作品数据挂载;2. 需要配置密码
➜ ~ docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/mysql.conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# -----------------------------------------------------------------------------------
# 说明:
-d # 后台运行
-p # 端口映射
-v # 卷挂载(第一个为本地终端路径,第二个为docker路径)
-e # 环境配置
--name # 容器名字
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf
2. Docker安装MySQL实例
# 获取镜像
➜ ~ docker pull cptactionhank/atlassian-jira-software:8.1.0
➜ ~ docker run -d -p 80:8080 --name jira-software cptactionhank/atlassian-jira-software:8.1.0
# -----------------------------------------------------------------------------------
# 说明:
-d # 后台运行
-p # 端口映射
-v # 卷挂载
-e # 环境配置
--name # 容器名字
1.3.3 具名和匿名挂载
# 1. 匿名挂载: 通过 -v 容器内的路径(而没有写容器外的路径)
➜ ~ docker run -d -P --name nginx01 -v /etc/nginx nginx
➜ ~ docker volume ls # 查看所有的volume的情况
# -----------------------------------------------------------------------------------
# 说明:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
# -----------------------------------------------------------------------------------
DRIVER VOLUME NAME
local 6c971401bf6872f045a210dca5dd90252639cc7552f07c2ee14979caa46ecce4
# 2. 具名挂载: 通过 -v 卷名:容器内路径
➜ ~ docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx nginx
➜ ~ docker volume ls
# -----------------------------------------------------------------------------------
DRIVER VOLUME NAME
local juming-nginx
所有的docker容器内的卷,在没有指定目录的情况下都是在/var/lib/docker/valumes/xxxx/_data
我们通过具名挂载可以方便的找到我们的一个卷,绝大多数情况下使用具名挂载
扩展
# 通过 -v 容器内路径, ro rw改变挂载的读写权限
# ro readonly 只读
# rw readwrite 可读可写
# 一旦通过该方法设置了容器的权限,容器对我们挂载出来的内容就有了限定
# 例如
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:ro nginx # 只能从宿主机改变,容器无法操作
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
1.3.4 初始Dockerfile
Dockerfile
就是用来构建docker镜像的构建文件,实质为命令脚本,通过这个脚本可以生成镜像,由于镜像是一层一层的,这个脚本也是一层一层的;
# 1. 创建一个dokcerfile文件,名字可以随机,建议以dockerfile为名
# 文件中的内容(指令)均为大写
FROM centos
VOLUME ["volume01","volume02"] # 匿名挂载
CMD echo "----end-----"
CMD /bin/bash
# 2. 使用docker build命令
docker build -f /home/docker-test-volumes/dockerfile -t kuanshen/centos:1.0 .
# 3. 查看容器信息
docker inspect 容器id