Docker学习笔记

目录

一、Docker常用命令

1.帮助命令

2.镜像命令

3.容器命令

二、Docker存储

1.bind mount(绑定挂载)

2.volume卷(数据卷)

3.tmpfs(临时挂载)

4.绑定挂载和卷挂载的传播覆盖原则

三、Dockerfile(构建镜像)

1.联合文件系统

2.镜像加载原理

3.分层理解

4.Dockerfile

四、Docker网络

1.bridge网络

2.自定义网络


一、Docker常用命令

1.帮助命令

docker version               显示docker的版本信息

docker info                     显示docker的系统信息

docker 命令 --help         帮助命令(重要)可查命令的选项   不会就查帮助手册!!!

官方帮助文档:docker | Docker Docs

2.镜像命令

列出镜像

docker images                查看本地主机上的所有镜像

#可选项

-a                列出所有

-q                只列出镜像ID

搜索镜像

docker search [image]                搜索镜像

eg:   docker search mysql

下载镜像

docker pull [image]:[tag]             下载镜像

eg: docker pull mysql                #如果不写tag,默认就是latest

[jackbewater@hecs-156417 ~]$ docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete                      #分层下载,docker image的核心,联合文件系统
93619dbc5b36: Pull complete 
99da31dd6142: Pull complete 
626033c43d70: Pull complete 
37d5d7efb64e: Pull complete 
ac563158d721: Pull complete 
d2ba16033dad: Pull complete 
688ba7d5c01a: Pull complete 
00e060b6d11d: Pull complete 
1c04857f594f: Pull complete 
4d7cfa90e6ea: Pull complete 
e0431212d27d: Pull complete 
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709   #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest   #拉取镜像的真实地址,docker pull mysql等价于docker pull docker.io/library/mysql:latest

下载别的版本的mysql

[jackbewater@hecs-156417 ~]$ docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists                 #分层下载的好处,共用文件极大程度节省空间
93619dbc5b36: Already exists 
99da31dd6142: Already exists 
626033c43d70: Already exists 
37d5d7efb64e: Already exists 
ac563158d721: Already exists 
d2ba16033dad: Already exists 

0ceb82207cd7: Pull complete 
37f2405cae96: Pull complete 
e2482e017e53: Pull complete 
70deed891d42: Pull complete 
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

删除镜像

docker rmi -f [镜像ID]                删除指定镜像

docker rmi -f [镜像ID]  [镜像ID]  [镜像ID]          删除多个镜像

docker rmi -f $(docker images -aq)        删除所有镜像

3.容器命令

创建容器并启动

docker run [可选参数] images

#可选参数

--name="NAME"        给运行的容器命名,用于区分容器

-d                               以后台方式运行

-it                               使用交互方式运行,进入容器查看容器内部的东西

-p                               指定容器的端口   -p 8080 : 8080

        -p 主机端口 : 容器端口

列出运行的容器

docker ps                        列出正在运行的容器

#可选参数

-a                                列出正在运行的所有参数和历史运行过的容器

-n=数字                       列出最近几个创建的容器

-q                                列出容器的ID

退出镜像

exit                #退出并停止容器

Ctrl + P + Q                #退出容器但是不停止运行

删除容器

docker rm 容器ID              #删除指定容器,但是不能删除正在运行的容器,除非加上- f 选项

docker rm -f $(docker ps -aq)        #删除所有的容器

启动和停止容器

dokcer start 容器ID

docker restart 容器ID

docker stop 容器ID

docker kill 容器ID

查看日志

docker logs -t -f --tail 数字 容器ID

#可选参数

-tf                 #显示带有时间戳的参数

--tail 数字     #显示日志的条数

查看容器中的进程信息

docker top 容器ID

[jackbewater@hecs-156417 ~]$ docker top 349983cda77a
UID                 PID                 PPID                C                   STIME               TTY                
root                168272              168252              0                   Apr17               ?               

查看容器的元数据

docker inspect 容器ID

#测试

进入当前正在运行的容器

#容器通常使用后台运行,进入容器是为了进行一些配置

