docker从入门到精通
本文参考转自:https://blog.csdn.net/2401_84578953/article/details/145607494
【1】初始化操作
(1.1)docker卸载与安装
# 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 # 推荐使用阿里云的。 # 安装容器之前,更新yum软件包索引。 yum makecache fast # 4.安装容器相关的。docker-ce(社区版)docker-ee(企业版) yum install docker-ce docker-ce-cli containerd.io # 5.启动docker systemctl start docker # 6.使用docker version查看是否安装成功
(1.2)拉取、执行第一个镜像
docker run hello-world # 如果不行则 docker search docker.1ms.run/hello-world # 过程:run会从本地镜像找,没有就从官网下载、再运行

(1.3)阿里云加速
- 登录阿里云,找到容器服务。
- 找到镜像加速地址。
- 配置使用。
四个命令,依次执行即可:
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://xxx.xxx.xxx.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
二、docker常用操作
(2.1)docker基本命令参考
Docker常用命令原理图_胡伟煌的博客-CSDN博客 这个是一个大佬写的原理图!!! yyds
(2.1)帮助命令
docker version # 显示docker的版本信息 docker info # 显示docker的系统信息,包括镜像和容器的数量 docker 命令 --help # 帮助命令 如 docker run --help (2.2)镜像 docker images # 查看所有镜像 docker search image # 查找镜像 docker pull image # 从仓库下载镜像
docker push image # 上传本地镜像到仓库 docker rmi image/id # 根据镜像名/镜像ip删除镜像 (2.3)容器命令基础 docker run <参数> image # 根据镜像新建容器并启动。 --name 给容器起一个自定义名字 -d 为后台守护进程启动 -it 为交互式启动一个新终端(通常用于通过bash进入容器OS) -p 指定容器的端口,也可以指定容器与宿主机的端口映射关系 docker run -d -p 宿主机端口:容器端口 镜像id
案例:docker run -d --name nginx01 -p 3344:80 nginx docker ps -a # 列出所有容器运行信息 -q 为仅列出id docker rm container/id # 删除容器,若容器正在执行则无法删除,除非使用 rm -f 参数强制执行
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
(2.4)docker 导入导出镜像
docker save 保存的是镜像,docker export 保存的是容器
docker load 是用来加载镜像包,docker import 是用来加载容器包,但两者都会恢复为镜像
docker load 不能对载入的镜像重命名,而 docker import 可以为镜像指定新名称
使用场景:save/load 适合原生包迁移,export/import 适合在容器中配置了基础环境后的自定义镜像导入导出
docker save -o myimage.tar myimage:tag # 把 myimage:tag 镜像打包成 myimage.tar,多个镜像到一个镜像包的话,以空格分割即可
# save 如果指定的是 containerid,那么打包的是生成该容器的镜像文件
docker save i # 查看打包进度
docker load -i myimage.tar # 把 myimage.tar 中的镜像导入到本地 docker,如果本地有同名的,将会被覆盖
docker export -o file.tar containerid # 把容器的文件系统打包生成 file.tar 容器包文件
docker import postgres-export.tar postgres:latest # 把容器导出的文件恢复成一个镜像 postgres:lasest
(2.5)容器运维实用命令
docker run -d image # 后台进程运行镜像
docker logs -f 容器id/名字 # 查看容器日志 默认在/var/lib/docker/comtainers/容器id/容器id-json.log
--details 显示更多的信息
-f, --follow # 动态更新日志
--since string # 显示自某时间之后的日志或相对时间 docker logs -f -t --since="2020-02-02" --tail=10 容器ID/名称
--tail string # 显示末尾开始指定行,默认是全部 docker logs -f -t --tail=25 容器ID/名称
-t, --timestamps # 日志显示时间戳
--until string # 显示自某时间之后的日志或相对时间 docker logs -t --since="2020-05-06T12:00:00" --until "2020-05-07T12:00:00" 容器ID/名称
docker inspect 容器id # 获取容器元数据
docker exec -it 容器id /bin/bash # (常用)以一个新终端进入容器OS
docker attach 容器id # (不建议)进入容器正在执行的终端,不会启动新进程
docker copy 容器id:容器内路径 目的主机路径 # 复制文件案例:docker cp 容器id:容器内路径 目的主机的路径
docker run -d --name nginx01 -p 3344:80 nginx
(2.2)docker 所有命令参数
转自:docker常用命令_JWei_7的博客-CSDN博客

