docker基础

前言

本文主要整理了docker的一些常用命令,是一篇关于容器和镜像的入门级文章,不涉及太多原理性的内容,主要做为个人笔记方便日后查找。

容器使用

获取镜像

想要使用一个容器首先要有该容器的镜像
以ubuntu为例
如果我们本地没有 ubuntu镜像, 我们可以使用 docker pull 命令来载入 ubuntu镜像

1
docker pull ubuntu

默认的是拉取Tag为latest的镜像

启动容器

以下命令使用ubuntu镜像启动一个容器 , 参数为以命令模式进入该容器:

1
docker run -ti ubuntu /bin/bash

参数说明:

  • -i: 交互式操作
  • -t: 终端
  • ubuntu: ubuntu镜像 , 可以在ubuntu后加冒号表明使用哪一个具体的镜像 , 例:ubuntu:latest
  • /bin/bash : 放在镜像名后的是命令 , 这里我们希望有一个交互式shell , 因此用的是 /bin/bash

要退出终端 , 直接输入exit
退出后 docker ps 发现在没有正在运行的docker容器了

注意 : 需要注意的是每使用 run 命令启动一个容器 , 都是创建一个新的容器的过程 , 即使使用的镜像相同 , 也会创建出不同的容器来
如下图 , 有两个镜像为 ubuntu:15.04 的容器

image
补充docker run命令的其他参数

  • -d:后台运行容器,并返回容器ID;
  • -i:以交互模式运行容器,通常与-t同时使用
  • -P:随机端口映射,容器内部端口随机映射到主机的端口
  • -p:指定端口映射,格式为:主机(宿主)端口:容器端口
  • -t:为容器重新分配一个伪输入终端,通常与-i同时使用
  • –name=“nginx-lb”:为容器指定一个名字
  • -h “mars” :指定容器的hostname
  • -m:设置容器使用内存最大值
  • –expose=[]:开放一个端口或一组端口

补充docker ps命令的其他参数

  • -a:显示所有的容器,包括未运行的
  • -s:显示总的文件大小
  • -l:显示最近创建的容器
  • -f: 根据条件过滤显示的内容

输出详情介绍
CONTAINER ID:容器ID
IMAGE:使用的镜像
COMMAND:使用容器时运行的命令
CREATED:容器的创建时间
STATUS:容器状态
状态有7种

  • create(已创建)
  • restarting(重启中)
  • running(运行中)
  • removing(迁移中)
  • paused(暂停)
  • exited(停止)
  • dead(死亡)

启动已停止运行的容器

docker ps -a 查看容器状态, 找到一个处于停止状态的容器
image

使用docker start 启动这个已停止的容器
docker start 8a847fc4c308
image
可以看到后台运行中的容器中有该容器

后台运行

我们可以通过 -d 在运行容器之初指定容器的运行模式
加了-d 参数默认不会进入容器 , 想要进入容器需要使用指令 docker exec

例: 创建一个后台运行的ubuntu镜像, 名称为ubuntu-test
image
此容器便在后台运行 , 而不是在运行之初进入交互模式

进入容器

如上述,当使用-d参数时,容器启动会进入后台。此时想要进入容器,可以通过以下指令进入:

  • docker attach
  • docker exec

推荐使用第二个
这两个指令的区别在于:
docker attach 指令进入容器退出后容器会停止
docker exec 指令进入容器退出后容器继续在后台运行不会停止

演示 :
docker attach
image
容器退出后便停止

docker exec
image
容器退出后在后台运行

停止容器

docker stop <容器Id>
停止掉的容器在使用 docker ps 查看时便不存在了
使用docker ps -a 可以查看到所有正在运行或停止状态的容器

导入和导出容器

导出容器

如果要导出本地某个容器 , 可以使用 docker export 命令

//导出到当前文件夹
docker export b00ac6809556 > ubuntu.tar
//导出到指定文件夹
docker export b00ac6809556 > ./docker/ubuntu.tar

导出容器 b00ac6809556 快照到本地文件 ubuntu.tar
image

导入容器快照

可以使用docker import 从容器快照文件中再导入为镜像 , 以下实例文件将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1

//压缩包所在的目录下执行
cat ubuntu.tar | docker import - test/ubuntu:v1

在压缩包所在的目录处导入镜像到docker
image

此外, 也可以通过指定URL或者某个目录来导入 , 例如:
docker import http://example.com/exampleimage.tgz example/imagerepo

删除容器

删除容器使用docker rm <容器id> 命令
下面的命令可以清理掉所有处于终止状态的容器
docker container prune

运行一个web应用

在docker容器中运行一个Python Flask应用来运行一个web应用

其实就是一段简短的web程序, 访问时在网页输出一个 hello world