docker exec -it 容器ID bashshell

eg: docker exec -it 349983cda77a /bin/bash

方法二:

docker attach 容器ID

exec是进入容器后开启一个新的终端

attach是进入容器正在执行的终端,不会启动新的进程

从容器内拷贝文件到主机上

docker cp 容器ID : 目的路径 目的的主机路径

二、Docker存储

将数据存储在容器中,一旦容器被删除,容器内的数据也会消失。而且,随着容器的运行,容器的内的数据会越来越大,这样不方便恢复和迁移。将数据存储在容器之外,这样删除容器也不会丢失数据。容器发生故障时,我们可以重新创建一个容器,并将数据挂载到新的容器中,这样就可以快速恢复。

1.bind mount(绑定挂载)

绑定挂载可以将主机文件系统上的目录或文件装载到容器中,但是主机上的非docker进程可以修改它们,同时在容器中也可以修改主机的文件系统。包括创建、修改、删除文件或目录,使用不当,会带来安全隐患。即双向绑定,双方都可以修改对方的文件或目录。

绑定挂载适用以下场景:

• 将配置文件从主机共享到容器

• 在Docker主机上的开发环境和容器之间共享源代码或编译目录。

在创建并运行容器时添加- v参数进行挂载

docker run -v 主机目录 : 容器内目录

绑定挂载会将主机上的文件或目录装载到容器中。绑定挂载会覆盖容器中的目录或文件。

如果主机的目录不存在,docker会自动创建这个目录。但是docker只会自动创建文件夹,不会创建文件。

eg:

docker run -e MYSQL_ROOT_PASSWORD=123456 \
           -v /home/mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro  \
           -v /home/mysql/data:/var/lib/mysql  \
           -d mysql:5.7 

在这个例子中,配置文件设置为了只读(read-only)防止容器更改主机的文件,这个挂载的文件不再是双向绑定。

eg:

[jackbewater@hecs-156417 ~]$ docker run --name centos2 -it -v /home/测试:/home:ro 5d0da3dc9764 /bin/bash                        #将主机的目录/home/测试挂载到了容器内的/home目录下,并且设置了只读。即,主机能对该目录进行读写,而容器内只能查看这个目录,但是不能删除和创建

查看容器的详细信息:

测试:

主机能创建文件

容器内只能查看,不能删除,因为设置了ro只读

2.volume卷(数据卷)

卷 是docker 容器存储数据的首选方式,卷有以下优势:

  • 卷可以在多个正在运行的容器之间共享数据。仅当显式删除卷时,才会删除卷。
  • 当你想要将容器数据存储在外部网络存储上或云提供商上,而不是本地时。
  • 卷更容易备份或迁移,当您需要备份、还原数据或将数据从一个 Docker 主机迁移到另一个 Docker 主机时,卷是更好的选择。

 创建和挂载卷

-v 卷名:容器内路径

eg:

docker volume create my-data

docker run -e MYSQL_ROOT_PASSWORD=123456 \
           -v /home/mysql/conf.d/my.cnf:/etc/mysql/conf.d/my.cnf:ro  \     #绑定挂载
           -v my-data:/var/lib/mysql  \            #数据卷挂载
           -d mysql:5.7 

创建的数据卷是在主机上的,数据卷的目录是/var/lib/docker/volumes(图片中的橙色部分)

卷挂载分为具名挂载匿名挂载

匿名挂载:-v后面只有容器内路径,这就是匿名挂载,docker会自动生成一个匿名卷

docker run -e MYSQL_ROOT_PASSWORD=123456 \
           -v /home/mysql/conf.d/my.cnf:/etc/mysql/conf.d/my.cnf:ro  \     #绑定挂载
           -v /var/lib/mysql  \            #数据卷匿名挂载
           -d mysql:5.7 

查看数据卷的信息

docker volume inspect 卷名

注意:不论是绑定挂载还是卷挂载,都可以设置挂载目录的权限,

# ro 只读代表容器内只能读,不能改写,能在容器外修改

# rw 只写代表容器内可读可写

ro和rw是针对容器的权限的