attach Attach 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 from a container to a HOSTDIR or to STDOUT #从容器中拷贝指定文件或者目录到宿主机中 create Create a new container #创建一个新的容器,同run 但不启动容器 diff Inspect changes on a container's filesystem #查看docker容器变化 events Get real time events from the server#从docker服务获取容器实时事件 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包中的内容创建一个新的文件系统映像(对应export) info Display system-wide information #显示系统相关信息 inspect Return low-level information on a container or image #查看容器详细信息 kill Kill a running container #kill指定docker容器 load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save) login Register or log in to a Docker registry#注册或者登陆一个docker源服务器 logout Log out from a Docker registry #从当前Docker registry退出 logs Fetch the logs of a container #输出当前容器日志信息 pause Pause all processes within a container#暂停容器 port List port mappings or a specific mapping for the CONTAINER #查看映射端口对应的容器内部源端口 ps List containers #列出容器列表 pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像 push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器 rename Rename a container #重命名容器 restart Restart a running container #重启运行的容器 rm Remove one or more containers #移除一个或者多个容器 rmi Remove one or more images #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除) run Run a command in a new container #创建一个新的容器并运行一个命令 save Save an image(s) to a tar archive#保存一个镜像为一个tar包(对应load) search Search the Docker Hub for images #在docker hub中搜索镜像 start Start one or more stopped containers#启动容器 stats Display a live stream of container(s) resource usage statistics #统计容器使用资源 stop Stop a running container #停止容器 tag Tag an image into a repository #给源中镜像打标签 top Display the running processes of a container #查看容器中运行的进程信息 unpause Unpause all processes within a container #取消暂停容器 version Show the Docker version information#查看容器版本号 wait Block until a container stops, then print its exit code #截取容器停止时的退出状态值 ———————————————— 原文链接:https://blog.csdn.net/qq_54729417/article/details/127945665
三、docker图形化与原理
(3.1)Docker可视化界面工具 portainer
什么是portainer ?
Docker图形化界面管理工具!提供一个后台面板供我们操作!类似于 宝塔面板
8088 外网访问端口 9000 是内部映射端口
docker.1ms.run/
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# 如果不行则最末尾改成 docker.1ms.run/portainer/portainer
然后URL访问即可 ip:8088,配置账户密码

登录后如下图

(3.2)docker镜像概念与原理
1. 镜像基础原理
Docker镜像
镜像是什么?
镜像是一种轻量级,可执行化的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件锁需要的所有内容,包括代码,运行时(库,环境变量和配置文件)。
所有的应用 直接打包docker 镜像 就可以直接跑起来!
镜像加速原理
(1)UnionFS(联合文件系统)
我们下载的时候看到的一层层就是这个!

UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
**特性:**一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
2. 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等等。


平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。
由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
(虚拟机是分钟级,容器是秒级!)
3. 分层理解
分层镜像

我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
Docker镜像要采用这种分层的好处?
**资源共享** 有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像。
同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
- 所有的Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
- 举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;
- 如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。

简单来说 就是 原本有的 就共享 没有的咱就下载 更新了 就替换新的
特点:
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!

4. commit镜像
# 提交容器成为一个新的副本
docker commit
# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
- # 1.启动一个默认的tomcat。
- # 2.发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的。
- # 3.我自己拷贝进去了基本的文件。
- # 4.将我们操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像。

小结: commit镜像就是游戏存档 tag是版本版本信息
四、docker容器数据卷
(4.1) 什么是容器数据卷?
Docker容器数据卷,即Docker Volume(卷)
当Docker容器运行的时候,会产生一系列的数据文件,这些数据文件会在关闭Docker容器时,直接消失的。
但是其中产生部分的数据内容,我们是希望能够把它给保存起来,另作它用的。
关闭Docker容器=删除内部除了image底层数据的其他全部内容,即删库跑路。
- Docker容器产生的数据同步到本地,这样关闭容器的时候,数据是在本地的,不会影响数据的安全性。
- docker的容器卷技术也就是将容器内部目录和本地目录进行一个同步,即挂载。
总结: 容器的持久化和同步化操作,容器之间也是可以数据共享的(但是注意挂载不是等同于同步!!!)
(4.2) 使用数据卷(容器数据持久化,删掉容器数据也还在)
使用命令来挂载 -v,主机目录和容器内的目录是映射关系
docker run -it -v 主机目录:容器内目录 镜像名 /bin/bash # 测试,查看容器信息 docker inspect 容器id
- mounts 加载的文件系统
- source 是源地址 就是 当前你这个docker里面的地址目录
- destination 是 这个容器的目录

