Docker 相关

管理员
管理员 2024-7-23

三、使用示例

docker 内服务器拷贝到物理服务器

# docker ps 查找容器ID或名称

CONTAINER ID   IMAGE                                                                                       COMMAND                  CREATED          STATUS          PORTS                                           NAMES
78b819acf529   registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10   "/bin/bash"              27 minutes ago   Up 26 minutes   0.0.0.0:10096->10095/tcp, :::10096->10095/tcp   keen_clarke
45bc3f3ed834   registry.cn-hangzhou.aliyuncs.com/goodrain/rainbond:v5.11.0-release-allinone                "/usr/bin/supervisord"   17 months ago    Up 48 minutes   0.0.0.0:7070->7070/tcp, :::7070->7070/tcp       rainbond-allinone


# docker cp 复制假设容器ID为container_id,您想复制的文件在容器中的路径为/path/in/container,物理服务器上的目标路径为/path/on/host

docker cp container_id:/path/in/container /path/on/host

例如

docker cp 78b819acf529:/workspace/FunASR/runtime/html5 ./

替换container_id/path/in/container, 和 /path/on/host 为实际的容器ID、容器内的文件路径和物理服务器上的目标路径。


1、基础命令

容器运行的方式:交互式/守护式进程

1.1运行一个交互式容器

docker run 参数  镜像名称  运行命令:创建&运行一个容器

--name [a-zA-z0-9_.-]:为待创建的容器制定一个名称,后续对该容器的操作可使用这个名称来指定容器。所以容器名称必须唯一

-i:开启容器的STDIN

-t:为创建的容器分配一个伪tty终端

示例1:创建一个交互容器

docker run --name=hello_world -i -t  ubuntu /bin/bash

首先docker会查找本地是否存在 ubuntu 镜像

如果本地没有 ubuntu 镜像,Docker会连接Docker Hub Register查找镜像是否存在,存在则下载改镜像保存于本地宿主机

随后docker使用改镜像创建一个新的容器

最后,Docker在该容器中运行 /bin/bash命令启动一个bash shell

示例2:funasr Docker 启动示例

sudo docker run -p 10096:10095 -it --privileged=true   -v $PWD/funasr-runtime-resources/models:/workspace/models   registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10

image.png

查看容器状态 docker ps

1.2 以守护式进程运行容器

docker run --name demon_hw -d ubuntu /bin/sh -c "while true;do echo hello world;sleep 1;done"

-d:以守护式进程运行容器,没有交互式会话

1.3 查看容器日志

docker logs 容器名/短ID/长ID

1.4 停止一个容器

docker stop 容器名/短ID/长ID   此命令将向容器进程发送SIGTERM信号

docker kill 容器名/短ID/长ID   此命令将向容器进程发送SIGKILL信号

1.5 启动一个容器

docker start 容器名/短ID/长ID

1.6 重启一个容器

docker restart 容器名/短ID/长ID

如果需要让Docker自动对因为各种原因导致的容器退出进行自动重启,在docker run 添加 --restart参数

docker run --restart=always   针对所有情况(无论正常退出退出码为0 还是 异常退出退出码非0)都会对容器进行重启

docker run --restart=on-failure 针对非正常退出的容器(退出码非0)会对容器进行容器

docker run --restart=on-failure:3  可添加最多重启次数,超过次数则不再自动重启

1.7 删除一个容器

docker rm 容器名/短ID/长ID

rm命令 默认只能针对停止的容器进行操作,可添加 -f参数来强制删除运行中的容器

1.8 创建容器(但不运行)

docker create 

docker create --name hello_world -i -t ubuntu /bin/bash

1.9 重新连接至容器

docker attach 容器名/短ID/长ID 重新附着到容器, 此时并不创建新的进程

docker start hello_world
docker attach hello_world

docker exec 容器名/短ID/长ID 运行命令, 在容器中启动新的进程

docker exec -i -t deamon_hw /bin/bash
top //查看进程


1.10 查看容器内进程

docker top 容器名/短ID/长ID

image.png

1.11 显示一组容器的统计信息

docker stats [容器名/短ID/长ID...]

image.png

1.12 查看容器更多信息

docker inspect [容器名/短ID/长ID...]

-f  以go模版方式输出 eg:-f {{.Id}}


2、Docker ps 命令参数&使用场景

2.1、docker ps 

会列出出正在运行的容器信息。

image.png

CONTAINER ID:每个容器的唯一标识符号,自动生成。类似于数据库中的主键。