3.tmpfs(临时挂载)

临时挂载将数据保留在主机内存中,当容器停止时,文件将被删除。

docker run -d -it --tmpfs /tmp nginx:1.22-alpine

 卷挂载和绑定挂载的区别:

数据卷由Docker(宿主机上的)管理,并且与主机的核心功能隔离,非 Docker 进程不能修改文件系统的这一部分。而绑定挂载机上的非 Docker 进程可以修改它们,同时在容器中也可以更改主机文件系统

4.绑定挂载和卷挂载的传播覆盖原则

挂载一个空卷时:容器内目录的内容会传播(复制)到卷中。

绑定挂载或挂载非空卷时:容器内目录的内容会被卷或绑定的主机目录覆盖。

ps:今天24.5.14我在运行nginx容器后,需要对容器内的/etc/nginx/conf.d配置文件进行修改,但是由于容器内没有vim编辑器不能修改,于是我想将/etc/nginx配置目录挂载出来(想法就是错的),然后我就在启动容器时添加了挂载参数,将一个本机上的空目录绑定挂载到了容器上(实际是挂不上的),容器始终无法启动。这个错误排了半天,容器启动时需要读取/etc/nginx的配置文件,但是因为我将一个空目录绑定挂载到了配置文件的目录上,导致给覆盖了,因此无法启动容器。

遇见问题第一时间要看容器的日志!!!!!这下真对传播覆盖原则有了深刻的理解了。

三、Dockerfile(构建镜像)

在了解dockerfile之前,先要知道UnionFS(联合文件系统)和docker镜像的加载原理

1.联合文件系统

UnionFS(联合文件系统)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层一层叠加。联合文件系统是docker镜像的基础,镜像通过分层来进行继承,基于基础镜像,可以制作出各种具体的应用镜像。

2.镜像加载原理

docker镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。

bootfs(boot file system)主要包含bootloader和kernel

   1.引导加载程序(bootloader):引导加载程序是在计算机启动时运行的程序,其主要任务是引导加载操作系统内核。它负责从存储设备(如硬盘、固态硬盘等)中加载内核到计算机内存中,并启动内核的执行。常见的引导加载程序包括GRUB、LILO等。
2.内核(kernel):内核是操作系统的核心部分,负责管理计算机的硬件资源(如CPU、内存、设备等)以及提供基本的系统服务。在Linux系统中,一旦内核加载到内存中并开始执行,它就会接管系统的控制权,并开始初始化系统的其他部分。

在Docker镜像的底层,bootfs是最底层的文件系统,包含了引导加载程序和内核。当系统启动时,引导加载程序会从bootfs中加载内核到内存中,随后内核开始初始化系统并加载更高层次的文件系统,例如根文件系统(root filesystem)。一旦内核加载完成并接管系统控制权,bootfs就会被卸载,内存的管理也完全由内核接管。


 

3.分层理解

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上创建新的镜像层。

注意!!!镜像都是只读的,当容器启动时,一个新的可写层会被加载到镜像的顶部,这一层通常成为容器层,容器层之下都是镜像层。容器运行时我们对容器的操作就在容器层中进行。

4.Dockerfile

dockerfile是用来构建镜像的文本文件,是命令参数脚本,其中包含了一条一条的指令,每一条指令构建一层。

构建镜像的步骤:

1.编写dockerfile

2.docker build构建成为镜像

3.docker run 运行镜像

4.docker push 发布镜像(DockerHub)

dockerfile的常用指令如下:

FROM ubuntu:18.04
WORKDIR /app
COPY . .
RUN make .
CMD python app.py
EXPOSE 80

FROM 打包使用的基础镜像

WORKDIR相当于cd命令,进入工作目录

COPY 将宿主机的文件复制到容器内

RUN打包时执行的命令,相当于打包过程中在容器中执行shell脚本,通常用来安装应用程序所需要的依赖、设置权限、初始化配置文件等

ADD 添加压缩包,并解压

CMD运行容器时执行的命令,只有dockerfile中最后一个CMD生效

