docker_study

1. Docker 概念

  1. Docker 可以让开发者打包应用以及依赖包到一个轻量级、可移植的容器中
  2. 容器完全使用沙箱机制,相互隔离
  3. 容器性能开销很低
  4. Docker 是一种容器技术,解决软件跨环境移植的问题

2. Docker 架构

image-20240408212837962|530

  • 镜像 Image Docker 镜像 Image, 相当于一个 root 文件系统
  • 容器 Container 镜像和容器的关系就像是类和对象,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等
  • 仓库 Repository 仓库可以看成一个代码控制中心,用来保存镜像,docker hub

3. Docker 命令

3.1 Docker 服务命令

# 启动docker
systemctl start docker
# 停止docker
systemctl stop docker
#...

3.2 Docker 镜像命令

# 查看本地镜像
docker images
# 搜索镜像
docker search ${image_name}
# 拉取镜像 默认是从hub.docker.com 拉取
# Tag默认是 latest
docker pull image_name:Tag
# 删除镜像
docker rmi image_id
# or
docker rmi image_name:Tag

3.3 Docker 容器命令

image-20240409204236382
1.创建、进入容器
docker run -it --name xx IMAGE_NAME:TAG /bin/bash

  • -i -t, -it: -t 为容器分配终端 -i 容器保持运行
  • --name xxx: 容器名字
  • /bin/bash: 进入容器的初始化命令
  • -it 创建的容器会自动进入终端, exit 退出后容器自动关闭
    docker run -id --name xxx IMAGE_NAME:TAG
  • -d 表示后台运行容器,不会立刻进入容器内部
  • 想要进入这个容器:docker exec -it CONTAINER_NAME /bin/bash
  • exit 后容器不会关闭

2.查看容器
查看所有容器 docker ps -a

3. 启动、停止和删除容器

docker start CONTAINER_NAME
docker stop CONTAINER_NAME
docker rm CONTAINER_NAME
  1. 查看容器信息
    docker inspect CONTAINER_NAME

4. Docker 容器的数据卷

4.1 数据卷概念及作用

image-20240409212154310|382

  • Docker 容器删除后,在容器中产生的数据也会随之销毁?
  • Docker 容器和外部机器可以直接交换文件吗?
  • Docker 容器之间怎样进行数据交互?
    数据卷的概念
  • 数据卷是宿主机中的一个目录或文件
  • 当容器目录和数据卷目录绑定后,对方的修改会立即同步
  • 一个数据卷可以被多个容器同时挂载
  • 一个容器也可以挂载多个数据卷
    数据卷的作用
  • 容器数据持久化
  • 外部机器和容器间接通信
  • 容器之间数据交换

4.2 配置数据卷

  • 创建或者启动容器时,使用 -v 参数设置数据卷
    docker run ... -v 宿主机目录(文件):容器内目录(文件)...
    1. 目录必须是绝对路径
    2. 如果目录不存在,会自动创建
    3. 可以挂载多个数据卷

4.3 数据卷容器

image-20240409220820712|528
多容器进行数据交换

  1. 多个容器挂载同一个数据卷,容器多之后不是很方便
  2. 数据卷容器, 其他容器挂载这个容器 --volumes-from CONTAINER_NAME

创建数据卷容器
docker run -it --name xxx -v /volume IMAGE_NAME:TAG /bin/bash

-v /volume 没有指定 左边的宿主机目录,会自动分配一个目录,默认在 docker 目录下的 CONTAINER 目录下

image-20240409221325649
挂载数据卷容器
docker run -it --name xxx --volumes-from DATA_CONTAINER ...

5. Dockerfile

5.1 Docker 镜像原理

image-20240409224044415|380

  • Docker 镜像是由特殊的文件系统叠加而成
  • 最低端是 bootfs, 并复用宿主机的 bootfs ubuntu 宿主机无法安装 windows 的 image,boot 无法复用
  • 第二层是 root 文件系统 rootfs, 也称为 base image
  • 然后再往上可以叠加其他的镜像文件
  • 统一文件系统技术可以将不同的层整合成一个文件系统,为这些层提供一个统一的视角,这样就隐藏了多层的存在,在用户的角度来看,只存在一个文件系统 如果要拉取上图中的 tomcat 镜像,就需要把其父镜像都拉取下来才行
  • 一个镜像可以放在另一个镜像的上面,位于下面的镜像称为父镜像,最底部的镜像是基础镜像
  • 当一个镜像启动容器时,Docker 会在最顶层加载一个读写文件系统作为容器