通过 -v挂载目录后 会对这个俩个目录中的数据进行 双向绑定(bind):
在容器的/home文件夹下,新建test.java文件,会同步到主机的/home/ceshi文件夹下。一方目录删除另外一方目录也没有了文件。
(4.3)docker安装mysql
# 获取镜像 docker pull mysql:5.7 # 运行容器,需要做数据目录挂载。(安装启动mysql,注意:需要配置密码) # 官方启动mysql docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag # 我们启动mysql(-e是环境配置) [root@JWei_0124 home]# docker run -d -p 8081:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:8.0.27 # 启动成功之后,我们在本地使用navicat来接测试一下。 # navicat连接到服务器的8081端口和容器内的3306映射,这个时候我们就可以连接上了! # 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!(OK的) # 连接验证 mysql -uroot -p123456 -h 127.0.0.1:8081 -- 没问题,换个机器用 navicat 之类的工具也没问题,证明docker mysql 里面有默认的root%,密码与我们这个相同
-v 的宿主机目录不存在的话会被新建
删除容器,但与宿主机同步挂载的目录下依然有文件。见下图:

(4.4)卷挂载的几种方式(匿名,具名,指定路径)
默认 volume 路径为 /var/lib/docker/volumes
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data"(xxxx是卷名)
匿名则为一个UUID,署名则名字是什么在该目录下文件夹名就是什么
docker run -d -p --name nginx01 -v /etc/nginx nginx # 匿名,只写了容器内的路径 /etc/nginx docker run -d -p 3344:80 --name nginx02 -v juming-nginx:/etc/nginx nginx # 指定名称juming-nginx docker run -d -v /data/nginx:/etc/nginx nginx # 指定绝对路径 ,不会在默认路径下显示 # 查看所有的volume的情况 docker volume ls
# 查看volume详细信息 docker volume inspect volume_name
# 如何查看 volumn和容器的关联关系 docker inspect container_id/name
[root@JWei_0124 ~]#
docker volume ls DRIVER VOLUME NAME
local 964b8e505f12f65fb23fd21f05cfa9ecd6c2c6b2ca89c0e44f168bb017dfabd6 # 这种就是匿名挂载:我们在-v挂载目录时,只写了容器内的路径,没有写容器外的路径。
local juming-nginx # 这就是具名挂载 -v 时给容器内路径取了一个名字 juming-nginx
# 如何确定是具名挂载,还是匿名挂载,还是指定路径挂载
-v 容器内的路径 # 匿名挂载
-v 卷名:容器内的路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
扩展:权限
# 通过 -v 容器内的路径:ro rw 改变读写权限 ro read only # 只读 rw read write # 可读可写 # 一旦设置了容器权限,容器对我们挂载出来的内容就有了限定。 docker run -d -p 3344:80 --name nginx02 -v juming-nginx:/etc/nginx:ro nginx docker run -d -p 3344:80 --name nginx02 -v juming-nginx:/etc/nginx:rw nginx # 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
(4.5)dockerfile初实践
dockerfile 就是用来构建 docker 镜像的构建文件。 命令脚本!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个一个的命令,每个命令都是一层!
# 创建一个dockerfile文件,名字可以随机,建议dockerfile # 文件中的内容:指令都是大写
cat >>dockerfile01 <<EOF FROM centos VOLUME ["volume01","volume02"] CMD echo "-----end-----" CMD /bin/bash # 这里的每个命令,就是镜像的一层。
EOF
docker build if ./dockerfile01 -t centos:1.0 ./
生成的镜像如下:

运行镜像查看:如下图,我们在dockerfile01文件中配置了2个 volume
(VOLUME ["volume01","volume02"] ,没写路径默认就是在 / 根目录下)
显示在下面,对应会有一个宿主机目录

查看一下卷挂载的路径:docker inspect 容器id,如下图所示,和默认的匿名挂载存放的宿主机位置一样

测试一下文件是否同步出去:在容器的volume01文件夹下创建文件,查看宿主机对应目录是否同步成功。
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!
如果构建镜像时候没有挂载卷,就需要自己手动镜像挂载目录!
同步测试如下,同步成功。但我是开了2个进程。 或者使用 docker exec -it docker_id/name 进去。


(4.6)容器复用同一个卷,复用别的容器挂载的卷

docker run -d -name centos01 centos:1.0 # 用上面自己构建的镜像 docker run -d -name centos02 --volumes-from centos01 centos:1.0 # 引用centos01容器的
docker run -d -name centos03 --volumes-from centos01 centos:1.0 # 引用centos01容器的
docker01/02/03 共享一个目录,互相可以删除、增加 均会反馈到对方目录。
因为是做了匿名挂载的,即使 docker rm centos01 ,centos02/03 里的数据依然不会消失。
因为对于的宿主机文件还存在(我们之前说过,持久化后容器删除不会删除对于映射宿主机目录中的文件)
【mysql数据目录同步案例】
# 一个配置文件2个容器公用、同步,和现在的云共享文档一样。 [root@iZbp13qr3mm4ucsjumrlgqZ ~]# docker run -d -p 7777:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 [root@iZbp13qr3mm4ucsjumrlgqZ ~]# docker run -d -p 7777:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7 # 这个时候,可以实现两个容器数据同步!
五、Dockerfile
(5.1)什么是DockerFile ?
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run运行镜像
4、docker push发布镜像(DockerHub、阿里云镜像仓库!)
(5.2) 搭建步骤
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序执行
3、# 表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!

dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
DockerFile:构建文件,定义了一切的步骤,源代码。
Dockerlmages:通过DockerFile构建生成的镜像,最终发布和运行的产品。
Docker容器:容器就是镜像运行起来提供服务的。
(5.3)dockerfile命令
FROM # 基础镜像,一切从这里开始构建 MAINTAINER # 镜像是谁写的:姓名+邮箱 RUN # 镜像构建的时候需要运行的命令 ADD # 步骤:tomcat镜像,这个tomcat压缩包!添加内容 WORKDIR # 镜像的工作目录 VOLUME # 挂载的目录 EXPOSE # 暴露端口配置 CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令 ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的指令。触发指令。 COPY # 类似ADD,将我们文件拷贝到镜像中 ENV # 构建的时候设置环境变量!
作用如下图:

(5.4)测试实践
Docker Hub中99%镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行的构建。
# 1. 编写dockerfile02文件 FROM centos:7 MAINTAINER sywl<xxx@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH
RUN echo -e '[aliyun]\nname=Alimama Mirror\nbaseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/\ngpgcheck=1\nenabled=1\ngpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7' > /etc/yum.repos.d/CentOS-Base.repo
RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "-----end-----" CMD /bin/bash # 2. 通过这个文件构建镜像 # 命令:docker build -f dockerfile文件路径 -t 镜像名:[tag] docker build -f dockerfile02 -t mycentos:0.1 . Successfully built 285c2064af01 Successfully tagged mycentos:0.1 # 3. 测试运行

查阅变更历史:docker history 镜像id

(5.5)CMD和ENTRYPOINT区别
详情参考:https://blog.csdn.net/qq_54015483/article/details/132823037
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
测试CMD
# 1. 编写dockerfile文件 [root@iZbp13qr3mm4ucsjumrlgqZ dockerfile]# vim mydockerfile-cmd-test [root@iZbp13qr3mm4ucsjumrlgqZ dockerfile]# cat mydockerfile-cmd-test FROM centos:7 CMD ["ls","-a"] # 2. 构建镜像 [root@iZbp13qr3mm4ucsjumrlgqZ dockerfile]# docker build -f mydockerfile-cmd-test -t cmdtest . # 3. run运行,发现我们的"ls -a"命令生效、执行

# 4. 我们先追加一个命令"l",构成"ls -al"命令,发现报错 [root@iZbp13qr3mm4ucsjumrlgqZ dockerfile]# docker run ec0d2dd226b3 -l docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown. ERRO[0000] error waiting for container: context canceled # 原因:CMD命令的情况下,"-l"替换了CMD["1s","-a"]命令,因为"-l"不是命令,所以报错!
测试ENTRYPOINT
# 1. 编写dockerfile文件 [root@iZbp13qr3mm4ucsjumrlgqZ dockerfile]# vim mydockerfile-entrypoint-test [root@iZbp13qr3mm4ucsjumrlgqZ dockerfile]# cat mydockerfile-entrypoint-test FROM centos:7 ENTRYPOINT ["ls","-a"] # 2. 构建镜像 [root@iZbp13qr3mm4ucsjumrlgqZ dockerfile]# docker build -f mydockerfile-entrypoint-test -t entrypointtest . # 3. run运行,发现我们的"ls -a"命令生效、执行

# 4. 我们先追加一个命令"l",构成"ls -al"命令,发现命令生效、执行

# 原因:ENTRYPOINT命令的情况下,"-l"追加在ENTRYPOINT ["1s","-a"]命令后面,得到"ls -al"的命令,所以命令正常执行!
# (我们的追加命令,是直接拼接在我们的ENTRYPOINT命令的后面)
(5.6)CMD和ENTRYPOINT使用总结
上面案例都是添加选项。
还有覆盖操作,如:docker run -it mycentos:0.1 date ,会执行date,具体执行、报错、覆盖情况如下:
Dockerfile的命令 命令是否可以被dcoker run 覆盖 是否可以添加选项
CMD cal 可以被覆盖 不能添加选项,添加选项后会报错
CMD [“cal”] 可以被覆盖 不能添加选项,添加选项后会报错
ENTRYPOINT cal 不可以被覆盖,添加的命令会被忽略 不能添加选项,添加的选项被忽略
ENTRYPOINT [“cal”] 不可以被覆盖,添加命令后会报错 可以添加选项
ENTRYPOINT [“/bin/bash”,“-c”,“cal”] 不可以被覆盖,添加的命令会被忽略 不能添加选项,添加的选项被忽略
ENTRYPOINT-shell形式的语法:ENTRYPOINT command param1 param2
ENTRYPOINT-exec 形式语法:(1)ENTRYPOINT [“cal”] (2)ENTRYPOINT [“/bin/bash”,“-c”,“cal”]
六、Docker 网络
(6.1)docker默认网络
docker默认有一个虚拟路由docker0,docker0的网络模式就是bridge桥接模式,docker容器之间个主机之间通过这个虚拟路由进行转发,相当于一个局域网;
创建容器时docker会为每个容器创建一个虚拟网卡。

