Docker基本管理
Docker基本管理
一、Docker概述
1. Docker是什么
Docker是一个开源的应用容器引擎,基于go语言开发并遵循了apache2.0协议开源。
Docker是在Linux容器里运行的开源工具,是一种轻量级的“虚拟机”。
Docker的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的、自给自足的容器。
目前Docker只能支持64位系统。
2. Docker的设计宗旨
Docker的Logo设计为蓝色鲸鱼,拖着许多集装箱。
鲸鱼可看作为宿主机,集装箱可理解为相互隔离的容器,每个集装箱中都包含自己的应用程序。
Docker的设计宗旨:Build,Ship and Run Any APP,Anywhere
即通过对应用组件的封装、发布、部署、运行等生命周期的管理,达到应用组件级别的“一次封装,导出运行”的目的。这里的组件,既可以是一个应用,也可以是一套服务,甚至是一个完整的操作系统。
3. 容器的优点
容器化越来越受欢迎,因为容器是:
● 灵活:即使是最复杂的应用也可以集装箱化
● 轻量级:容器利用并共享主机内核
● 可互换:可以即时部署更新和升级
● 便携式:可以再本地构建,部署到云,并在任何地方运行
● 可扩展:可以增加并自动分发容器副本
● 可堆叠:可以垂直和即时堆叠服务
4. Docker容器和虚拟机的区别
容器是在Linux上本机运行,并与其他容器共享主机的内核,它运行的是一个独立的进程,不占用其他任何可执行文件的内存,非常轻量。
虚拟机运行的是一个完整的操作系统,通过虚拟机管理程序对主机资源进行虚拟访问,相比之下需要的资源更多。
特性 | Docker容器 | openstack虚拟机 |
---|---|---|
部署难度 | 非常简单 | 组件多,部署复杂 |
启动速度 | 秒级 | 分钟级 |
执行性能 | 和物理系统几乎一致 | vm会占用一些资源 |
镜像体积 | 镜像MB级别 | 虚拟机镜像GB级别 |
管理效率 | 管理简单 | 组件相互依赖,管理复杂 |
可管理性 | 单进程 | 完整的系统管理 |
网络连接 | 比较弱 | 借助neutron可以灵活组件各类网络管理 |
计算能力损耗 | 几乎无 | 损耗50%左右 |
性能 | 接近原生 | 弱于 |
系统支持量(单机) | 上千个 | 几十个 |
隔离性 | 资源隔离/限制 | 完全隔离 |
5. 容器的三种重要技术(namespace/cgroup)
docker本质就是宿主机的一个进程,docker是通过namespace实现资源隔离,通过cgroup实现资源限制,通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500G并不是实际占用物理磁盘500G)。
6. namespace的六项隔离
namespace | 系统调用参数 | 隔离内容 |
---|---|---|
UTS | CLONE_NEWUTS | 主机名与域名 |
IPC | CLONE_NEWWIPC | 信号量、消息队列和共享内存 |
PID | CLONE_NEWPID | 进程编号 |
NETWORK | CLONE_NEWNET | 网络设备、网络栈、端口等 |
MOUNT | CLONE_NEWNS | 挂载点(文件系统) |
USER | CLONE_NEWUSER | 用户和用户组(3.8以后的内核才支持) |
7. Docker核心的三个概念
7.1 镜像
Docker的镜像是创建容器的基础,类似虚拟机的快照,可以理解为一个面向Docker容器引擎的只读模板。
通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量和配置文件。
Docker镜像也是一个压缩包,只是这个压缩包不只是可执行文件,环境部署脚本,它还包含了完整的操作系统。因为大部分的镜像都是基于某个操作系统来构建,所以很轻松的就可以构建本地和远程一样的环境,这也是Docker镜像的精髓。
7.2 容器
Docker的容器是从镜像创建的运行实例,它可以被启动、停止和删除。所创建的每一个容器都是相互隔离、互不可见,以保证平台的安全性。
可以把容器看做是一个简易版的Linux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行在其他的应用程序。
7.3 仓库
Docker仓库是用来集中保存镜像的地方,当创建了自己的镜像之后,可以使用push命令将它上传到公有仓库(Public)或者私有仓库(Private)。当下次要在另外一台机器上使用这个镜像时,只需从仓库获取。
Docker的镜像、容器、日志等内容全部都默认存储在/var/lib/docker目录下。
二、安装Docker
1. 服务器环境
[root@localhost ~]# hostnamectl set-hostname docker
[root@localhost ~]# su
[root@docker ~]# systemctl disable --now firewalld
[root@docker ~]# setenforce 0
setenforce: SELinux is disabled
2. 安装依赖包
[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@docker ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum-utils:提供了yum-config-manager工具
device mappper:是Linux内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构。
device mapper存储驱动程序需要device-mapper-persistent-data和lvm2。
3. 设置阿里云镜像源
[root@docker ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
已加载插件:fastestmirror, langpacks
adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
4. 安装Docker-CE并设置为开机自动启动
[root@docker ~]# yum install -y docker-ce docker-ce-cli containerd.io
[root@docker ~]# systemctl enable --now docker.service
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
安装好的Docker系统有两个程序,Docker服务端和Docker客户端。其中Docker服务端是一个服务进程,负责管理所有容器。Docker客户端则扮演着Docker服务端的远程控制器,可以用来控制Docker的服务端进程。大部分情况下Docker服务端和客户端运行在一台机器上。
三、Docker镜像创建与操作
1. 搜索镜像
格式:docker search 关键字
[root@docker ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 15592 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 2071 [OK]
······
2. 获取镜像
格式:docker pull 仓库名称[:标签]
如果下载镜像时不指定标签,则默认会下载仓库中最新版本的镜像,即选择标签为latest标签。
[root@docker ~]# docker pull nginx:latest
latest: Pulling from library/nginx
07aded7c29c6: Pull complete
bbe0b7acc89c: Pull complete
44ac32b0bba8: Pull complete
91d6e3e593db: Pull complete
8700267f2376: Pull complete
4ce73aa6e9b0: Pull complete
Digest: sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
3. 镜像加速下载
浏览器访问http://cr.console.aliyun.com/cn-hangzhou/instances/mirrors获取镜像加速器配置
[root@docker ~]# sudo mkdir -p /etc/docker
[root@docker ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
> {
> "registry-mirrors": ["https://3c7tpzyf.mirror.aliyuncs.com"]
> }
> EOF
{
"registry-mirrors": ["https://3c7tpzyf.mirror.aliyuncs.com"]
}
[root@docker ~]# sudo systemctl daemon-reload
[root@docker ~]# sudo systemctl restart docker
4. 查看镜像信息
镜像下载后存放在/var/lib/docker
[root@docker ~]# cd /var/lib/docker
[root@docker docker]# ls
buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
5. 查看下载的镜像文件信息
[root@docker docker]# cat /var/lib/docker/image/overlay2/repositories.json
{"Repositories":{"nginx":{"nginx:latest":"sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b","nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506":"sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b"}}}[root@docker docker]#
6. 查看下载到本地的所有镜像
[root@docker docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f8f4ffc8092c 9 days ago 133MB
REPOSITORY:镜像属于的仓库
TAG:镜像的标签信息,标记同一个仓库中的不同镜像
IMAGE ID:镜像的唯一ID号,唯一标识一个镜像
CREATED:镜像创建的时间
SIZE:镜像大小
7. 根据镜像的唯一标识ID号,获取镜像详细信息
格式:docker inspect 镜像ID号
[root@docker docker]# docker inspect f8f4ffc8092c
[
{
"Id": "sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b",
"RepoTags": [
"nginx:latest"
],
"RepoDigests": [
"nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506"
],
"Parent": "",
"Comment": "",
"Created": "2021-09-28T08:26:07.57996119Z",
"Container": "449a8a48a9f56c3616a0b58ce3fea705fa34293def3c95bc32b50b9bc52f3ff7",
"ContainerConfig": {
"Hostname": "449a8a48a9f5",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.21.3",
"NJS_VERSION=0.6.2",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"nginx\" \"-g\" \"daemon off;\"]"
],
"Image": "sha256:dce61176f89cfe1ba4ca3eb3c39097b455d90108498072a77ebaac245c5732cc",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
"DockerVersion": "20.10.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.21.3",
"NJS_VERSION=0.6.2",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "sha256:dce61176f89cfe1ba4ca3eb3c39097b455d90108498072a77ebaac245c5732cc",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 133283279,
"VirtualSize": 133283279,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/d209395c04e25258ee5d6029d28579d8c9eabae6fd9c4e75eca097cd636d5a70/diff:/var/lib/docker/overlay2/c32ed3dd1b8f6f3fbb5fa90494b6578f6be0d27f429918ddfbd54771e5c6fc46/diff:/var/lib/docker/overlay2/4b4964fbccb1d5f34ce6d9dd3e1a9aa94212920b51715fd51267bc59e4ffad2f/diff:/var/lib/docker/overlay2/2b7617c1eccf93ba0dd8c325d31d0e53fdc2891de6cc4c2d0b465780e151573d/diff:/var/lib/docker/overlay2/0c0bdab8cb886b4142733b85ac7e1ee5c758664bf5c576ec2edcee0efa8b5920/diff",
"MergedDir": "/var/lib/docker/overlay2/8226a8090467251bcc01b1b49b8f492646a9c73fcbe3d4a974cde9346c8582cd/merged",
"UpperDir": "/var/lib/docker/overlay2/8226a8090467251bcc01b1b49b8f492646a9c73fcbe3d4a974cde9346c8582cd/diff",
"WorkDir": "/var/lib/docker/overlay2/8226a8090467251bcc01b1b49b8f492646a9c73fcbe3d4a974cde9346c8582cd/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:476baebdfbf7a68c50e979971fcd47d799d1b194bcf1f03c1c979e9262bcd364",
"sha256:5259501115588b1be0b1bb6eee115422d2939f402137979603cea9d9f1e649ec",
"sha256:0772cb25d5cae1b4e6e47ff15af95fa1d2640c3b7c74cb4c008d61e2c8c28559",
"sha256:6e109f6c2f99fdfa436dd66299d2ed87a18fee00b5f22fbd761dbacac27b76a6",
"sha256:88891187bdd7d71eeaa5f468577eb253eca29f57e3577ea0a954f6991313fd71",
"sha256:65e1ea1dc98ccb565bf8dd0f7664fc767796d3a6eecaf29b79ce7e9932517ae5"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
8. 为本地的镜像添加新的标签
格式:docker tag 名称[:标签] 新名称[:标签]
[root@docker docker]# docker tag nginx:latest nginx:test
[root@docker docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f8f4ffc8092c 9 days ago 133MB
nginx test f8f4ffc8092c 9 days ago 133MB
9. 删除镜像
格式1:docker rmi 仓库名称:标签
当一个镜像有多个标签时,只是删除其中指定的标签
[root@docker docker]# docker rmi nginx:latest
Untagged: nginx:latest
[root@docker docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx test f8f4ffc8092c 9 days ago 133MB
格式2:docker rmi 镜像ID号
会彻底删除该镜像
[root@docker docker]# docker rmi f8f4ffc8092c
Untagged: nginx:test
Untagged: nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
Deleted: sha256:ed6dd2b44338215d30a589d7d36cb4ffd05eb28d2e663a23108d03b3ac273d27
Deleted: sha256:c9958d4f33715556566095ccc716e49175a1fded2fa759dbd747750a89453490
Deleted: sha256:c47815d475f74f82afb68ef7347b036957e7e1a1b0d71c300bdb4f5975163d6a
Deleted: sha256:3b06b30cf952c2f24b6eabdff61b633aa03e1367f1ace996260fc3e236991eec
Deleted: sha256:476baebdfbf7a68c50e979971fcd47d799d1b194bcf1f03c1c979e9262bcd364
若该镜像的标签数大于1,需要使用-f强制删除
[root@docker docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f8f4ffc8092c 9 days ago 133MB
nginx test f8f4ffc8092c 9 days ago 133MB
[root@docker docker]# docker rmi f8f4ffc8092c
Error response from daemon: conflict: unable to delete f8f4ffc8092c (must be forced) - image is referenced in multiple repositories
[root@docker docker]# docker rmi f8f4ffc8092c -f
Untagged: nginx:latest
Untagged: nginx:test
Untagged: nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
Deleted: sha256:ed6dd2b44338215d30a589d7d36cb4ffd05eb28d2e663a23108d03b3ac273d27
Deleted: sha256:c9958d4f33715556566095ccc716e49175a1fded2fa759dbd747750a89453490
Deleted: sha256:c47815d475f74f82afb68ef7347b036957e7e1a1b0d71c300bdb4f5975163d6a
Deleted: sha256:3b06b30cf952c2f24b6eabdff61b633aa03e1367f1ace996260fc3e236991eec
Deleted: sha256:476baebdfbf7a68c50e979971fcd47d799d1b194bcf1f03c1c979e9262bcd364
注意:如果该镜像已经被容器使用,正确的做法是先删除依赖该镜像的所有容器,再去删除镜像。
10. 存入镜像:将镜像保存称为本地文件
格式:docker save -o 存储文件名 存储的镜像
[root@docker docker]# docker save -o nginx.tar nginx:latest
[root@docker docker]# ls -lh
总用量 132M
······
drwxr-x--- 3 root root 19 10月 8 11:21 network
······
11. 载入镜像:将镜像文件导入到镜像库中
格式:
docker load < 镜像文件
[root@docker docker]# docker rmi nginx:latest
Untagged: nginx:latest
Untagged: nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
Deleted: sha256:ed6dd2b44338215d30a589d7d36cb4ffd05eb28d2e663a23108d03b3ac273d27
Deleted: sha256:c9958d4f33715556566095ccc716e49175a1fded2fa759dbd747750a89453490
Deleted: sha256:c47815d475f74f82afb68ef7347b036957e7e1a1b0d71c300bdb4f5975163d6a
Deleted: sha256:3b06b30cf952c2f24b6eabdff61b633aa03e1367f1ace996260fc3e236991eec
Deleted: sha256:476baebdfbf7a68c50e979971fcd47d799d1b194bcf1f03c1c979e9262bcd364
[root@docker docker]# docker load < nginx.tar
476baebdfbf7: Loading layer [==================================================>] 72.53MB/72.53MB
525950111558: Loading layer [==================================================>] 64.97MB/64.97MB
0772cb25d5ca: Loading layer [==================================================>] 3.072kB/3.072kB
6e109f6c2f99: Loading layer [==================================================>] 4.096kB/4.096kB
88891187bdd7: Loading layer [==================================================>] 3.584kB/3.584kB
65e1ea1dc98c: Loading layer [==================================================>] 7.168kB/7.168kB
Loaded image: nginx:latest
或者
docker load -i 镜像文件
[root@docker docker]# docker rmi nginx:latest
Untagged: nginx:latest
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
Deleted: sha256:ed6dd2b44338215d30a589d7d36cb4ffd05eb28d2e663a23108d03b3ac273d27
Deleted: sha256:c9958d4f33715556566095ccc716e49175a1fded2fa759dbd747750a89453490
Deleted: sha256:c47815d475f74f82afb68ef7347b036957e7e1a1b0d71c300bdb4f5975163d6a
Deleted: sha256:3b06b30cf952c2f24b6eabdff61b633aa03e1367f1ace996260fc3e236991eec
Deleted: sha256:476baebdfbf7a68c50e979971fcd47d799d1b194bcf1f03c1c979e9262bcd364
[root@docker docker]# docker load -i nginx.tar
476baebdfbf7: Loading layer [==================================================>] 72.53MB/72.53MB
525950111558: Loading layer [==================================================>] 64.97MB/64.97MB
0772cb25d5ca: Loading layer [==================================================>] 3.072kB/3.072kB
6e109f6c2f99: Loading layer [==================================================>] 4.096kB/4.096kB
88891187bdd7: Loading layer [==================================================>] 3.584kB/3.584kB
65e1ea1dc98c: Loading layer [==================================================>] 7.168kB/7.168kB
Loaded image: nginx:latest
12. 上传镜像
默认上传到docker hub官方公共仓库,需要注册使用公共仓库的账户。http://hub.docker.com。
可以使用docker login命令来输入用户名、密码和邮箱来完成注册和登录。
在上传镜像之前,还需要先对本地镜像添加新的标签,然后再使用docker push命令进行上传。
[root@docker docker]# docker tag nginx:latest ding1201/nginx:test
[root@docker docker]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: ding1201
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@docker docker]# docker push ding1201/nginx
Using default tag: latest
The push refers to repository [docker.io/ding1201/nginx]
tag does not exist: ding1201/nginx:latest
#上传失败,上传需要镜像名称:标签,无标签默认为latest
[root@docker docker]# docker push ding1201/nginx:test
The push refers to repository [docker.io/ding1201/nginx]
65e1ea1dc98c: Mounted from library/nginx
88891187bdd7: Mounted from library/nginx
6e109f6c2f99: Mounted from library/nginx
0772cb25d5ca: Mounted from library/nginx
525950111558: Mounted from library/nginx
476baebdfbf7: Mounted from library/nginx
test: digest: sha256:39065444eb1acb2cfdea6373ca620c921e702b0f447641af5d0e0ea1e48e5e04 size: 1570
[root@docker docker]# docker search ding1201
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ding1201/nginx 0
##上传成功
四、Docker容器操作
1. 容器创建
容器创建就是将镜像加载到容器的过程。
新创建的容器默认处于停止状态,不允许任何程序,需要在其中发起一个进程来启动容器。
格式:docker create [选项] 镜像
常用选项:
-i:让容器的输入保持打开
-t:让Docker分配一个伪终端
[root@docker docker]# docker create -it ding1201/nginx:test /bin/bash
5a5c3c2e785f5aa66d228cc6755be55d1b846a6c66b2e5d2ccb303589bdc85fa
2. 查看容器的运行状态
[root@docker docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a5c3c2e785f ding1201/nginx:test "/docker-entrypoint.…" 56 seconds ago Created strange_hofstadter
-a选项可以显示所有的容器
CONTAINER ID:容器ID号
IMAGE:加载的镜像
COMMAND:运行的程序
CREATED:创建时间
STATUS:当前状态
PORTS:端口映射
NAMES:名称(未定义将随机创建)
3. 启动容器
格式:docker start 容器ID/名称
[root@docker docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a5c3c2e785f ding1201/nginx:test "/docker-entrypoint.…" 56 seconds ago Created strange_hofstadter
[root@docker docker]# docker start 5a5c3c2e785f
5a5c3c2e785f
[root@docker docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a5c3c2e785f ding1201/nginx:test "/docker-entrypoint.…" 7 minutes ago Up 5 seconds 80/tcp strange_hofstadter
4. 创建并启动容器
可以直接执行docker run命令,等同于先执行docker create命令,再执行docker start命令。
注意:容器是一个与其中运行的shell命令共存亡的终端,命令运行容器运行,命令结束容器退出。
[root@docker docker]# docker run centos:7 bash -c ls /
anaconda-post.log
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@docker docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3fb76edd101c centos:7 "bash -c ls /" 10 seconds ago Exited (0) 10 seconds ago naughty_ganguly
##命令执行后,容器直接退出
4.1 docker运行条件
docker容器默认会把容器内部第一个进程,也就是pid=1的程序作为docker容器是否正在运行的依据,如果docker容器中pid=1的进程挂了,那么docker容器便会只会退出,也就是说docker容器中必须有一个前台进程,否则认为容器已经挂掉。
可以对docker容器执行一条死循环命令,防止容易的自动退出。
[root@docker docker]# docker run centos:7 bash -c "while true;do echo hello;done"
##此时终端将不停显示hello,ctrl+c无法退出,需再另一台终端stop该容器
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41d204a8820d centos:7 "bash -c 'while true…" 31 seconds ago Up 30 seconds elastic_brown
[root@docker ~]# docker stop 41d204a8820d
41d204a8820d
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41d204a8820d centos:7 "bash -c 'while true…" 5 minutes ago Exited (137) 4 minutes ago elastic_brown
为避免占用终端无法退出的情况可以使用-d选项,docker容器以守护形式在后台运行。
容器所运行的程序不能结束。
[root@docker docker]# docker run -d centos:7 bash -c "while true;do echo hello;done"
745cb6e27cc93cf314cc77e8eebe61d92eb619b9323ef28b7aeb7bf8a50a9d86
[root@docker docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
745cb6e27cc9 centos:7 "bash -c 'while true…" 46 seconds ago Up 45 seconds reverent_heyrovsky
41d204a8820d centos:7 "bash -c 'while true…" 7 minutes ago Exited (137) 6 minutes ago elastic_brown
4.2 创建容器并持续运行
[root@docker ~]# docker run -itd --name test centos:7 bash
a7db7eff73bfd9af9147b76b6b686e8be5098bcc7588c02f379c4d682fd9b052
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7db7eff73bf centos:7 "bash" 1 second ago Up 1 second test
4.3 docker在后台的标准运行过程
当利用docker run来创建容器时,Docker在后台的标准运行过程是:
(1)检查本地是否存在指定的镜像。当镜像不存在时,会从公有仓库下载;
(2)利用镜像创建并启动一个容器;
(3)分配一个文件系统给容器,在只读的镜像层外面挂载一层可读写层;
(4)从宿主主机配置的网桥接口中桥接一个虚拟机接口到容器中;
(5)分配一个地址池中的IP地址给容器;
(6)执行用户指定的应用程序,执行完毕后容器被终止运行。
5. 终止容器运行
格式:docker stop 容器的ID/名称
[root@docker ~]# docker stop test
test
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7db7eff73bf centos:7 "bash" 4 minutes ago Exited (137) 2 seconds ago test
6. 容器的进入
需要进入容器进行命令操作时,可以使用docker exec命令进行运行着的容器。
格式:docker exec -it 容器ID/名称 /bin/bash
-i:让容器的输入保持打开
-t:让那个Docker分配一个伪终端
[root@docker ~]# docker start test
test
[root@docker ~]# docker exec -it test bash
[root@a7db7eff73bf /]# ls
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@a7db7eff73bf /]# exit
exit
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7db7eff73bf centos:7 "bash" 8 minutes ago Up About a minute test
也可在run创建容器时,使用-it选项进入容器,但是退出容器时,容器也将停止运行。
[root@docker ~]# docker run -it --name test1 centos:7 bash
[root@3d9cd43c52f2 /]# exit
exit
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d9cd43c52f2 centos:7 "bash" 8 seconds ago Exited (0) 2 seconds ago test1
a7db7eff73bf centos:7 "bash" 11 minutes ago Up 5 minutes test
7. 复制
7.1 主机复制到容器中
[root@docker ~]# docker cp test.txt test:/opt
[root@docker ~]# docker exec -it test bash
[root@a7db7eff73bf /]# cd /opt
[root@a7db7eff73bf opt]# ls
test.txt
[root@a7db7eff73bf opt]# cat test.txt
test
7.2 从容器复制到主机
[root@docker ~]# docker cp test:/opt/test.txt 111.txt
[root@docker ~]# cat 111.txt
test
8. 容器的导出与导入
用户可以将任何一个Docker容器从一台机器迁移到另一台机器。在迁移过程中,可以使用“docker export”命令将已经创建好的容器导出为文件,无论这个容器是处于运行状态还是停止状态均可导出。可将导出文件传输到其他机器,通过相应的导入命令实现容器的迁移。
8.1 导出
格式:docker export 容器ID/名称 文件名
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d9cd43c52f2 centos:7 "bash" 17 minutes ago Exited (0) 17 minutes ago test1
a7db7eff73bf centos:7 "bash" 29 minutes ago Up 22 minutes test
[root@docker ~]# docker export test > /opt/centos.tar
[root@docker ~]# cd /opt
[root@docker opt]# ls
apr-1.6.2.tar.gz apr-util-1.6.0.tar.gz centos.tar containerd rh
8.2 导入
格式:cat 文件名 | docker import - 镜像名称:标签
[root@docker opt]# docker stop test
test
[root@docker opt]# docker rm test
test
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d9cd43c52f2 centos:7 "bash" 21 minutes ago Exited (0) 21 minutes ago test1
[root@docker opt]# cat centos.tar | docker import - centos7:test
sha256:e180fc5d26ee4f4c13fabb682871bec45790711a4b1a9ac33dd88c9674cfcfc2
[root@docker opt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7 test e180fc5d26ee 8 seconds ago 204MB
ding1201/nginx test f8f4ffc8092c 10 days ago 133MB
nginx latest f8f4ffc8092c 10 days ago 133MB
centos 7 eeb6ee3f44bd 3 weeks ago 204MB
9. 删除容器
格式:docker rm [-f] 容器ID/名称
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d9cd43c52f2 centos:7 "bash" 34 minutes ago Exited (0) 34 minutes ago test1
[root@docker opt]# docker rm test1
test1
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
容器在运行状态下,需要先stop停止容器才可以将其删除,或使用-f选项
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7a80d181e011 centos:7 "bash" 23 seconds ago Up 23 seconds test2
d5a47ba9ab3a centos:7 "bash" 27 seconds ago Up 26 seconds test1
[root@docker opt]# docker rm test1
Error response from daemon: You cannot remove a running container d5a47ba9ab3adf0e0524820d03d942961a6d38d1b5effa973b7569dd29b04241. Stop the container before attempting removal or force remove
[root@docker opt]# docker rm test1 -f
test1
[root@docker opt]# docker stop test2
test2
[root@docker opt]# docker rm test2
test2
10. 批量操作容器
10.1 批量停止容器
docker ps -a | awk 'NR>=2{print "docker stop "$1}' | bash
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c1cfde56390 centos:7 "bash" 4 minutes ago Up 4 minutes test2
39dec37b50e2 centos:7 "bash" 4 minutes ago Up 4 minutes test1
[root@docker opt]# docker ps -a | awk 'NR>=2{print "docker stop "$1}' | bash
1c1cfde56390
39dec37b50e2
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c1cfde56390 centos:7 "bash" 5 minutes ago Exited (137) 27 seconds ago test2
39dec37b50e2 centos:7 "bash" 5 minutes ago Exited (137) 17 seconds ago test1
docker ps -a | awk 'NR>=2{print $1}' | xargs docker stop
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e97a856029c centos:7 "bash" 7 seconds ago Up 6 seconds test2
c2fbd6242fd5 centos:7 "bash" 12 seconds ago Up 11 seconds test1
[root@docker opt]# docker ps -a | awk 'NR>=2{print $1}' | xargs docker stop
3e97a856029c
c2fbd6242fd5
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e97a856029c centos:7 "bash" About a minute ago Exited (137) 2 seconds ago test2
c2fbd6242fd5 centos:7 "bash" About a minute ago Exited (137) 2 seconds ago test1
10.2 批量删除容器
docker ps -a | awk 'NR>=2{print "docker rm "$1}' | bash
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e97a856029c centos:7 "bash" About a minute ago Exited (137) 2 seconds ago test2
c2fbd6242fd5 centos:7 "bash" About a minute ago Exited (137) 2 seconds ago test1
[root@docker opt]# docker ps -a | awk 'NR>=2{print "docker rm "$1}' | bash
3e97a856029c
c2fbd6242fd5
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker ps -a | awk 'NR>=2{print $1}' | xargs docker rm -f
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
79f61b5fd0f1 centos:7 "bash" About a minute ago Up About a minute test2
c1090fa3dabc centos:7 "bash" About a minute ago Up About a minute test1
[root@docker opt]# docker ps -a | awk 'NR>=2{print $1}' | xargs docker rm -f
79f61b5fd0f1
c1090fa3dabc
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
10.3 批量删除镜像
方法一:docker images | awk 'NR>=2{print "docker rmi -f "$3}' | bash
[root@docker opt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7 test e180fc5d26ee 29 minutes ago 204MB
ding1201/nginx test f8f4ffc8092c 10 days ago 133MB
nginx latest f8f4ffc8092c 10 days ago 133MB
centos 7 eeb6ee3f44bd 3 weeks ago 204MB
[root@docker opt]# docker images | awk 'NR>=2{print "docker rmi "$3}' | bash
Untagged: centos7:test
Deleted: sha256:e180fc5d26ee4f4c13fabb682871bec45790711a4b1a9ac33dd88c9674cfcfc2
Deleted: sha256:00c0399f999b4346d00935727757bd37db1245f98c55633d31982522cb05b7a7
Error response from daemon: conflict: unable to delete f8f4ffc8092c (must be forced) - image is referenced in multiple repositories
Error response from daemon: conflict: unable to delete f8f4ffc8092c (must be forced) - image is referenced in multiple repositories
Untagged: centos:7
Untagged: centos@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987
Deleted: sha256:eeb6ee3f44bd0b5103bb561b4c16bcb82328cfe5809ab675bb17ab3a16c517c9
Deleted: sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02
[root@docker opt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f8f4ffc8092c 10 days ago 133MB
ding1201/nginx test f8f4ffc8092c 10 days ago 133MB
##部分镜像需要使用-f选项进行强删
[root@docker opt]# docker images | awk 'NR>=2{print "docker rmi -f "$3}' | bash
Untagged: ding1201/nginx:test
Untagged: ding1201/nginx@sha256:39065444eb1acb2cfdea6373ca620c921e702b0f447641af5d0e0ea1e48e5e04
Untagged: nginx:latest
Deleted: sha256:f8f4ffc8092c956ddd6a3a64814f36882798065799b8aedeebedf2855af3395b
Deleted: sha256:f208904eecb00a0769d263e81b8234f741519fefa262482d106c321ddc9773df
Deleted: sha256:ed6dd2b44338215d30a589d7d36cb4ffd05eb28d2e663a23108d03b3ac273d27
Deleted: sha256:c9958d4f33715556566095ccc716e49175a1fded2fa759dbd747750a89453490
Deleted: sha256:c47815d475f74f82afb68ef7347b036957e7e1a1b0d71c300bdb4f5975163d6a
Deleted: sha256:3b06b30cf952c2f24b6eabdff61b633aa03e1367f1ace996260fc3e236991eec
Deleted: sha256:476baebdfbf7a68c50e979971fcd47d799d1b194bcf1f03c1c979e9262bcd364
Error: No such image: f8f4ffc8092c
[root@docker opt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
方法二:docker rmi $(docker images -q)
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat test 8a7be313dd18 19 minutes ago 960MB
nginx test a8b4c04322fc 44 minutes ago 545MB
systemctl test ef46e114991b 2 hours ago 438MB
sshd test beca19c54c1c 21 hours ago 438MB
httpd test2 6440a6fa57e0 22 hours ago 623MB
httpd test1 5ebb94751288 22 hours ago 623MB
debian test f7fd702b88cc 25 hours ago 215MB
centos test1 3e6e91b628ef 26 hours ago 204MB
nginx latest 87a94228f133 2 days ago 133MB
centos 7 eeb6ee3f44bd 4 weeks ago 204MB
[root@docker ~]# docker images -q
8a7be313dd18
a8b4c04322fc
ef46e114991b
beca19c54c1c
6440a6fa57e0
5ebb94751288
f7fd702b88cc
3e6e91b628ef
87a94228f133
eeb6ee3f44bd
[root@docker ~]# docker rmi -f $(docker images -q)
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
10.4 批量删除容器
docker rm $(docker ps -a -q)
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4eb290837722 centos:7 "bash" 13 seconds ago Up 13 seconds test2
1be1b151ffa7 centos:7 "bash" 18 seconds ago Up 17 seconds test1
[root@docker ~]# docker ps -a -q
4eb290837722
1be1b151ffa7
[root@docker ~]# docker rm $(docker ps -a -q)
Error response from daemon: You cannot remove a running container 4eb2908377223d0f0183ddf731e1ecda58b6802b7c86734c35227ad3f84cc42a. Stop the container before attempting removal or force remove
Error response from daemon: You cannot remove a running container 1be1b151ffa70aeb16a684f32e4caa90988741755d9bcfd69faf6ad02cabb90d. Stop the container before attempting removal or force remove
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4eb290837722 centos:7 "bash" About a minute ago Up About a minute test2
1be1b151ffa7 centos:7 "bash" About a minute ago Up About a minute test1
[root@docker ~]# docker rm -f $(docker ps -a -q)
4eb290837722
1be1b151ffa7
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
11. 查看容器进程号
docker inspect -f '{{.State.Pid}}' 容器ID/名称
[root@docker ~]# docker run -itd --name test1 centos:7 bash
b71d24b8f8e72ccfb0973ec23180ca8a8f87ef71cb83f5dcb03125f83c3502ef
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b71d24b8f8e7 centos:7 "bash" 1 second ago Up 1 second test1
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test1
4473
[root@docker ~]# docker inspect -f '{{.State.Pid}}' b71d24b8f8e7
4473
五、Docker网络
1. Docker网络实现原理
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网络的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
2. Docker网桥
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时通过-p或-P参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器
[root@docker ~]# docker run -d --name test1 -P nginx
514ae4b4bec05707b66a7dab89a1f0c49e5ef2266ae15d5f72b45e38495c4e25
[root@docker ~]# docker run -d --name test2 -p 43000:80 nginx
##使用固定的43000端口
36e92b38ea300478fbd4b699ea6dcaf1c91213ce53aeab92311d18d011e49df5
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
36e92b38ea30 nginx "/docker-entrypoint.…" 9 seconds ago Up 9 seconds 0.0.0.0:43000->80/tcp, :::43000->80/tcp test2
514ae4b4bec0 nginx "/docker-entrypoint.…" 16 seconds ago Up 16 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp test1
验证
[root@docker ~]# curl http://192.168.122.10:43000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@docker ~]# curl http://192.168.122.10:49153
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
3. Docker的网络模式
网络模式 | 说明 |
---|---|
Host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。 |
Container | 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。 |
None | 该模式关闭了容器的网络功能。 |
Bridge | 默认为该模式,此模式会为每一个容器分配、设置IP等,并将容器连接到一个Docker0虚拟网桥,通过docker0网桥以及iptables nat表配置与宿主机通信。 |
自定义网络 | 自定义网络后,可指定容器IP |
4. 查看容器网络
安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、none、host。
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
358c6341c661 bridge bridge local
8efcfd849c5a host host local
21745308f633 none null local
[root@docker ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
358c6341c661 bridge bridge local
8efcfd849c5a host host local
21745308f633 none null local
5. 创建网络
使用docker run创建Docker容器时,可以用--net或--network选项指定容器的网络模式
● host模式:使用--net=host指定
● none模式:使用--net=none指定
● container模式:使用--net=container:NAME_or_ID指定
● bridge模式:使用--net=bridge指定,默认设置,可省略
6. 网络模式详解
6.1 host模式
相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。
[root@docker ~]# docker run -itd --name test1 --net=host centos:7 bash
151137e9ce767273f776e56bada9baba23fec48ddfe8a30c89216341d4bbf1ab
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
151137e9ce76 centos:7 "bash" 3 seconds ago Up 2 seconds test1
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test1
##查看容器进程号
5117
[root@docker ~]# ls -l /proc/5117/ns
##查看容器的进程、网络、文件系统等命名空间编号
总用量 0
lrwxrwxrwx 1 root root 0 10月 11 16:04 ipc -> ipc:[4026532576]
lrwxrwxrwx 1 root root 0 10月 11 16:04 mnt -> mnt:[4026532574]
lrwxrwxrwx 1 root root 0 10月 11 16:04 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 10月 11 16:04 pid -> pid:[4026532577]
lrwxrwxrwx 1 root root 0 10月 11 16:04 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 10月 11 16:04 uts -> uts:[4026532575]
[root@docker ~]# docker run -itd --name test2 --net=host centos:7 bash
6f519f4fc026f67766b08ff1d098a6fd6ab7440359795a64350e2d1b2c61f05c
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test2
5209
[root@docker ~]# ls -l /proc/5209/ns
总用量 0
lrwxrwxrwx 1 root root 0 10月 11 16:05 ipc -> ipc:[4026532580]
lrwxrwxrwx 1 root root 0 10月 11 16:05 mnt -> mnt:[4026532578]
lrwxrwxrwx 1 root root 0 10月 11 16:05 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 10月 11 16:05 pid -> pid:[4026532581]
lrwxrwxrwx 1 root root 0 10月 11 16:05 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 10月 11 16:05 uts -> uts:[4026532579]
##net与user的命名空间相同,host模式与系统共享IP
6.2 container模式
在理解了host模式后,这个模式也就好理解了。这个模式指定新常见的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信
[root@docker ~]# docker run -itd --name test1 centos:7 bash
16cfef748ce1e1653e19925b6c38b28f70ebadb85a4ff5c8913befe1d1b6a7e9
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test1
5428
[root@docker ~]# ls -l /proc/5428/ns
总用量 0
lrwxrwxrwx 1 root root 0 10月 11 16:18 ipc -> ipc:[4026532578]
lrwxrwxrwx 1 root root 0 10月 11 16:18 mnt -> mnt:[4026532576]
lrwxrwxrwx 1 root root 0 10月 11 16:13 net -> net:[4026532581]
lrwxrwxrwx 1 root root 0 10月 11 16:18 pid -> pid:[4026532579]
lrwxrwxrwx 1 root root 0 10月 11 16:18 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 10月 11 16:18 uts -> uts:[4026532577]
[root@docker ~]# docker run -itd --name test2 --net=container:test1 centos:7 bash
477032acba96fa0f4adb590a6846792fa99615e2eb9744e250cf14a9d7092a53
[root@docker ~]# docker inspect -f '{{.State.Pid}}' test2
5597
[root@docker ~]# ls -l /proc/5597/ns
总用量 0
lrwxrwxrwx 1 root root 0 10月 11 16:20 ipc -> ipc:[4026532699]
lrwxrwxrwx 1 root root 0 10月 11 16:20 mnt -> mnt:[4026532697]
lrwxrwxrwx 1 root root 0 10月 11 16:20 net -> net:[4026532581]
lrwxrwxrwx 1 root root 0 10月 11 16:20 pid -> pid:[4026532700]
lrwxrwxrwx 1 root root 0 10月 11 16:20 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 10月 11 16:20 uts -> uts:[4026532698]
##net与user的命名空间相同,container模式之间共享IP
6.3 none模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。这种网络模式下容器只有lo回环网络,没有其他网卡。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
6.4 bridge模式
bridge模式是docker的默认网络模式,不用--net参数,就是bridge模式。
相当于Vmware中的nat模式,容器使用独立Network Namespace,并连接到docker0虚拟网卡。通过docker0网桥以及iptables nat表配置与宿主机通信,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
(1)当docker进程启动时,会在主机上创建一个名为Docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
(2)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
(3)Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以veth*这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
(4)使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
[root@docker ~]# docker run -itd --name test1 -P centos:7 bash
92f615aecf1e9e22956446536db4bcfa91d2ce94dd9e3e9253c40a5e1d2b0fde
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
92f615aecf1e centos:7 "bash" 15 seconds ago Up 14 seconds test1
[root@docker ~]# iptables -t nat -vnL
······
Chain POSTROUTING (policy ACCEPT 531 packets, 39905 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
······
6.5 自定义网络
6.5.1 使用bridge指定IP
直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错
[root@docker ~]# docker run -itd --name test1 --network=bridge --ip 172.17.0.8 centos:7 bash
0e1c5c2a0ed99d3e857dbf9a42046c670235d4eac4a5aa2690e4d7ce703cca5e
docker: Error response from daemon: user specified IP address is supported on user defined networks only.
##IP错误,无法使用
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0e1c5c2a0ed9 centos:7 "bash" About a minute ago Created test1
[root@docker ~]# docker start test1
Error response from daemon: user specified IP address is supported on user defined networks only
Error: failed to start containers: test1
##IP错误,无法启动
6.5.2 创建自定义网络
可以先自定义网络,再使用指定IP运行docker
[root@docker ~]# docker network create --subnet=172.111.0.0/16 --opt "com.docker.network.bridge.name"="docker" mynetwork
716c662b9ad34a62ecab84510ae5d1d1ed760b455bf26a0f2b2bb48874e41eba
[root@docker ~]# ifconfig
docker: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.111.0.1 netmask 255.255.0.0 broadcast 172.111.255.255
ether 02:42:0d:82:b4:9d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
······
docker:为执行ifconfig -a命令时,显示的网卡名,如果不使用--opt参数指定此名称,那你在使用ifconfig -a命令查看网络信息时,看到的是类似br-110eb56a0b22这样的名字,这显然不怎么好记。
mynetwork:为执行docker network list命令时,显示的bridge网络模式名称。
验证:
[root@docker ~]# docker run -itd --name test1 --net mynetwork --ip 172.111.0.11 centos:7 bash
d4fb4caa7742252627858dc9fbc2df47c900040fdf4e7aa145d8c7e1849c2d5a
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d4fb4caa7742 centos:7 "bash" 3 seconds ago Up 2 seconds test1
[root@docker ~]# docker exec -it test1 bash
[root@d4fb4caa7742 /]# ifconfig
bash: ifconfig: command not found
[root@d4fb4caa7742 /]# yum install -y net-tools
[root@d4fb4caa7742 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.111.0.11 netmask 255.255.0.0 broadcast 172.111.255.255
ether 02:42:ac:6f:00:0b txqueuelen 0 (Ethernet)
RX packets 4806 bytes 18886571 (18.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3302 bytes 182103 (177.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1 (Local Loopback)
RX packets 83 bytes 7777 (7.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 83 bytes 7777 (7.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
六、资源控制
1. CPU资源控制
1.1 cgroups
cgroups(Control groups),是一个非常强大的linux内核工具,他不仅可以限制被namespace隔离起来的资源,还可以为资源设置权重、计算使用量、操控进程启停等等。所以cgroups实现了对资源的配额和度量。
1.2 cgroups的四大功能
● 资源限制:可以对任务使用的资源总额进行限制
● 优先级分配:通过分配的cpu时间片数量以及磁盘IO带宽大小,实际上相当于控制了任务运行优先级
● 资源统计:可以统计系统的资源使用量,如cpu时长,内存用量等
● 任务控制:cgroup可以对任务执行挂起、恢复等操作
1.3 CPU资源控制的三种方式
设置CPU使用率上限
设置CPU资源占用比(设置多个容器时才生效)
设置容器绑定指定的CPU
1.4 设置CPU使用率上限
1.4.1 使用率配置
Linux通过CFS(Completely Fair Schedular,完全公平调度器)来调度各个进程对CPU的使用。CFS默认的调度周期是100ms。我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少CPU时间。
使用--cpu-period即可设置调度周期,使用--cpu-quota即可设置在每个周期内容器能使用的CPU时间。两者可以配合使用。
CFS周期的有效范围1ms1s,对应的--cpu-period的数值范围是10001000000。
而容器的CPU配额必须不小于1ms,即--cpu-quota的值必须>=1000。
[root@docker ~]# docker run -itd --name test1 centos:7 bash
a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9c1ed9d865b centos:7 "bash" 7 seconds ago Up 5 seconds test1
[root@docker ~]# cd /sys/fs/cgroup/cpu/docker/a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a/
##路径为/sys/fs/cgroup/cpu/docker/容器ID开头的文件名
[root@docker a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a]# ls
cgroup.clone_children cgroup.procs cpuacct.usage cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release
cgroup.event_control cpuacct.stat cpuacct.usage_percpu cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat tasks
[root@docker a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a]# cat cpu.cfs_quota_us
-1
[root@docker a9c1ed9d865bec0dd2df5bd42adc157686e916abc1425f6dc9bd624006b1d45a]# cat cpu.cfs_period_us
100000
cpu.cfs_period_us:cpu分配的周期(微秒,所以文件名中用us表示,microsecond),默认为100000。
cpu.cfs_quota_us:表示该cgroups限制占用的时间(微秒),默认为-1,表示不限制。如果设为50000,表示占用50000/100000=50%的CPU。
1.4.2 压力测试
[root@docker ~]# docker exec -it test1 bash
[root@a9c1ed9d865b /]# vim /cpu.sh
bash: vim: command not found
[root@a9c1ed9d865b /]# vi cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done
[root@a9c1ed9d865b /]# chmod +x cpu.sh
[root@a9c1ed9d865b /]# ./cpu.sh
另开终端查看cpu负载
[root@docker ~]# top
top - 19:59:59 up 6:17, 2 users, load average: 0.94, 0.43, 0.20
Tasks: 213 total, 2 running, 210 sleeping, 1 stopped, 0 zombie
%Cpu(s): 46.2 us, 3.5 sy, 0.0 ni, 50.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4030168 total, 2481744 free, 625300 used, 923124 buff/cache
KiB Swap: 4194300 total, 4194300 free, 0 used. 3058428 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
9732 root 20 0 11688 1096 916 R 100.0 0.0 2:44.05 cpu.sh
##来自cpu.sh的命令占用了近50%的CPU资源
1.5 设置CPU资源占用比(设置多个容器时才生效)
1.5.1 资源占比设置
Docker通过--cpu-shares指定CPU份额,默认值为1024,值为1024的倍数。
创建两个容器为test1和tests2,若只有这两个容器,设置容器的权重,使得test1和test2的CPU资源占比为1/3和2/3。
[root@docker ~]# docker run -itd --name test1 --cpu-shares 1024 centos:7
b4b37e6d33a914756296f165c6cc7317fd48324b4b2a05482bc49ad2f3a5ed06
[root@docker ~]# docker run -itd --name test2 --cpu-shares 2048 centos:7
900ebea2c5ed9fd6adc3fe2b7a823b041f904312e67b9cbd4b9023ae64e38149
#若出现WARNING: IPv4 forwarding is disabled. Networking will not work.
#如下开启宿主机的IP转发功能即可
[root@docker ~]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
[root@docker ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@docker ~]# systemctl restart network
[root@docker ~]# systemctl restart docker
1.5.2 压力测试(设置宿主机为4核)
test1容器
[root@docker ~]# docker exec -it test1 bash
[root@b4b37e6d33a9 /]# yum install -y epel-release && yum install -y stress
[root@b4b37e6d33a9 /]# stress -c 4
stress: info: [93] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
test2容器
[root@docker ~]# docker exec -it test2 bash
[root@900ebea2c5ed /]# yum install -y epel-release && yum install -y stress
[root@900ebea2c5ed /]# stress -c 4
stress: info: [110] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
宿主机查看负载
[root@docker ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
29900b8c61c3 test1 132.90% 2.586MiB / 3.843GiB 0.07% 2.42kB / 0B 4.88MB / 0B 7
c062b6088afb test2 265.13% 1008KiB / 3.843GiB 0.03% 648B / 0B 1.18MB / 0B 7
##由于宿主机开了4核,因此cpu负载为400%
1.6 设置容器绑定指定的CPU
1.6.1 指定CPU设置
[root@docker ~]# docker run -itd --name test1 --cpuset-cpus 0,3 centos:7 bash
##指定本容器使用 0和3号cpu
a8efc1d070d82266478473be987d98d1a0689c5a44dbbf6f75e6fde70769a346
1.6.2 压力测试
进入容器压测
[root@docker ~]# docker exec -it test1 bash
[root@a8efc1d070d8 /]# yum install -y epel-release && yum install -y stress
[root@a8efc1d070d8 /]# stress -c 4
stress: info: [166] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
宿主机查看负载
[root@docker ~]# top
top - 17:07:25 up 15 min, 2 users, load average: 0.17, 1.41, 1.61
Tasks: 232 total, 6 running, 226 sleeping, 0 stopped, 0 zombie
%Cpu0 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4030168 total, 2522948 free, 564680 used, 942540 buff/cache
KiB Swap: 4194300 total, 4194300 free, 0 used. 3134820 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2989 root 20 0 7312 96 0 R 49.8 0.0 0:02.78 stress
2990 root 20 0 7312 96 0 R 49.8 0.0 0:02.78 stress
2991 root 20 0 7312 96 0 R 49.8 0.0 0:02.79 stress
2992 root 20 0 7312 96 0 R 49.8 0.0 0:02.78 stress
······
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a8efc1d070d8 test1 201.01% 168.7MiB / 3.843GiB 4.29% 27.7MB / 490kB 52.8MB / 25.2MB 7
2. 对内存使用的限制
2.1 物理内存
-m(--memory=)选项用于限制容器可以使用的最大内存
[root@docker ~]# docker run -itd --name test1 -m 1g centos:7 bash
add63bbc42c166dc0c7336c36c352760162193f338e4a1b78973ab553ebc7b29
[root@docker ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
add63bbc42c1 test1 0.00% 392KiB / 1GiB 0.04% 578B / 0B 0B / 0B 1
##MEM LIMIT为物理内存大小
2.2 交换空间内存
--memory-swap可限制swap分区的内存大小,但必须与-m命令一起使用。
正常情况下,--memory-swap的值包含容器可用内存和可用swap。
所以-m 300m --memory-swap=1g的含义为:容器可以使用300M的物理内存,并且可以使用700M(1G-300M)的swap。
如果--memory-swap设置为0或者不设置,则容器可以使用的swap大小为-m值的两倍。
如果--memory-swap的值和-m相同,则容器不能使用swap。
如果--memory-swap的值为-1,它表示容器程序使用的内存受限,而可以使用的swap空间使用不受限制(宿主机有多少swap容器就可以使用多少)。
[root@docker ~]# docker run -itd --name test1 -m 300m --memory-swap=1G centos:7 bash
cd4169e1c9a9cba52b5cff580fb60d3694b09d9f5ac843bee339aadc63c6d7a5
##给与容器300M物理内存以及700M交换空间
3. 对磁盘IO配额控制(blkio)的限制
--device-read-bps:限制某个设备上的读速度bps(数据量),单位可以是kb、mb(M)或者gb。
例:docker run -itd --name test1 --device-read-bps /dev/sda:1M centos:7 bash
--device-write-bps:限制某个设备上的写速度bps(数据量),单位可以是kb、mb(M)或者gb。
例:docker run -itd --name test2 --device-write-bps /dev/sda:1mb centos:7 bash
--device-read-iops:限制读某个设备的iops(次数)
--device-write-iops:限制写入某个设备的iops(次数)
3.1 创建容器并限制写速度
[root@docker ~]# docker run -it --name test --device-write-bps /dev/sda:1mb centos:7 bash
[root@d638b2689beb /]# dd if=/dev/zero of=write_test bs=1M count=10 oflag=direct
##添加oflag参数以规避掉文件系统cash
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 10.003 s, 1.0 MB/s
3.2 创建容器并限制写次数
[root@docker ~]# docker run -itd --name test --device-write-iops /dev/sda:10 centos:7 bash
480096c14d1a13953a03573097826b2c151f63a8942998316a67ba45403e6177
[root@docker ~]# docker inspect test
······
"BlkioDeviceWriteIOps": [
{
"Path": "/dev/sda",
"Rate": 10
}
],
······
3.3 清理docker占用的磁盘空间
docker system prune -a
清除停止的容器以及未被使用的镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 87a94228f133 9 hours ago 133MB
centos 7 eeb6ee3f44bd 3 weeks ago 204MB
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c754e5c5f4f centos:7 "bash" 6 minutes ago Up 6 minutes test1
480096c14d1a centos:7 "bash" 7 minutes ago Exited (137) 5 seconds ago test
[root@docker ~]# docker system prune -a
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all images without at least one container associated to them
- all build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
480096c14d1a13953a03573097826b2c151f63a8942998316a67ba45403e6177
Deleted Images:
untagged: nginx:latest
untagged: nginx@sha256:b0c17557e2a3a17bcf18498222824312832f69dbf78edab10f08334900bd7fda
deleted: sha256:87a94228f133e2da99cb16d653cd1373c5b4e8689956386c1c12b60a20421a02
deleted: sha256:55b6972054b24c53054322a52748324df5797eefbb6dc374e41522a91d532dd5
deleted: sha256:6b88aa6f4485486bfc779cccfbe4a7a47a502a7cff2cd70be89c59dcd0db12a8
deleted: sha256:472c64059965c7b6b1b534ba07374c1d034b17c99acb3cf4534fe78abed41101
deleted: sha256:788a5cf1e4599312b5923694f53e556ba0e2eb4a6bbb51958e0ec2b510345a49
deleted: sha256:410f31f9ae37c62af85e8f9575c5f4d75542be1739ac1ca5982cf461be0b13bc
deleted: sha256:e81bff2725dbc0bf2003db10272fef362e882eb96353055778a66cda430cf81b
Total reclaimed space: 133.3MB
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 7 eeb6ee3f44bd 3 weeks ago 204MB
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c754e5c5f4f centos:7 "bash" 6 minutes ago Up 6 minutes test1