5. 创建镜像
当我们从docker镜像仓库中下载的镜像不能满足我们的需求时, 我们可以通过以下两种方式对镜像进行更改:
. 从已经创建的容器中更新镜像, 并且提交这个镜像
. 使用Dockerfile指令来创建一个新的镜像
6. 更新镜像
更新镜像之前, 我们需要使用镜像来创建一个容器.
docker run -t -i centos:6.10 /bin/bash
在运行的容器内使用 apt-get update 命令进行更新.
在完成操作之后, 输入exit命令来退出这个容器
此时 id 为 e218edb10236 的容器, 是按我们的需求更改的容器. 我们可以通过命令docker commit来提交容器副本.
docker commit -m="has update" -a="jin" e218edb10236 jin/centos:6.10
sha256:70bf1840fd7c0d2d8ef0a42a817eb29f854c1af8f7c59fc03ac7bdee95236236
各个参数说明:
-m: 提交的描述信息
-a: 指定镜像作者
e218edb10236: 容器ID
jin/centos:6.10: 指定要创建的目标镜像名
我们可以使用 docker images 命令来查看我们的新镜像 jin/centos:6.10 :
```bash
docker images
jin@jinLab:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jin/centos v3 70bf1840fd7c 15 seconds ago 158.5 MB
ubuntu 14.04 90d5884b1ee0 5 days ago 188 MB
php 5.6 f40e9e0f10c8 9 days ago 444.8 MB
使用我们的新镜像jin/centos来启动一个容器
docker run -t -i jin/centos:v3 /bin/bash
root@1a9fbdeb5d23:/#
7. 构建镜像
我们使用命令 docker build, 从零开始来创建一个新的镜像. 为此, 我们需要创建一个 Dockerfile 文件, 其中包含一组指令来告诉 Docker如何构建我们的镜像.
cat Dockerfile
FROM centos:6.10
MAINTAINER Fisher "[email protected]"
RUN /bin/echo 'root@123456' | chpasswd
RUN useradd jin
RUN /bin/echo 'jin:123456' | chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" > /etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
每一个指令都会在镜像上创建一个新的**层**, 每一个指令的前缀都必须是**大写的**.
第一条FROM, 指定使用哪个镜像源
RUN 指令告诉docket在镜像内执行命令,安装了什么.
然后,我们使用 Dockerfile文件, 通过docker build命令来构建一个镜像
```bash
docker build -t jin/centos:6.10 .
Sending build context to Docker daemon 17.92 KB
Step 1 : FROM centos:6.10
---> d95b5ca17cc3
Step 2 : MAINTAINER Fisher "[email protected]"
---> Using cache
---> 0c92299c6f03
Step 3 : RUN /bin/echo 'root:123456' |chpasswd
---> Using cache
---> 0397ce2fbd0a
Step 4 : RUN useradd jin
......
参数说明:
-t: 指定要创建的目标镜像名
.: Dockerfile 文件所在目录,可以指定 Dockerfile的绝对路径
使用 docker images 查看创建的镜像已经在列表中存在, 镜像 ID为 860c279d2f23
docker images
jin@jinLab:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jin/centos 6.10 860c279d2f23 About a minute ago 190.6 MB
ubuntu 14.04 90d5884b1ee0 6 days ago 188 MB
我们可以使用新的镜像来创建容器
docker run -t -i jin/centos:6.10 /bin/bash
id jin
从上面看到新镜像已经包含我们创建的用户 jin
8. 设置镜像标签
我们可以使用 docker tag命令, 为镜像添加一个新的标签.
docker tag 860c279d2f23 jin/centos:dev
docker tag 镜像ID: 860c279d2f23, 用户名称, 镜像源名( repository name )和新的标签名(tag).
使用 docker images 命令可以看到, ID为 860c279d2f23的镜像多一个标签.
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jin/centos 6.10 860c279d2f23 About a minute ago 190.6 MB
jin/centos dev 860c279d2f23 About a minute ago 190.6 MB
ubuntu 14.04 90d5884b1ee0 6 days ago 188 MB
Docker容器使用
1. Docker客户端
docker客户端非常简单, 我们可以直接输入 docker命令来查看到 Docker客户端的所有命令选项.
docker
可以通过命令 docker command --help 更深入的了解指定的 Docker命令使用方法.
例如我们要查看docker stats 指令的具体使用方法:
jin@jinLab:~# docker stats --help
#2. 运行一个web应用
前面我们运行的容器并没有一些特别的用处.
接下来让我们尝试使用docker构建一个web应用程序.
我们将在docker容器中运行一个Python Flask应用来运行一个web应用.
```bash
docker pull training/webapp # 载入镜像
docker run -d -P training/webapp python app.py
参数说明:
-d: 让容器在后台运行
-P: 将容器内部使用的网络端口映射到我们使用的主机上
#3. 查看WEB应用容器
使用docker ps来查看我们正在运行的容器:
```bash
docker ps
CONTAINER ID IMAGE COMMAND ... PORTS
d3d5e39ed933 training/webapp "python app.py" ... 0.0.0.0:32769->5000/tcp
这里多了端口信息.
0.0.0.0:32769->5000/tcp
Docker 开放了5000端口(默认Python Flask端口)映射到主机端口32769上
这时我们可以通过浏览器访问WEB应用
http://192.168.239.130:32769
hello world!
我们也可以通过-p参数来设置不一样的端口:
docker run -d -p 5000:5000 training/webapp python app.py
docker ps 查看正在运行的容器:
docker ps
CONTAINER ID IMAGE PORTS NAMES
bf08b7f2cd89 training/webapp ... 0.0.0.0:5000->5000/tcp wizardly_chandrasekhar
d3d5e39ed933 training/webapp ... 0.0.0.0:32769->5000/tcp xenodochial_hoov
容器内部的5000端口映射到我们本地主机的5000端口上.
4. 网络端口的快捷方式
通过 docker ps命令可以查看到容器的端口映射, docker还提供了另一个快捷方式 docker port, 使用docker port 可以查看指定( ID或者名字 )容器的某个确定端口映射到宿主机的端口号.
上面我们创建的web应用容器 ID为 bf08b7f2cd89 名字为 wizardly_chandrasekhar.
我们可以使用 docker port bf08b7f2cd89 或者 docker port wizardly_chandrasekhar 来查看容器端口的映射情况.
jin@jinLab:~$ docker port bf08b7f2cd89
5000/tcp -> 0.0.0.0:5000
jin@jinLab:~$ docker port wizardly_chandrasekhar
5000/tcp -> 0.0.0.0:5000
5. 查看WEB应用程序日志
docker logs [ID或者名字] 可以查看容器内部的标准输出
docker logs -f bf08b7f2cd89
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.3.23 - - [09/May/2016 16:30:37] "GET / HTTP/1.1" 200 -
192.168.3.23 - - [09/May/2016 16:30:37] "GET /favicon.ico HTTP/1.1" 404 -
-f: 让 docker logs像使用 tail -f一样来输出容器内部的标准输出.
从上面, 我们可以看到应用程序使用的的是 5000 端口并且能够查看到应用程序的访问日志.
6. 查看WEB应用程序容器的进程
我们还可以使用docker top来查看容器内部运行的进行
docker top wizardly_chandrasekhar
UID PID PPID ... TIME CMD
root 23225 23223 ... 00:00:00 python app.py
6. 检查WEB应用程序
使用 docker inspect 来查看 Docker的底层信息. 它会返回一个JSON文件记录着 docker 容器的配置和状态信息.
docker inspect wizardly_chandrasekhar
7. 停止WEB应用程序
docker stop wizardly_chandrasekhar
8. 重启WEB应用程序
docker start wizardly_chandrasekhar
查询最后一次创建的容器:
docker ps -l
CONTAINER ID IMAGE PORTS NAMES
bf08b7f2cd89 training/webapp ... 0.0.0.0:5000->5000/tcp wizardly_chandrasekhar
正在运行的容器,可以使用 docker restart 命令来重启.
9. 移除WEB应用容器
我们可以使用 docker rm 命令来删除不需要的容器
docker rm wizardly_chandrasekhar
删除容器时, 容器必须是停止状态, 否则会报如下错误
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容器.
1. 网络端口映射
我们创建了一个python应用的容器
docker run -d -P training/webapp python app.py
另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1
我们使用-P参数创建一个容器, 使用 docker ps 来看到端口5000绑定主机端口 32768
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fce072cc88ce training/webapp "python app.py" 4 minutes ago Up 4 minutes 0.0.0.0:32768->5000/tcp grave_hopper
我们也可以使用-p标识来指定容器端口绑定到主机端口.
两种方式的区别是:
-P: 是容器内部端口随机映射到主机的高端口
-p: 是容器内部端口绑定到指定的主机端口
docker run -d -p 5000:5000 training/webapp python app.py
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33e4523d30aa training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp berserk_bartik
fce072cc88ce training/webapp "python app.py" 8 minutes ago Up 8 minutes 0.0.0.0:32768->5000/tcp grave_hopper
另外, 我们可以指定容器绑定的网络地址,比如绑定: 127.0.0.1
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
95c6ceef88ca training/webapp "python app.py" 6 seconds ago Up 6 seconds 5000/tcp, 127.0.0.1:5001->5000/tcp adoring_stonebraker
33e4523d30aa training/webapp "python app.py" 3 minutes ago Up 3 minutes 0.0.0.0:5000->5000/tcp berserk_bartik
fce072cc88ce training/webapp "python app.py" 10 minutes ago Up 10 minutes 0.0.0.0:32768->5000/tcp grave_hopper
这样我们就可以通过访问127.0.0.1:5001 来访问容器的5000端口
上面例子中, 默认都是绑定 tcp端口, 如果要绑定 udp 端口, 可以在端口后面加上 /udp
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6779686f06f6 training/webapp "python app.py" 4 seconds ago Up 2 seconds 5000/tcp, 127.0.0.1:5000->5000/udp drunk_visvesvaraya
95c6ceef88ca training/webapp "python app.py" 2 minutes ago Up 2 minutes 5000/tcp, 127.0.0.1:5001->5000/tcp adoring_stonebraker
33e4523d30aa training/webapp "python app.py" 5 minutes ago Up 5 minutes 0.0.0.0:5000->5000/tcp berserk_bartik
fce072cc88ce training/webapp "python app.py" 12 minutes ago Up 12 minutes 0.0.0.0:32768->5000/tcp grave_hopper
docker port命令可以让我们快捷地查看端口的绑定情况:
docker port adoring_stonebraker 5000
2. Docker容器连接
端口映射并不是唯一把docker连接到另一个容器的方法
docker有一个连接系统允许将多个容器连接在一起,共享连接信息
docker连接会创建一个父子关系,其中父容器可以看到子容器的信息
3. 容器命名
当我们创建一个容器的时候, docker会自动对它进行命名. 另外,我们也可以使用--name标识来命名容器. e.g.:
docker run -d -P --name pyWebApp training/webapp python.py
我们可以使用 docker ps命令来查看容器名称
docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
43780a6eabaa training/webapp "python app.py" 3 minutes ago Up 3 minutes 0.0.0.0:32769->5000/tcp pyWebApp