IMAGE :创建容器使用的镜像名称。

COMMAND:运行容器时的命令。

CREATED:容器创建的时间。

STATUS:容器的运行状态,Up 17 hours 指容器已运行17小时。

-created(已创建)

-restarting(重启中)

-running(运行中)

-removing(迁移中)

-paused(暂停)

-exited(停止)

-dead(死亡)

PORTS:容器开放的端口信息。

NAME:容器的别名,在运行容器执行docker run 时可使用 --name进行指定。


2.2、docker ps -a 

会列出当前服务器中所有的容器,无论是否在运行。

image.png

此时可以看到,列表STATUS中多了其他状态

Exited (129) 5 days ago 代表:容器已退出(停止运行)退出时状态为 0 退出时间 5天前

同时我们看到PORTS中

 0.0.0.0:10096->10095/tcp, :::10096->10095/tcp 这代表两层含义 1:容器中开放了10095端口,使用TCP协议,对应宿主机使用10095端口进行映射。此时可以使用"宿主机IP:10095" 对容器10095端口提供的服务进行访问


2.3、docker ps -s

会列出容器的文件大小(容器增加的大小/容器的虚拟大小)

image.png

SIZE:128KB(virtual 4.12GB)容器在镜像(4.12GB)的大小的基础上增加了128KB,例如在容器中运行apt-get update 指令,会在写入层新增文件。

容器的虚拟大小=容器镜像的大小+容器增加大小


2.4、docker ps -q

仅列出CONTAINER ID 字段

image.png

此命令常用于批量操作的参数

如批量停止所有容器  docker stop `docker ps -a -q`


2.5、docker ps -l

显示最后一个运行的容器(无论该容器目前处于什么状态)

docker ps -n 数量x:显示最后 x 个运行容器,当x为1时和 -l 含义相同。(无论该容器目前处于什么状态)image.png

常用于快速查找最近运行的容器


2.6、docker ps --no-trunc

不对输出进行截断操作,此时可以看到完整的COMMAND,CONTAINER ID

image.png


2.7、高级指令 docker -f

使用过滤器来过滤输出

目前支持过滤器:

id (容器的id)

label

name(容器名称)

exited (整数-容器退出状态码,只有在使用-all才有用)

status 容器状态(created,restarting,running,paused,exited,dead)

ancestor 过滤从指定镜像创建的容器

before (容器的名称或id),过滤在给定id或名称之后创建的容器

isolation (default process hyperv) (windows daemon only)

volume (数据卷名称或挂载点),--过滤挂载有指定数据卷的容器

network(网络id或名称),过滤连接到指定网络的容器


docker ps -f status=exited  获取状态为exited的容器

image.png


docker ps -f ancestor=597ce1600cf4 -f status=exited -a  过滤多个条件,镜像&状态

image.png

注意:ancestor过滤镜像,如果制定的是某个父镜像,则过滤出的结果包含以此镜像构建的子镜像创建的容器,不仅仅是以该镜像直接创建的容器


docker ps --formart {{.Names}}:以go的形式格式化输出列表

go模板

.ID 容器的ID

.Image 镜像的ID

.Command 容器启动的命令

.CreatedAt 创建容器的时间点

.RunngingFor 从容器创建到现在过去的时间

.Ports 暴露的端口

.Status 容器的状态

.Size 容器硬盘的大小

.Names 容器的名称

.Label 指定label的值

.Mounts 挂载到这个容器的数据卷名称


3、docker镜像基础命令

3.1 docker images

查看Docker主机上可用的镜像

REPOSITORY:仓库名

TAG:仓库下同一镜像的不同版本

IMAGE ID:镜像的唯一标识,

SIZE:镜像的大小

image.png


3.1 docker images 镜像名

查看指定景象的所有版本

本地镜像文件存储于宿主机/var/lib/docker目录下image.png

同时,如果要查看宿主机下的所有容器/var/lib/docker/containers目录下


3.2 Registry

镜像仓库分为:公共和私有两种

公共仓库:Docker Hub是Docker公司运营的公共Registry,用户可以在Docker Hub上注册账户来存储&分享自己的镜像

私有仓库用户可以建立内网建立自己的私有Registry

查看Docker宿主机配置的镜像仓库:docker info | grep "Registry"

image.png

在docker服务器根据某个镜像创建容器,需要保证镜像已经在宿主机上,运行 docker run时docker会先检查本地是否存在镜像,如果不存在会根据镜像仓库配置,从仓库中拉取镜像到本地并运行

手动拉取镜像到本地

