docker基础

1. 运行容器

sudo run -i -t ubnutu /bin/bash
Docker执行 docker run命令,并指定了-i-t两个命令行参数,告诉Docker为新创建的容器提供一个交互式shell。其中 ubuntu镜像是一个常备镜像,也可以成为"基础"(base)镜像,它由docker公司提供,保存在Docker Hub Registry上。 常用的 docker run 容器命令选项有:

-i :表示以交互模式运行容器,通常与-t结合使用

-t:为容器重新分配一个伪输入终端,通常与-i结合使用

-d:后台运行容器,并返回容器 ID,即启动守护式容器 (这样创建的容器不会分配一个伪输入终端,如果是以-it两个参数启动,启动后则会分配一个伪输入终端)

-p:指定端口映射,格式为:-p 主机(宿主机)端口:容器映射端口,可以使用多个-p做多个端口映射

-v:指定挂载主机目录 / 文件 到容器目录 / 文件 上,即挂载容器数据卷,格式为:-v 主机(宿主机)目录/文件的绝对路径:容器内目录/文件的绝对路径[:读取权限],可以使用多个-v做多个目录或文件映射,默认为rw读写模式ro表示只读

rw读写模式:表示宿主机能对数据卷进行读取和更改,容器也能对其进行读取和更改。
ro表示只读:表示宿主机能对数据卷进行读取和更改,容器只能对其进行读取不能更改。

--name:为创建的容器指定一个名称,格式为:--name=容器名称

2. 查看所有容器

sudo docker ps -a ,其中docker ps只能看到正在运行的容器。

3. 容器命名

sudo docker run --name bob_the_container -i -t ubuntu /bin/bash

4. 启动容器 | 重启容器

启动容器: sudo docker start bob_the_container

重启容器: sudo docker restart aa3f365f0f4e

5. 进入正在运行的容器内并以命令行交互
bash 复制代码
//以exec方式进入到容器
docker exec -it 容器ID/容器名称 /bin/bash 或 /bin/sh

//以attach方式进入到容器
docker attach 容器ID/容器名称

//如果不想进入容器,直接获取相关指令的运行结果,可在后面填写相关操作指令
docker exec -it 容器ID/容器名称 相关命令

exec 与 attach 的区别:

  • exec:是在容器中打开新的终端,并且可以启动新的进程 (推荐)

  • attach:是直接进入容器启动命令的终端,不会启动新的进程

    sudo docker attach bob_the_container 附着在容器上,然后就又重新回到了容器的Bash提示符,如下所示。
    root@aa3f365f0f4e:/#

6. 获取容器日志

sudo docker logs daemon

获取容器日志,可以在命令后使用-f参数来监控Docker的日志。(提示:可以通过Ctrl+C退出日志跟踪)

sudo 复制代码
hello word 
hello word 
hello word 
···

我们也可以跟踪容器日志的某一片段,和之前类似,只需要在tail命令后加入-f--lines标志即可。例如可以用docker logs --tail 10 daemon_dave获取日志的最后10行内容。另外也可以用docker logs --tail 0 -f daemon_dave命令来跟踪某个容器的最新日志而不必读取整个日志文件。为了让调试更简单,我们还可以使用-t标志为某条日志项加上时间戳,如下所示:\

csharp 复制代码
$ sudo docker logs -ft daemon_dave 
[May 10 13:06:17.934] hello world
[May 10 13:06:18.935] hello world
[May 10 13:06:19.937] hello world
[May 10 13:06:20.939] hello world
[May 10 13:06:21.942] hello world
···
7. 查看容器映射端口号

查看容器已公开的 80端口映射到了哪个端口。

makefile 复制代码
$ sudo docker port 09a570cc2267 80
0.0.0.0:49160
8. 查看容器内的进程
css 复制代码
$ sudo docker top daemon_dave

该命令执行后,我们可以看到容器内的所有进程(主要还是我们的while循环)、运行进程的用户及进程ID,如下所示:

bash 复制代码
PID USER COMMAND
977 root /bin/sh -c while true; do echo hello world; sleep 1; done
1123 root sleep 1
9. 在容器内部运行进程,我们可以通过docker exec命令在容器内部额外启动新进程。可以在容器内运行的进程有两种类型:后台任务和交互式任务。

后台任务:

shell 复制代码
$ sudo docker exec -d daemon_dave touch /etc/new_config_file

交互式任务:

shell 复制代码
$ sudo docker exec -t -i daemon_dave /bin/bash
10. 停止守护式容器

docker stop命令向docker容器进程发生SIGTERM信号。如果你想快速停止某个容器,也可以使用docker kill命令来向容器进行发送SIGKILL信号。

arduino 复制代码
$ sudo docker stop daemon_dave

要想查看已经停止的容器的状态,则可以使用docker ps命令。还有一个很实用的命令docker ps -n x,该命令会显示最后x个容器,不论这些容器正在运行还是已经停止。

11. 自动重启容器:--restart

默认的行为是Docker不会重启容器。

ini 复制代码
$ sudo docker run --restart=always --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

