Docker

docker最早接触是之前学渗透时,零零散散学过一点(指简单拉了个靶场镜像,run一下😂),不过也忘得差不多了

Docker

安装

Ubuntu安装docker:

https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

创建并加入docker用户组(不然只能root用户)

sudo systemctl enable docker
sudo systemctl start docker
sudo groupadd docker
sudo usermod -aG docker $USER

配置镜像加速器

镜像加速源

/etc/docker/daemon.json 里写下 ps:个人感觉阿里云好用点

{
"registry-mirrors": [
"加速地址",
"加速地址"
]
}

重启docker服务

sudo systemctl daemon-reload
sudo systemctl restart docker

docker info看到下面即可

Registry Mirrors:
加速地址

Docker中的三个重要概念

  • Image(镜像)
  • Container(容器)
  • Repository(仓储)

Image(镜像)

一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,镜像构建时,会一层层构建,在构建之后不会被改变

Container(容器)

容器是镜像运行时的实体,通过一个镜像,我们可以创建许多个不同的容器,每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为 容器存储层。容器器消亡时,容器存储层也随之消亡。

Repository(仓库)

集中的存储、分发镜像的服务,类似于github的代码仓库

https://hub.docker.com/

<仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

Docker基础命令

镜像

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]获取镜像

  • Docker Registry默认地址是 Docker Hub(docker.io)。
  • 仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library

docker image ls 列出镜像

docker system df 查看镜像、容器、数据卷所占用的空间

docker image rm [选项] <镜像1> [<镜像2> ...] 删除镜像

  • docker image rm $(docker image ls -q redis) 配合使用删除所有仓库名为redis的镜像

docker commit [选项] <容器ID或容器名> [<新镜像名>[:<标签>]] 保持修改过存储层的容器为新的镜像 慎用,可能会修改很多层的东西,导致镜像臃肿

docker build [选项] <上下文路径/URL/->

  • -t 指定镜像名称 name:tag

  • docker build 命令会将上下文路径目录下的内容打包交给 Docker 引擎以帮助构建镜像

  • -f 可以手动指定dockerfile

容器

docker ps 或者docker container ls查看当前运行中的容器

docker run 启动新容器

  • -t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。
  • -d 容器以后台的方式运行 执行成功后,会返回一个容器 ID
  • ``-p local:container` 把容器端口containe映射到主机端口local

docker container start 将终止(exited)的容器启动运行,而不是创建一个新容器

docker container stop 终止一个运行中的容器

docker container restart 重启一个正在运行的容器

docker container rm 来删除一个处于终止状态的容器

docker container prune来删除所有处于终止状态的容器

docker network ls 查看网络列表

docker exec

  • docker exec -it [container ID or NAMES] 进入到已运行的 Docker 容器

Dockerfile

用来构建Docker镜像的构建文件,Dockerfile 中每一个指令都会建立一层

FROM 基础镜像(latest作为默认标签)

  • FROM scratch 意味着你不以任何镜像为基础 比如一些静态编译的程序不需要什么支持

RUN 容器构建时需要运行的命令

  • RUN <命令>
  • RUN [“可执行文件”, “参数1”, “参数2”]

由于Dockerfile中每一个指令都会建立一层(构建的过程就是RUN启动容器,执行这条指令后commit一下),所以能一层完成的尽量用&&连接多个命令,每一层构建完成后删除不必要的东西,来减少容器大小

FROM debian:stretch

RUN set -x; buildDeps='gcc libc6-dev make wget' \
&& apt-get update \
&& apt-get install -y $buildDeps \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& mkdir -p /usr/src/redis \
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
&& make -C /usr/src/redis \
&& make -C /usr/src/redis install \
&& rm -rf /var/lib/apt/lists/* \
&& rm redis.tar.gz \
&& rm -r /usr/src/redis \
&& apt-get purge -y --auto-remove $buildDeps

COPY 从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

  • COPY [–chown=:] <源路径>… <目标路径>
  • <源路径> 可以是多个,<目标路径>可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
  • --chown=<user>:<group>来改变文件的所属用户及所属组

ADD 相比于COPY多了压缩文件自动解压,URL自动下载

CMD 容器启动命令,指定容器启动程序及参数

  • shell 格式:CMD <命令>
  • exec 格式:CMD [“可执行文件”, “参数1”, “参数2”…]
  • shell格式的CMD echo $HOME执行时会变为CMD[ “sh”, “-c”, “echo $HOME” ]

ENTRYPOINT 指令格式和目的和CMD一样

ENV 设置环境变量,后面的其它指令可以使用此变量,和shell下行为一致

  • ENV = =

ARG 设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的

  • ARG <参数名>[=<默认值>]
  • docker build –build-arg <参数名>=<值>可以来覆盖值

VOLUME 定义匿名卷,用于数据保存和持久化工作

  • VOLUME [“<路径1>”, “<路径2>”…]

EXPOSE 仅仅是声明容器打算使用什么端口

  • EXPOSE <端口1> [<端口2>…]

WORKDIR 指定工作目录,以后各层的当前目录就被改为指定的目录

  • WORKDIR <工作目录路径>

USER 指定当前用户

  • USER <用户名>[:<用户组>]
  • 改变环境状态并影响以后的层
  • 用户必须是提前建立好的

HEALTHCHECK 健康检测

ONBUILD 后面的指令在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行

  • ONBUILD <其它指令>

LABEL 给镜像以键值对的形式添加一些元数据

  • LABEL <key>=<value> <key>=<value> <key>=<value> …

SHELL 指定 RUN ENTRYPOINT CMD 指令的 shell

  • SHELL [“executable”, “parameters”]

Docker Compose

一个项目可以由多个服务(容器)关联而成,Compose 面向项目进行管理

安装

root@Ubuntu22:/home/grxer# sudo curl -L https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 56.6M 100 56.6M 0 0 12.3M 0 0:00:04 0:00:04 --:--:-- 14.1M
root@Ubuntu22:/home/grxer# sudo chmod +x /usr/local/bin/docker-compose
root@Ubuntu22:/home/grxer# docker-compose --version
Docker Compose version v2.20.3x

命令

docker-compose.yml

参考

https://yeasy.gitbook.io/docker_practice