查询远程仓库是否存在某个镜像:docker search ubuntu

NAME:仓库名

Discription:镜像描述

Stars:用户评价

Offical:是否官方

Automated:表示镜像是否由Docker Hub的自动构建流程创建的

image.png


手动拉取远程镜像到本地:docker pull ubuntu:12.04


可以看到我的本地存在两个ubuntu镜像,在同一个仓库中可以存在多个镜像的不同版本,可以通过TAG来进行区分,比如ubuntu仓库下存在多个ubuntu镜像,他们使用tag(12.04,12.10,precise等)进行区分,注意同一个版本的镜像可以设置多个不同的TAG,需要通过ImageID来进行区分是否为同一镜像版本

在Docker Hub中有两种类型的仓库:用户仓库和顶层仓库

用户仓库:由用户创建,命名由用户名/仓库名组成 eg:k8s.gcr.io/etcd

顶层仓库:由Docker内部管理,命名只有仓库名 eg:ubuntu

运行指定镜像的方式

docker run -t -i --name use_tag ubuntu:12.04 /bin/bash

docker run -t -i --name use_imageId 5b117edd0b76 /bin/bash


4、构建Docker镜像

1).使用 docker commit命令

2).使用docker build命令&Dockerfile文件 


4.1 使用docker commit命令构建镜像

docker commit 容器名称/容器ID  镜像仓库名/镜像名称[:TAG]

-a "作者信息"

-m "提交信息"

步骤:

1).选取一个基础镜像创建一个容器

2).对容器进行相关修改

3).使用docker commit命令提交修改

example:基于ubuntu基础镜像制作包含apache2的镜像

1).运行一个基于ubuntu基础镜像的交互式容器:docker run -i -t ubuntu /bin/bash

2).进入容器中利用apt-get包管理工具安装apache:

apt-get update

apt-get install apache2

exit

3).退出容器后提交

docker commit 

更改容器



提交容器

docker images

使用 docker inspect 镜像名  查看详情


docker inspect path/ apache2


可以看到:Parent字段存储了父镜像ubuntu的imageId,container:保存了docker commit 提交时容器的id



4.3 使用dockerfile构建镜像

对比使用docker commit构建镜像,dockerfile提供了镜像构建的可重复性,透明性,幂等性。

核心步骤:

1.创建Dockerfile文件,在Dockerfile中使用DLS(Domain Specific Language)领域专用语言来定义每一步操作。

2.使用Docker build命令基于Dockerfile中的指令构建一个新的镜像。

后续描述会基于一下形式描述

一些基本概念->镜像构建实例->docker build指令&dockerfile详细语法详解 

1.一些基本概念

构建环境:保存Dockerfile文件的目录,也称构建上下文,在该目录中可以存放

Dockerfile文件:用来存储如何构建镜像的语句的文件,存储于构建上下文的根目录下。

.dockerignore:在构建上下文的根目录下,如果存在该文件,该文件内容会被按行切割,每行都是一条文件过滤匹配模式,其作用类似于git系统的.gitignore,该文件用来防止构建上下文中不属于构建需要的文件被上传至Docker守护进程

2.一个简单的镜像构建实例

创建上下文环境:nginx_image

创建Dockfile文件

mkdir nginx_image
ls
cd nginx_image
touch Dockerfile
ls
vim Dockerfile

编辑Dockfile并保存,查看编辑内容

cat nginx_image/Dockerfile

FROM ubuntu
MAINTAINER info0512 "info@0512cs.top"
RUN apt-get update && apt-get install -y nginx
RUN echo "hello world" > /usr/ share/nginx/html/index.html
EXPOSE 80

在上下文环境下运行docker build -t "path/nginx"   构建镜像

此时一个可用的镜像就已经构建好了,相关Dockfile指令&docker build命令含义参照下面的说明


4.3 docker build指令&dockerfile详细语法详解 

docker build 


构建缓存:

Docker会为Dockerfile中的每一条语句新建一个镜像,每个镜像都是一个可复用模块,后续其他构建流程中可使用已经构建过的镜像层来加速构建流程。

任何事情都有两面

好的一面:构建缓存加速了构建过程,同时也减少了存储,因为Docker使用  “写时复制”  使用同一镜像层构建的新镜像,增加的存储只是本条命令产生的新文件。

坏的一面:对于一些非幂等的语句由于使用了构建缓存导致结果不符合预期,例如:RUN apt-get update 指令,如果使用了构建缓存,此时的更新还是使用构建缓存镜像的更新。为了避免这个情况的发生可以使用--no-cache来强制不使用构建缓存。

