Fork me on GitHub

Docker 常用命令

为虚拟化应用而生,生产环境一键打包

Docker 是一个开源的 应用容器引擎,基于 Go 语言 并遵 从Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口( 类似 iPhoneApp ),更重要的是容器性能开销极低。

应用场景


  • Web 应用的自动化打包和发布;
  • 自动化测试和持续集成、发布;
  • 在服务型环境中部署和调整数据库或其他的后台应用;
  • 从头编译或者扩展现有的 OpenShift 等平台来搭建自己的PaaS环境;

Docker


官网:www.docker.com

仓库:

  1. docker 官网仓库: http://hub.docker.com
  2. docker 中国区官网仓库: https://registry.docker-cn.com
  3. 阿里镜像仓库: https://dev.aliyun.com
  4. 163 仓库(需注册): http://c.163yun.com/hub

安装:

  1. MacOS 安装: 官网教程地址
  2. Ubuntu 安装: 官网教程地址
  3. Ubuntu 简单旧版安装:

    1
    2
    3
    uname -r 	# 内核版本需要 > 3.10
    sudo apt-get install -y docker.io # 安装系统自带的 docker ( 可能不是最新版本 )
    docker version # 出现客户端和服务端版本

Docker初体验


拉取镜像

docker pull [OPTIONS] NAME[:TAG]

NAME 必须指定,TAG 表示版本,默认不写为 latest 最新版本

默认 pull 的地址为 docker 官方镜像地址: https://hub.docker.com/explore/

如:

1
2
3
4
docker pull hello-world		# 拉取 hello-world 镜像
docker pull tomcat # 拉取 tomcat 镜像
docker pull nginx # 拉取 nginx 镜像
docker pull mysql # 拉取 mysql 镜像

但是国内该地址常常被墙,所以国内大公司出了自己的镜像仓库,在上一节已经说明。

这里以用 163 蜂巢的镜像为例,地址: https://c.163.com/hub#/m/home/

地址里含有 libary 为 163 从 docker 官网复制过来的镜像。

如:

1
2
3
docker pull hub.c.163.com/library/tomcat:latest	# 拉取 tomcat 镜像
docker pull hub.c.163.com/library/nginx:latest # 拉取 nginx 镜像
docker pull hub.c.163.com/library/mysql:latest # 拉取 mysql 镜像

查看本机镜像

docker images [OPTIONS] [REPOSITORY[:TAG]]

1
docker images

运行镜像

docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG]

一个镜像运行起来就变为容器了,容器是动态的运行时的称呼。同一个镜像可以运行出多个容器,因为只要运行镜像,其内部内存占用等等一定不相同,所以镜像与容器是 1对多 的关系。

1
2
3
4
5
6
7
8
9
# 直接运行
docker run hello-world # 如果没有此镜像则会自动从官方下载镜像
docker run tomcat # 通过命令行运行 tomcat,按 ctrl+c 就可以结束
# 也可以带参数 [OPTIONS] 运行
docker run -d hello-world # -d 表示后台运行tomcat镜像
# 也可以带命令运行
docker run learn/tutorial echo "hello word" # 输出 hello world
docker run learn/tutorial apt-get install -y ping # 安装 ping 工具
docker run lean/ping ping www.google.com # 执行 ping 命令

查看本机容器

相信用过 Linux 的同学应该知道 ps 这个工具,代表 process 即进程。程序与进程的区别 和 镜像与容器的关系是一致的,进程和容器都是运行时状态,因此,查看本机容器的关键名也是 ps.

1
2
3
4
# 查看当前 docker 所运行的容器
docker ps # 列出所有运行着的容器
# 要查看所有容器,包括未运行的容器
docker ps -a # 显示所有容器

运行容器命令

docker exec [OPTIONS] CONTAINER [COMMAND] [ARG]

前面 运行镜像 时已经说明直接运行镜像时可以带上命令以一起运行,那如果容器已经被启动了,怎么再在里面运行命令呢?那就是这个命令。

1
2
3
4
5
6
7
8
# 在容器中运行命令,查看帮助文档
docker exec --help # 查看帮助文档
# 其中 -i 和 -t 参数最常用,其这两者常搭配使用
# -i 表示以交互模式运行容器;
# -t 表示为容器重新分配一个伪输入终端;
docker exec -it f4e5 bash # 在某个容器里运行 bash
# 其中 f4e5 表示运行着的容器的 ID ,大家用前面的 docker ps 看到的 ID 就是;
# ID 可以选择前几个字符就可以的,因为前几个字符基本就能确定到这个容器了。

停止容器

docker stop CONTAINER_ID

1
2
# 停止某个容器 ( 可以为容器的 Id,也可以是容器的名称 )
docker stop 56f433965490 # 以容器 Id 停止容器

打包成镜像

docker commit CONTAINER_ID IMAGE_NAME

容器既然是镜像运行时状态,那我们如果在容器里装很多软件,而自己又不想每次用这个镜像都想重新装一遍软件,那么就可以将自己 DIY 的容器存为镜像,以后我们再 DIY 时就从我们已经装完软件的那个时刻开始了。将容器打包为镜像命令如上。

1
2
3
# 将容器打包成一个新的镜像
docker commit 56f tomcat/property
# 将 Id 为 56f 的容器打包成一个镜像,镜像名称自己起就可以了

删除镜像和容器

1
2
3
4
5
6
7
8
# 1. 删除容器
docker rm CONTAINER_ID
# 2. 删除所有容器,-q 表示显示容器 Id
docker rm $(docker ps -a -q)
# 3. 删除镜像,rmi 中的 i 表示 image
docker rmi IMAGES_NAME
# 4:举例:删除 tomcat 镜像
docker rmi tomcat

