一、Docker 架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。
容器与镜像的关系类似于面向对象编程中的对象与类。
Docker | 面向对象 |
---|---|
容器 | 对象 |
镜像 | 类 |
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker 仓库(Registry) | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。
Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
二、Docker的安装(CentOS7)
# yum install docker -y
启动
[root@node1 ~]# systemctl start docker.service [root@node1 ~]# systemctl status docker.service
测试运行 hello-world
[root@node1 ~]#docker run hello-world
三、Docker的使用
1.Docker 容器使用
Docker 客户端
docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。
# docker
可以通过命令 docker command –help 更深入的了解指定的 Docker 命令使用方法。
例如我们要查看 docker cp 指令的具体使用方法:
# docker cp --help
运行一个web应用
接下来让我们尝试使用 docker 构建一个 web 应用程序。
我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。
# docker pull training/webapp # 载入镜像 # docker run -d -P training/webapp python app.py
- -d:让容器在后台运行。
- -P:将容器内部使用的网络端口映射到我们使用的主机上。
查看 WEB 应用容器
使用 docker ps 来查看我们正在运行的容器
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a5642146bb0b training/webapp "python app.py" About a minute ago Up 56 seconds 0.0.0.0:32768->5000/tcp sharp_wescoff
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32768 上。
这时我们可以通过浏览器访问WEB应用
我们也可以指定 -p 标识来绑定指定端口。
# docker run -d -p 5000:5000 training/webapp python app.py
docker ps查看正在运行的容器
容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
网络端口的快捷方式
通过docker ps 命令可以查看到容器的端口映射,docker还提供了另一个快捷方式:docker port,使用 docker port 可以查看指定 (ID或者名字)容器的某个确定端口映射到宿主机的端口号。
上面我们创建的web应用容器ID为:1fe8bac621b1 名字为:gloomy_borg
我可以使用docker port 1fe8bac621b1 或docker port gloomy_borg来查看容器端口的映射情况
# docker port 1fe8bac621b1 5000/tcp -> 0.0.0.0:5000
# docker port gloomy_borg 5000/tcp -> 0.0.0.0:5000
查看WEB应用程序日志
docker logs [ID或者名字] 可以查看容器内部的标准输出。
# docker logs -f 1fe8bac621b1
- -f:让 dokcer logs 像使用 tail -f 一样来输出容器内部的标准输出。
查看WEB应用程序容器的进程
我们还可以使用 docker top 来查看容器内部运行的进程
# docker top gloomy_borg
检查WEB应用程序
使用 docker inspect 来查看Docker的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
# docker inspect gloomy_borg
停止WEB应用容器
# docker stop gloomy_borg
gloomy_borg
重启WEB应用容器
已经停止的容器,我们可以使用命令 docker start 来启动。
# docker start gloomy_borg
gloomy_borg
docker ps -l 查询最后一次创建的容器:
移除WEB应用容器
我们可以使用 docker rm 命令来删除不需要的容器
# docker rm gloomy_borg
gloomy_borg
删除容器时,容器必须是停止状态,否则会报如下错误
# docker rm gloomy_borg Error response from daemon: You cannot remove a running container 7a38a1ad55c6914b360b565819604733db751d86afd2575236a70a2519527361. Stop the container before attempting removal or use -f
2.Docker 镜像使用
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
列出镜像列表
我们可以使用 docker images 来列出本地主机上的镜像。
[root@node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/hello-world latest f2a91732366c 9 weeks ago 1.848 kB docker.io/training/webapp latest 6fae60ef3446 2 years ago 348.7 MB
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
如果你不指定一个镜像的版本标签,将默认使用 ubuntu:latest 镜像。
获取一个新的镜像
当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。
查找镜像
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个httpd的镜像来作为我们的web服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。
# docker search httpd
- NAME:镜像仓库源的名称
- DESCRIPTION:镜像的描述
- OFFICIAL:是否docker官方发布
拖取镜像
我们决定使用上图中的httpd 官方版本的镜像,使用命令 docker pull 来下载镜像。
# docker pull httpd
下载完成后,我们就可以使用这个镜像了。
# docker run httpd
创建镜像
当我们从docker镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
- 1.从已经创建的容器中更新镜像,并且提交这个镜像
- 2.使用 Dockerfile 指令来创建一个新的镜像
使用 Dockerfile
定义容器
Dockerfile
将在您的容器内定义环境中执行的操作。对网络接口和磁盘驱动器等资源的访问在此环境内实现虚拟化,这将独立于系统的其余部分,因此您必须将端口映射到外部,并具体说明您要“复制”到该环境的文件。但是,在执行此操作后,您可以期望此 Dockerfile
中定义的应用构建的行为在运行时始终相同。
更新镜像
更新镜像之前,我们需要使用镜像来创建一个容器。
# docker run -t -i ubuntu:15.10 /bin/bash
在运行的容器内使用 apt-get update 命令进行更新。
在完成操作之后,输入 exit命令来退出这个容器。
此时ID为e218edb10161的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit来提交容器副本。
# docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
- -m:提交的描述信息
- -a:指定镜像作者
- e218edb10161:容器ID
- runoob/ubuntu:v2:指定要创建的目标镜像名
我们可以使用 docker images 命令来查看我们的新镜像 runoob/ubuntu:v2:
# docker images
# docker run -t -i runoob/ubuntu:v2 /bin/bash
构建镜像
我们使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
# cat Dockerfile FROM centos:7.0 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
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
# docker build -t runoob/centos:7.0 . Sending build context to Docker daemon 17.92 kB Step 1 : FROM centos:7.0 ---> d95b5ca17cc3 Step 2 : MAINTAINER Fisher "fisher@sudops.com" ---> Using cache ---> 0c92299c6f03 Step 3 : RUN /bin/echo 'root:123456' |chpasswd ---> Using cache ---> 0397ce2fbd0a Step 4 : RUN useradd runoob ......
参数说明:
- -t :指定要创建的目标镜像名
- . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
使用docker images 查看创建的镜像已经在列表中存在,镜像ID为860c279d2fec
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE runoob/centos 7.0 860c279d2fec About a minute ago 190.6 MB runoob/ubuntu v2 70bf1840fd7c 17 hours ago 158.5 MB
我们可以使用新的镜像来创建容器
# docker run -t -i runoob/centos:7.0 /bin/bash # id runoob uid=500(runoob) gid=500(runoob) groups=500(runoob)
从上面看到新镜像已经包含我们创建的用户runoob
设置镜像标签
我们可以使用 docker tag 命令,为镜像添加一个新的标签。
# docker tag 860c279d2fec runoob/centos:dev
docker tag 镜像ID,这里是 860c279d2fec ,用户名称、镜像源名(repository name)和新的标签名(tag)。
使用 docker images 命令可以看到,ID为860c279d2fec的镜像多一个标签。
# docker images
docker build -t friendlyname .# 使用此目录的 Dockerfile 创建镜像
docker run -p 4000:80 friendlyname # 运行端口 4000 到 90 的“友好名称”映射
docker run -d -p 4000:80 friendlyname # 内容相同,但在分离模式下
docker ps # 查看所有正在运行的容器的列表
docker stop <hash> # 平稳地停止指定的容器
docker ps -a # 查看所有容器的列表,甚至包含未运行的容器
docker kill <hash> # 强制关闭指定的容器
docker rm <hash> # 从此机器中删除指定的容器
docker rm $(docker ps -a -q) # 从此机器中删除所有容器
docker images -a # 显示此机器上的所有镜像
docker rmi <imagename> # 从此机器中删除指定的镜像
docker rmi $(docker images -q) # 从此机器中删除所有镜像
docker login # 使用您的 Docker 凭证登录此 CLI 会话
docker tag <image> username/repository:tag # 标记 <image> 以上传到镜像库
docker push username/repository:tag # 将已标记的镜像上传到镜像库
docker run username/repository:tag # 运行镜像库中的镜像
3.Docker 容器连接
前面我们实现了通过网络端口来访问运行在docker容器内的服务。下面我们来实现通过端口连接到一个docker容器
网络端口映射
我们创建了一个 python 应用的容器。
# docker run -d -P training/webapp python app.py 1c742e90359043506e09073f7eee1e55104e717431dbdf60d15cb69455ea5c3f
另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。
我们使用 -P 参数创建一个容器,使用 docker ps 来看到端口5000绑定主机端口32768。
runoob@runoob:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a5642146bb0b training/webapp "python app.py" 58 minutes ago Up 58 minutes 0.0.0.0:32768->5000/tcp sharp_wescoff
我们也可以使用 -p 标识来指定容器端口绑定到主机端口。
两种方式的区别是:
- -P :是容器内部端口随机映射到主机的高端口。
- -p : 是容器内部端口绑定到指定的主机端口。
# docker run -d -p 5000:5000 training/webapp python app.py e29a4bc8b95d6d16409a0c9dc322917d48e4dff9e80f764ba081b2e82f749272
# docker ps
另外,我们可以指定容器绑定的网络地址,比如绑定127.0.0.1。
# docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py 473fca33b392af025d1b826a561915d0ef0388c658db12ab6a4e732af11e77fc # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 473fca33b392 training/webapp "python app.py" 21 seconds ago Up 20 seconds 127.0.0.1:5001->5000/tcp pensive_ride 1c742e903590 training/webapp "python app.py" 4 minutes ago Up 4 minutes 0.0.0.0:32769->5000/tcp sharp_bhaskara 1fe8bac621b1 training/webapp "python app.py" 54 minutes ago Up 54 minutes 0.0.0.0:5000->5000/tcp gloomy_borg
这样我们就可以通过访问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 c42ab43c0bf69c5cb5285c68f57d621c5dbd1bea66f6e818d42ee22b07578204 # docker ps
docker port 命令可以让我们快捷地查看端口的绑定情况。
# docker port pensive_ride 5000 127.0.0.1:5001
Docker容器连接
端口映射并不是唯一把 docker 连接到另一个容器的方法。
docker有一个连接系统允许将多个容器连接在一起,共享连接信息。
docker连接会创建一个父子关系,其中父容器可以看到子容器的信息。
容器命名
当我们创建一个容器的时候,docker会自动对它进行命名。另外,我们也可以使用–name标识来命名容器,例如:
# docker run -d -P --name runoob training/webapp python app.py 263945c7b2a8eb52706de33013940427dc1a5898a1d91837d4d0a407bcba622fv
我们可以使用 docker ps 命令来查看容器名称。
# docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 263945c7b2a8 training/webapp "python app.py" 20 seconds ago Up 18 seconds 0.0.0.0:32770->5000/tcp runoob Docker 资源汇总
Docker官方英文资源
docker官网:http://www.docker.com
Docker windows入门:https://docs.docker.com/windows/
Docker Linux 入门:https://docs.docker.com/linux/
Docker mac 入门:https://docs.docker.com/mac/
Docker 用户指引:https://docs.docker.com/engine/userguide/
Docker中文资源
Docker中文网站:https://www.docker-cn.com/
Docker安装手册:https://docs.docker-cn.com/engine/installation/
原创文章,作者:nene,如若转载,请注明出处:http://www.178linux.com/91263