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会从本地镜像找,没有就从官网下载、再运行

  image

 

(1.3)阿里云加速

  1. 登录阿里云,找到容器服务。
  2. 找到镜像加速地址。
  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博客

image

 

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,配置账户密码

   img_v3_02r5_7708787c-b2e8-45d5-b85b-8b93f45cfa2m

 登录后如下图

   img_v3_02r5_d092418c-33d9-4c94-aac5-1b9ad664995m

(3.2)docker镜像概念与原理

1. 镜像基础原理

Docker镜像
镜像是什么?
  镜像是一种轻量级,可执行化的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件锁需要的所有内容,包括代码,运行时(库,环境变量和配置文件)。

  所有的应用 直接打包docker 镜像 就可以直接跑起来!


镜像加速原理
(1)UnionFS(联合文件系统)
我们下载的时候看到的一层层就是这个!

image

 

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等等。

 image

 

image

 

平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?

  对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。
  由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

(虚拟机是分钟级,容器是秒级!)

3. 分层理解

分层镜像

   image

我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!

Docker镜像要采用这种分层的好处?

  **资源共享** 有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像。

  同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

  • 所有的Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
  • 举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;
  • 如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。

image

 简单来说 就是 原本有的 就共享 没有的咱就下载 更新了 就替换新的

特点:

  Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
  这一层就是我们通常说的容器层,容器之下的都叫镜像层!

image

 

 

4. commit镜像

# 提交容器成为一个新的副本
  docker commit
# 命令和git原理类似
  docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

  • # 1.启动一个默认的tomcat。
  • # 2.发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的。
  • # 3.我自己拷贝进去了基本的文件。
  • # 4.将我们操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像。

image

 

小结: 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 是 这个容器的目录

image

通过 -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 的宿主机目录不存在的话会被新建

  删除容器,但与宿主机同步挂载的目录下依然有文件。见下图:

img_v3_02ra_04b9148d-204c-414e-947c-48234afcd66m

(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 ./

生成的镜像如下:

  img_v3_02ra_b0cae2c9-ce1a-4738-9295-7c6c42e232fm

 运行镜像查看:如下图,我们在dockerfile01文件中配置了2个 volume

(VOLUME ["volume01","volume02"]   ,没写路径默认就是在 / 根目录下)

显示在下面,对应会有一个宿主机目录

  img_v3_02ra_fbaa1feb-9308-469b-81f8-8b6374d70a3m

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

img_v3_02ra_4b03d37d-434c-4634-93b5-17f35320f51m

 

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

同步测试如下,同步成功。但我是开了2个进程。  或者使用 docker exec -it docker_id/name 进去。

  img_v3_02ra_f0bad7fd-6ac9-41f9-8766-f973c9f17bcm

 

img_v3_02ra_33137e3e-9d21-474a-a246-e6ddabf8e8cm

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

image

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、每一个指令都会创建提交一个新的镜像层,并提交!

image

 

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            # 构建的时候设置环境变量!

作用如下图:

  image

 

(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. 测试运行

   

    img_v3_02rf_81d3fafc-b0ff-4f43-b08e-19ac60a27f1m

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

img_v3_02rg_72e19743-d83d-4742-a091-e34eb3920cem

(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"命令生效、执行

  image

 

# 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"命令生效、执行

image

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

image

 

# 原因: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会为每个容器创建一个虚拟网卡。

image

 查看宿主机网络信息。

img_v3_02ro_15a9736b-96d8-4769-a3e6-174f9dce055m

查看 docker0 在哪里

img_v3_02ro_ef197f89-f68b-4120-ac28-79e78786de0m

 启动一个新容器,会自动生成一个vethxx@ifxxx的网卡。

docker run -d -P --name nginx01 docker.1ms.run/nginx 
docker run -d -P --name nginx02 docker.1ms.run/nginx 

 

img_v3_02ro_a9046438-0ce0-41b7-a9af-3a71944c895m

 

  • 所以 我们可以发现 容器带来的网卡 都是一对一对的,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

image

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

 

image

 Docker中的所有的网络接口都是虚拟的。虚拟的转发效率高!(内网传递文件!)
只要容器删除,对应网桥一对就没了!

(6.3)网络模式与自定义网络

(1)概念

网络模式:docker network ls          

  • bridge:桥接 docker(默认,自己创建也使用bridge桥接模式)

  • none:不配置网络

  • host:和主机共享网络

  • container:容器网络连通!(用的少!局限很大)

docker network inspect network_id(查阅详情),我们查看了刚 bridge的网络id,如下图,我们默认的应用启动的网络地址信息均存在于其中。

image

(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

img_v3_02ro_d85284b2-621b-4127-b47d-6ea9a795a01m

我们自定义的网络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 网段的网卡

详情见下图:

img_v3_02ro_8c29aa7f-0fd4-4fb3-98ee-dc66a765664m

 

 发现其原理竟然在对方网络里加块网卡,此时 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由哪几部分组成 ?

posted @ 2023-02-23 15:03  郭大侠1  阅读(122)  评论(0)    收藏  举报