查看宿主机网络信息。

查看 docker0 在哪里

启动一个新容器,会自动生成一个vethxx@ifxxx的网卡。
docker run -d -P --name nginx01 docker.1ms.run/nginx
docker run -d -P --name nginx02 docker.1ms.run/nginx

- 所以 我们可以发现 容器带来的网卡 都是一对一对的,59ID,下一个容器就是61ID了。这里好像不是核能体现出一对
- veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连。
- 正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的。
- openstack,Docker容器之间的连接,OVS的连接,都是使用**veth-pair**技术。
- 注意,如果你进入容器,ip addr(apt install -y iproute2)发现eth0@if58 网卡后面的@if58会对应外面的@if59,这就是一对的体现
(6.2)容器默认网络,默认NAT模式
启动容器后,查看容器ip,在宿主机的 ip a 命令中并没有显示出来ipv4,如上图。
# 启动容器
docker run -d -P --name nginx01 docker.1ms.run/nginx
docker run -d -P --name nginx01 docker.1ms.run/nginx
docker inspect nginx01| grep IPAddress # 查看容器ip地址,发现默认会从 172.17.0.2开始dhcp自动分配,网关为docker0网卡 即172.17.0.1 # 在容器里安装ping命令 docker exec -it nginx01 apt-get update
docker exec -it nginx01 apt-get install -y 'iputils-ping' # 测试宿主机,容器之间网络是否通畅 ping 10.17.0.2 # 宿主机访问nginx01 ping 10.17.0.3 # 宿主机访问nginx02 docker exec -it nginx01 ping 172.17.0.3 docker exec -it nginx02 ping 172.17.0.2

结论:tomcat01和tomcat02是公用的一个路由器,dockero。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP

Docker中的所有的网络接口都是虚拟的。虚拟的转发效率高!(内网传递文件!)
只要容器删除,对应网桥一对就没了!
(6.3)网络模式与自定义网络
(1)概念
网络模式:docker network ls
-
bridge:桥接 docker(默认,自己创建也使用bridge桥接模式)
-
none:不配置网络
-
host:和主机共享网络
-
container:容器网络连通!(用的少!局限很大)
docker network inspect network_id(查阅详情),我们查看了刚 bridge的网络id,如下图,我们默认的应用启动的网络地址信息均存在于其中。