常用命令


基本命令

下面给出做 web 方向常用到的一些命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 从 163镜像中心 下载 nginx 镜像
docker pull hub.c.163.com/library/nginx:latest
# 或者从官网镜像中心下载 nginx 镜像
docker pull nginx

# 运行 Nginx 镜像, 没有端口映射,只能本机访问
docker run hub.c.163.com/library/nginx # 前台运行
docker run -d hub.c.163.com/library/nginx # 后台运行

# 运行 Nginx 镜像,端口映射本机 80 端口,
# 这样其他机器访问本机的 80 自动映射到容器 80 服务
# docker run -d -p 80:80 --name webserver nginx
# --name 表示给容器起名,这里为 webserver

# 停止运行 Nginx 镜像的 webserver 容器
docker stop webserver
# 或者用容器 Id 停止
docker stop CONTAINER_ID

# 在容器里运行 bash
docker exec -it f4e5 bash # 打开 f4e5 容器里的 bash 命令行界面

# 查看容器 ip
docker inspect f4e5 | grep IPAddress

容器端口映射

1
2
3
4
5
# 将本机 8080 端口映射到容器的 80 端口,-p 代表开放端口
docker run -d -p 8080:80 hub.c.163.com/library/nginx
netstat -na | grep 8080 // 可以检查本机端口状态
# 将本机随机的端口映射到容器的 80 和 443 端口
docker run -d -P hub.c.163.com/library/nginx

容器运行 WAR 包

这是我在一个项目里面用这种方式尝试过了,使用 tomcat 镜像运行出的容器,把本地的 war 包映射到容器 tomcat 里的 ROOT 目录,同时端口也要映射出来,最后可以通过外网访问。

1
2
3
4
5
6
7
8
9
10
docker run -d -it -p 8089:8080 -v $(pwd)/ROOT.war:/usr/local/tomcat/webapps/ROOT.war -v $(pwd)/ROOT:/usr/local/tomcat/webapps/ROOT -v $(pwd)/uploads:/usr/local/webapps/uploads tomcat
# 1. 将本地 8089 映射到容器的 8080 端口,
# 2. 将本地磁盘的 ROOT.war 映射到容器里 tomcat 的 webapps 目录,
# 3. 将本地磁盘的 ROOT 目录,映射到容器里 tomcat 的 ROOT 目录,
# 4. 将本地磁盘的 uploads 目录,映射到容器里 tomcat 的 webapps/uploads 目录 (这是我们项目上传文件的地址)
# 5. 最后为镜像名称,如果为 163蜂巢的镜像名 则应改为蜂巢的镜像名
# -v : 为加载本地硬盘
# -it : 为执行容器里命令开启
# -i : --interactive 打开STDIN,用于控制台交互
# -t : --tty 分配tty设备,该可以支持终端登录

制作自己的镜像

这个是从构建文件制作自己的镜像的,主要是写 Dockerfile, 这个目前还涉及的较少,只写下基本的构建过程。主要分为 Dockerfile 编写 和 build 命令:

Dockerfile

1
2
3
from hub.c.163.com/library/tomcat		# 镜像从 tomcat 继承
MAINTAINER jiyi xxx@163.com # 著作者名和邮箱
COPY jpress.war /usr/local/tomcat/webapps # 镜像操作,这里将 jpress.war 放到 tomcat/webapps 目录下

docker build [OPTIONS] [PATH]

1
2
3
4
5
# 直接在包含 Dockerfile 的当前目录 build
docker build .
# 或者 -t 为生成的镜像配一个 tag 说明,这里 jpress 为名字,lastest 为 tag
# 注意还有一个 . 表示 [PATH],这里还是指当前路径
docker build -t jpress:latest .

私有仓库部署

很多公司里需要构建自己的私有仓库,因此这里也简单介绍下。

假设有两台机器:

A: 192.168.31.115 (作为仓库)

B: 192.168.31.215 (提交镜像者)

(1). A: 下载仓库镜像

1
docker pull registry

(2). A: 运行镜像

应该将本地某个目录映射到 /tmp/registry 中以保存镜像,官方文档: 点我,这里还是说下不同版本的 registry 镜像中仓库地址是不一样的:

  • 版本 1.0 的数据保存在 /tmp/registry
  • 版本 2.0 的数据存储在 /var/lib/registry

示例命令如下:

1
docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry

(3). B: 先下载一个小镜像

1
docker pull busybox

(4). B: 修改该镜像的 tag

1
docker tag busybox 192.168.31.115:5000/busybox

(5). B: 上传镜像

1
docker push 192.168.31.115:5000/busybox

出现问题不能 https,官方说明配置:https://docs.docker.com/registry/insecure/,这里说下我自己尝试的方法:

如果是在 Mac 上操作的,直接在docker 图标的设置里添加 Insecure-registry:192.168.31.115:5000, 保存重启软件就可以了。

如果是 Linux 系统,则修改 Docker 的配置文件 /etc/docker/daemon.json, 如下:

1
2
3
{
"insecure-registries" : ["myregistrydomain.com:5000"]
}

(6). B: 检查是否上传成功

1
2
3
4
curl -XGET http://registry:5000/v2/_catalog
curl -XGET http://192.168.31.115:5000/v2/_catalog
curl -XGET http://registry:5000/v2/image_name/tags/list
curl -XGET http://192.168.31.115:5000/v2/192.168.31.115:5000/busybox/tags/list

返回结果示例:

1
2
3
4
5
{
"repositories": [
"busybox"
]
}

相关链接

苟且一下