首先载入镜像
docker pull training/webapp
运行容器docker run -d -P training/webapp python app.py
参数说明:
-d : 后台运行容器
-P : 将容器内部使用的网络端口映射到我们使用的主机上
至此web应用便运行起来了

查看web应用容器

使用docker ps 来查看我们正在运行的容器:
image
发现多了PORTS这一列, 该列说明了端口的映射情况
docker开放的5000端口映射到了主机端口32768上
此时通过命令curl localhost:32768 , 可以访问该应用, 打印出 hello world 即为成功

我们也可以通过 -p 参数来设置不一样的端口:
docker run -d -p 5000:5000 training/webapp python app.py
然后通过 curl localhost:5050 得到同样结果

网络端口的快捷方式

网络端口映射除了使用docker ps查看之外, 还可以使用 docker port这种快捷方式 , 使用该命令可以查看指定(ID或者名字)容器的某个确定端口映射到宿主机的端口号
例如
docker port bf08b7f2cd89
就能查看id为bf08b7f2cd89的容器的端口映射情况

查看web应用程序容器的进程

我们还可以使用docker top来查看容器内容运行的进程
docker top <容器ID/名称>

查看WEB应用程序日志

docker logs -f <容器ID/名称>
-f: 让 docker logs 像使用 tail -f 一样来输出容器内部的标准输出。

从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志

检查WEB应用程序

docker inspect 来查看Docker的底层信息。他会返回一个JSON文件记录着docker容器的配置和状态信息

停止WEB应用程序

docker stop <容器名称/id>

重启WEB应用程序

已经停止的docker容器我们可以使用docker start 容器id/名称 来进行重启

docker ps -l 查询最后一次创建的容器
正在运行的容器可以使用 docker restart 来进行重启

移除WEB应用容器

我们可以使用docker rm 命令来删除不需要的容器 删除容器时,容器必须是停止状态,否则会报错
runoob@runoob:~$ docker rm wizardly_chandrasekhar Error response from daemon: You cannot remove a running container bf08b7f2cd897b5964943134aa6d373e355c286db9b9885b1f60b6e8f82b2b85. Stop the container before attempting removal or force remove

镜像使用

当想要运行一个容器时, 必须要有相对应的镜像, 如果使用的镜像不再本地中, docker就会自动从docker镜像仓库中下载, 默认是从Docker Hub公共镜像源下载

列出镜像列表

docker images 可以列出当前本机中有的镜像信息
image
其中各个列的含义为:

  • REPOSITORY: 表示镜像的仓库源
  • TAG: 镜像的标签
  • IMAGE ID: 镜像ID
  • CREATED: 镜像创建时间
  • SIZE: 镜像大小

同一仓库源可以有多个TAG, 代表这个仓库源的不同版本, 例如ubunt的仓库源就有15.04和15.10两个版本
通常使用 REPOSITORY:TAG 的组合来定义不同的镜像
所以, 如果想要以ubuntu 15.10的仓库源为镜像来运行一个容器, 就要这样使用命令

1
docker run -ti ubuntu:15.10 /bin/bash

如果不指定ubuntu:15.10 , 则docker会默认使用 ubuntu:latest镜像, 这时候如果本地中没有TAG为latest的镜像, 他会先拉取镜像然后在运行容器

查找并获取镜像

平时使用docker的过程中我们可以在Docker Hub网站上搜索想要使用的镜像, 网址为: www.hub.docker.com

也可以在docker中直接搜索想要的镜像
docker search <镜像名称>

以httpd的镜像为例 :
image
其中有几列信息分别为:

  • NAME: 镜像仓库源的名称
  • DESCRIPTION: 镜像的描述
  • OFFICIAL: 是否docker官方发布
  • stars: 类似Github 里面的star, 表示喜欢,点赞的意思
  • AUTOMATED: 自动构建

拖取镜像
查找到自己需要的镜像后直接
docker pull <镜像名>
就可以拿到自己需要的镜像了
如:

1
2
docker pull httpd
docker run httpd

删除镜像

删除镜像使用docker rmi <镜像id> 命令

需要注意的是, 删除的镜像必须没有从该镜像创建的容器 , 如果有容器是从该镜像创建的并且仍然存在则必须先删除容器才能够彻底删除该镜像

创建镜像

当Docker Hub中的镜像不能满足我们的需求的时候 , 或者我们需要把自己本地的某个应用变成一个镜像, 这个时候就需要我们自己创建镜像
通常有两种创建镜像的方法, 分别为 :

  1. 从已经创建的容器中更新镜像,并且提交这个镜像
  2. 使用Dokcerfile指令来创建一个新的镜像

更新镜像并提交之commit指令

1.更新镜像之前需要先用该镜像运行一个容器 , 此处以 ubuntu为例

1
2
docker run -t -i --name ubuntu-test ubuntu:latest /bin/bash
root@b00ac6809556:/#