在本例中,--restart标志被设置为always。无论容器的退出代码是什么,Docker都会自动重启该容器。除了always,我们还可以将这个标志设为on-failure,这样,只有当容器的退出代码为非0值的时候,才会自动重启。另外,on-failure还接受一个可选的重启次数参数,如下所示:

ini 复制代码
--restart=on-failure:5

这样,当容器退出代码为非0时,Docker会尝试自动重启该容器,最多重启5次。

12. 深入容器
ruby 复制代码
$ sudo docker inspect daemon_dave
13. 删除容器
shell 复制代码
$ sudo docker rm 80430f8d0921

需要注意的是,运行中的Docker容器是无法删除的!你必须先通过docker stopdocker kill命令停止容器,才能将其删除。

一次性删除全部容器:

css 复制代码
docker rm `docker ps -a -q`
14. 列出镜像
ruby 复制代码
$ sudo docker images
REPOSITORY  TAG     IMAGE ID      CREATED      VIRTUAL SIZE
ubuntu      latest  c4ff7513909d  6 days ago   225.4 MB 

本地镜像都保存在Docker宿主机的/var/lib/docker目录下。每个镜像都保存在Docker所采用的存储驱动目录下面,如aufs或者devicemapper。也可以在/var/lib/docker/containers目录下面看到所有的容器。

镜像从仓库下载下来。镜像保存在仓库中,而仓库存在于Registry中。默认的Registry是有Docker公司运营的公共Registry服务,即Docker Hub

Docker Hub(或者你自已运营的Registry)中,镜像是保存在仓库中的。可以将镜像仓库想象为类似Git仓库的东西。它包括镜像、层以及关于镜像的元数据(metadata)。

15. 查找镜像

我们可以通过docker search命令来查找所有Docker Hub上公共的可用镜像,如下所示:

bash 复制代码
$ sudo docker search puppet
NAME                  DESCIRPTIOM STARS OFFICIAL AUTOMATED
wfarr/puppet-module...
jamtur01/puppetmaster
...

也可以在Docker Hub网站上在线查找可用镜像。

让我们从上面的结果中拉取一个镜像:

shell 复制代码
$ sudo docker pull jamtur01/puppetmaster

这条命令会下载jamtur01/puppetmaster镜像到本地(这个镜像里预装了Puppetmaster)。

接着就可以用这个镜像构建一个容器了。下面就用docker run命令来构建一个容器。

ini 复制代码
$ sudo docker run -i -t jamtur01/puppetmaster /bin/bash
root
architecture => amd64
augeasversion => 1.2.0
...
root@4655dee672d3:/# puppet --version
3.4.3

可以看到,我们已经从jamtur01/puppetmaster镜像启动了一个新容器。我们一交互式的方式启动了该容器,并且在里面运行了Bash shell

16. 构建镜像
  1. 使用 docker commit 命令
ruby 复制代码
$ sudo docker run -i -t ubuntu /bin/bash
root@4aab3ce3cb76:/#

接下来,在容器中安装Apache,如下所示:

ruby 复制代码
root@4aab3ce3cb76:/# apt-get -yqq update
...
root@4aab3ce3cb76:/# apt-get -y install apache2
...

我们启动了一个容器,并在里面安装了Apache。我们会将这个容器作为一个Web服务器来运行,所有我们想把它的当前状态保存下来。这样就不必每次都创建一个新容器并再次在里面安装Apache了。为了完成此项工作,需要先使用exit命令从容器里退出,之后再运行docker commit命令,代码如下所示:

shell 复制代码
$ sudo docker commit 4aab3ce3cb76 jamtur01/apache2
8ce0ea7a1528
  1. 使用 docker build 命令和 Dockerfile 文件

现在我们并不推荐使用docker commit命令,而应该使用更灵活、更强大的 Dockerfile 来构建Docker镜像。\

17. Dockerfile指令:
  • CMD
    CMD指令用于指定一个容器启动时要运行的命令。类似于RUN指令,只是RUN指令是指定镜像被构建时要运行的命令,而CMD是指容器被启动时要运行的命令。这和使用docker run命令启动容器时指定要运行的命令非常类似,比如代码清单:
shell 复制代码
$ sudo docker run -i -t jamtur01/static_web /bin/true

可以认为代码清单所示的命令和在Dockerfile中使用如下代码所示的CMD指令是等效的。

css 复制代码
CMD ["/bin/true"]
  • ENTRYPOINT
    ENTRYPOINT 是指定容器启动时要执行的可执行文件或脚本,并且该命令在运行容器时不能被覆盖。ENTRYPOINT可以看作是容器的默认执行命令,它会在运行容器时自动执行。如果在运行容器时指定了其他命令,则这些命令将作为ENTRYPOINT命令的参数传递给容器。

例如,在Dockerfile中指定ENTRYPOINT为一个可执行文件,如下所示:

css 复制代码
ENTRYPOINT ["./app"]

在运行容器时可以使用以下命令:

arduino 复制代码
docker run myapp arg1 arg2