ENTRYPOINT运行容器时执行的命令,可以追加命令

EXPOSE指定容器在运行时监听的网络端口,它并不会公开端口,仅起到声明的作用,公开端口需要容器运行时使用-p参数指定。   

docker build 构建镜像

docker build -f 指定的dockerfile -t 生成镜像的名字:版本号 .     注意不要丢掉命令结尾的 .

dockerfile的官方文件名是Dockerfile,在build时不需要-f指定,会自动寻找。

ENTRYPOINTCMD的区别(重要)

CMD运行容器时执行的命令,只有dockerfile中的最后一个CMD生效,并且不能追加参数

ENTRYPOINT运行容器时执行的命令,可以追加命令

dockerfile应该至少包含一个ENTRYPOINTCMD

CMD

当运行容器时追加参数会报错,-l会替换掉ls -a,然而-l并不是命令,所以会报错。

ENTRYPOINT

在容器运行时可以追加参数和命令,不会覆盖。

ENTRYPOINT指定容器启动时执行的默认程序,一般运行容器时不会被替换或覆盖。除非在运行容器时使用--entrypoint进行指定新命令,这样才会覆盖

docker run -it --entrypoint /bin/bash redis 

如果镜像中ENTRYPOINTCMD都存在,则CMD将作为ENTRYPOINT的参数使用。

自己制作tomcat镜像:

准备tomcat和jdk文件:

编辑dockerfile:

docker build构建镜像:

构建成功:

 创建并运行容器:

将本地文件home/jackbewater/tomcat/test和/home/jackbewater/tomcat/tomcatlogs分别挂载到容器内的/usr/local/apache-tomcat-9.0.88/webapps/test和/usr/local/apache-tomcat-9.0.88/logs上(绑定挂载)

测试访问:

四、Docker网络

在安装docker时,会自动创建三种网络:bridge、host、none

bridge网络模式:使用--net=bridge指定,或不指定net即使用默认设置。

host网络模式:使用--net=host指定。(不常用)

nono网络模式:使用--net=none指定。(不常用)

1.bridge网络

bridge网络(默认模式):此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及iptables nat表配置与宿主机通信。在bridge网络模式下容器没有公网IP,只有宿主机可以直接访问,外部主机不可访问,但是容器可以通过宿主机的NAT规则后可以访问外网。

创建并运行容器时,不指定网络模式,就会使用bridge模式,docker守护进程会利用veth pair技术,在主机上创建两个虚拟网络接口(docker0上的veth接口和容器上的eth接口)

容器与主机可以进行通信,容器与容器之间也可以通信(都使用的是bridge网络)注意并不是直接通信,而是通过docker0 网桥进行通信。

在docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上以bridge网络模式启动的容器都会连接到虚拟网桥上。docker0的工作方式类似于路由器,一般docker会使用172.17.0.0/16这个网段,并将172.17.0.1分配给网桥(在主机上使用ip addr命令可以查看docker0,可以认为他是网桥的网关)

2.自定义网络

Docker提供三种网络驱动:bridge、overlay和macvlan。其中overlay和macvlan用于创建跨主机网络。以下只介绍自定义bridge网络。

创建自定义的bridge网络:

docker network creat --driver bridge my_net

通过docker inspect my_net查看自定义bridge网络的详细信息

创建自定义网络时可通过--subnet和--gateway参数来指定网桥的网段和网关: 

 使用自定义网络:

docker run -d --network=my_net 镜像名

在启动容器时可以通过--ip 参数指定一个静态IP,但是要注意的是,只有使用--subnet参数创建的网路才能指定静态IP。如果创建自定网络时没有指定--subnet,那么容器启动时指定静态IP就会报错。

自定义bridge网络需要注意的几个点:

1.自定义bridge网络是有域名解析的,即自定义bridge网络下的容器之间,可以通过容器名ping通。而默认网桥没有域名解析。

2.不同的自定义bridge网络下的容器之间不能通信,除非在一方的网桥上添加另一方的网卡。

3.自定义网桥和默认网桥下的容器之间也不能通信,也需要添加网卡。

  • 16
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值