文末有下载地址。如有侵权请联系作者谢谢!
docker学习笔记:https://blog.csdn.net/m0_46188681/article/details/128993319
Docker容器配置和资源限制:https://www.cnblogs.com/xiugeng/p/16254087.html
容器的监控和日志管理:https://www.cnblogs.com/xiugeng/p/16285637.html
学习docker的前提:熟悉linux基本命令和熟悉git命令。
一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验
Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。
环境配置如此麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。
之前在服务器配置一个应用的运行环境,要安装各种软件,就拿尚硅谷电商项目的环境来说吧,Java/Tomcat/MySQL/JDBC驱动包等。安装和配置这些东西有多麻烦就不说了,它还不能跨平台。假如我们是在 Windows 上安装的这些环境,到了 Linux 又得重新装。况且就算不跨操作系统,换另一台同样操作系统的服务器,要移植应用也是非常麻烦的。
传统上认为,软件编码开发/测试结束后,所产出的成果即是程序或是能够编译执行的二进制字节码等(java为例)。而为了让这些程序可以顺利执行,开发团队也得准备完整的部署文件,让维运团队得以部署应用程式,开发需要清楚的告诉运维部署团队,用的全部配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的状况。Docker镜像的设计,使得Docker得以打破过去「程序即应用」的观念。透过镜像(images)将作业系统核心除外,运作应用程式所需要的系统环境,由下而上打包,达到应用程式跨平台间的无缝接轨运作。
Docker是基于Go语言实现的云开源项目。
Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。
Linux 容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用运行在 Docker 容器上面,而 Docker 容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。
虚拟机就是带环境安装的一种解决方案,它可以在一种操作系统里面运行另一种操作系统,比如在Windows 系统里面运行Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。
虚拟机的缺点:
更快速的应用交付和部署: 传统的应用开发完成后,需要提供一堆安装程序和配置说明文档,安装部署后需根据配置文档进行繁杂的配置才能正常运行。Docker化之后只需要交付少量容器镜像文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像里已经内置好,大大节省部署配置和测试验证时间。
更便捷的升级和扩缩容: 随着微服务架构和Docker的发展,大量的应用会通过微服务方式架构,应用的开发构建将变成搭乐高积木一样,每个Docker容器将变成一块“积木”,应用的升级将变得非常容易。当现有的容器不足以支撑业务处理时,可通过镜像运行新的容器进行快速扩容,使应用系统的扩容从原先的天级变成分钟级甚至秒级。
更简单的系统运维: 应用容器化运行后,生产环境运行的应用可与开发、测试环境的应用高度一致,容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的BUG。当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复。
更高效的计算资源利用: Docker是内核级虚拟化,其不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上可以运行很多个容器实例,可大大提升物理服务器的CPU和内存的利用率。
#查看自己的内核 uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)
uname -r
#查看已安装的CentOS版本信息
cat /etc/redhat-release
小总结:
需要正确的理解仓储/镜像/容器这几个概念:
ce社区版 | ee企业版
#查看本机是否安装 gcc:
yum list installed | grep gcc
#如果没有 执行以下命令
yum -y install gcc gcc-c++
#卸载以前的docker旧版本
yum -y remove docker docker-common docker-selinux docker-engine
#安装需要的软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
#设置stable镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#更新软件包索引
yum makecache fast
#安装docker-ce、docker-ce-cli、containerd
yum install -y docker-ce-24.0.4 docker-ce-cli-24.0.4 containerd.io
#启动docker
systemctl start docker
#测试是否安装成功
docker version
docker run hello word
#配置镜像加速
#阿里云镜像地址: https://promotion.aliyun.com/ntms/act/kubernetes.html
#登录进去找到 镜像加速器
vim /etc/docker/daemon.json
#网易云
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
#或者阿里云
{
"registry-mirrors": ["https://{自已的编码}.mirror.aliyuncs.com"]
}
#刷新配置并重启docker
systemctl daemon-reload
systemctl restart docker
#将docker设为开机启动
systemctl enable docker
#卸载docker
systemctl stop docker
yum -y remove docker-ce
rm -rf /var/lib/docker
docker info
运行 :docker run hello-world
测试docker是否安装成功
docker run hello-world
都做了什么?(和maven的概念差不多)
docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。 容器,是一个运行时环境,就是我们前面说到的集装箱。
为什么docker比vm快?
#查看docker帮助文档: docker 具体命令 --help
docker --help
docker -h
#启动docker
systemctl start docker
#停止docker
systemctl stop docker
#重启docker
systemctl restart docker
#查看docker状态
systemctl status docker
#开机启动docker
systemctl enable docker
#查看docker概要信息
docker info
#命令 docker search,例如查询mysql
docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
镜像名称 镜像说明 点赞数量 是否官方认证 是否自动认证
#详细参数
Options:
-f, --filter string 过滤掉输出结果
#docker search --filter=STARS=9000 mysql [搜索 STARS >9000的 mysql 镜像]
--format string 标准格式输出
#格式化输出 docker search --format "{{.Name}}: {{.StarCount}}" nginx
-.Description 镜像描述
-.StarCount star数量
-.IsOfficial “OK” 表示官方镜像
- IsAutomated “OK” 表示自动构建
--limit int 最大搜索结果数(默认为25)
#docker search --limit 20 mysql [搜索 mysql 镜像 只显示前20条]
--no-trunc 不用截断输出
#命令:
docker images [Options]
#详细参数
Options:
-a, --all 显示所有镜像(默认隐藏中间镜像)
--digests 显示摘要
-f, --filter filter 根据提供的条件过滤输出
--format string 使用 Go 模板打印漂亮的图像
--no-trunc 使用 Go 模板打印漂亮的图像
-q, --quiet 只显示镜像id
#展示信息说明
REPOSITORY: 来自于哪个仓库,比如phpswoole/swoole表示swoole官网的镜像
TAG : 镜像的标签信息,比如18.04、latest表示不同的版本信息。标签只是标记,并不能标识镜像内容,latest标识最新的版本
IMAGE ID: 镜像的ID(唯一标识镜像),如果两个镜像的ID相同,说明它们实际上指向了同一个镜像,只是具有不同标签名称而已
CREATED: 创建时间,说明镜像最后的更新时间
SIZE: 镜像大小,优秀的镜像往往体积都较小
#--format 模板说明
.ID 镜像id
.Repository 镜像名称
.Tag 镜像标签
.Digest 镜像简介
.CreatedSince 自创以来经过的时间
.CreatedAt 创建图像的时间
.Size 镜像大小
#命令:
docker pull [Options] 镜像名称:tag
#详细参数
Options:
-a, --all-tags 下载镜像仓库中所有的指定镜像
--disable-content-trust 跳过镜像验证(默认值是true)
--platform string 如果服务具有多平台功能,则设置平台
-q, --quiet 一直详细输出
#没有TAG就是最新版 等价于 docker pull 镜像名称:latest
#命令:
docker system [Options]
#详细参数
Options:
df 整体磁盘的使用情况
events 获取docker系统实时事件,不包括容器内的
info 查看整个docker系统的信息
prune 清理资源,此操作尤其需要注意 # 清理停止的容器,清理没有使用的网络,清理废弃的镜像
#命令
docker rmi [Options] 镜像名称|镜像ID
#详细参数
Options:
-f : 通过 SIGKILL 信号强制删除一个运行中的容器。
–no-prune : 不移除该镜像的过程镜像,默认移除
#删除全部镜像,谨慎使用
docker rmi -f $(docker images -qa)
#谈谈docker虚悬镜像是什么?
#仓库名、标签都是的镜像,俗称虚悬镜像dangling image
#命令:
docker history [Options] 镜像名称|镜像ID
#详细参数
Options:
-H, --human 以可读的格式打印镜像大小和日期,默认为true
--no-trunc 显示完整的提交记录
-q, --quiet 仅列出提交记录ID
#命令
docker save [OPTIONS] IMAGE [IMAGE...]
参数
-o : 输出到的文件
#示例:将镜像jb51/ubuntu:v3 生成my_ubuntu_v3.tar文档
docker save -o my_ubuntu_v3.tar jb51/ubuntu:v3
ll my_ubuntu_v3.tar
-rw------- 1 jb51 jb51 142102016 Jul 11 01:37 my_ubuntu_v3.tar
#命令
docker build [OPTIONS] PATH | URL |
#详细参数
Options:
–build-arg=[] : 设置镜像创建时的变量;
–cpu-shares : 设置 cpu 使用权重;
–cpu-period : 限制 CPU CFS周期;
–cpu-quota : 限制 CPU CFS配额;
–cpuset-cpus : 指定使用的CPU id;
–cpuset-mems : 指定使用的内存 id;
–disable-content-trust : 忽略校验,默认开启;
-f : 指定要使用的Dockerfile路径;
–force-rm : 设置镜像过程中删除中间容器;
–isolation : 使用容器隔离技术;
–label=[] : 设置镜像使用的元数据;
-m : 设置内存最大值;
–memory-swap : 设置Swap的最大值为内存+swap,"-1"表示不限swap;
–no-cache : 创建镜像的过程不使用缓存;
–pull : 尝试去更新镜像的新版本;
–quiet, -q : 安静模式,成功后只输出镜像 ID;
–rm : 设置镜像成功后删除中间容器;
–shm-size : 设置/dev/shm的大小,默认值是64M;
–ulimit : Ulimit配置。
–squash : 将 Dockerfile 中所有的操作压缩为一层。
–tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
–network: 默认 default。在构建期间设置RUN指令的网络模式
#标记本地镜像将其归入某一仓库
docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
#示例将本地myapp:1.0镜像归入aim下
docker tag myapp:1.0 aim/myapp:1.0
#如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
docker login [OPTIONS] [SERVER]
-u : 登陆的用户名
-p : 登陆的密码
#如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
docker logout [OPTIONS] [SERVER]
#要先登陆到镜像仓库
docker push [OPTIONS] 镜像名称:[镜像标签]
#-f 根据提供的条件过滤输出;-q 只显示镜像id
docker images -f "dangling=true" -q
#删除虚悬镜像
docker rmi $(docker images -f "dangling=true" -q)
#这个命令会删除所有未使用到的镜像,即使并不是没有仓库名或没有标签。
docker image prune -a -f
#-a 显示所有镜像(默认隐藏中间镜像);-f 根据提供的条件过滤输出;-q 只显示镜像id
docker images -a -f "dangling=true" -q
docker容器的使用和操作:https://www.cnblogs.com/xiugeng/p/16008671.html
容器(Container):在docker中指的是从镜像创建的应用程序运行实例。
可以将容器看作将一个 应用程序及其依赖环境打包
而成的集装箱。
容器的实质是进程,与直接在主机执行不同,容器进程在属于自己的独立的命名空间内运行。这种特性使得容器封装的应用程序比直接在主机上运行的应用程序更加安全。
#命令
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
#docker run -it IMAGE_ID /bin/bash 常用
#详细参数
Options:
--add-host 添加自定义主机到IP的映射(host:ip)
--attach , -a 登录容器
--blkio-weight block io (相对权重),介于10到1000之间,或者为0禁用(默认为0)
--blkio-weight-device block IO 设备权重(相对设备权重)
--cap-add 添加 Linux 容量
--cap-drop 删除 Linux 容量
--cgroup-parent 容器的可选父cgroup
--cgroupns 在其自己的私有cgroup命名空间中运行容器
--cidfile 将容器ID写入文件
--cpu-count CPU数量(仅windows)
--cpu-percent CPU百分比(仅Windows)
--cpu-period 限制CPU CFS(完全公平的调度程序)期限
--cpu-quota 限制CPU CFS(完全公平的调度程序)配额
--cpu-rt-period 限制CPU实时时间(以微秒为单位)
--cpu-rt-runtime 限制CPU实时运行时间(以微秒为单位)
--cpu-shares , -c CPU份额(相对)
--cpus CPU数量
--cpuset-cpus 允许执行的CPU数量(0-3,0,1)
--cpuset-mems 允许执行的MEM数量(0-3,0,1)
--detach , -d 在后台运行容器并打印容器ID
--detach-keys 覆盖后台容器的键序列
--device 将主机设备添加到容器
--device-cgroup-rule 将规则添加到“允许cgroup的设备”列表中
--device-read-bps 限制从设备读取的速率(每秒字节数)
--device-read-iops 限制从设备读取的速率(每秒IO)
--device-write-bps 限制对设备的写入速率(每秒字节数)
--device-write-iops 限制对设备的写入速率(每秒IO)
--disable-content-trust true 跳过图像验证
--dns 设置自定义DNS服务器
--dns-opt 设定DNS选项
--dns-option 设定DNS选项
--dns-search 设置自定义DNS搜索域
--domainname 容器NIS域名
--entrypoint 覆盖图像的默认ENTRYPOINT
--env , -e 设置环境变量
--env-file 读入环境变量文件
--expose 公开一个或多个端口
--gpus 添加GPU设备到容器
--group-add 添加其他群组加入
--health-cmd 运行命令以检查运行状况
--health-interval 运行检查间隔时间(ms
--health-retries 连续故障,报告不健康
--health-start-period 开始运行状况重试倒计时之前,容器初始化的开始时间(ms
--health-timeout 允许执行一次检查的最长时间(ms
--help 打印用法,获取帮助
--hostname , -h 容器的主机名
--init 在容器内运行一个初始化程序,以转发信号并获取进程
--interactive , -i
--io-maxbandwidth 系统驱动器的最大IO带宽限制(仅Windows)
--io-maxiops 系统驱动器的最大IOps限制(仅Windows)
--ip IPV4地址
--ip6 IPV6地址
--isolation
--kernel-memory 内核内存限制
--label , -l 在容器上设置元数据
--label-file 读入行分隔的标签文件
--link 指定容器间的关联,使用其他容器的IP、env等信息
--link-local-ip 容器IPv4 / IPv6链接本地地址
--log-driver 容器的日志记录驱动程序
--log-opt 日志驱动程序选项
--mac-address 容器MAC地址
--memory , -m 内存限制
--memory-reservation 内存软限制
--memory-swap 交换限制等于内存加交换:“-1”以启用无限交换
--memory-swappiness 调音容器内存交换(0到100)
--mount 将文件系统挂载附加到容器
--name 为容器分配一个名称
--net 将容器连接到网络
--net-alias 为容器添加网络范围的别名
--network 将容器连接到网络
--network-alias 为容器添加网络范围的别名
--no-healthcheck 禁用任何容器指定的健康检查
--oom-kill-disable 禁用OOM Killer
--oom-score-adj 主机OOM首选项
--pid 使用PID命名空间
--privileged 赋予此容器扩展的特权
--publish , -p(小写) 将容器的端口发布到主机
--publish-all , -P(大写) 将所有公开的端口发布到随机端口
--read-only 将容器的根文件系统挂载为只读
--restart 容器退出时重新启动策略以应用:no-容器退出时不重启,默认设置/on-failure[:max-retries]-容器以非0状态退出时重启,max-retries指定重启的次数/always-不管退出状态始终重启,无限次/unless-stopped-不管退出状态始终重启,(Docker守护进程启动时,容器处于运行状态才生效)
--rm 退出时自动删除容器
--runtime
--tmpfs 挂载tmpfs目录
--tty , -t 分配伪TTY
--user , -u 用户名或UID(格式:<名称
--volume , -v 绑定挂载卷
--volume-driver 容器的可选卷驱动器
--volumes-from 从指定的容器挂载卷
--workdir , -w 容器内的工作目录
#查看已启动的服务
systemctl list-units --type=service
#查看已启动的服务
systemctl list-unit-files | grep enable
#设置开机启动
systemctl enable docker.service
#关闭开机启动
systemctl disable docker.service
docker容器的重启策略
Docker提供重启策略控制容器退出时或Docker重启时是否自动启动该容器。
容器默认不支持自动重启,要使用 --restart
选项指定重启策略。
作用:容器自动重启;重启策略能够确保关联的多个容器按照正确的顺序启动。
容器重启策略选项值:
选项值 | 功能 |
---|---|
no | 容器退出时不重启,默认设置 |
on-failure[:max-retries] | 容器以非0状态退出时重启,max-retries指定重启的次数 |
always | 不管退出状态始终重启,无限次 |
unless-stopped | 不管退出状态始终重启,(Docker守护进程启动时,容器处于运行状态才生效) |
使用重启策略时的注意事项:
--live-restore
选项,这个选项可使Docker升级中,即使网络和用户输入都终端,容器依然保持运行。#1.开启自启,在docker启动容器时可以增加参数
docker run –-restart=always
#容器已经启动,通过update命令进行修改
docker update –-restart=always <CONTAINER ID>
#重启在运行的所有容器
docker restart $(docker ps -q)
#2.关闭自启,容器关闭自启动:
docker update --restart=no <CONTAINER ID>
#取消所有容器自启动
docker update --restart=no $(docker ps -q)
默认情况下,Docker守护进程终止时,正在运行的容器会关闭。
实时恢复(Live Restore):管理员配置守护进程,让容器在守护进程不可用时依然运行。
实时恢复的作用:减少因Docker守护进程崩溃、计划停机或升级导致的容器停机时间。
第一种方式是在Docker守护进程配置文件中设置:
sighup(挂断)信号在控制终端或者控制进程死亡时向关联会话中的进程发出,默认进程对SIGHUP信号的处理时终止程序,所以我们在shell下建立的程序,在登录退出连接断开之后,会一并退出。
nohup 故名思议就是忽略SIGHUP信号,一般搭配& 一起使用,&表示将此程序提交为后台作业或者说后台进程组。
[root@localhost ~]# vi /etc/docker/daemon.json
{
"live-restore":true
}
# 配置生效方法一:
# 修改配置后重启守护进程生效
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
# 配置生效方法二:
# 重新加载Docker守护进程,避免容器停止
[root@localhost ~]# systemctl reload docker
# 案例1:
# 1.启动两个容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1dd65fa55b80 top "/bin/sh -c 'exec to…" 5 weeks ago Up 38 seconds test_exec_entry
52a7de98ccc7 test_shell_entry "/bin/sh -c 'top -b'" 5 weeks ago Up 52 seconds test:
# 2.停止docker守护进程
[root@localhost ~]# systemctl stop docker
Warning: Stopping docker.service, but it can still be activated by:
docker.socket
[root@localhost ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Wed 2022-05-11 00:23:16 CST; 8s ago
Docs: https://docs.docker.com
Process: 1697 ExecReload=/bin/kill -s HUP $MAINPID (code=exited, status=0/SUCCESS)
Process: 1853 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=0/SUCCESS)
Main PID: 1853 (code=exited, status=0/SUCCESS)
# 3.查看容器是否依然运行
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1dd65fa55b80 top "/bin/sh -c 'exec to…" 5 weeks ago Up About a minute test_exec_entry
52a7de98ccc7 test_shell_entry "/bin/sh -c 'top -b'" 5 weeks ago Up 2 minutes test
# 案例2:apache容器测试实时恢复
# 1.修改守护进程配置文件,启动实时恢复
[root@localhost ~]# vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://nxwgbmaq.mirror.aliyuncs.com"],
"live-restore":true
}
# 2.重启守护进程
[root@localhost ~]# systemctl restart docker
# 3.运行一个apache容器
[root@localhost ~]# docker pull httpd
[root@localhost ~]# docker run --rm -d -p 8080:80 httpd
27c266f2fbc9bb5dd67e442a99b82db440d135506b9d912d624331baae675ca9
# 4.重新加载Docker守护进程
[root@localhost ~]# systemctl reload docker
# 5.查看当前容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27c266f2fbc9 httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:8080->80/tcp, :::8080->80/tcp inspiring_robinson 《————容器依然运行
# 6.kill结束进程
[root@localhost ~]# ps -e | grep dockerd
5052 ? 00:00:01 dockerd 《————查看获取进程号
[root@localhost ~]# kill -SIGHUP 5052 《————向进程发送sighup信号
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27c266f2fbc9 httpd "httpd-foreground" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp inspiring_robinson 《————容器依然运行
# 7.访问apache验证服务是否正常
[root@localhost ~]# curl 127.0.0.1:8080
<html><body><h1>It works!</h1></body></html>
另一种恢复方式:在手动启动dockerd进程时指定–live-restore选项。
不建议使用这种方式,因为不会设置systemd或其他进程管理器的环境,会导致意外发生。
实时恢复功能支持Docker守护进程在升级期间保持容器的运行。
存在的问题:
只支持Docker 补丁版本升级,不支持主要版本和次要版本的升级。
升级过程中跳过版本,守护进程可能无法恢复其与容器的连接。
限定条件:只有Docker守护进程选项未发生变化,实时恢复才能恢复容器。
守护进程停止,正在运行的容器可能会填满守护进程通常读取的FIFO日志,阻止容器记录更多日志数据。
缓冲区填满,必须重新启动Docker守护进程来刷新。
可以更改/proc/sys/fs/pipe-max=size
来修改内核的缓冲区大小。
[root@localhost ~]# cat /proc/sys/fs/pipe-max-size
1048576
# 执行该命令显示最后200行linux系统日志信息,并滚动刷新
[root@localhost home]# tail -200f /var/log/messages
# 再开一个session,执行命令
[root@localhost /]# systemctl daemon-reload
[root@localhost /]# systemctl restart docker
# 可以看到日志刷新的信息,即可根据信息提示完成修复
Apr 23 19:32:45 localhost dockerd: unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character '}' looking for beginning of object key string
注意:一个容器可以有多个进程,但为了高效利用Docker,不要让一个容器负责整个应用程序的多个方面,而要通过用户定义网络和共享卷连接多个容器来实现应用程序的多个方面。
容器的主进程负责管理它启动的所有进程。
解决子进程回收:--init
选项可以将一个精简的初始化进程作为主进程插入容器,并在容器退出时回收所有的进程。
解决多进程启停最好方式:设置一个上层的进程统一处理这些进程的生命周期(sysinit\upstart\systemd)
在一个容器运行多个服务的方式:
Supervisor 是 Linux/UNIX系统下的一个进程管理工具,守护进程名为supervisord,可以方便地监听、启动、停止、重启一个或多个进程。
该工具管理进程时,如遇到进程被意外杀死,守护进程监听到后,会自动重启。
# 1.创建项目目录
[root@localhost ~]# mkdir php-nginx-supervisord && cd php-nginx-supervisord/
# 2.创建nginx子目录和supervisor子目录,并准备配置文件
[root@localhost php-nginx-supervisord]# mkdir nginx
[root@localhost php-nginx-supervisord]# mkdir supervisor
[root@localhost php-nginx-supervisord]# touch nginx/nginx.conf
[root@localhost php-nginx-supervisord]# mkdir nginx/conf.g
[root@localhost php-nginx-supervisord]# touch nginx/conf.g/site.conf
[root@localhost php-nginx-supervisord]# mkdir supervisor/conf.d/
[root@localhost php-nginx-supervisord]# touch supervisor/conf.d/supervisord.conf
# 查看目录结构
[root@localhost php-nginx-supervisord]# tree
.
├── nginx
│ ├── conf.g
│ │ └── site.conf
│ └── nginx.conf
└── supervisor
└── conf.d
└── supervisord.conf
4 directories, 3 files
# 3.编写supervisord.conf文件内容
[root@localhost php-nginx-supervisord]# vi supervisor/conf.d/supervisord.conf
[supervisord]
gfile=/tmp/supervisord.log ; # 日志
logfile_maxbytes=50MB ; # 最大50M日志
logfile_backups=10 ; # 轮循日志备份10个
loglevel=info ; # 日志等级记录info的
pidfile=/tmp/supervisord.pid ;pid
nodaemon=true ; # 在前台启动
minfds=102400 ; # 文件描述符限制
minprocs=2000 ; # 进程数
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
[program:nginx]
command=/usr/sbin/nginx -g 'daemon off'; # 前台启动nginx
autostart=true ; # 随着supervisor自动启动
startsecs=10 ; # 启动10s后算正常启动
autorestart=true ; # 程序退出后自动重启
startretries=3 ; # 启动失败自动重试次数
stdout_logfile_maxbytes=20MB ;stdout # 日志文件大小最大20Mb
stdout_logfile=/var/log/nginx/out.log
[program:php7-fpm]
command=/usr/local/sbin/php-fpm
autostart=true ; # 随着supervisor自动启动
startsecs=10 ; # 启动10s后算正常启动
autorestart=true ; #程序退出后自动重启
startretries=3 ; # 启动失败自动重试次数
stdout_logfile_maxbytes=20MB ;stdout 日志文件大小最大20Mb
# 4.尝试登录这个php容器,判断系统版本
[root@localhost php-nginx-supervisord]# docker run -ti php:7.3-fpm /bin/bash
# 进入容器检查信息
root@16fddccbb4ce:/var/www/html# cat /etc/issue
Debian GNU/Linux 11 \n \l
root@16fddccbb4ce:/var/www/html# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
# 由此得知为debian 11版本的系统
# 5.准备debian11换源文件sources.list
[root@localhost php-nginx-supervisord]# touch sources.list
[root@localhost php-nginx-supervisord]# vi sources.list
deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb-src http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
# 6.准备nginx.conf文件
[root@localhost php-nginx-supervisord]# vi nginx/nginx.conf
#一个主进程和多个工作进程
worker_processes 1;
events {
#每个工作进程最大的并发数(一个工作进程可以有多少个线程)
worker_connections 1024;
}
#http服务器设置
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
#长连接超时时间
keepalive_timeout 65;
#配置虚拟主机
server {
#虚拟主机使用的端口
listen 80;
#虚拟主机域名
server_name localhost;
#定义web根路径
location / {
#根目录路径
root html;
#索引页
index index.html index.htm;
}
}
}
# 6.编写Dockerfile文件内容
[root@localhost php-nginx-supervisord]# vi Dockerfile
FROM php:7.3-fpm
COPY sources.list /etc/apt/
RUN apt-get clean && apt-get update && apt-get -y install nginx supervisor procps net-tools && mkdir -p /var/log/supervisor
COPY nginx /etc/nginx
COPY supervisor /etc/supervisor
WORKDIR /var/www
RUN usermod -u 1000 www-data
EXPOSE 80
CMD ["/usr/bin/supervisord"]
# 7.基于Dockerfile构建镜像
[root@localhost php-nginx-supervisord]# docker build -t php-nginx-supervisord .
[+] Building 134.0s (14/14) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 350B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/php:7.3-fpm 0.0s
=> CACHED [1/9] FROM docker.io/library/php:7.3-fpm 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 902B 0.0s
=> [2/9] COPY sources.list /etc/apt/ 0.0s
=> [3/9] RUN apt-get clean && apt-get update 34.9s
=> [4/9] RUN apt-get -y install nginx supervisor procps net-tools 85.5s
=> [5/9] RUN mkdir -p /var/log/supervisor 0.3s
=> [6/9] COPY nginx /etc/nginx 0.0s
=> [7/9] COPY supervisor /etc/supervisor 0.0s
=> [8/9] WORKDIR /var/www 0.0s
=> [9/9] RUN usermod -u 1000 www-data 0.3s
=> exporting to image 12.9s
=> => exporting layers 12.9s
=> => writing image sha256:801d960db6395bde049fe7f3ffcec0de1a8e3b918a219b27 0.0s
=> => naming to docker.io/library/php-nginx-supervisord 0.0s
# 8.基于该镜像启动容器
[root@localhost php-nginx-supervisord]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
php-nginx-supervisord latest 62a3c736e277 About a minute ago 516MB
[root@localhost php-nginx-supervisord]# docker run -tid -p 8080:80 php-nginx-supervisord
44e42a4ae258ebe1f37a0b940afda5462f79260686477c89270cd8103ac61adf
# 9.测试web服务
访问:http://192.168.200.103:8080/
登录容器查看进程:
[root@localhost php-nginx-supervisord]# docker exec -ti 5b6d610e032e /bin/bash
root@5b6d610e032e:/var/www# ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 41 0.0 0.1 4100 3456 pts/1 Ss 08:57 0:00 /bin/bash
root 51 0.0 0.1 6700 2816 pts/1 R+ 08:58 0:00 \_ ps auxf
root 1 0.3 1.2 29492 24156 pts/0 Ss+ 08:57 0:00 /usr/bin/python3 /usr/bin/supervi
root 7 0.4 1.1 73228 22332 pts/0 S 08:57 0:00 php-fpm: master process (/usr/loc
www-data 15 0.0 0.4 73228 8784 pts/0 S 08:57 0:00 \_ php-fpm: pool www
www-data 16 0.0 0.4 73228 8784 pts/0 S 08:57 0:00 \_ php-fpm: pool www
root 49 0.0 0.0 8532 1424 ? Ss 08:58 0:00 nginx: master process /usr/sbin/n
nobody 50 0.0 0.1 8988 2576 ? S 08:58 0:00 \_ nginx: worker process
# 案例:将supervisord和配置和要管理的应用程序(nginx和tomcat)打包到一个镜像中,一个容器运行多个服务
# 1.创建dockerfile目录
[root@hecs-hqs-01 ~]# mkdir web-supervisord
[root@hecs-hqs-01 web-supervisord]# cd web-supervisord/
# 2.编写Dockerfile
[root@hecs-hqs-01 web-supervisord]# vi Dockerfile 《————dockerfile目录
FROM centos:7
MAINTAINER [email protected]
COPY CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
COPY nginx_install.sh /tmp/nginx_install.sh
RUN sh /tmp/nginx_install.sh; \rm -rf /usr/local/src/*
RUN sed -i -e '/worker_processes/a daemon off;' /usr/local/nginx/conf/nginx.conf;
COPY jdk-8u162-linux-x64.tar.gz /usr/local/src/jdk-8u162-linux-x64.tar.gz
COPY tomcat_install.sh /tmp/tomcat_install.sh
RUN sh /tmp/tomcat_install.sh; \rm -rf /usr/local/src/*
COPY supervisor_install.sh /tmp/supervisor_install.sh
COPY supervisord.conf /etc/supervisord.conf
COPY start_tomcat.sh /usr/local/tomcat/bin/mystart.sh
RUN sh /tmp/supervisor_install.sh; \rm -rf /tmp/*.sh
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
# 3.默认源下载慢且总有问题,更换为163的yum源
[root@hecs-hqs-01 web-supervisord]# vi CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
baseurl=http://mirrors.163.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=http://mirrors.163.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=http://mirrors.163.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://mirrors.163.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
# 4.准备nginx安装脚本
[root@hecs-hqs-01 web-supervisord]# vi nginx_install.sh
yum install -y wget tar gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel
cd /usr/local/src
wget 'http://nginx.org/download/nginx-1.12.2.tar.gz'
tar -zxvf nginx-1.12.2.tar.gz
cd nginx-1.12.2
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-stream --with-stream_ssl_module
make
make install
exit 0
# 5.准备tomcat安装脚本
[root@hecs-hqs-01 web-supervisord]# vi tomcat_install.sh
yum install -y wget tar
cd /usr/local/src/
tar -zxvf jdk-8u162-linux-x64.tar.gz
mv jdk1.8.0_162 /usr/local/
#/usr/local/jdk1.8.0_162/bin/java -version
#配置java环境变量
echo 'JAVA_HOME=/usr/local/jdk1.8.0_162/' >>/etc/profile
echo 'PATH=$PATH:$JAVA_HOME/bin' >>/etc/profile
echo 'CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH' >>/etc/profile
source /etc/profile
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.78/bin/apache-tomcat-8.5.78.tar.gz
tar -zxvf apache-tomcat-8.5.78.tar.gz
mv apache-tomcat-8.5.78 /usr/local/tomcat
# 6.下载jdk
# 官网下载地址:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html 需要注册才能下载
[root@hecs-hqs-01 web-supervisord]# ls
# 7.准备supervisor安装脚本
[root@hecs-hqs-01 web-supervisord]# vi supervisor_install.sh
yum -y install epel-release
yum -y install python2-pip
pip install supervisor
# 8.准备supervisor配置文件
[root@hecs-hqs-01 web-supervisord]# vi supervisord.conf
[unix_http_server]
file=/tmp/supervisor.sock ; the path to the socket file
[supervisord]
logfile=/tmp/supervisord.log ; # 日志
logfile_maxbytes=50MB ; # 最大50M日志
logfile_backups=10 ; # 轮循日志备份10个
loglevel=info ; # 日志等级记录info的
pidfile=/tmp/supervisord.pid ;pid
nodaemon=true ; # 在前台启动
minfds=102400 ; # 文件描述符限制
minprocs=2000 ; # 进程数
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
[program:nginx]
command=/usr/local/nginx/sbin/nginx ; # 前台启动nginx
autostart=true ; # 随着supervisor自动启动
startsecs=10 ; # 启动10s后算正常启动
autorestart=true ; # 程序退出后自动重启
startretries=3 ; # 启动失败自动重试次数
stdout_logfile_maxbytes=20MB ;stdout # 日志文件大小最大20Mb
stdout_logfile=/usr/local/nginx/logs/out.log
[program:tomcat]
command=sh /usr/local/tomcat/bin/mystart.sh ; # 前台启动tomcat
autostart=true ; # 随着supervisor自动启动
startsecs=10 ; # 启动10s后算正常启动
autorestart=true ; #程序退出后自动重启
startretries=3 ; # 启动失败自动重试次数
stdout_logfile_maxbytes=20MB ;stdout 日志文件大小最大20Mb
stdout_logfile=/usr/local/tomcat/logs/catalina.out
# 9.tomcat启动脚本准备
# 由于supervisor无法使用source,需要编写个脚本来启动
[root@hecs-hqs-01 web-supervisord]# vi start_tomcat.sh
source /etc/profile
/usr/local/tomcat/bin/catalina.sh run
# 10.构建镜像
[root@hecs-hqs-01 web-supervisord]# docker build -t web-supervisor .
[root@localhost web-supervisord]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web-supervisor latest 5198c5737571 7 minutes ago 1.44GB
# 11.启动容器测试
[root@localhost web-supervisord]# docker run -d web-supervisor /bin/bash -c 'supervisord -c /etc/supervisord.conf'
a326e2589794c4b2a19c23d177f2c418d0583c87605342fd7445694dc40e2219
# 6.基于镜像启动容器和测试web服务
docker exec -it 76782ab /bin/bash
ifconfig
curl 127.0.0.1
curl 127.0.0.1:8080
进程级的健康检查:最简单的,检验进程是否运行。重启策略可以根据检查情况重启已停止的容器。这个检查不足:无法发现应用程序问题。
Docker提供了健康检查机制,可以通过Dockerfile文件在镜像中注入,也可以在启动容器时通过相应选项实现。
可以在Dockerfile中使用HEALTHCHECK指令声明健康检测配置,用于判断容器主进程的服务状态是否正常,反映容器的实际健康状态。
Dockerfile构建镜像时,加入了HEALTHCHECK指令,基于这样镜像启动的容器,就具备了健康状态检查能力,能自动进行健康检查。
Dockerfile中,只能出现一次HEALTHCHECK指令,出现多次,仅最后一次生效。
一旦有一次健康检查成功,Docker就会确认容器为健康状态。
HEALTHCHECK指令格式:
设置检查容器健康状况的命令
HEALTHCHECK [选项] CMD <命令>
# 选项:
--interval:设置容器运行后开始健康检查的时间间隔,默认30s。
--timeout:设置允许健康检查命令允许的最长时间,默认30s。超时即失败。
--start-period:设置容器启动的初始化时间。(启动过程中的健康检查失败不报错)
--retries:设置允许连续重试的次数,默认3次。(连续检查失败后视为不健康)
# CMD指令后的命令:指定执行健康检查的具体命令。可以使用shell格式或exec格式。
# 返回值:CMD指令后面的“命令” 执行完毕返回值表示容器的运行状况。
0:成功。容器是健康且可用的。
1:失败。容器不健康,不能正常工作。
2:保留值。暂时不要使用。
# 示例:每5分钟健康检查一次,访问web服务器主页,每次检查3秒以内
# || 表示上一条命令执行失败后,才执行下一条命令,退出返回值为1,告诉docker健康检查失败
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1
表示禁止从基础镜像继承HEALTHCHECK指令设置
HEALTHCHECK NONE
可以在执行 docker run
或 docker create
命令启动创建容器时指定容器的健康检查策略。
[root@localhost ~]# docker run --help
# 指定和运行健康检查
--health-cmd string Command to run to check health
# 设置容器运行后开始健康检查的时间间隔(单位:ms/s/m/h),默认是0s
--health-interval duration Time between running the check (ms|s|m|h) (default 0s)
# 设置连续失败需要报告的次数
--health-retries int Consecutive failures needed to report unhealthy
# 设置容器启动的初始化时间(单位:ms/s/m/h),默认是0s
--health-start-period duration Start period for the container to initialize before starting
health-retries countdown (ms|s|m|h) (default 0s)
# 设置允许健康检查命令允许的最长时间(单位:ms/s/m/h),默认是0s
--health-timeout duration Maximum time to allow one check to run (ms|s|m|h) (default 0s)
# 禁用容器健康检查指令
--no-healthcheck Disable any container-specified HEALTHCHECK
容器启动,开始执行健康检查命令,并周期执行,如果返回0,容器处于健康状态。如果返回非0值,容器不健康。
案例1:dockerfile中实现健康检查案例
# 改写上面的php-nginx-supervisord案例
[root@localhost php-nginx-supervisord]# vi Dockerfile
FROM php:7.3-fpm
COPY sources.list /etc/apt/
RUN apt-get clean && apt-get update
RUN apt-get -y install nginx supervisor procps net-tools
RUN mkdir -p /var/log/supervisor
COPY nginx /etc/nginx
COPY supervisor /etc/supervisor
WORKDIR /var/www
RUN usermod -u 1000 www-data
EXPOSE 80
HEALTHCHECK --interval=1m --timeout=3s CMD curl -f http://localhost/ || exit 1
CMD ["/usr/bin/supervisord"]
# 构建镜像、启动容器
[root@localhost php-nginx-supervisord]# docker build -t php-nginx-supervisord .
[root@localhost php-nginx-supervisord]# docker run -tid -p 8080:80 php-nginx-supervisord
# 查看容器状态
[root@localhost php-nginx-supervisord]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7bcf645de0ee php-nginx-supervisord "docker-php-entrypoi…" 2 seconds ago Up 2 seconds (health: starting) 9000/tcp, 0.0.0.0:8080->80/tcp, :::8080->80/tcp nervous_bartik
[root@localhost php-nginx-supervisord]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7bcf645de0ee php-nginx-supervisord "docker-php-entrypoi…" 3 minutes ago Up 3 minutes (healthy) 9000/tcp, 0.0.0.0:8080->80/tcp, :::8080->80/tcp nervous_bartik
案例2:启动容器时设置选项实现健康检查
# 1.下载busybox镜像
[root@localhost ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
5cc84ad355aa: Pull complete
Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
# 2.创建容器设置健康检查,检查间隔20s,失败重复1次;并立即查看容器的健康检查状态
[root@localhost ~]# docker run --rm --name test-health -d \
> --health-cmd 'stat /etc/passwd || exit 1' \
> --health-interval 20s --health-retries 1 \
> busybox sleep 1d;
[root@localhost ~]# docker inspect --format '{{.State.Health.Status}}' test-health
d8fa5965abc02ec8d01722f98257ba2b8f76d50af05890dc8c6e1a18573ee6a3
starting 《————容器启动后的健康状态为Starting
# 3.延迟20s时间,再次查看容器的健康检查状态
[root@localhost ~]# sleep 20s;docker inspect --format '{{.State.Health.Status}}' test-health
healthy 《————容器处于健康状态
# 4.删除容器的/etc/passwd文件,模拟健康问题
[root@localhost ~]# docker exec test-health rm /etc/passwd
# 5.延迟20s时间,再次查看容器的健康检查状态
[root@localhost ~]# sleep 20s;docker inspect --format '{{.State.Health.Status}}' test-health
unhealthy 《————容器处于不健康状态
# 进一步查看容器的详情
[root@localhost ~]# docker inspect --format '{{json .State.Health}}' test-health
{"Status":"unhealthy","FailingStreak":6,"Log":[{"Start":"2022-05-12T04:06:13.855633253+08:00","End":"2022-05-12T04:06:13.899152317+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"},{"Start":"2022-05-12T04:06:33.910019299+08:00","End":"2022-05-12T04:06:33.953470925+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"},{"Start":"2022-05-12T04:06:53.956520997+08:00","End":"2022-05-12T04:06:53.998897439+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"},{"Start":"2022-05-12T04:07:14.002929368+08:00","End":"2022-05-12T04:07:14.045233889+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"},{"Start":"2022-05-12T04:07:34.050748795+08:00","End":"2022-05-12T04:07:34.090015044+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"}]}
# 上述信息中报错:stat: can't stat '/etc/passwd': No such file or directory\n,符合前面模拟的健康问题
# 6.查看容器的当前状态
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d8fa5965abc0 busybox "sleep 1d" 5 minutes ago Up 5 minutes (unhealthy) test-health
Dockerfile中的FROM
、MAINTAINER
、RUN
和ADD
这四个指令在运行时是不能被覆盖的,其他的指令在执行docker run(或docker create)命令时都会被相应地覆盖。
从镜像运行一个容器时,可以指定一个新的命令来覆盖Dockerfile的CMD指令。
如果镜像的Dockerfile还声明了ENTRYPOINT指令,则Dockerfile的CMD指令或容器运行时指定的命令均作为参数追加到ENTRYPOINT指令中。
从镜像运行一个容器的时候,可以指定一个新命令来覆盖Dockerfile中的CMD指令。
[root@localhost ~]# docker history ubuntu
IMAGE CREATED CREATED BY SIZE COMMENT
ff0fea8310f3 7 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B 《——————默认命令
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:1d3b09cf9e041d608… 72.8MB
# 语法
[root@localhost ~]# docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 不覆盖的案例:使用CMD的默认命令
[root@localhost ~]# docker run -tid ubuntu
d6adcb9ca10de89dcb1a1f8ab49b33a715b502e4aa4f1ec240774a7f4d2aa9f5
# 覆盖案例
[root@localhost ~]# docker run -tid ubuntu top 《————top替换默认的bash
0485fee218e64e858ca5b2214b9349b523a3bd41d1ad86c08877240635fa0d32
使用 --entrypoint
选项可以覆盖定义镜像的 Dockerfile 中的 ENTRYPOINT 指令设置。
镜像的 ENTRYPOINT
指令定义容器启动时要执行的命令,在启动容器时不容易被覆盖。
注意:运行时使用--entrypoint
选项将清除镜像任何默认命令。
# 语法
[root@localhost ~]# docker run --help
--entrypoint string Overwrite the default ENTRYPOINT of the image
# 案例
[root@localhost ~]# docker pull redis
[root@localhost ~]# docker history redis
IMAGE CREATED CREATED BY SIZE COMMENT
7614ae9453d1 4 months ago /bin/sh -c #(nop) CMD ["redis-server"] 0B
<missing> 4 months ago /bin/sh -c #(nop) EXPOSE 6379 0B
<missing> 4 months ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B
<missing> 4 months ago /bin/sh -c #(nop) COPY file:df205a0ef6e6df89… 374B
<missing> 4 months ago /bin/sh -c #(nop) WORKDIR /data 0B
<missing> 4 months ago /bin/sh -c #(nop) VOLUME [/data] 0B
<missing> 4 months ago /bin/sh -c mkdir /data && chown redis:redis … 0B
...省略
# 默认自动运行redis-server的容器中,再运行一个shell
[root@localhost ~]# docker run -ti --entrypoint /bin/bash redis
root@484cb9c42858:/usr/local/bin# ls
docker-entrypoint.sh redis-benchmark redis-check-rdb redis-sentinel
gosu redis-check-aof redis-cli redis-server
root@bd7640ba7206:/data# exit
exit
# 传递更多参数给ENTRYPOINT
# 默认传递--help给redis-server
[root@localhost ~]# docker run -ti redis --help
Usage: ./redis-server [/path/to/redis.conf] [options] [-]
./redis-server - (read config from stdin)
./redis-server -v or --version
./redis-server -h or --help
...省略
# 传递--help给redis-cli
[root@localhost ~]# docker run -ti --entrypoint redis-cli redis --help
redis-cli 6.2.6
Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
-h <hostname> Server hostname (default: 127.0.0.1).
-p <port> Server port (default: 6379).
-s <socket> Server socket (overrides hostname and port).
...省略
# 传递空字符串重置容器的入口命令
[root@localhost ~]# docker run -ti --entrypoint="" redis bash
root@5cb647f12d63:/data# exit
exit
EXPOSE指令定义对外提供服务的初始传入端口,这些端口可用于容器中的进程。
[root@localhost ~]# docker run --help
--expose list Expose a port or a # 对外暴露容器的一个端口或一个端口范围
range of ports
--link list Add link to another # 添加到其他容器的连接
container
-p, --publish list Publish a container s # 将容器的一个端口或端口范围发布到主机
port(s) to the host
-P, --publish-all Publish all exposed # 将所有的端口发布到主机随机端口
ports to random ports
# 案例:
[root@localhost ~]# mkdir expose-test && cd expose-test/
[root@localhost expose-test]# vi default.conf
server {
listen 81;
listen [::]:81;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
[root@localhost expose-test]# vi Dockerfile
FROM nginx
ADD default.conf /etc/nginx/conf.d/
# 构建镜像
[root@localhost expose-test]# docker build -t expose-test .
# 运行容器
[root@localhost expose-test]# docker run -tid --expose 81 -P expose-test
[root@localhost expose-test]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cfd19ef475fd expose-test "/docker-entrypoint.…" 2 seconds ago Up 2 seconds 0.0.0.0:49155->80/tcp, :::49155->80/tcp, 0.0.0.0:49154->81/tcp, :::49154->81/tcp determined_allen
# 访问网页发现49154端口才可以访问到网页
linux中的容器,Docker自动设置了如下环境变量(默认值):
可以使用若干 -e
选项设置任何环境变量,并可以覆盖上述默认环境变量或Dockerfile中ENV指令定义的环境变量。
# 语法
[root@localhost ~]# docker run --help
-e, --env list Set environment variables # 设置环境变量
--env-file list Read in a file of # 读取文件中环境变量
environment variables
# 案例
[root@localhost ~]# export today=Sunday
[root@localhost ~]# echo $today
Sunday
[root@localhost ~]# docker run -t -e "deep=purple" \
> -e today \
> --rm alpine env
# 输出如下信息
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=40951973766d
TERM=xterm
deep=purple
today=Sunday
HOME=/root
覆盖HEALTHCHECK的相关选项:
[root@localhost ~]# docker run --help
# 指定和运行健康检查
--health-cmd string Command to run to check health
# 设置容器运行后开始健康检查的时间间隔(单位:ms/s/m/h),默认是0s
--health-interval duration Time between running the check (ms|s|m|h) (default 0s)
# 设置连续失败需要报告的次数
--health-retries int Consecutive failures needed to report unhealthy
# 设置容器启动的初始化时间(单位:ms/s/m/h),默认是0s
--health-start-period duration Start period for the container to initialize before starting
health-retries countdown (ms|s|m|h) (default 0s)
# 设置允许健康检查命令允许的最长时间(单位:ms/s/m/h),默认是0s
--health-timeout duration Maximum time to allow one check to run (ms|s|m|h) (default 0s)
# 禁用容器健康检查指令
--no-healthcheck Disable any container-specified HEALTHCHECK
容器中运行二进制文件的默认工作目录是根目录(/),Dockerfile中可以使用WORDDIR指令自定义工作目录。还可以使用 -w
选项覆盖WORKDIR指令设置。
[root@localhost ~]# docker run --help
-w, --workdir string Working directory # 修改容器的工作目录
inside the container
# 案例:
[root@localhost expose-test]# docker run -tid -e "NGINX_VERSION=2.20.1" -e "HOME=/usr" -e today=Sunday \
> nginx
[root@localhost expose-test]# docker exec -ti 4399b3795e13 /bin/bash
root@4399b3795e13:/# pwd
/ 《————工作目录为根目录
[root@localhost expose-test]# docker run -tid -w /usr/local nginx
[root@localhost expose-test]# docker exec -ti 59362a6f79d4 /bin/bash
root@59362a6f79d4:/usr/local# pwd
/usr/local 《————工作目录为/usr/local
容器默认用户是root(UID=0),Dockerfile的USER指令可以指定容器运行第一个进程时的默认用户。
启动容器的时候,可以使用 -u(--user)
选项指定新的默认用户覆盖镜像的USER指令。
# 语法
[root@localhost ~]# docker run --help
-u, --user string Username or UID # 指定容器运行第一个进程的默认用户,可以使用用户名、UID、组名、GID参数
(format:
<name|uid>[:<group|gid>])
# 案例
[root@localhost expose-test]# docker run -ti -u daemon ubuntu
daemon@8aeca4a93520:/$
[root@localhost expose-test]# docker run -ti -u mail ubuntu
mail@137b5fdfa150:/$
Dockerfile中可以使用 VOLUME 指令定义一个或多个与镜像关联的卷。
容器启动时可以使用 -v
、--mount
、--volume-from
选项来指定挂载卷。详见:Docker存储管理 https://www.cnblogs.com/xiugeng/p/16194410.html
容器可使用的内容包括:物理内存、交换空间(SWAP)。
Docker 默认没有设置内存限制的,容器进程可以根据需要尽可能多地使用内存和交换空间。
硬限制:仅允许容器使用不超过给定值的用户内存或系统内存。
软限制:允许容器按需使用内存,但不能影响到内存使用或与占用主机内存。
同时设置内存和交换空间时,交换空间限制必须大于物理内存限制。
[root@localhost ~]# docker run --help
-m, --memory bytes Memory limit # 容器可用内存限制,最低是4MB
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable # 容器可以使用的交换空间,-1为无限
unlimited swap
# 案例1:对容器内存使用不限制
[root@localhost ~]# docker run -ti ubuntu /bin/bash
# 案例2:设置内存限制并取消交换空间的限制
[root@localhost ~]# docker run -ti -m 300M --memory-swap -1 ubuntu /bin/bash
# 案例3:只设置内存限制
[root@localhost ~]# docker run -ti -m 300M ubuntu /bin/bash
[root@localhost ~]# docker inspect --format='{{.HostConfig.Memory}}' a84ca902dbab
314572800 《————314572800/1024/1024=300
# 案例4:同时设置内存和交换空间
[root@localhost ~]# docker run -ti -m 300M --memory-swap 1G ubuntu /bin/bash
内核内存不能使用交换空间,消耗过多的内核内存会导致系统服务被阻塞。
内核内存不独立于用户内存,一般在用户内存限制的基础上限制内核内存。
限制内核内存的效果:当内核内存太多时,系统会阻止新进程创建。
[root@localhost ~]# docker run --help
--kernel-memory bytes Kernel memory limit # 容器内核内存限制
# 案例1:同时设置用户内存和内核内存
[root@localhost ~]# docker run -ti -m 200M --kernel-memory 50M ubuntu /bin/bash
# 案例2:只设置内核内存,内存不限制
[root@localhost ~]# docker run -ti --kernel-memory 50M ubuntu /bin/bash
作为一个软限制功能,内存预留并不能保证不会超过限制。主要目的是确保当内存争用严重时,内存就按预留设置进行分配。
内存软限制设置效能:确保容器不会长时间消耗过多内存,每次内存回收将容器内存消耗缩减到软限制之下。
软限制设置规则:
[root@localhost ~]# docker run --help
--memory-reservation bytes Memory soft limit # 设置内存预留。0表示无限制
# 示例1:限制内存为500MB,内存预留值(软限制)为200MB
[root@localhost ~]# docker run -ti -m 500M --memory-reservation 200M ubuntu /bin/bash
# 示例2:设置内存软限制为1GB,没有设置内存硬限制
[root@localhost ~]# docker run -ti --memory-reservation 1G ubuntu /bin/bash
默认设置是所有容器都可以平等地使用主机CPU资源而不受限制。
默认情况,所有容器得到相同比例的CPU周期。
通过设置CPU份额权重,分配容器可以使用的CPU周期。
[root@localhost ~]# docker run --help
-c, --cpu-shares int CPU shares (relative weight) # 设置CPU份额权重,默认值1024
# 案例
[root@localhost ~]# docker run -tid -c 1024 ubuntu /bin/bash
17ea3842fe624a9719817255dba50ba809f3f30c0ffbd1b50e1fd42172e032f0
[root@localhost ~]# docker run -tid -c 512 ubuntu /bin/bash
5c51e13530879ab7ed56bc42c1f71de0b6a2bff9cadbac6fb1364fa4c11c529a
默认的CFS(完全公平调度器)周期为100ms(100000us)。
设置CPU周期限制容器CPU资源使用。
[root@localhost ~]# docker run --help
# --cpu-period 和 --cpu-quota 选项都是以1个CPU为基准。
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period # 限制容器CPU CFS周期
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota # 限制容器CPU CFS配额
--cpus decimal Number of CPUs # 指定容器可用CPU资源,浮点数,默认0.000(不受限)
# 案例:若只有一个cpu,容器可以每50ms获得50%的CPU运行时间
[root@localhost ~]# docker run -ti --cpu-period=50000 --cpu-quota=25000 ubuntu /bin/bash
# 案例2:效果同上
[root@localhost web-supervisord]# docker run -ti --cpus=0.5 ubuntu /bin/bash
限制容器进程运行在什么CPU上。
[root@localhost web-supervisord]# docker run --help
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
# 案例:
# 容器的进程允许运行在cpu1\cpu2\cpu3
[root@localhost ~]# docker run -ti --cpuset-cpus='1-3' ubuntu /bin/bash
# 容器的进程允许运行在cpu0
[root@localhost ~]# docker run -ti --cpuset-cpus='0' ubuntu /bin/bash
# 容器的进程允许运行在cpu0\cpu4
[root@localhost ~]# docker run -ti --cpuset-cpus='0,4' ubuntu /bin/bash
--cpu-quota
限制容器进程的CPU配额。
默认值0
表示容器占用一个CPU 100%的CPU资源。
设为 50000
表示容器至多使用CPU50%的资源。
# 容器每100ms(100000us)占用50%
[root@localhost ~]# docker run -tid --cpu-quota=50000 ubuntu
# 容器占用CPU 100%的资源
[root@localhost ~]# docker run -tid --cpu-quota=0 ubuntu
块I/O带宽(Block I/O Bandwith,Blkio):磁盘读写带宽。
Docker 可设置权重,限制容器读写磁盘的带宽。
使用--blkio-weight
选项设置一个容器相对于所有其他正在运行的容器的块I/O带宽权重。
可设置的块I/O带宽权重范围是10-1000。
默认所有的容器的权重值为500。0表示被禁用。
[root@localhost ~]# docker run --help
--blkio-weight uint16 Block IO (relative
weight), between 10
and 1000, or 0 to
disable (default 0)
案例:
[root@localhost ~]# docker run -tid --blkio-weight 300 ubuntu /bin/bash
[root@localhost ~]# docker run -tid --blkio-weight 0 ubuntu /bin/bash
Docker 按照两种指标限制容器的设备读写速率:每秒字节数、每秒I/O次数。
1)每秒字节数
使用--device-read-bps
选项限制指定设备的读取速率,即每秒读取的字节数。
使用--device-write-bps
选项限制指定设备的写入速率
单位可以是kb,mb或gb
中的一个。
[root@localhost ~]# docker run --help
--device-read-bps list Limit read rate (bytes
per second) from a
device (default [])
--device-write-bps list Limit write rate
(bytes per second) to
a device (default [])
# 案例:限制/dev/sda的读取速率为1kb/s
[root@localhost ~]# docker run -ti --device-read-bps /dev/sda:1kb ubuntu # /dev/sda1和/dev/sda2会报错,只能控制磁盘IO不能控制分区IO
[root@localhost ~]# docker inspect --format="{{json .HostConfig.BlkioDeviceReadBps}}" 5d377a47bfe4
[{"Path":"/dev/sda","Rate":1024}] 《——————1024byte即1kb
# 限制/dev/sda的写入速率为1mb/s
[root@localhost ~]# docker run -tid --device-write-bps /dev/sda:1mb ubuntu
[root@localhost ~]# docker inspect --format="{{json .HostConfig.BlkioDeviceWriteBps}}" 37cd8b0da954
[{"Path":"/dev/sda","Rate":1048576}] 《——————1048576byte即1mb
2)每秒I/O次数
限制指定设备的读取和写入速率,用每秒I/O次数表示。
[root@localhost ~]# docker run --help
--device-read-iops list Limit read rate (IO
per second) from a
device (default [])
--device-write-iops list Limit write rate (IO
per second) to a
device (default [])
# 案例:限制/dev/sda设备的读取速率为每秒1000次
[root@localhost ~]# docker run -ti --device-read-iops /dev/sda:1000 ubuntu
[root@localhost ~]# docker inspect --format="{{json .HostConfig.BlkioDeviceReadIOps}}" 1a9e1fb4c8fc
[{"Path":"/dev/sda","Rate":1000}]
# 限制 /dev/sda 设置的写入速率为每秒15次
[root@localhost ~]# docker run -ti --device-write-iops /dev/sda:15 ubuntu
[root@localhost ~]# docker inspect d5440f301bc5 --format="{{json .HostConfig.BlkioDeviceWriteIOps}}"
[{"Path":"/dev/sda","Rate":15}]
对容器使用的内存、CPU和块I/O带宽资源的限制具体是由控制组的相应子系统来实现的。
注意:在docker run命令中使用–cpu-shares、–memory、–device-read-bps等选项实际上就是在配置控制组,相关的配置文件保存在/sys/fs/cgroup
目录中。
# 1.创建容器内存限额300M,CPU权重512
[root@localhost docker]# docker run -tid -p 8080:80 -m 300M --cpu-shares=512 httpd
3cdbdafe0398d40daa8bf334413dc748a3a707cfac96c8ff0ee22a87e5d85e60
# 2.查看/sys/fs/cgroup目录中容器CPU的配置信息
[root@localhost ~]# cd /sys/fs/cgroup/cpu/docker
# 里面有容器ID命名的目录,包含容器CPU相关配置
[root@localhost 3cdbdafe0398d40daa8bf334413dc748a3a707cfac96c8ff0ee22a87e5d85e60]# cat cpu.shares
512
# 3.查看容器内存限制信息
[root@localhost ~]# cd /sys/fs/cgroup/memory/docker/3cdbdafe0398d40daa8bf334413dc748a3a707cfac96c8ff0ee22a87e5d85e60/
[root@localhost 3cdbdafe0398d40daa8bf334413dc748a3a707cfac96c8ff0ee22a87e5d85e60]# cat memory.limit_in_bytes
314572800 《——————换算为300M
docker update
命令可以动态地更新容器配置,防止容器在主机上使用太多的资源。
除了kernel-memory
选项,其他选项都是立即生效。
kernel-memory
选项只能应用于停止的容器,在下一次重启时生效。
[root@localhost ~]# docker update --help
Usage: docker update [OPTIONS] CONTAINER [CONTAINER...]
Update configuration of one or more containers
Options:
--blkio-weight uint16 Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
--cpu-rt-period int Limit the CPU real-time period in microseconds
--cpu-rt-runtime int Limit the CPU real-time runtime in microseconds
-c, --cpu-shares int CPU shares (relative weight)
--cpus decimal Number of CPUs
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--kernel-memory bytes Kernel memory limit
-m, --memory bytes Memory limit
--memory-reservation bytes Memory soft limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--pids-limit int Tune container pids limit (set -1 for unlimited)
--restart string Restart policy to apply when a container exits
# 案例:
[root@localhost docker]# docker run -tid -p 8080:80 -m 300M --cpu-shares=512 httpd
[root@localhost ~]# docker inspect e2b4e487a27f --format="{{.HostConfig.CpuShares}}-{{.HostConfig.Memory}}-{{.HostConfig.MemorySwap}}"
512-314572800-629145600
[root@localhost ~]# docker update -m 500M --cpu-shares=400 --memory-swap 800M e2b4e487a27f
[root@localhost ~]# docker inspect e2b4e487a27f --format="{{.HostConfig.CpuShares}}-{{.HostConfig.Memory}}-{{.HostConfig.MemorySwap}}"
400-524288000-838860800
#进入容器内部
#docker exec -it CONTAINER_ID bash|sh|redis-cli|...
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
#详细参数
Options:
-d :分离模式: 在后台运行
-i :即使没有附加也保持STDIN 打开
-t :分配一个伪终端
#退出容器内部
exit:直接退出容器并且停止容器运行
ctrl+p+q:退出容器,容器正常运行
#https://blog.tag.gg/showinfo-3-36188-0.html
#Docker容器中执行命令会报例如 bash: ping: command not found 错误,原因是容器中没安装该命令
#支持ip/ping/curl/route/ifconfig/vi/yum命令安装
#如下命令需登录容器内部执行
#bash: ip: command not found
apt-get update && apt-get install -y iproute2
#bash: yum: command not found
apt-get update && apt-get install yum
#bash: ping: command not found
apt-get update && apt install iputils-ping
#bash: ifconfig: command not found
apt-get update && apt install net-tools
#bash: vi: command not found
apt-get update && apt-get install vim
#bash: route: command not found
apt-get update && apt-get install -y iproute2 && apt-get update && apt install net-tools
#bash: netstat: command not found
apt-get update && apt install net-tools
#bash: ps: command not found
apt-get update && apt-get install procps
#bash: top: command not found
apt-get update && apt-get install procps
#启动已停止运行的容器
docker start 容器ID或者容器名
#重启容器
docker restart 容器ID或者容器名
#停止容器
docker stop 容器ID或者容器名
#强制停止容器
docker kill 容器ID或容器名
#删除容器
docker rm 容器ID
#一次性删除多个容器实例
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
监控容器最简单的方法是使用Docker自带的监控命令:docker ps、docker top、docker stats。
可以使用 docker ps
或 docker container ls
命令显示容器列表。
#命令:
docker ps [OPTIONS]
#详细参数
Options:
-a 显示所有的容器,包括未运行的。
-f 根据条件过滤显示的内容。
--format 指定返回值的模板文件。
-l 显示最近创建的容器。
-n 列出最近创建的n个容器。
--no-trunc 不截断输出。
-q 静默模式,只显示容器编号。
-s 显示总的文件大小。
#格式化选项(–-format)
.ID 容器ID
.Image 镜像ID
.Command Quoted command
.CreatedAt 创建容器的时间点.
.RunningFor 从容器创建到现在过去的时间.
.Ports 暴露的端口.
.Status 容器状态.
.Size 容器占用硬盘大小.
.Names 容器名称.
.Labels 容器所有的标签.
.Label 指定label的值 例如'{{.Label “com.docker.swarm.cpu”}}’
.Mounts 挂载到这个容器的数据卷名称
# 案例
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4fd309be3850 ubuntu "/bin/bash" 3 seconds ago Up 2 seconds busy_cray
容器的监控和日志管理 https://www.cnblogs.com/xiugeng/p/16285637.html
对运行中的容器,Docker会将日志发送到容器的 STDOUT 和STDERR 上。
可以将STDOUT 和STDERR视为容器的控制台终端。
docker logs
命令输出正在运行的容器的日志信息。默认输出自容器启动以来完整的日志。
docker logs
命令可能不会显示有用信息的两种情形:
如果使用将日志发送到文件、外部主机、数据库或另外一个后端日志系统的日志驱动,
则docker logs命令不会显示有用信息,这时可以通过其他方式处理日志。
如果镜像运行的是Web服务器或数据库等非交互式进程,那么应用程序可能会将输出发送到日志文件而不是STDOUT和STDERR中。
如果容器以后台方式运行,则也不能看到输出的日志。
#命令,docker logs 60176bb01f53 -f -t -n 20
docker logs [OPTIONS] 容器ID或容器名
# 语法
[root@localhost ~]# docker logs --help
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
Options:
--details Show extra details provided to logs # 显示更详细的日志信息
-f, --follow Follow log output # 跟踪日志输出
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m
for 42 minutes) # 显示某时间戳之后的日志或显示多少时间之内的日志
-n, --tail string Number of lines to show from the end of the logs (default "all") # 从最后一行开始显示N行
-t, --timestamps Show timestamps # 显示时间戳
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g.
42m for 42 minutes) # 显示某时间戳之前的日志或显示多少分钟之前的日志
# 案例1:访问查看日志
# 1.创建apache容器
[root@localhost ~]# docker run --rm -d -p 8080:80 --name web-http httpd
8e226c5a8c4fdcd3bcb91f716d01b2876dda98cc8bc0179021ae783ddf45196b
# 2.访问apache和查看日志
在浏览器访问:http://10.10.10.111:8080
[root@localhost ~]# docker logs web-http
...省略
10.10.10.1 - - [25/May/2022:08:23:32 +0000] "GET / HTTP/1.1" 200 45
# 3.显示更详细信息
[root@localhost ~]# docker logs --details web-http 《————对httpd容器没有区别
# 案例2:持续显示新日志
[root@localhost ~]# docker logs -f web-http
...省略
10.10.10.1 - - [25/May/2022:08:32:04 +0000] "GET / HTTP/1.1" 304 - 《————每次访问页面都会输出新日志
10.10.10.1 - - [25/May/2022:08:32:06 +0000] "GET / HTTP/1.1" 304 -
10.10.10.1 - - [25/May/2022:08:32:08 +0000] "GET / HTTP/1.1" 304 -
# 案例3:显示时间戳(对没有时间的日志非常有用)
[root@localhost ~]# docker logs -t web-http
2022-05-25T08:22:59.900685745Z AH00558: httpd: Could not reliably determine the servers f.. 《————前面都会加上时间戳
# 案例4:显示最后几行
[root@localhost ~]# docker logs -n 3 web-http
10.10.10.1 - - [25/May/2022:08:32:06 +0000] "GET / HTTP/1.1" 304 -
10.10.10.1 - - [25/May/2022:08:32:08 +0000] "GET / HTTP/1.1" 304 -
10.10.10.1 - - [25/May/2022:08:32:55 +0000] "-" 408 -
# 案例5:显示最后一分钟内的日志
[root@localhost ~]# docker logs --since 1m web-http
10.10.10.1 - - [25/May/2022:08:41:51 +0000] "GET / HTTP/1.1" 304 -
# 案例6:显示某个时间戳之后的日志
[root@localhost ~]# docker logs --since 2022-05-25T08:32:10.339156073Z web-http
10.10.10.1 - - [25/May/2022:08:32:55 +0000] "-" 408 -
10.10.10.1 - - [25/May/2022:08:41:51 +0000] "GET / HTTP/1.1" 304 -
10.10.10.1 - - [25/May/2022:08:42:42 +0000] "-" 408 -
# 案例7:显示多少分钟之前的日志
[root@localhost ~]# docker logs --until 30m web-http
...省略
10.10.10.1 - - [25/May/2022:08:23:32 +0000] "GET / HTTP/1.1" 200 45
10.10.10.1 - - [25/May/2022:08:24:23 +0000] "-" 408 -
# 案例8:显示某时间戳之前的日志
[root@localhost ~]# docker logs --until 2022-05-25T08:32:10.339156073Z web-http
...省略
10.10.10.1 - - [25/May/2022:08:31:56 +0000] "GET / HTTP/1.1" 304 -
10.10.10.1 - - [25/May/2022:08:32:04 +0000] "GET / HTTP/1.1" 304 -
docker service logs
命令显示swarm某服务/任务的所有容器的日志信息。
该命令适用于集群环境。
# 语法
[root@localhost ~]# docker service logs --help
Usage: docker service logs [OPTIONS] SERVICE|TASK
Fetch the logs of a service or task
Options:
--details Show extra details provided to logs
-f, --follow Follow log output
--no-resolve Do not map IDs to Names in output
--no-task-ids Do not include task IDs in output
--no-trunc Do not truncate output
--raw Do not neatly format logs
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m
for 42 minutes)
-n, --tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
日志驱动(Logging Driver):Docker提供的帮助用户从运行的容器中提取日志信息的机制。默认的日志驱动是 json-file
。
选项值如下:
选项值 | 说明 |
---|---|
none | 禁用容器日志,docker logs命令不会输出任何日志信息 |
json-file | Docker默认的日志驱动。该驱动将日志保存在JSON文件中,Docker负责格式化其内容并输出到STDOUT和STDERR |
syslog | 将日志信息写入syslog日志系统,syslog守护进程必须在主机上运行 |
journald | 将日志信息写入journald日志系统,journald守护进程必须在主机上运行 |
gelf | 将日志信息写入像Graylog或Logstash这样的GELF(Graylog Extended Log Format)终端 |
fluentd | 将日志信息写入fluentd,fluentd守护进程必须在主机上运行 |
splunk | 将日志信息写入使用HTTP事件搜集器的splunk |
将daemon.json
文件中的log-driver
值设为日志驱动名称。
案例1:将默认日志驱动设为syslog
[root@localhost ~]# vi /etc/docker/daemon.json
[root@localhost ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://nxwgbmaq.mirror.aliyuncs.com"],
"log-driver":"syslog"
}
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
# 查看确认日志驱动已经改了
[root@localhost ~]# docker info | grep "Logging Driver"
Logging Driver: syslog
# 开启一个新session,跟踪syslog日志输出
[root@localhost ~]# tail -f /var/log/messages
# 启动一个新的redis容器
[root@localhost ~]# docker run -tid redis
# 可以看到syslog显示redis容器相关日志
May 17 00:40:04 localhost a0e2ba47cf5f[4870]: _._
May 17 00:40:04 localhost a0e2ba47cf5f[4870]: _.-``__ ''-._
May 17 00:40:04 localhost a0e2ba47cf5f[4870]: _.-`` `. `_. ''-._ Redis 7.0.11 (00000000/0) 64 bit
May 17 00:40:04 localhost a0e2ba47cf5f[4870]: .-`` .-```. ```\/ _.,_ ''-._
May 17 00:40:04 localhost a0e2ba47cf5f[4870]: ( ' , .-` | `, ) Running in standalone mode
May 17 00:40:04 localhost a0e2ba47cf5f[4870]: |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
May 17 00:40:04 localhost a0e2ba47cf5f[4870]: | `-._ `._ / _.-' | PID: 1
log-opts
可以配置可配置选项。
案例2:日志驱动可配置选项
[root@localhost ~]# vi /etc/docker/daemon.json 《————注意:改之前将之前驱动的容器都删除
{
"registry-mirrors": ["https://nxwgbmaq.mirror.aliyuncs.com"],
"log-driver":"json-file",
"log-opts":{
"labels":"production_status",
"env":"os,customer"
}
}
# 重新加载daemon和重启docker服务
[root@localhost ~]# docker info | grep 'Logging Driver'
Logging Driver: syslog
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
# 查看守护进程的默认日志驱动是否改变:
[root@localhost ~]# docker info | grep 'Logging Driver'
Logging Driver: json-file
# 查看容器的配置选项
[root@localhost ~]# docker run -tid --name test-opt ubuntu
5d8ad65d59bca65a988ef0b5c17504601fdc82d2d14b41619e981983bc9bc76d
[root@localhost ~]# docker inspect -f='{{.HostConfig.LogConfig.Type}}--{{.HostConfig.LogConfig.Config}}' test-opt
json-file--map[env:os,customer labels:production_status]
启动容器时,可以使用--log-driver
选项来配置日志驱动,可以使用--log-opt
设置可配置选项(可以以键值对的方式配置多个)。
注意:同一个值配两次,最后一个生效。
[root@localhost ~]# docker run --help
--log-driver string Logging driver for the
container # 配置容器的日志驱动
--log-opt list Log driver options # 配置容器的日志驱动可配置选项
# 案例1:配驱动和查看
[root@localhost ~]# docker run --rm -d --log-driver none --name redis redis
cf2d244c250a8b9d457e4f601cd359c73dc9d530788890b6ffd74406293c94f0
[root@localhost ~]# docker inspect -f='{{.HostConfig.LogConfig.Type}}' redis
none
# 案例2:配驱动和可配置选项
[root@localhost ~]# docker run --rm -d --log-driver syslog --log-opt env=os,customer --log-opt labels='test' --name redis02 redis
8cd319bde772774fa00950efa80608ea05823023799554a5e45248c768a3ce29
[root@localhost ~]# docker inspect -f='{{.HostConfig.LogConfig.Type}}-{{.HostConfig.LogConfig.Config}}' redis02
syslog-map[env:os,customer labels:test]
容器的日志文件会占用大量的空间,经常需要进行清理。如果直接删除 /var/lib/docker/containers/<容器id>
目录下的日志文件,并不会释放磁盘空间,因为日志文件是被打开的。
#!/bin/sh
logs=$(find /var/lib/docker/containers/ -name *-json.log)
for log in $logs
do
echo "clean logs : $log"
cat /dev/null > $log
done
在daemon.json配置文件中通过log-opts选项来限制日志大小的上限
#设置容器日志大小上限是500M,容器最多有两个日志文件。
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://nxwgbmaq.mirror.aliyuncs.com"],
"log-driver":"json-file",
"log-opts": {"max-size":"500m", "max-file":"2"}
}
运行在Linux操作系统的Docker主机上可以通过配置日志驱动将容器的日志重定向到Linux日志系统。
syslog
是Linux标配的日志记录工具,主要用来收集系统产生的各种日志,日志文件默认放在/var/log目录下。
选择syslog作为日志驱动可将日志定向输出到syslog日志系统中,条件是:syslog守护进程必须在主机上运行。
# 打开或复制一个终端窗口,使用tail工具实时监控系统日志文件/var/log/messages。
[root@host1 ~]# tail -f /var/log/messages
# 打开另一个终端窗口,创建容器,将该容器的日志记录到syslog日志文件。
[root@localhost containers]# docker run --rm -d --log-driver syslog --name redis03 redis
2d7cba9c0c6466c0ecb18e4bfd156710148c8205b299e05f3eed987f873f8b8e
# 观察/var/log/messages输出:
May 26 03:01:06 localhost dockerd: time="2022-05-26T03:01:06.231489908+08:00" level=info msg="Configured log driver does not support reads, enabling local file cache for container logs" container=2d7cba9c0c6466c0ecb18e4bfd156710148c8205b299e05f3eed987f873f8b8e driver=syslog
journald
是一个收集并存储日志数据的 systemd 日志系统服务,可以使用 journalctl
命令查看它。
选择journald作为日志驱动可将日志定向输出到systemd日志系统中。
# 创建容器
[root@localhost ~]# docker run --rm -d --log-driver journald --name ubuntu01 ubuntu
cdd3963ab27eac51e8a7d5fc43f92e0f9fb921705e235af822b41bf555a80e23
# 查看systemd日志系统
[root@localhost containers]# journalctl
# 进入日志系统后,输入大写"GG",翻到日志的最后一页
May 26 03:36:10 localhost.localdomain dockerd[3090]: time="2022-05-26T03:36:10.292765481+08:00" level=info msg="ignoring event" container=cdd3963ab27eac51e8a7d5fc43f92e0f9fb921705e235af822b
May 26 03:36:10 localhost.localdomain containerd[876]: time="2022-05-26T03:36:10.293637172+08:00" level=info msg="shim disconnected" id=cdd3963ab27eac51e8a7d5fc43f92e0f9fb921705e235af822b41
May 26 03:36:10 localhost.localdomain containerd[876]: time="2022-05-26T03:36:10.293708026+08:00" level=warning msg="cleaning up after shim disconnected" id=cdd3963ab27eac51e8a7d5fc43f92e0f
May 26 03:36:10 localhost.localdomain containerd[876]: time="2022-05-26T03:36:10.293715955+08:00" level=info msg="cleaning up dead shim"
May 26 03:36:10 localhost.localdomain containerd[876]: time="2022-05-26T03:36:10.302648699+08:00" level=warning msg="cleanup warnings time=\"2022-05-26T03:36:10+08:00\" level=info msg=\"sta
Logspout
是一个 Docker 容器,大小仅 14MB,使用 BusyBox 作为其核心,它可以将来自容器应用程序的日志发送到某一个中央位置,比如单一 JSON 对象或者通过 HTTP API 可获得的流式端点。
-t 选项容器会以前台方式运行。
-e 选项可以设置容器环境变量。可以用来排除对某个容器日志路由:`-e "LOGSPOUT=ignore"
案例:将所有日志转发给远程的syslog服务器,这里将本地服务器作为远程syslog服务器。
# 1.修改centos7的日志服务器rsyslog配置文件
[root@localhost ~]# vi /etc/rsyslog.conf
# 找到以下内容(15\16行)去除行首的‘#’
$ModLoad imudp
$UDPServerRun 514
# 改完后,就允许rsyslog服务在UDP的514端口接收日志信息了。
# 2.重启rsyslog,检查514端口是否开启
[root@localhost ~]# systemctl restart rsyslog
# 安装网络工具
[root@localhost ~]# yum install -y net-tools
# 检查514端口
[root@localhost ~]# netstat -antup | grep 514
tcp 0 0 192.168.100.111:22 192.168.100.1:55959 ESTABLISHED 1514/sshd: root@pts
udp 0 0 0.0.0.0:514 0.0.0.0:* 4172/rsyslogd
udp6 0 0 :::514 :::* 4172/rsyslogd
# 3.启动logspout容器,将日志转发到docker主机的syslog服务中
# 下载logspout镜像
[root@localhost ~]# docker pull gliderlabs/logspout
Using default tag: latest
latest: Pulling from gliderlabs/logspout
8572bc8fb8a3: Pull complete
Digest: sha256:2d81c026e11ac67f7887029dbfd7d36ee986d946066b45c1dabd966278eb5681
Status: Downloaded newer image for gliderlabs/logspout:latest
docker.io/gliderlabs/logspout:latest
# 拉起容器
# 注意:logspout需要访问docker守护进程来获取日志,因此需要把UNIX sockets挂载到容器内。
[root@localhost ~]# docker run --name="logspout" --volume=/var/run/docker.sock:/var/run/docker.sock gliderlabs/logspout syslog+udp://192.168.100.111:514
2022/05/25 20:03:20 # logspout v3.2.14 by gliderlabs
2022/05/25 20:03:20 # adapters: tls udp multiline raw syslog tcp
2022/05/25 20:03:20 # options :
2022/05/25 20:03:20 persist:/mnt/routes
2022/05/25 20:03:20 # jobs : http[routes,health,logs]:80 pump routes
2022/05/25 20:03:20 # routes :
# ADAPTER ADDRESS CONTAINERS SOURCES OPTIONS
# syslog+udp 192.168.100.111:514 map[]
# 4.监控和验证
# 打开syslog日志监控
[root@localhost containers]# tail -f /var/log/messages
# 启动一个新容器
[root@localhost ~]# docker run --rm -d --name redis10 redis
8113851c267c18a5cfe51cde0ad923c8abb5b949aec34df528ba3db3b61a90ed
# 查看到新刷出的日志信息
May 26 04:06:43 localhost containerd: time="2022-05-26T04:06:43.783205236+08:00" level=info msg="starting signal loop" namespace=moby path=/run/containerd/io.containerd.runtime.v2.task/moby/8113851c267c18a5cfe51cde0ad923c8abb5b949aec34df528ba3db3b61a90ed pid=4728
使用 Logspout
的HTTP流模块,可以实时查看由它聚合的本地日志,而不用提供日志路由的URI。
# 1.使用Logspout的HTTP流模块,实时查看由它聚合的本地日志
[root@localhost ~]# docker run -d --name="logspout02" --volume=/var/run/docker.sock:/var/run/docker.sock \
> --publish=127.0.0.1:8000:80 gliderlabs/logspout
5571173f20bfb08f7935cb0e819d34580753a22b3963d1573f26c8df7ad75900
# 2.使用curl观察容器的日志流。
[root@localhost ~]# curl http://127.0.0.1:8000/logs
# 3.打开另一个终端窗口,启动redis容器
[root@localhost ~]# docker run --rm -d --name redis06 redis
7cd8769551266de5955147e409dd48ed9d6df6c41a6d33a9326beed0924a030f
# 4.切回日志流的终端窗口,会发现关于redis容器启动的日志流。
redis06|1:C 26 May 2022 20:09:47.862 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis06|1:C 26 May 2022 20:09:47.862 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
...略
容器的监控和日志管理 https://www.cnblogs.com/xiugeng/p/16285637.html
查看容器中正在运行的进程。
docker top 容器ID
# 语法
[root@localhost ~]# docker top --help
Usage: docker top CONTAINER [ps OPTIONS]
Display the running processes of a container
# 案例
# 查看已有的容器的进程
[root@localhost ~]# docker top busy_cray 《————注意替换为自己的容器
UID PID PPID C STIME TTY TIME CMD
root 1467 1448 0 01:33 pts/0 00:00:00 /bin/bash
[root@localhost ~]# docker run -tid --name redis-test redis
3a0d4ca05b5c3ab4b65beb333264b504247c6dd4cedee323a7ecdb41c518f6bc
[root@localhost ~]#
[root@localhost ~]# docker top redis-test
UID PID PPID C STIME TTY TIME CMD
polkitd 1655 1636 0 01:34 pts/0 00:00:00 redis-server *:6379
# 案例:跟参数的情况
[root@localhost ~]# docker top redis-test -e
PID TTY TIME CMD
1655 pts/0 00:00:03 redis-server
[root@localhost ~]# docker top redis-test -f
UID PID PPID C STIME TTY TIME CMD
polkitd 1655 1636 0 01:34 pts/0 00:00:03 redis-server *:6379
[root@localhost ~]# docker top redis-test -ef
UID PID PPID C STIME TTY TIME CMD
polkitd 1655 1636 0 01:34 pts/0 00:00:00 redis-server *:6379
[root@localhost ~]# docker top redis-test aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
polkitd 1655 0.1 0.4 52812 9880 pts/0 Ssl+ 01:34 0:00 redis-server *:6379
# 案例:查看所有正在运行的容器中的进程信息
[root@localhost ~]# for i in `docker ps | grep Up|awk '{print $1}'`;do echo \ &&docker top $i;done
UID PID PPID C STIME TTY TIME CMD
polkitd 1655 1636 0 01:34 pts/0 00:00:00 redis-server *:6379
UID PID PPID C STIME TTY TIME CMD
root 1467 1448 0 01:33 pts/0 00:00:00 /bin/bash
UID PID PPID C STIME TTY TIME CMD
root 1521 1503 0 01:33 pts/0 00:00:00 /bin/bash
UID PID PPID C STIME TTY TIME CMD
root 1575 1556 0 01:33 pts/0 00:00:00 /bin/bash
docker stats
实时查看用 docker stats
命令实时查看容器的系统资源使用情况。
# 语法
[root@localhost ~]# docker stats --help
Usage: docker stats [OPTIONS] [CONTAINER...]
Display a live stream of container(s) resource usage statistics
Options:
-a, --all Show all containers (default shows just running) # 显示所有的容器(默认只显示运行中的容器)
--format string Pretty-print images using a Go template # 根据指定格式显示内容
--no-stream Disable streaming stats and only pull the first result # 只显示第一条记录
--no-trunc Do not truncate output # 不截断输出,显示出完整的信息(id)
# 案例1:默认查看————连续刷新输出
[root@localhost ~]# docker run -tid --name test1 -m 300M ubuntu /bin/bash
a63b5add08d9039c0347ddd16a64098ce43e1f917463ee2215f6974031772e2b
[root@localhost ~]# docker stats
容器ID 容器名称 CPU使用百分比 使用内存/最大可用内存 内存使用百分比 网络I/O 磁盘I/O 进程ID
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a63b5add08d9 test1 0.00% 536KiB / 300MiB 0.17% 648B / 0B 0B / 0B 1
3a0d4ca05b5c redis-test 0.10% 7.695MiB / 1.936GiB 0.39% 648B / 0B 39.4MB / 0B 5
4fd309be3850 busy_cray 0.00% 1.59MiB / 300MiB 0.53% 1.09kB / 0B 8.16MB / 0B 1
53c7acadfb91 quizzical_clarke 0.00% 544KiB / 300MiB 0.18% 996B / 0B 0B / 0B 1
687d85c07aaf xenodochial_swanson 0.00% 552KiB / 1.936GiB 0.03% 996B / 0B 0B / 0B 1
# 案例2:只输出当前状态(仅一条)
[root@localhost ~]# docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
6a5891ff7c91 distracted_galois 0.00% 540KiB / 300MiB 0.18% 648B / 0B 0B / 0B 1
ca8e91bf5a35 test 0.00% 1.586MiB / 1.936GiB 0.08% 1.09kB / 0B 8.13MB / 0B 1
# 指定某个容器且只输出一次
[root@localhost ~]# docker stats --no-stream test1
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a63b5add08d9 test1 0.00% 536KiB / 300MiB 0.17% 648B / 0B 0B / 0B 1
# 案例3:只输出一次,且输出所有容器(包含停止)的状态
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4393de823c60 ubuntu "bash" 36 seconds ago Exited (0) 36 seconds ago happy_leakey
df240f1a0d45 ubuntu "bash" 37 seconds ago Exited (0) 37 seconds ago interesting_poitras
2570e260027e ubuntu "bash" 47 seconds ago Exited (0) 46 seconds ago adasdsad
...略
[root@localhost ~]# docker stats --no-stream -a
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
4393de823c60 happy_leakey 0.00% 0B / 0B 0.00% 0B / 0B 0B / 0B 0
df240f1a0d45 interesting_poitras 0.00% 0B / 0B 0.00% 0B / 0B 0B / 0B 0
2570e260027e adasdsad 0.00% 0B / 0B 0.00% 0B / 0B 0B / 0B 0
a63b5add08d9 test1 0.00% 536KiB / 300MiB 0.17% 648B / 0B 0B / 0B 1
3a0d4ca05b5c redis-test 0.08% 7.695MiB / 1.936GiB 0.39% 648B / 0B 39.4MB / 0B 5
4fd309be3850 busy_cray 0.00% 1.91MiB / 300MiB 0.64% 1.09kB / 0B 8.16MB / 0B 1
53c7acadfb91 quizzical_clarke 0.00% 544KiB / 300MiB 0.18% 996B / 0B 0B / 0B 1
687d85c07aaf xenodochial_swanson 0.00% 552KiB / 1.936GiB 0.03% 996B / 0B 0B / 0B 1
# 案例4:查看某个容器内存限制
[root@localhost ~]# docker stats test1
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a63b5add08d9 test1 0.00% 536KiB / 300MiB 0.17% 648B / 0B 0B / 0B 1
# 案例5:自定义输出的内容和格式
[root@localhost ~]# docker stats --no-stream --format "{{.ID}}"
6a5891ff7c91
ca8e91bf5a35
[root@localhost ~]# docker stats --no-stream --format "{{.Name}}" test1
test1
[root@localhost ~]# docker stats --no-stream --format "{{json .Name}}" test1
"test1"
[root@localhost ~]# docker stats --no-stream --format "{{json .Name}}-{{.CPUPerc}}-{{.MemUsage}}" test1
"test1"-0.00%-536KiB / 300MiB
[root@localhost ~]# docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" test1
NAME CPU % MEM USAGE / LIMIT
test1 0.00% 536KiB / 300MiB
[root@localhost ~]# docker stats --no-stream --format "table {{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDs}}" myweb
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
463b15216693 myweb 0.00% 11.57MiB / 1.936GiB 0.58% 2.84kB / 1.5kB 11.9MB / 0B 109
[root@localhost ~]# docker stats --no-stream --format "{{.ID}}-{{.Name}}-{{.CPUPerc}}-{{.MemUsage}}-{{.MemPerc}}-{{.NetIO}}-{{.BlockIO}}-{{.PIDs}}" myweb
463b15216693-myweb-0.00%-11.57MiB / 1.936GiB-0.58%-2.84kB / 1.5kB-11.9MB / 0B-109
用于分析正在运行的容器的资源占用情况和性能指标,是具有图形界面、最易于入门的Docker容器监控工具。
cAdvisor以守护进程方式运行,负责收集、聚合、处理、输出运行中容器的数据,可以监控资源隔离参数、历史资源使用情况和网络统计数据。
cAdvisor优势:可以将监控数据导出给第三方工具;
劣势:只能监控一个主机,数据展示功能有限。
# 使用cAdvisor案例
# 1.启动容器用于测试
[root@localhost ~]# docker run --rm -d --name redis redis
b1435f629a764712cf235b63a498e6b5cd58c44e8384146467e79f43233c4652
[root@localhost ~]# docker run --rm -d --name myweb -p 80:80 httpd
dfe1728c9576d72ef2d3652bc0b319e977ff63c8064f8f5aa35ff79b141ff32d
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dfe1728c9576 httpd "httpd-foreground" 5 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp myweb
b1435f629a76 redis "docker-entrypoint.s…" 30 seconds ago Up 29 seconds 6379/tcp redis
# 2.创建启动cAdvisor容器
# 拉取镜像
[root@localhost ~]# docker pull google/cadvisor
Using default tag: latest
latest: Pulling from google/cadvisor
ff3a5c916c92: Pull complete
44a45bb65cdf: Pull complete
0bbe1a2fe2a6: Pull complete
Digest: sha256:815386ebbe9a3490f38785ab11bda34ec8dacf4634af77b8912832d4f85dca04
Status: Downloaded newer image for google/cadvisor:latest
docker.io/google/cadvisor:latest
# 启动容器:
# 4个volume定义的绑定挂载都不能缺,否则无法连接docker守护进程
# centos/redhat主机的容器,必须加上--privileged选项,才能真正拥有root权限,检测主机上的设备
[root@localhost ~]# docker run --privileged \
> --volume /:/rootfs:ro --volume /var/run:/var/run:rw \
> --volume /sys:/sys:ro --volume /var/lib/docker/:/var/lib/docker:ro \
> --publish 8080:8080 --detach --name cadvisor google/cadvisor:latest
7ecef0c00cb922d9686db11234325a00609bf38bde3c9b26f3529245f0eb59af
# 3.访问 cAdvisor监控服务
# 再创建一个限制资源的容器
[root@localhost ~]# docker run -m 300M --memory-swap 500M --memory-reservation 200M -c 512 -tid ubuntu
d2eb61efefcf30687a4e70a43793866ffccb7d286e1f2f1ba144a43e91928a8f
#访问网址:http://[主机IP]:8080
#案例访问:http://192.168.100.111:8080/containers/
#cAdvisor提供配置:
--storage_duration:历史数据保存的时间,默认为2min,即只保存最近2min的数据。
--allow_dynamic_housekeeping:控制cAdvisor如何和何时执行周期性的容器状态收集工作。
--global_housekeeping_interval:设置检测是否有新容器的时间周期。
--housekeeping_interval:统计每个容器数据的时间周期,默认每1s取一次数据,选取统计到的最近的60个数据。
#cAdvisor将数据直接导出到本地文件:
[root@localhost ~]# docker run --volume /:/rootfs:ro \
--volume /var/run:/var/run:rw --volume /sys:/sys:ro \
--volume /var/lib/docker/:/var/lib/docker:ro \
--publish 8080:8080 --name cadvisor-stdout \
google/cadvisor:latest --storage_driver stdout >> data
[root@localhost ~]# du -sh *
4.0K anaconda-ks.cfg
104K data
[root@localhost ~]# cat data
开源的故障诊断与监控工具,除了用于Docker外,还可以用于Kubernetes集群。
Weave Scope会自动生成容器之间的关系图,便于管理员直观地以可视化的方式监控容器化和微服务化的应用。
Weave Scope能够进行跨主机监控,并且消耗的资源非常少。
Weave Scope主要功能:
前提是安装并运行Docker,此软件以容器方式运行。
# 1.下载二进制安装脚本
curl -L git.io/scope -o /usr/local/bin/scope
# 2.赋予脚本可执行权限
chmod a+x /usr/local/bin/scope
# 3.执行命令下载镜像并启动容器
[root@localhost ~]# scope launch
Unable to find image 'weaveworks/scope:1.13.2' locally
1.13.2: Pulling from weaveworks/scope
ba3557a56b15: Pull complete
dd0e726a9a15: Pull complete
05cb5f9d0d32: Pull complete
e956cf3e716a: Pull complete
Digest: sha256:8591bb11d72f784f784ac8414660759d40b7c0d8819011660c1cc94271480a83
Status: Downloaded newer image for weaveworks/scope:1.13.2
6ac75f19cb9cb7d72036d88de376c0f367acfb16cfb4f1e130f86fa875a1ee04
Scope probe started
Weave Scope is listening at the following URL(s):
* http://192.168.100.111:4040/
#以 json 格式得到 docker 镜像/容器的元数据
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
#详细参数
Options:
--format 指定输出格式,可以使用 Go 模板语言自定义输出格式;
--type 指定要查看的 Docker 对象类型,包括 container、image、network、volume;
--size 显示 Docker 对象的磁盘使用情况;
-v , --verbose 显示更详细的信息
#从容器复制文件到宿主机
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
#从宿主机复制文件到容器
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
docker copy /web/redis-6.2-rc2/redis.conf 92323cd4d868:/etc/redis/redis.conf
#SRC_PATH 指定一个文件
#若 DEST_PATH 不存在
#创建 DEST_PATH 所需的文件夹,文件正常保存到 DEST_PATH 中
#若 DEST_PATH 不存在,并以 / 结尾
#错误:目标目录必须存在
#若 DEST_PATH 存在并且是一个文件
#目标被源文件的内容覆盖
#若 DEST_PATH 存在并且是目录
#使用 SRC_PATH 中的基本名称将文件复制到此目录中
#SRC_PATH指定目录
#若 DEST_PATH 不存在
#将 DEST_PATH 创建为目录,并将源目录的内容复制到该目录中
#若 DEST_PATH存在并且是一个文件
#错误:无法将目录复制到文件
#若 DEST_PATH存在并且是目录
#SRC_PATH 不以 /. 结尾,源目录复制到此目录
#SRC_PATH 以 /. 结尾,源目录的内容被复制到该目录中
docker镜像:https://www.cnblogs.com/xiugeng/p/15980752.html
是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。分层的镜像
以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理:
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M??
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
为什么 Docker 镜像要采用这种分层结构呢?
镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。
比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
重点理解
Docker镜像层都是只读的,容器层是可写的 当容器启动时,一个新的可写层被加载到镜像的顶部。 这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
docker commit提交容器副本使之成为一个新的镜像
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
#容器的导出
docker export CONTAINER_ID > containerName.tar
docker export b48f679497e4 > rabbitMQ.tar
# 容器的导入
cat fileName.tar | docker import - MIRROR_USER/MIRROR_NAME:MIRROR_VERSION
docker export 容器ID/容器Name > xxx.tar 导出一个容器快照
docker import xxx.tar NewImageName:tag 导入一个容器快照到本地镜像库
适用场景:主要用来制作基础镜像,比如从一个ubuntu镜像启动一个容器,然后安装一些软件和进行一些设置后,使用docker export保存为一个基础镜像。然后把这个镜像分发给其他人使用,作为基础的开发环境。(因为export导出的镜像只会保留从镜像运行到export之间对文件系统的修改,所以只适合做基础镜像)
注意事项:
①会丢弃历史记录和元数据。
②启动export与import命令导出导入的镜像必须加/bin/bash或者其他/bin/sh,否则会报错。
③docker export 导出的镜像是不带历史记录的,如果原本的镜像有3层,export 之后只会有1层,这一层为从镜像运行到export之间对文件系统的修改。
④可以使用docker history ImageName/ImageID 查看镜像,只有一层(待测试)。
docker commit 容器ID/容器Name 生成新的镜像名字
选项说明:
-a:提交的镜像作者
-c:使用dockerfile指令来创建镜像
-m:提交时的说明文字
-p:在commit的时候,将正在运行的容器暂停
适用场景:主要作用是将配置好的一些容器复用,再生成新的镜像。
注意事项:
commit是合并了save、load、export、import这几个特性的一个综合性的命令,它主要做了:
将container当前的读写层保存下来,保存成一个新层
和镜像的历史层一起合并成一个新的镜像
如果原本的镜像有3层,commit之后就会有4层,最新的一层为从镜像运行到commit之间对文件系统的修改。
docker save -o xxx.tar 镜像名 将指定镜像导出。
docker load -i xxx.tar 导入镜像到本地镜像库
适用场景:生产环境没有外网,在本机将镜像打包成tar。拷贝到生产环境,再通过docker push到生产环境本地镜像仓库。
区别:
docker save 保存的是镜像(image)
docker export 保存的是容器(container)
docker load /docker import 载入的时候,两者都会恢复为镜像。
docker load 无法对镜像重命名,docker import 可以对镜像指定新名称。
docker export 比 docker save的包要小,原因是save的是一个分层的文件系统,export导出的只是一层文件系统。
docker commit保存镜像文件系统的历史层,docker export保存从镜像运行到export之间对文件系统的修改的最新一层。
docker commit -m="" -a="作者" 容器ID 要创建的目标镜像
docker login --username=阿里云账号 registry.cn-hangzhou.aliyuncs.com
docker pull registry.cn-hangzhou.aliyuncs.com/compasss/compass-registry:3.9
docker login --username=crazy2732195202 registry.cn-hangzhou.aliyuncs.com
docker tag 108b9ad78dcd registry.cn-hangzhou.aliyuncs.com/compasss/compass-registry:3.9
docker push registry.cn-hangzhou.aliyuncs.com/compasss/compass-registry:3.9
Docker注册中心:https://www.cnblogs.com/xiugeng/p/16043012.html
### 8.1.下载 registry
docker pull registry
### 8.2.启动
docker run -d --name reg -p 5000:5000 registry
### 8.3.推送到私服
docker tag redis:6.0 192.168.22.162:5000/edis:6.0
docker push 192.168.22.162:5000/edis:6.0
### 8.4.pull到本地
docker pull 192.168.22.162:5000/edis:6.0
Docker存储管理:https://www.cnblogs.com/xiugeng/p/16194410.html
Docker挂载主机目录访问如果出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个–privileged=true参数即可
如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,
在SELinux里面挂载目录被禁止掉了额,如果要开启,我们一般使用–privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
docker run -it --privileged=true -v /host_dir:/container_dir IMAGR_NAME
特点:
1:数据卷可在容器之间共享或重用数据
2:卷中的更改可以直接实时生效
3:数据卷中的更改不会包含在镜像的更新中
4:数据卷的生命周期一直持续到没有容器使用它为止
5:即使docker停止了,重新启动,也会从主机上把文件同步过来
docker run -it --privileged=true -v /host_dir:/container_dir:ro IMAGR_NAME
#容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。
docker run -it --privileged=true -v /host_dir:/container_dir --volumes-from CONTIANER_NAME IMAGR_NAME
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段:
Dockerfile是软件的原材料
Docker镜像是软件的交付品
Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
# user defined centos7
# 定义当前镜像基于centos
FROM centos
# 定义作者的名字和邮箱
MAINTAINER compass<[email protected]>
# 用来在构建镜像过程中设置环境变量
ENV MYPATH /usr/local
# 指定在创建容器后,终端默认登陆的进来工作目录
WORKDIR $MYPATH
# 容器构建时需要运行的命令
RUN yum -y install vim
RUN yum -y install net-tools
# 对外开放的端口号
EXPOSE 80
# 指定一个容器启动时要运行的命令
CMD echo $MYPATH
CMD echo "my defined centos7 build success"
CMD /bin/bash
指定当前镜像是基于那个镜像进行构建
# 例如基于centos镜进行构建
FROM centos:7
标识镜像的维护作者和邮箱
# 例如
MAINTAINER compass<[email protected]>
指定主机和容器之间数据同步的目录
#格式:
VOLUME ["/path/to/dir"]
#示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache", "/etc/apache"]
当前容器对外暴露的端口号
EXPOSE 3060
容器构建完毕后,使用终端进入容器的默认路径
WORKDIR /usr/local/bin/software
指定用于以什么样的角色去执行,如果不指定,默认是root
USER root
容器构建过程中设置的环境变量
#定义环境变量
ENV CLASS_PATH /usr/local/jdk/bin
#别的地方引用环境变量
WORKDIR $CLASS_PATH
将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
将宿主机目录下的文件拷贝到镜像里面 (会自动解压 tar 压缩包),src 可以是一个本地文件或者是一个本地压缩文件,压缩文件会自动解压。还可以是一个 url,如果把 src 写成一个 url,那么 ADD 就类似于 wget 命令,然后自动下载和解压。
#格式:
ADD <src>... <dest>
ADD ["" ,... "" ] # 用于支持包含空格的路径
#示例:
ADD hom* /mydir/ # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
COPY ["src", "dest"]
容器构建时需要执行的shell指令
#例如容器构建时安装vim编辑器 [shell格式]
RUN yum install vim
#例如容器构建时安装vim编辑器 [CMD格式]
RUN ['可执行文件','参数1','参数n']
RUN ['./statat.sh','-p','3306']
指定容器启动后的要干的事情
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
#CMD 指令:类似于 RUN 指令,用于运行程序,但二者运行的时间点不同;CMD 在docker run 时运行,而非docker build;
#CMD 指令的首要目的在于为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束;
#注意: CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
#语法格式:
CMD <command> 或
CMD ["" ,"" ,"" ,...]
CMD ["" ,"" ,...] #该写法是为 ENTRYPOINT 指令指定的程序提供默认参数;
容器启动后需要执行的指令,不会被覆盖
#NTRYPOINT 指令:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序;
#但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序;
#语法格式:
ENTRYPOINT <command> 或
ENTRYPOINT ["" ,"" ,"" ,...]
当该镜像被用于构建其他基础镜像的时候需要触发的操作
#格式:
ONBUILD [INSTRUCTION]
#示例:
ONBUILD ADD . /app/src
为镜像添加标签
#说明:LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖
LABEL <key>=<value> <key>=<value> <key>=<value> ...
#例如 \ 表示换行
LABEL multi.label1="value1" \
multi.label2="value2" \
指定构建参数
#设置变量命令,ARG命令定义了一个变量,在docker build创建镜像的时候,使用 --build-arg = 来指定参数
#如果用户在build镜像时指定了一个参数没有定义在Dockerfile种,那么将有一个Warning
ARG username # 声明变量
ARG buildVersion=1 #给变量赋默认值
当容器停止时给系统发送什么样的指令,默认是15
STOPSIGNAL signal
Docker构建镜像:https://www.cnblogs.com/xiugeng/p/16074850.html
#语法:
docker build [OPTIONS] PATH | URL | -
#OPTIONS说明:
--build-arg=[] :设置镜像创建时的变量;
--cpu-shares :设置 cpu 使用权重;
--cpu-period :限制 CPU CFS周期;
--cpu-quota :限制 CPU CFS配额;
--cpuset-cpus :指定使用的CPU id;
--cpuset-mems :指定使用的内存 id;
--disable-content-trust :忽略校验,默认开启;
-f :指定要使用的Dockerfile路径;
--force-rm :设置镜像过程中删除中间容器;
--isolation :使用容器隔离技术;
--label=[] :设置镜像使用的元数据;
-m :设置内存最大值;
--memory-swap :设置Swap的最大值为内存+swap,"-1"表示不限swap;
--no-cache :创建镜像的过程不使用缓存;
--pull :尝试去更新镜像的新版本;
--quiet, -q :安静模式,成功后只输出镜像 ID;
--rm :设置镜像成功后删除中间容器;
--shm-size :设置/dev/shm的大小,默认值是64M;
--ulimit :Ulimit配置。
--squash :将 Dockerfile 中所有的操作压缩为一层。
--tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
--network: 默认 default。在构建期间设置RUN指令的网络模式
# 基础镜像
FROM centos:7
#作者信息
MAINTAINER compass<[email protected]>
# bash进入终端时的默认路径
WORKDIR /
# 下载工具包
RUN yum install -y yum-utils
# 安装vim
RUN yum install -y vim
# 下载网络工具包
RUN yum install -y net-tools
#创建目录
RUN mkdir -p /soft/java
# 将外部的jdk解压到指定路径 指定 -C解压到指定路径,不然解压后不知道存放到哪儿去了
COPY ["jdk-11.0.8_linux-x64_bin.tar.gz", "/soft/java/"]
RUN tar -zxvf /soft/java/jdk-11.0.8_linux-x64_bin.tar.gz -C /soft/java
# 配置环境变量
ENV JAVA_HOME=/soft/java/jdk-11.0.8
ENV JRE_HOME=${JAVA_HOME}/jre
ENV CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH=${JAVA_HOME}/bin:$PATH
# 暴露端口
EXPOSE 8080
# 执行构建成功的命令
CMD echo "build success"
# 进入到bash终端
CMD /bin/bash
镜像构建,注意最后的.
符号
# 文件名必须是叫 DockerFile ,在Dockerfile路径下准备好jdk,并且需要确认解压后的名称和Dockerfile中的名称一致
docker build -t centos-java:11 .
Docker网络:https://www.cnblogs.com/xiugeng/p/16135849.html
docker启动后,网络情况会产生一个名为docker0的虚拟网桥
[root@server100 ~]# docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
Run 'docker network [COMMAND] --help' for more information on a command.
#1.查看docker网络模式命令
docker network ls
#2.查看网络数据源
docker network inspect [NETWORT_NAME]
#3.删除网络
docker network rm [NETWORT_NAME]
#4.创建一个网络
docker network create [NETWORT_NAME]
#5.将正在运行的容器连接到网络
docker network connect [NETWORT_NAME] CONTATINER_NAME
#6.指定容器的ip地址
docker network connect --ip 10.10.10.10 网络名 容器
#7.启动容器时需要连接的网络
docker run -itd --network=网络名 即将启动的容器
#8.删除没有使用的网络
docker network prune
#9.强制停止容器的网络
docker network disconnect 网络名 容器
为每一个容器分配、设置IP等,并将容器连接到docker0的虚拟网桥。若没有特别申明,则为默认自带一个IP以及网络设置。(一人一个)
--network bridge
#没有进行特殊申明的话默认为docker0
容器不会虚拟出自己的网卡、IP等,而是使用宿主机的IP和端口。(多人一个)
--network host
容器有自己独立的Network namespace,但是没有进行任何的相关配置。(有,但是空的)
--network none
新创建的容器不会创建自己的网卡,没有自己的IP,也不会进行相应的配置。而是和一个指定的容器共享IP端口范围等。(自己没有,用别人的)
--network container:[容器名或容器ID]
自定义网络新建时默认依旧是bridge模式,连接到这个自定义网络的容器可以使用服务名称进行通信
#创建一个网络
docker network create van_network
#让容器使用自定义网络
docker run -d -p 8081:8080 --network van_network --name tomcat81 billygoo/tomcat8-jdk8
Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器
Docker-Compose是Docker官方的开源项目, 负责实现对Docker容器集群的快速编排。
docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题?
如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具
例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等
Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。
下载地址:https://docs.docker.com/compose/install/
官网:https://docs.docker.com/compose/compose-file/compose-file-v3/
二进制下载地址:https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64
#docker-compose离线下载:
https://github.com/docker/compose/releases
#docker compose的v1\v2版本安装及使用上的区别
https://github.com/docker/compose/releases?page=5
https://blog.csdn.net/hanxiaotongtong/article/details/125477514
#安装docker-compose。使用下面的命令行直接将二进制文件存储到/usr/local/bin目录,并重命名为docker-compose:
curl -L https://github.com/docker/compose/releases/download/1.26.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#换一种下载方式
wget https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m) -O /usr/local/bin/docker-compose
#对二进制文件应用可执行权限
chmod +x /usr/local/bin/docker-compose
#创建连接放入/usr/bin,因为/usr/bin在PATH目录下可以不用绝对路径直接访问
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
#查询docker-compose版本信息:
docker-compose version
#完成!
#如果报错:
bash: line 37: docker-compose: command not found
#原因: jenkins用户执行命令式,会从/usr/bin里找命令。
#解决办法:建立软连接:
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
#####################################################
#docker-compose命令:https://blog.csdn.net/t_200609/article/details/130634600
#docker-compose up/down 和 restart 的区别:https://blog.csdn.net/weixin_40734030/article/details/113500085
问题的引出:工作中修改了yaml文件,执行restart命令,发现服务没有实现重启,遂去网上学习了一下,发现先down再up,和直接restart效果不一样。
区别体现:
只要xxx.yaml文件(默认是docker-compose.yaml文件)有任何修改,一定要执行docker-compose up才会生效,执行docker-compose restart是不会生效的;
如果是code发生变化,执行docker-compose restart是有效的。
#卸载docker-compse
rm -f /usr/local/bin/docker-compose
#查看帮助
docker compose -h
#启动所有docker-compose服务
docker compose up
#启动所有docker-compose服务并后台运行
docker compose up -d
#停止并删除容器、网络、卷、镜像。
docker compose down
#进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
docker compose exec yml里面的服务id
#展示当前docker-compose编排过的运行的所有容器
docker compose ps
#展示当前docker-compose编排过的容器进程
docker compose top
#查看容器输出日志
docker compose logs yml里面的服务id
#检查配置
docker compose config
#检查配置,有问题才有输出
docker compose config -q
#重启服务
docker compose restart
#启动服务
docker compose start
#停止服务
docker compose stop
version: "3"
services:
microService:
image: order_service:1.6
container_name: ms01
ports:
- "6001:6001"
volumes:
- /app/microService:/data
networks:
- docker_compose_net
depends_on:
- redis
- mysql
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- docker_compose_net
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'db2021'
MYSQL_USER: 'root'
MYSQL_PASSWORD: 'root'
ports:
- "3306:3306"
volumes:
- /app/mysql/db:/var/lib/mysql
- /app/mysql/conf/my.cnf:/etc/my.cnf
- /app/mysql/init:/docker-entrypoint-initdb.d
networks:
- docker_compose_net
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks:
docker_compose_net:
#执行
docker compose up -f xxx.yml
#或者(推荐后台执行)
docker compose up -d -f xxx.yml
文章仅供学习使用,非盈利谢谢!
本篇文章下载:docker学习和进阶2023