这样将运行容器,自动执行ENTRYPOINT命令"./app",并将"arg1""arg2"作为参数传递给它。

CMD是指定容器启动时要执行的默认命令或参数。它可以被覆盖,如果在运行容器时指定了其他命令,则这些命令将替换掉CMD命令。

例如,在Dockerfile中指定CMD为一个默认参数,如下所示:

css 复制代码
CMD ["--port", "80"]

在运行容器时可以使用以下命令:

arduino 复制代码
docker run myapp --port 8080

这样将运行容器,并使用"--port 8080"替换掉默认的CMD命令参数"--port 80"

总结来说,ENTRYPOINT是指定容器启动时要执行的默认命令,它在运行容器时不能被覆盖。而CMD是指定容器启动时要执行的默认命令参数,它可以被覆盖。通常情况下,ENTRYPOINT用于指定容器启动时要运行的应用程序,而CMD用于指定应用程序的默认参数。

  • WORKDIR
    WORKDIR指令用来在镜像创建一个新容器时,在容器内部设置一个工作目录,ENTRYPOINTCMD指定的程序会在这个目录下执行。
bash 复制代码
WORKDIR /opt/webapp/db
RUN bundle install
WORKDIR /opt/webapp
ENTRYPORT [ "rackup" ]

这里,我们将工作目录切换为/opt/webapp/db后运行了bundle install命令,之后又将工作目录设置为/opt/webapp,最后设置了ENTRYPOINT指令来启动rackup命令。

可以通过-w标志在运行时覆盖工作目录,如代码所示:

bash 复制代码
$ sudo docker run -ti -w /var/log ubuntu pwd
/var/log

该命令会将容器内的工作目录设置为/var/log

  • ENV ENV指令用来在镜像构建过程中设置环境变量,如代码所示:
arduino 复制代码
ENV RVM_PATH /home/rvm/

我们也能在其他指令中直接使用这些环境变量。

bash 复制代码
ENV TARGET_DIR /opt/app
WORKDIR $TARGET_DIR

这里我们设定了一个新的环境变量TARGET_DIR,并在WORKDIR中使用了它的值。因此实际上WORKDIR指令的值会被设为opt/app

  • USER
    USER指令用来指定该镜像会以什么样的用户去运行,如代码所示:
sql 复制代码
USER nginx
  • VOLUME
    VOLUME指令用来向基于镜像创建的容器添加卷。卷功能让我们可以将数据(如源代码)、数据库或者其他内容添加到镜像中而不是将这些内容提交到镜像中,并且允许我们在多个容器间共享这些内容。

  • ADD
    ADD指令用来将构建环境下的文件和目录复制到镜像中。在ADD文件时,Docker通过目的地址参数末尾的字符来判断文件源是目录还是文件。如果目标地址以/结尾,那么Docker就认为源位置指向的是一个目录。如果目的地址不是以/结尾,那么Docker就认为源位置指向的是文件。

    最后指的一提的是,ADD在处理本地归档文件(tar arhive)时还有一些小魔法。如果将一个归档文件(合法的归档文件包括gzipbzip2xz)指定为源文件,Docker会自动将归档文件解开(unpack)。

  • COPY
    COPY指令非常类似于ADD,它们根本的不同是COPY只关心构建上下文中复制本地文件,而不会去做文件提取(extraction)和解压(decompression)的工作。

javascript 复制代码
COPY conf.d/ /etc/apache2/

这条指令将会把本地conf.d目录中的文件复制到/etc/apache2目录中。

  • ONBUILD ONBUILD指令能为镜像添加触发器(trigger)。
    触发器会在构建过程中插入新指令,我们可以认为这些指令是紧跟在FROM之后指定的。触发器可以是任何构建指令,比如代码所示:
bash 复制代码
ONBUILD ADD . /app/src
ONBUILD RUN cd /app/src && make

上面的代码会在构建镜像中加入ONBUILD触发器,ONBUILD指令可以在镜像上运行docker inspect命令来查看:

ruby 复制代码
$ sudo docker inspect 508efa4e4bf8
···
"OnBuild":[
    "ADD . /app/src",
    "RUN cd /app/src && make"
    ]
...
相关推荐
码农土豆几秒前
PaddlePaddle飞桨Linux系统Docker版安装
linux·docker·paddlepaddle
wm104326 分钟前
java web springboot
java·spring boot·后端
龙少95432 小时前
【深入理解@EnableCaching】
java·后端·spring
溟洵4 小时前
Linux下学【MySQL】表中插入和查询的进阶操作(配实操图和SQL语句通俗易懂)
linux·运维·数据库·后端·sql·mysql
SomeB1oody6 小时前
【Rust自学】6.1. 定义枚举
开发语言·后端·rust
SomeB1oody7 小时前
【Rust自学】5.3. struct的方法(Method)
开发语言·后端·rust
啦啦右一8 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
森屿Serien8 小时前
Spring Boot常用注解
java·spring boot·后端
盛派网络小助手10 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
明 庭10 小时前
Ubuntu下通过Docker部署NGINX服务器
服务器·ubuntu·docker