Docker build用于通过dockerfile定义的指令来构建镜像

格式:Docker build 额外参数 构建上下文

构建上下文:用于指明构建上下文目录的路径,其可以是git仓库源地址,必须保证dockerfile存在于构建上下文的根目录下

额外参数

-t  仓库/镜像:TAG     用于指定构建后镜像的镜像名&Tag

-no-cache  不使用构建缓存,

查看镜像构建过程&镜像层

docker history 镜像ID


dockerfile 的指令

FROM

形式:FROM  基础镜像名

含义:指定一个构建过程的基础镜像,后续构建过程将基于此镜像展开。所以每个Dockerfile的第一条指令必须是FROM

例子:FROM ubuntu:14.04  制定构建基础镜像为ubuntu 14.04


MAINTAINER

形式:MAINTAINER  作者相关信息

含义:用于说明本次构建镜像的作者信息(作者姓名 联系方式)

例子:MAINTAINER  uname uname@example.com



RUN

形式: RUN 命令 参数

     RUN ["命令","参数”,..]

含义:RUN指令会在当前镜像创建的容器中运行制定指令,默认情况下RUN指令会在shell中使用命令包装器/bin/sh -c 来执行

     如果运行的镜像不支持shell平台,或不希望在shell中运行可使用exec格式的RUN指令  RUN ["指令","参数"]


例子:

RUN apt-get update && apt-get install -y nginx  使用shell包装器来执行,apt-get包管理器更新&安装nginx

RUN ["apt-get","update"]    使用exec格式制定指令

RUN ["apt-get","install","-y","nginx"]


EXPORT

形式:EXPORT [端口/协议(默认tcp,可指定tpc/udp):通知Docker容器在运行时侦听指定的端口

含义:EXPOSE 指令实际上并未发布端口。它充当构建镜像的人员和运行容器的人员之间的一种文档类型,有关打算发布哪些端口的信息。要在运行容器时实际发布端口,请在 docker run 上使用 -p 标志来发布和映射一个或多个端口,或使用 -P 标志来发布所有公开的端口并将它们映射为高阶端口。

注意:如果将 -P 和 docker run 一起使用,将公开EXPORT指定的端口,但是-P 在主机上使用临时的高阶主机端口,因此该端口对于                 TCP 和 UDP 将是不同的。论使用哪种 EXPOSE 设置,都可以在运行时使用 -p 标志覆盖它们


例子:

EXPORT  80/tcp

CMD 

形式: CMD ["命令","参数",".."]

       CMD 命令 参数    使用该形式Docker会在指定的命令前加上 /bin/sh -c ,不建议使用

含义: CMD用于指定容器启动时要运行的命令,效果同docker run 中指定的命令

注意: CMD命令可以被docker run 中的命令覆盖

       Dockerfile 中只能存在一条CMD指令,如果存在多条也只有最后一条会被执行

       如果容器想运行多个进程,可以使用类似supervisor的服务管理工具

例子:

CMD ["nginx","-g","daemon off;"]

CMD nginx -g "daemon off;"


ENTRYPOINT

形式:ENTRYPOINT ["命令“,"参数",..]

           ENTRYPOINT 命令 参数    使用该形式Docker会在指定的命令前加上 /bin/sh -c ,不建议使用

含义:ENTRYPOINT用于指定容器启动时要运行的命令,效果同docker run 中指定的命令,但是不会被docker run中的参数覆盖,此时如果docker run 存在指令参数,将被作为ENTRYPOINT 指定的命令的参数 传递进来,如果docker run 中没有指定参数,但此时dockerfile文件中存在CMD指令,则cmd指令的参数将作为ENTRYPOINT指定的命令的参数传递进来

注意:如果要强制覆盖ENTRYPOINT的命令,可使用 docker run --entrypoint 进行覆盖


例子:

Dokerfile文件中相关内容如下

----------------------------------

CMD ["-g","daemon off;"]

ENTRYPOINT ["nginx"]

----------------------------------

docker  run -d -P upath/nginx :相当于容器启动是的命令为 nginx -g “daemon off;"

docker run -d - P upath/nginx -h :相当于容器启动时的命令为 nginx -h,此时覆盖了CMD中指定的参数


WORKDIR

形式: WORKDIR 路径名

含义:用来从镜像创建一个新容器时,在容器内部设置一个工作目录,CMD,ENTRYPOINT指定的程序会在这个目录下执。同时可以               使用该指令为Dockerfile中的后续一系列指令设置工作目录

注意:在运行Docker run时可以通过-w参数予以覆盖

例子:

WORKDIR /usr/local 切换当前工作目录为/usr/local


ENV

形式:ENV  变量名   变量值 (只可以设置单个环境变量)

     ENV 变量名1=变量值 变量名2=变量值 

含义:用来在镜像构建过程中设置环境变量。新的环境变量可以在后续的任何RUN指令中使用,同时环境变量也将在后续由该镜像创建的任何容器中生效。

注意:在运行Docker run时 可以通过 -e 来传递环境变量此时只对该容器的运行时有效

例子:

ENV WDPATH = /usr/local

WORKDIR $WDPATH


USER

形式: USER user/uid:group/gid(用户名必须已经存在,可使用镜像中存在的,或在之前使用RUN useradd 进行新增)

含义:用来指定该镜像会以什么样的用户运行,默认会以root用户运行

注意:在运行Docker run 时,可以通过 -u 来更改用户

例子:

USER 0 使用root用户运行容器



VOLUME

形式:VOLUME ["挂载点",...]

含义:用于向基于镜像创建的容器添加卷。

注意:1.卷可以在容器间共享&重用

      2.卷的挂载点会绕过联合文件系统

      3.对卷的修改会立即生效,但不会对更新镜像产生影响

      4.卷会一直存在知道没有任何容器使用它

例子:

VOLUME   ["/opt/test"]


ADD

形式:ADD 构建上下文的文件目录/url地址    镜像中的目的地址

含义:用来将构建上线文中的文件目录复制到镜像中

注意: ADD 指令通过目的地址的末尾字符来判定文件源时目录还是文件,如果以/结尾,那么Docker认为源位置指向一个目录,否则认   为指向一个文件

不能将构建上下文之外的文件进行ADD操作

如果源文件是归档格式,ADD命令会自动进行unpakc操作

如果目的路径不存在,ADD会自动进行创建,形如使用了mkdir -p

例子:

ADD main.go /usr/local/src/main.go


COPY

形式:ADD 构建上下文的文件目录    镜像中的位置

含义:同ADD命令,但是不会针对归档文件进行unpack操作

例子:

COPY    main.go /usr/local/src/main.go


LABLE

形式:LABEL 键="值"    键="值"

含义:使用LABEL为镜像添加元数据

例子:

LABEL version="1.0"    location="Shanghai"    role="Register Center"


STOPSIGNAL

形式:STOPSIGNAL 信号值/信号名称

含义:用于指定在执行docker stop执行停止容器时,会发给容器的信号,默认情况下会发出SIGTERM,其目的是为了让容器能够优雅的退出,但是如果容器在接受相应指令后(10s)内还是没有停止,此时Docker会帮它退出,此时会发送SIGKILL信号将容器杀死。

例子:

STOPSIGNAL 9

STOPSIGNAL SIGKILL


ARG

形式: ARG  变量名 

         ARG  变量名=默认值

含义:设置构建过程中使用的变量,和ENV不同,其在镜像生成的容器中并不会存在。

特点:1.ARG存在两个作用域,在FROM命令前定义的变量仅对FROM命令有效,对后续命令无效,在FROM后设置的ARG变量对后续命令有效

例子:

ARG base_image  

ARG tag="latest"

FROM ${base_image}:${tag}

Docker build --build-arg base_image=ubuntu

此时效果为

FROM ubuntu:latest


ONBUILD

形式:ONBUILD    Dockerfile内部其他指令

含义:用于为镜像构建创建触发器。当以该镜像作为基础镜像的子镜像在构建时,ONBUILD指令会执行。

特点:ONBUILD指令只能被继承一次,即只会在子镜像中执行,而不会在孙子镜像中执行。ONBUILD常用于创建模版镜像

           ONBUILD内的指令不会在构建本镜像时执行

例子:

创建nginx镜像模版 path/nginx_tpl

FROM ubuntu


MAINTAINER uname "uname@example.com"

RUN apt-get update && apt-get install -y nginx

RUN rm /usr/share/nginx/html/index.html

ONBUILD ADD /www /usr/share/nginx/html/

EXPOSE 80

LABEL role="nginx server"

CMD ["-g","daemon off;"]

ENTRYPOINT ["nginx"]


在后续以  upath/nginx_tpl 为基础镜像的子镜像构建过程中,ONBUILD指令会在FROM之后执行


回帖
  • 2025-2-17
    回复

微信二维码

微信二维码

微信扫码添加微信好友