5.2 镜像制作

5.2.1 容器转为镜像

image-20240410234614768|471

# container to image
docker commit CONTAINER_ID IMAGE_NAME:TAG
# save image
docker save -o tar_file_name IMAGE_NAME:TAG
# load tar image
docker load -i tar_file_name
  • 当使用 commit 从容器创建新的镜像时,容器中通过挂载宿主机某个目录作为数据卷,数据卷中的文件操作不会携带到新的镜像中

5.2.2 Dockerfile 制作镜像

在 Dockerfile 文件的存放目录下,执行构建动作。
以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。
docker build -t nginx:v3 .
 .  是上下文路径,指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。

如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。

注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢

常用指令

5.2.2.1 FROM

FROM $BASE_IMAGE
指定基础镜像,用于后续的指令构建

5.2.2.2 RUN

RUN ...
在构建过程中在镜像中执行命令,, 每一个 RUN 都会新建一层
有两种格式:
shell 格式:

RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。

exec 格式:

RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。

例如:

FROM centos  
RUN yum -y install wget  
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"  
RUN tar -xvf redis.tar.gz  

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos  
RUN yum -y install wget \  
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \  
    && tar -xvf redis.tar.gz  

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

5.2.2.3 COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
格式:

COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]

[--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组。

<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

COPY hom* /mydir/
COPY hom?.txt /mydir/

<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

5.2.2.4 ADD

ADD 指令和 COPY 的使用格式类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

5.2.2.5 CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

  • CMD 在docker run 时运行。
  • RUN 是在 docker build。
    作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run命令行参数中指定要运行的程序所覆盖。

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

格式:

CMD <shell 命令> 
CMD ["<可执行文件或命令>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]  # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

5.2.2.6 ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

格式:

ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。
示例:

假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 

1、不传参运行
docker run nginx:test
容器内会默认运行以下命令,启动主进程。
nginx -c /etc/nginx/nginx.conf

2、传参运行
docker run nginx:test -c /etc/nginx/new.conf
容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
nginx -c /etc/nginx/new.conf

5.2.2.6 ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量,而且这个环境变量在构建好的 docker image 以及容器内都可以访问到。
格式:

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:

ENV NODE_VERSION 7.2.0

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"

5.2.2.7 ARG

构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

格式:

ARG <参数名>[=<默认值>]

5.2.2.8 WORKDIR

指定工作目录。
WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。

docker build 构建镜像过程中的每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

格式:

WORKDIR <工作目录路径>`

6. Docker 私有仓库

6.1 搭建私有仓库

Docker 官方仓库 https://hub.docker.com
私有仓库也是使用一个 docker image 实现的:

# 1. 拉取私有仓库镜像
docker pull registry
# 2. 启动私有仓库容器
docker run -id --name=registry -p 5000:5000 registry
# 3.添加私有仓库 key
# 4.重启docker服务
systemctl restart docker
docker start registry

打开浏览器,输入地址 http://私服ip:5000/v2/_catlog, 看到 {"repositories": []} 表示私有仓库搭建成功。
为了让 docker 信任私有仓库地址,在 daemon.json 中添加 key

vim /etc/docker/daemon.json

添加 key

{
"insecure-registries": ["私服ip:5000"]
}

6.2 镜像上传到私有仓库

# 1.将镜像标记为私有仓库镜像
docker tag IMAGE_NAME:TAG 私服IP:5000/IMAGE_NAME:TAG

# 2. 上传镜像
docker pull 私服IP:5000/IMAGE_NAME:TAG

image-20240412003622850

6.3 从私有仓库拉取镜像

docker pull 私服IP:5000/IMAGE_NAME:TAG

[!INFO] Ref
黑马IT_哔哩哔哩_bilibili
dokcer教程

posted @ 2024-04-12 00:40  rock_swc  阅读(17)  评论(0)    收藏  举报