Docker容器的使用和连接
在上一篇文章《Docker从安装部署到Hello World》介绍了如何在CentOS7上安装Docker。这篇文章主要介绍一下Docker容器的使用和连接。
vDocker 容器使用
1.0 Docker客户端命令集合
docker 客户端非常简单 ,我们可以直接输入 docker
命令来查看到 Docker 客户端的所有命令选项。
可以通过命令 docker command --help
更深入的了解指定的 Docker 命令使用方法。比如我们要查看 docker pull --help
指令的具体使用方法:
1.1 在docker中运行web应用
使用docker模拟一个web app, 我们将通过 docker run -d -P training/webapp python app.py
在docker容器中运行一个Python flask应用来run web app。
参数说明:
-d
:让容器在后台运行。-P
:将容器内部使用的网络端口映射到我们使用的主机上。
1.2 浏览器访问web应用
使用 docker ps
来查看我们正在运行的容器
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32768 上。可以根据机器(虚拟机)IP访问web应用。
也可以指定 -p 标识来绑定指定端口。 docker run -d -p 5000:5000 training/webapp python app.py
容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
1.3 网络端口的快捷方式
通过 docker ps
命令可以查看到容器的端口映射,docker还提供了另一个快捷方式: docker port
,使用 docker port
可以查看指定 (ID或者名字)容器的某个确定端口映射到宿主机的端口号。
上面我们创建的web应用容器ID为: 07f76b9440e0
名字为: gifted_lovelace
我可以使用 docker port 07f76b9440e0
或 docker port gifted_lovelace
来查看容器端口的映射情况
1.4 查看web app日志
docker logs -f [ID或者名字]
可以查看容器内部的标准输出。
-f
:让 dokcer logs
像使用 tail -f
一样来输出容器内部的标准输出。从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。
1.5 查看WEB应用程序容器的进程
使用 docker top [ID或者名字]
来查看容器内部运行的进程
1.6 检查WEB应用程序
使用 docker inspect [ID或者名字]
来查看Docker的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
JSON文件详情如下:
[
{
"Id": "07f76b9440e0394f60459deada7054119201985ccea16c3de445ccac5336ab15",
"Created": "2019-05-14T02:39:00.371684234Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 22625,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-05-14T02:39:01.258594246Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557",
"ResolvConfPath": "/var/lib/docker/containers/07f76b9440e0394f60459deada7054119201985ccea16c3de445ccac5336ab15/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/07f76b9440e0394f60459deada7054119201985ccea16c3de445ccac5336ab15/hostname",
"HostsPath": "/var/lib/docker/containers/07f76b9440e0394f60459deada7054119201985ccea16c3de445ccac5336ab15/hosts",
"LogPath": "",
"Name": "/gifted_lovelace",
"RestartCount": 0,
"Driver": "overlay2",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "journald",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"5000/tcp": [
{
"HostIp": "",
"HostPort": "5000"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "docker-runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": -1,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0
},
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/0c824ed7be43849857b3d81953e8a82c4b0df9a50c703c53e3da8e7bcac8b77c-init/diff:/var/lib/docker/overlay2/9eff7651dc75a63a5c6243eca14063f4ef766a57b76fc62f94eb0c258af0fb00/diff:/var/lib/docker/overlay2/f79cef924accdcf0421516f0523e4c40bcbfc76916ac24b9b4d108bce4a6d99a/diff:/var/lib/docker/overlay2/785c916ec6a256ed77ace6f995a67d18072d455382773c48aea989a9beda338a/diff:/var/lib/docker/overlay2/f238b66c1b47708f5c273d5fc3e7d14bf52dc05dbda21b7b5a4b3de953c42f58/diff:/var/lib/docker/overlay2/f8711f1331d01ae0e6f0725f0f5cf8aa497f5ebb1dc8f4ad1d9e8f69495c2a59/diff:/var/lib/docker/overlay2/e89f60204d0d6f68ed0460fcbb008e4c72aad6e5556860577325058967171c9a/diff:/var/lib/docker/overlay2/6676db9e6207469b67544c4b6bfb67750f43ac38ccd355b60acd607452fd4b98/diff:/var/lib/docker/overlay2/5535a46e9b1274c656b73ea54754b7a61a9ef91101657aaa1041db71a559098f/diff:/var/lib/docker/overlay2/e027a779b0efb0e8e875b2da7a63fd56a9a5ceaf617c593869c2d6f53872ec7c/diff:/var/lib/docker/overlay2/c9d47fb8428a576b59e6573749aa58c99000d00a41b5469158f30d29aba48a0b/diff:/var/lib/docker/overlay2/3a7eb8730a21876cfbdbcbe341e21449ff309642d39089cf2c12882c587cf773/diff:/var/lib/docker/overlay2/3b887f6f6933df5e2b1cb85ba23a38a2ed49b30bf31c583de9b33aab102bf633/diff:/var/lib/docker/overlay2/4f8367a65b99ce182e12598321f1637177cbf023ebd508ecd4142058eaa7b81f/diff",
"MergedDir": "/var/lib/docker/overlay2/0c824ed7be43849857b3d81953e8a82c4b0df9a50c703c53e3da8e7bcac8b77c/merged",
"UpperDir": "/var/lib/docker/overlay2/0c824ed7be43849857b3d81953e8a82c4b0df9a50c703c53e3da8e7bcac8b77c/diff",
"WorkDir": "/var/lib/docker/overlay2/0c824ed7be43849857b3d81953e8a82c4b0df9a50c703c53e3da8e7bcac8b77c/work"
}
},
"Mounts": [],
"Config": {
"Hostname": "07f76b9440e0",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"5000/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"python",
"app.py"
],
"Image": "training/webapp",
"Volumes": null,
"WorkingDir": "/opt/webapp",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "d59cfca49db6f6c5affe022950192d2a5905a62357e213ceded91048a19aa419",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"5000/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "5000"
}
]
},
"SandboxKey": "/var/run/docker/netns/d59cfca49db6",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "0f3d0758603b40b9aac59db3c747f44ba5392d89907647ad6141129584c34ba8",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "e9bebe59ae09f285b4fcf65177b356042c89f5ed2223ce4e1c3b40a817c02149",
"EndpointID": "0f3d0758603b40b9aac59db3c747f44ba5392d89907647ad6141129584c34ba8",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03"
}
}
}
}
]
1.7 开始/停止/停止/移除WEB应用容器
开始: docker start [ID或者名字]
停止: docker stop [ID或者名字]
重启: docker restart [ID或者名字]
删除: docker rm [ID或者名字]
注意:删除容器时,容器必须是停止状态,否则会报如下错误
vDocker 镜像使用
2.0 获取镜像列表
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
使用 docker images
来列出本地主机上的镜像。
各列列头说明:
- REPOSTITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如ubuntu仓库源里,有15.10、14.04等多个不同的版本,我们使用 REPOSTITORY:TAG 来定义不同的镜像。
所以,我们如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令是: docker run -t -i ubuntu:15.10 /bin/bash
如果要使用版本为13.10的ubuntu系统镜像来运行容器时,命令是: docker run -t -i ubuntu:13.10 /bin/bash
2.1 获取一个新的镜像
当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull
命令来下载它。
下载完成后,我们可以直接使用这个镜像来运行容器。
2.2 查找镜像
可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为:https://hub.docker.com/
也可以使用 docker search
命令来搜索镜像。比如我们需要一个httpd的镜像来作为我们的web服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。
NAME:镜像仓库源的名称;DESCRIPTION:镜像的描述;OFFICIAL:是否docker官方发布
拖取镜像
使用上图中的 httpd
官方版本的镜像,使用命令 docker pull
来下载镜像。
下载完成后,我们就可以通过 docker run httpd
使用这个镜像了。
2.3 创建镜像
如果从docker镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
- 从已经创建的容器中更新镜像,并且提交这个镜像
- 使用 Dockerfile 指令来创建一个新的镜像
2.4 更新镜像
更新镜像之前,我们需要使用 docker run -t -i ubuntu:15.10 /bin/bash
镜像来创建一个容器。
在运行的容器内使用 apt-get update
命令进行更新。
在完成操作之后,Ctrl+D或者输入 exit
命令来退出这个容器。
此时ID为3be2238c418a的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit -m="has update" -a="toutou" 3be2238c418a cnblogs/ubuntu:v2
来提交容器副本。
各个参数说明:
- -m:提交的描述信息
- -a:指定镜像作者
- 3be2238c418a:容器ID
- cnblogs/ubuntu:v2:指定要创建的目标镜像名
2.5 构建镜像
我们使用命令 docker build
, 从零开始来创建一个新的镜像。为此,我们需要创建一个Dockerfile文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
FROM centos:7.6 MAINTAINER Toutou "toutou@126.com" RUN /bin/echo 'root:123456' |chpasswd RUN useradd toutouge RUN /bin/echo 'toutouge: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 -t toutouge/centos:6.7 .
命令来构建一个镜像。
参数说明:
-t
:指定要创建的目标镜像名.
:Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
2.6 删除镜像
docker rmi [镜像ID]
Error response from daemon: conflict: unable to delete 500fc5b96d71 (must be forced) - image is being used by stopped container aedfe41307f4
错误解析:这是由于要删除的目标镜像中有容器存在,故无法删除镜像
解决办法:先删除镜像中的容器,再删除该镜像。
2.7 设置镜像标签
使用 docker tag cc191ecfb9c1 cnblogs/ubuntu:v3
命令,为镜像添加一个新的标签。
vDocker 容器连接
3.1 网络端口映射
上文中实现了通过网络端口来访问运行在docker容器内的服务。下面来实现通过端口连接到一个docker容器
创建了一个 python 应用的容器 docker run -d -P training/webapp python app.py
。
另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。我们使用 -P 参数创建一个容器,使用 docker ps 来看到端口5000绑定主机端口32768。
我们也可以使用 -p 标识来指定容器端口绑定到主机端口。
两种方式的区别是:
- -P :是容器内部端口随机映射到主机的高端口。
- -p : 是容器内部端口绑定到指定的主机端口。
另外,我们可以指定容器绑定的网络地址,比如绑定127.0.0.1。
上面的例子中,默认都是绑定 tcp 端口,如果要绑定 UPD 端口,可以在端口后面加上 /udp
。
docker port 命令可以让我们快捷地查看端口的绑定情况。
3.2 docker容器连接
端口映射并不是唯一把 docker 连接到另一个容器的方法。docker有一个连接系统允许将多个容器连接在一起,共享连接信息。docker连接会创建一个父子关系,其中父容器可以看到子容器的信息。
当我们创建一个容器的时候,docker会自动对它进行命名。另外,我们也可以使用--name标识来命名容器,例如: docker run -d -P --name demo training/webapp python app.py
v源码地址
https://github.com/toutouge/javademo/tree/master/hellospringboot
作 者:请叫我头头哥
出 处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!