2.容器运行起来后可以注意到该容器中没有vim工具, 没有net-tools工具等, 全部给他进行安装后在家目录下创建test.txt文件并写入内容,作为之后检测容器运行是否成功的标志
image

3.此时由ubutun:latest镜像产生的容器便被修改了, 使用exit退出容器
此时我们便可以使用commit命令来提交容器副本

1
docker commit -m="install tools" -a="tony" b00ac6809556 tony/ubuntue-test:v2

参数说明:

  • -m: 代表提交信息, 一般用来说明新的镜像变动内容
  • -a: 指定镜像作者
  • b00ac6809556: 即将作为镜像的容器的id
  • tony/ubuntue-test:v2: 创建的目标镜像名

4.此时使用docker images再次查看镜像, 发现刚刚创建的镜像就在其中
image
5.使用新镜像tony/ubuntu-test来启动一个容器
docker run -ti tony/ubuntu-test:v2 /bin/bash
并查看其中是否有刚刚下载的工具及test.txt文件
image

结果显示有刚才创建的test.txt文件, 至此已经将一个简单的应用环境打包成了一个镜像并运行为一个容器

使用Dockerfile来构建镜像

除过上述使用docker commit的方式构建镜像外, 还有一种方法就是使用docker build命令来创建一个新的镜像.
使用该命令, 我们需要先有一个Dockerfile文件, 其中包括一组指令来告诉Docker如何构建我们的镜像

Dockerfile中每一行都是一个指令 . 每一个指令都会在镜像上创建一个新的层, 每一个指令的前缀都必须是大写的.
第一天FROM , 指定使用那个镜像源
RUN指令告诉docker在镜像内执行命令, 安装什么
最后使用Dokcerfile文件, 通过docker build 命令来构建镜像, 下面是一个例子:

1
2
3
4
5
6
7
8
9
10
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"

RUN /bin/echo 'root:123456' | chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D

这段Dockerfile 大致就是按照centos:6.7版本的操作系统制作一个镜像, 在制作好的系统镜像中创建了runoob用户并且给他设置了密码 .

写好Dockerfile后在该文件所在目录下执行命令

1
docker build -t tony/centos:6.7 .

  • -t: 指定要创建的目标镜像名
  • . : Dockerfile文件所在目录, 可以指定Dockerfile的绝对路径

然后docker images 查看镜像便有了该镜像
通过docker run -ti <镜像id> /bin/bash 运行容器后 , 通过命令id runoob可以看到此时这个centos容器中已经有了该runoob用户 , 所以镜像创建成功

设置镜像标签

我们可以使用docker tag命令, 为镜像添加一个新的标签
dokcer tag <镜像id> 镜像名称:新的标签
例如:
docker tag 91a22f989e96 tony/centos:dev
此时便会生成一个新的标签为dev的tony/centos镜像
image

Docker容器连接

上面展示了通过网络端口来访问正在运行的docker容器内的服务
容器中可以运行一些网络应用, 要让外部也可以访问这些应用, 可以通过-P-p参数来指定端口映射
下面说说容器之间通过端口连接实现互相访问

回顾网络端口映射
创建一个python的应用容器 , 并映射容器端口到主机端口
1.使用-P随机映射端口
docker run -d -P training/webapp python app.py

使用docker ps可以查看映射后的端口情况
可以直接使用docker port <容器名> 容器端口号 来查看该端口的映射情况

2.使用-p指定容器端口绑定到主机端口
docker run -d -p 5000:5000 training/webapp python app.py

3.另外, 可以指定容器绑定的网络地址, 比如绑定127.0.0.1
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
这样就可以直接通过访问 127.0.0.1:5001 来访问容器的5000端口

上面例子中都是默认绑定tcp端口, 如果要绑定udp端口, 可以在端口号后面加上/udp
docker run -d -p 127.0.0.1:5001:5000/udp training/webapp python app.py

docker 容器互联

docker有一个连接系统, 允许将讲个容器连接在一起, 共享连接信息.
docker连接会创建一个父子关系, 其中父容器可以看到子容器的信息

1.新建网络 : 创建一个新的Docker网络, driver为bridge (默认就是bridge)
docker network create -d bridge test-net
其中参数 -d 用于指定网络类型, 有bridge,overlay

2.连接容器
运行一个容器并连接到新建的test-net网络
docker run -tid --name test1 --network test-net tony/ubuntu-test:v2 /bin/bash
再运行一个容器并连接到新建的test-net网络
docker run -tid --name test2 --network test-net tony/ubuntu-test:v2 /bin/bash

3.通过ping命令证明test1容器和test2容器建立了互联关系

1
2
docker exec -it test1 /bin/bsh
ping test2

发现ping命令成功,以此证明两个容器建立了互连关系

整个过程如下图所示
image
如果有多个容器需要互相连接, 推荐使用Docker Compose