(2)新建自定义网络
#1 创建一个网桥模式的自定义网络,子网为...网关为..名称为 mynet
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
docker network ls # 查阅是否已经有了
[root@iZbp13qr3mm4ucsjumrlgqZ ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 7254ffccbdf5 bridge bridge local 45610891738f host host local 266acd66473c mynet bridge local 7795cbc2686c none null local
#2 容器使用新网络启动
docker run -d -P --name tomcat-net-01 --net mynet tomcat:7.0
docker run -d -P --name tomcat-net-02 --net mynet tomcat:7.0
#3 互相访问
默认的brige里面是无法直接访问容器名称的(除非使用Link),自定义网络中的是可以互相识别容器名(自动配置维护dns)
docker exec -it tomcat-net-01 ping tomcat-net-02

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql -不同的集群使用不同的网络,保证集群是安全和健康的
(6.4)docker本地跨网段访问
bridge 网络下对应容器IP:
nginx01:172.17.0.2
nginx02:172.17.0.3
mynet 网络下对应容器IP:
ngxin-net01:192.168.0.2
ngxinx-net02:192.168.0.3
docker network connect mynet nginx01 # 把nginx01 连接上 mynet网段,其实就是给改容器加个网卡,地址为 mynet 网络中的地址(本案例为 192.168.0.4)
docker exec -it nginx01 ping 192.168.0.2 # 可以ping通 ip
docker exec -it ngxin_net01 ping nginx01 # 可以ping通,但ping容器名映射的地址是 192.168.0.4
docker exec -it ngxin_net01 ping 172.17.0.2 # 不能 ping 通,只能访问同网段地址,除非另起命令运行
# docker network connect bridge ngxin_net01 ,给 ngxin_net01容器添加一个 bridge 网段的网卡
详情见下图:

发现其原理竟然在对方网络里加块网卡,此时 ping 自然可以通了。
七、docker基本运维所有命令
一、服务管理命令
systemctl start docker:启动 Docker 服务。在安装好 Docker 后,首次使用或服务停止后需要启动时使用该命令。
systemctl stop docker:停止 Docker 服务。当需要对 Docker 进行维护、更新或临时停止使用时,可执行此命令。
systemctl restart docker:重启 Docker 服务。常用于使新的配置生效,比如修改了 Docker 的配置文件后,需要重启服务。
systemctl status docker:查看 Docker 服务状态。可以了解 Docker 服务是否正在运行,以及运行状态的详细信息,如启动时间、进程 ID 等。
systemctl enable docker:设置 Docker 服务开机自启。确保每次系统启动时,Docker 服务都能自动运行,方便后续使用。
systemctl disable docker:取消 Docker 服务开机自启。如果不想让 Docker 在开机时自动启动,可使用此命令。
docker info:查看 Docker 的系统信息,包括镜像和容器的数量、存储驱动、运行时等详细信息。有助于了解当前 Docker 环境的整体情况。
docker --help:查看 Docker 的帮助文档。当对某个 Docker 命令的用法不确定时,可通过此命令获取详细的帮助信息。
docker version:查看 Docker 的版本信息,包括客户端和服务端的版本号。在排查一些与版本相关的问题时非常有用。
二、镜像管理命令
docker images:列出本地所有镜像。展示镜像的仓库名称、标签、镜像 ID、创建时间和大小等信息,方便管理和查看本地镜像资源。
docker search [镜像名称]:在 Docker Hub 上搜索指定名称的镜像。可根据搜索结果选择合适的镜像进行拉取和使用,例如docker search nginx。
docker pull [镜像名称[:标签]]:从 Docker Hub 或其他镜像仓库拉取指定镜像到本地。若不指定标签,默认拉取最新版本(latest),如docker pull ubuntu:20.04。
docker rmi [镜像名称或ID]:删除本地指定的镜像。注意,若镜像正在被容器使用,则无法删除,需先停止并删除相关容器。可同时删除多个镜像,如docker rmi ubuntu:20.04 nginx:latest。
docker build -t [目标镜像名称:标签] [Dockerfile所在路径]:根据指定路径下的 Dockerfile 构建镜像。-t参数用于指定目标镜像的名称和标签,构建过程会根据 Dockerfile 中的指令逐步创建镜像。
docker tag [源镜像名称:标签] [目标镜像名称:标签]:为镜像添加标签(新建一个目标镜像名称:标签)。可用于给镜像打上新的版本号或别名,方便区分和管理不同版本的镜像,例如docker tag ubuntu:20.04 ubuntu:latest。
docker push [镜像名称:标签]:将本地镜像推送到 Docker Hub 或其他远程镜像仓库。需先登录到对应的仓库,如docker push myusername/nginx:latest。
docker history [镜像名称或ID]:查看镜像的构建历史。展示每一层镜像的创建信息,包括创建时间、执行的命令等,有助于了解镜像的构建过程和内容。
docker inspect [镜像名称或ID]:查看镜像的详细信息,以 JSON 格式输出。包含镜像的配置、环境变量、挂载点等各种详细信息,对于排查镜像相关问题非常有帮助。
docker save -o [保存文件名.tar] [镜像名称或ID]:将镜像保存为一个 tar 文件,便于在不同环境中传输和使用。例如docker save -o ubuntu_20.04.tar ubuntu:20.04。
docker load -i [保存文件名.tar]:从 tar 文件中加载镜像到本地。与docker save命令相对应,用于在新环境中恢复镜像。
docker import [容器归档文件路径] [目标镜像名称:标签]:从容器的归档文件创建镜像。可将容器的当前状态保存为一个新的镜像,常用于自定义镜像的制作。
三、容器管理命令
docker run [选项] [镜像名称[:标签]] [容器启动命令]:创建并启动一个容器。常见选项包括-d(后台运行)、-p(端口映射)、-v(卷挂载)等,例如docker run -d -p 80:80 nginx,表示在后台运行一个 nginx 容器,并将宿主机的 80 端口映射到容器的 80 端口。
docker ps:列出当前正在运行的容器。显示容器的 ID、名称、使用的镜像、运行状态、端口映射等信息。
docker ps -a:列出所有容器,包括已停止的容器。方便查看所有创建过的容器记录。
docker start [容器名称或ID]:启动一个已停止的容器。例如docker start mynginx,可将名为 mynginx 的容器启动。
docker stop [容器名称或ID]:停止一个正在运行的容器。通过向容器发送停止信号,让容器正常停止运行。
docker restart [容器名称或ID]:重启一个容器。先停止容器,然后再启动它,常用于使容器内的新配置生效。
docker rm [容器名称或ID]:删除一个已停止的容器。若容器正在运行,需先停止后才能删除,也可使用-f参数强制删除运行中的容器。
docker kill [容器名称或ID]:强制终止一个正在运行的容器。通过发送 SIGKILL 信号立即停止容器,可能导致数据丢失,一般在容器无法正常停止时使用。
docker exec -it [容器名称或ID] [要执行的命令]:在一个正在运行的容器内执行命令。例如docker exec -it mynginx bash,可进入 mynginx 容器的 bash 终端,进行交互式操作。
docker attach [容器名称或ID]:连接到一个正在运行的容器的标准输入、输出和错误输出流。与docker exec不同,docker attach会直接进入容器的主进程,退出时可能会导致容器停止。
docker diff [容器名称或ID]:查看容器内文件系统的变化。显示容器内新增、修改和删除的文件和目录,有助于了解容器运行过程中的文件操作情况。
docker commit -m "[提交信息]" -a "[作者信息]" [容器名称或ID] [目标镜像名称:标签]:从一个运行中的容器创建一个新的镜像。-m参数用于添加提交信息,-a参数指定作者信息,例如docker commit -m "updated nginx config" -a "John Doe" mynginx mynewnginx:1.0。
docker pause [容器名称或ID]:暂停容器内的所有进程。容器状态变为暂停,但资源仍被占用,可通过docker unpause恢复。
docker unpause [容器名称或ID]:恢复暂停的容器内的所有进程,使容器继续正常运行。
docker top [容器名称或ID]:查看容器内正在运行的进程信息,类似于在宿主机上使用top命令查看进程。
docker stats [容器名称或ID]:实时查看容器的资源使用情况,包括 CPU、内存、网络、磁盘 I/O 等指标。
docker cp [容器名称或ID]:[容器内文件路径] [宿主机目标路径]:从容器内复制文件或目录到宿主机。也可反向操作,将宿主机文件复制到容器内,例如docker cp mynginx:/etc/nginx/nginx.conf /tmp/。
docker logs [容器名称或ID]:查看容器的日志输出。可用于排查容器内应用程序的运行问题,例如查看 Web 服务器的访问日志或应用程序的错误日志。
docker logs -f [容器名称或ID]:实时跟踪容器的日志输出,类似于在 Linux 系统中使用tail -f命令查看日志文件,方便实时监控容器的运行状态。
docker logs --tail=[行数] [容器名称或ID]:查看容器日志的最后指定行数,例如docker logs --tail=100 mynginx,可查看 mynginx 容器日志的最后 100 行。
四、网络管理命令
docker network ls:列出所有 Docker 网络。展示网络的名称、ID、驱动类型、子网等信息,方便管理和查看当前的网络配置。
docker network create [网络名称]:创建一个新的 Docker 网络。默认创建的是桥接网络,也可通过指定--driver参数创建其他类型的网络,如docker network create --driver=overlay myoverlaynet。
docker network inspect [网络名称或ID]:查看指定 Docker 网络的详细信息,以 JSON 格式输出。包含网络的配置、连接的容器、子网掩码、网关等详细信息,有助于排查网络相关问题。
docker network rm [网络名称或ID]:删除指定的 Docker 网络。注意,若网络中还有容器连接,则无法删除,需先断开容器与网络的连接。
docker network connect [网络名称或ID] [容器名称或ID]:将容器连接到指定的网络。使容器能够与该网络中的其他容器进行通信,例如docker network connect mynet mynginx。
docker network disconnect [网络名称或ID] [容器名称或ID]:将容器从指定的网络中断开连接。容器将无法再与该网络中的其他容器通信,但仍可通过其他网络进行通信。
docker run --network=[网络名称或ID] [镜像名称[:标签]]:在创建容器时指定容器使用的网络。例如docker run --network=mynet -d nginx,创建一个使用 mynet 网络的 nginx 容器。
五、数据卷管理命令
docker volume ls:列出所有 Docker 数据卷。展示数据卷的名称、驱动、挂载点等信息,方便管理和查看数据卷资源。
docker volume create [数据卷名称]:创建一个新的 Docker 数据卷。数据卷用于在容器之间或容器与宿主机之间共享数据,可持久化保存数据。
docker volume inspect [数据卷名称]:查看指定 Docker 数据卷的详细信息,以 JSON 格式输出。包含数据卷的创建时间、挂载路径、使用的驱动等详细信息。
docker volume rm [数据卷名称]:删除指定的 Docker 数据卷。注意,若数据卷正在被容器使用,则无法删除,需先停止并删除相关容器。
docker run -v [数据卷名称]:[容器内挂载路径] [镜像名称[:标签]]:在创建容器时挂载数据卷到容器内。例如docker run -v myvolume:/data -d mysql,将名为 myvolume 的数据卷挂载到 mysql 容器的 /data 目录。
docker run -v [宿主机路径]:[容器内挂载路径]:在创建容器时将宿主机的目录挂载到容器内。实现容器与宿主机之间的数据共享,如docker run -v /hostdata:/containerdata -d ubuntu。
docker run -v [宿主机路径]:[容器内挂载路径]:ro:在创建容器时将宿主机的目录以只读方式挂载到容器内。容器只能读取挂载目录中的数据,无法进行写入操作,例如docker run -v /hostdata:/containerdata:ro -d ubuntu。
六、其他常用命令
docker system df:查看 Docker 系统的磁盘使用情况,包括镜像、容器、数据卷占用的磁盘空间。有助于了解系统资源的使用情况,及时清理不必要的资源。
docker system prune:清理 Docker 系统中未使用的资源,包括未使用的镜像、容器、网络和数据卷。释放磁盘空间,优化系统性能。
docker builder prune:清理 Docker 构建缓存。在构建镜像过程中,会产生一些缓存文件,使用此命令可清理这些缓存,减少磁盘占用。
docker swarm init:初始化一个 Docker Swarm 集群,将当前节点作为管理节点。用于搭建分布式容器编排环境,实现容器的集群化管理。
docker swarm join --token [令牌] [管理节点地址]:将当前节点加入到指定的 Docker Swarm 集群中。需要从管理节点获取加入令牌,实现集群的扩展。
docker stack deploy -c [docker-compose.yml文件路径] [堆栈名称]:使用 docker - compose 文件部署一个堆栈到 Docker Swarm 集群。方便在集群环境中部署和管理多个相关的容器服务。
docker-compose up:在当前目录下根据 docker - compose.yml 文件启动并运行所有服务容器。常用于本地开发和测试环境中,一键启动多个相关的容器服务。
docker-compose down:停止并删除由 docker - compose.yml 文件定义的所有服务容器、网络和数据卷。用于清理环境,停止相关服务的运行。
docker-compose build:根据 docker - compose.yml 文件构建镜像。如果镜像已经存在,会根据文件中的定义更新镜像。
docker-compose ps:列出由 docker - compose.yml 文件定义的所有服务容器的运行状态,方便查看当前启动的容器情况。
docker-compose logs:查看由 docker - compose.yml 文件定义的所有服务容器的日志输出,方便排查多个容器服务的运行问题。
docker-compose restart:重启由 docker - compose.yml 文件定义的所有服务容器,使新的配置生效。
docker-compose stop:停止由 docker - compose.yml 文件定义的所有服务容器,但保留容器的状态和数据。
docker-compose start:启动之前停止的由 docker - compose.yml 文件定义的所有服务容器。
docker secret create [秘密名称] [文件路径]:在 Docker Swarm 集群中创建一个秘密,用于存储敏感信息,如密码、密钥等。通过文件路径指定要存储的秘密内容。
docker config create [配置名称] [文件路径]:在 Docker Swarm 集群中创建一个配置,用于存储应用程序的配置文件。通过文件路径指定要存储的配置内容。
docker service create --name [服务名称] --replicas [副本数量] [镜像名称[:标签]]:在 Docker Swarm 集群中创建一个服务,指定服务名称、副本数量和使用的镜像。例如docker service create --name mynginx --replicas 3 nginx,创建一个名为 mynginx 的服务,包含 3 个 nginx 容器副本。
docker service update --replicas [新副本数量] [服务名称]:更新 Docker Swarm 集群中服务的副本数量。例如docker service update --replicas 5 mynginx,将 mynginx 服务的副本数量更新为 5 个。
docker service rm [服务名称]:删除 Docker Swarm 集群中的指定服务,停止并删除服务的所有容器副本。
docker service scale [服务名称]=[副本数量]:调整 Docker Swarm 集群中服务的副本数量,与docker service update --replicas命令功能类似。例如docker service scale mynginx = 4,将 mynginx 服务的副本数量调整为 4 个
————————————————
版权声明:本文为CSDN博主「leah126」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/leah126/article/details/151649252
【最佳实践】
(1)docker日志很多应该怎么办?
find /data/docker -type f -name "*.log" -exec sh -c "echo ''>{}" \; find /data/docker -type f -name "*.log"|xargs -I {} sh -c "echo ''>{}"
【参考文档】
转自:https://blog.csdn.net/weixin_64015933/article/details/125743089
四、 总结
1、如果镜像优化?
2、怎么看当下有多大号容器,怎么看当下所有容器占用的I/O有多少,占用内存多少?
3、容器有哪些状态?
4、overlay2由哪几部分组成 ?
浙公网安备 33010602011771号