Docker08-docker调优/管理/监控
容器=cgroup+namespace_rootfs+容器引擎
docker 实战 https://blog.csdn.net/woniu211111/article/details/108675525
docker compose https://blog.csdn.net/pushiqiang/article/details/78682323
rootfs
文件系统隔离
容器引擎:生命周期控制
namespace
主要用来访问隔离。原理是针对一类资源进行抽象,并将其封装在一起提供给一个容器使用,对于这类资源,
因为每个容器都有自己的抽象,而它们彼此之间是不可见的,所以就可以做到隔离
cgroup
cgroup 是 Linux 内核的一个重要特性,用于限制、管理和监控进程组的资源使用。在容器技术中,cgroup 被广泛用于限制容器的资源使用,如 CPU、内存、磁盘 I/O 和网络带宽等。通过合理配置 cgroup,可以有效地管理容器的资源使用,确保系统的稳定性和可预测性。
容器中的 cgroup 应用
CPU 限制:
通过 cgroup 可以为容器分配特定的 CPU 核心或 CPU 时间片。
这使得可以在多个容器之间公平地分配 CPU 资源,防止某个容器占用过多的 CPU 资源影响其他容器或系统。
内存限制:
cgroup 允许为容器设置内存限制,防止容器使用过多的系统内存,导致系统性能下降或因内存耗尽而崩溃。
通过 cgroup,可以限制容器的内存使用量,并在达到限制时触发内存回收或容器终止。
磁盘 I/O 控制:
使用 cgroup,可以限制容器对磁盘的输入输出操作。这使得可以控制容器的磁盘访问速率,
防止某个容器占用过多的磁盘 I/O 资源,影响其他容器的性能或系统的响应速度。
网络带宽控制:
虽然 Docker 容器默认不使用 cgroup 控制网络带宽,但是可以通过其他工具(如 tc 命令)
结合 cgroup 实现对容器的网络带宽控制。这使得可以限制容器的网络流量,防止某个容器占用过多的网络带宽,
影响其他容器或系统的网络通信。
cgroup 在容器中的实现
在容器技术中,cgroup 通常由容器运行时(如 Docker 或 Kubernetes)负责管理和应用。
当启动一个容器时,容器运行时会创建一个或多个 cgroup 来限制容器的资源使用。
容器运行时会根据容器的配置(如 CPU 限制、内存限制等)自动创建相应的 cgroup,并将容器的进程添加到这些 cgroup 中。
linux会为每个容器创建一个cgroup目录(/sys/fs/cgroup/cpu/docker/container_id),以容器的长ID命名
mount -t cgroup -o cpuset cpuset /sys/fs/cgroup/cpuset
mkdir /sys/fs/cgroup/cpuset/child # 创建cgroup
echo $$ > /sys/fs/cgroup/cpuset/child/tasks # 通过将当前进程ID写入tasks文件,就可以将进程移动到这个cgroup
也可以将进程ID写入cgroup.procs
写入tasks文件,只会将指定进程放入cgroup
写入cgroup.procs,会将进程所属的线程也放入child中
清理占用的磁盘空间
docker system df 类似linux中的df,可查看docker镜像和容器的数量以及占用磁盘大小
docker system prune 用于清理磁盘,删除关闭的容器,删除无用的数据卷和网络,删除没有tag的镜像
docker system prune -a 清理更加彻底,可以将没有容器使用的镜像也删除
监控Docker
docker监控子命令
docker ps
docker top
docker stats
docker events
sysdig
Sysdig是一种功能强大的系统监控工具,也可以用于监控和调试容器化环境,包括 Docker。
# 运行sysdig
docker run -it--rm--name=sysdig privileged=true \
--volume=/var/run/docker.sock:/host/var/run/docker.sock \
--volume=/dev:/host/dev \
--volume=/proc:/host/proc:ro \
--volume=/boot:/host/boot:ro \
--volume=/lib/modules:/host/lib/modules:ro \
--volume=/usr:/host/usr:ro \
sysdig/sysdig
指定volume和privileged是为了使sysdig获得足够多的系统信息
通过docker exec -it sysdig bash进入容器,执行csysdig以交互方式启动sysdig
进入容器后,执行这个命令将以实时方式显示容器的CPU使用情况
sysdig -pc -c topcontainers_cpu
Docker日志管理
docker logs
将容器日志发送到STDOUT和STDERR
docker logs -f container_name
-f:持续输出docker 日志,类似 tail -f
docker logging driver
- docker默认的 logging driver 是 json-file。
- json-file会将容器的日志保存在json文件中。Docker负责格式化其内容并输出到STDOUT和STDERR
- 在Host的容器目录中找到这个文件,容器路径为/var/lib/docker/containers/contariner_ID/contariner_ID-json.log。
docker还支持其他多种logging driver,例如
- none 是 disable 容器日志功能。
- syslog 和 jourald 是 Linux 上的两种日志管理服务。
- awslogs、splunk 和 gcplogs 是第三方日志托管服务。
docker info | grep "Logging Driver" # 查看logging driver
修改 Docker 容器的日志驱动器(log driver)
# 在启动容器时指定日志驱动器
docker run -it --name my_container --log-driver syslog ubuntu
# 也可以指定日志选项(log options):
docker run -it --name my_container --log-driver syslog \
--log-opt syslog-address=tcp://192.168.0.42:123 ubuntu
#编辑 Docker 的配置文件设置默认的日志驱动器,这样启动的所有容器都会使用该日志驱动器。
vim /etc/docker/daemon.json:
{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://192.168.0.42:123"
}
}
systemctl restart docker
# 对于已经运行的容器,无法直接修改其日志驱动器。你需要停止并重新创建容器,指定新的日志驱动器。
日志监控-ELK
见Elastic stack篇
日志监控-Fluentd
Fluentd是一个开源的数据收集器,支持上百种plugin,可以连接各种数据源和数据输出组件
可以用Filebeat将Fluentd收集的容器日志转发给Elasticsearch
fluent-plugin-elasticsearch插件可以让Fluentd直接将日志发送给Elasticsearch
使用Fluentd、Filebeat、Fluentd、Elasticsearch、Kibana监控容器日志
创建docker compose文件
# 创建一个 Docker Compose 文件 docker-compose.yml,配置 Fluentd、Elasticsearch、Kibana 和容器。
version: '3'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.13.1
container_name: elasticsearch
environment:
- discovery.type=single-node
volumes:
- esdata:/usr/share/elasticsearch/data
ports:
- "9200:9200"
- "9300:9300"
kibana:
image: docker.elastic.co/kibana/kibana:7.13.1
container_name: kibana
ports:
- "5601:5601"
depends_on:
- elasticsearch
environment:
ELASTICSEARCH_URL: http://elasticsearch:9200
fluentd:
image: fluent/fluentd:latest
container_name: fluentd
build:
context: ./fluentd
volumes:
- ./fluentd/conf:/fluentd/etc
ports:
- "24224:24224"
- "24224:24224/udp"
depends_on:
- elasticsearch
filebeat:
image: docker.elastic.co/beats/filebeat:7.13.1
container_name: filebeat
volumes:
# filebeat的配置文件
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
# 这个挂载用于让 Filebeat 可以监视 Docker 容器日志
- /var/lib/docker/containers:/var/lib/docker/containers:ro
# 允许与Docker引擎通信。将套接字挂载到容器中,Filebeat可以获取有关 Docker 容器的信息。
- /var/run/docker.sock:/var/run/docker.sock
command: ["-e", "-strict.perms=false", "-E", "output.elasticsearch.hosts=['elasticsearch:9200']"]
depends_on:
- elasticsearch
myapp:
image: yourappimage
container_name: myapp
logging:
driver: fluentd
options:
fluentd-address: localhost:24224
tag: docker.myapp
# 指定容器卷
volumes:
esdata:
driver: local
配置 Fluentd
创建 fluentd 目录并在该目录中创建 Dockerfile 和配置文件 fluent.conf。
vim /path/to/fluentd/Dockerfile
FROM fluent/fluentd:v1.12-1
USER root
RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-rdoc", "--no-ri", "--version", "4.0.7"]
COPY fluent.conf /fluentd/etc/fluent.conf
USER fluent
vim /path/to/fluentd/fluent.conf
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
<filter docker.**>
@type parser
format json
key_name log
reserve_data true
</filter>
<match **>
@type elasticsearch
host elasticsearch
port 9200
logstash_format true
include_tag_key true
tag_key @log_name
flush_interval 1s
</match>
配置 Filebeat
创建 filebeat 目录并在该目录中创建 filebeat.yml 配置文件。
vim /path/to/filebeat/filebeat.yml
filebeat.inputs:
- type: container
paths:
- /var/lib/docker/containers/*/*.log
processors:
- add_docker_metadata: ~
output.elasticsearch:
hosts: ["http://elasticsearch:9200"]
username: "elastic"
password: "changeme"
启动服务并访问 Kibana
在包含 docker-compose.yml 文件的目录中运行以下命令启动所有服务
docker-compose up -d
访问 http://<your-docker-host>:5601 进入 Kibana
日志监控-Graylog
编写docker compose文件
编写docker compose文件,配置mongo、es、graylog
version: '3'
services:
# MongoDB 作为 Graylog 的存储后端
mongo:
image: mongo:4.2
container_name: mongo
networks:
- graylog
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
container_name: elasticsearch
environment:
- http.host=0.0.0.0
- transport.host=127.0.0.1
- network.host=0.0.0.0
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.type=single-node # 单节点部署
ulimits:
memlock:
soft: -1
hard: -1
mem_limit: 1g
networks:
- graylog
graylog:
image: graylog/graylog:4.0
container_name: graylog
environment:
- GRAYLOG_PASSWORD_SECRET=cocDW72...UeL7wj
- GRAYLOG_ROOT_PASSWORD_SHA2=87de99fk...h68s2dc
- GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9000/
- GRAYLOG_TIMEZONE=Asia/Shanghai
- GRAYLOG_ROOT_TIMEZONE=Asia/Shanghai
# entrypoint: /usr/bin/tini -- wait-for-it elasticsearch:9200 -- /docker-entrypoint.sh # 容器启动命令
networks:
- graylog
depends_on:
- mongo
- elasticsearch
ports:
- "9000:9000" # Graylog的Web界面端口
- 5044:5044 # Filebeat工具提供端口
- 12201:12201 # Graylog接收GELF消息的TCP端口
- 12201:12201/udp # Graylog接收GELF消息的UDP端口
- 1514:1514 # Graylog接收Syslog消息的TCP端口
- 1514:1514/udp # Graylog接收Syslog消息的UDP端口
volumes:
- graylog_data:/usr/share/graylog/data
filebeat:
image: docker.elastic.co/beats/filebeat:7.15.0
user: root
container_name: filebeat
# filebeat的配置文件
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
# 这个挂载用于让 Filebeat 可以监视 Docker 容器日志
- /var/lib/docker/containers:/var/lib/docker/containers:ro
# 允许与Docker引擎通信。将套接字挂载到容器中,Filebeat可以获取有关 Docker 容器的信息。
- /var/run/docker.sock:/var/run/docker.sock
command: ["-e", "-strict.perms=false", "-E", "output.elasticsearch.hosts=['elasticsearch:9200']"]
networks:
- graylog
depends_on:
- elasticsearch
networks:
graylog:
driver: bridge
# 定义数据卷,这里会使用Docker的默认数据存储目录
volumes:
graylog_data:
driver: local
生成随机密码
# 生成password_secret密码
apt install -y pwgen
pwgen -N 1 -s 16
-N 获取1个密码,默认是20*8组成的阵列
-s 指定密码长度,不指定默认8位
# 生成GRAYLOG_ROOT_PASSWORD_SHA2的密码,从标准输入读取原数据进行sha256sum处理
echo -n "Enter Password: " && head -1 </dev/stdin | tr -d '\n' | sha256sum | cut -d" " -f1
tr -d '\n' 删除标准输入中的回车
sha256sum 不指定文件,默认从标准输入读取
cut -d" " 以空格作为sha256sum输出的分割符号
-f1 获取第一段分割
启动 Graylog、Elasticsearch 和 MongoDB
在包含 docker-compose.yml 文件的目录中运行以下命令启动所有服务:
docker-compose up -d
访问 Graylog
浏览器访问 http://127.0.0.1:9000 进入 Graylog
用户名: admin
密码: 使用 GRAYLOG_ROOT_PASSWORD_SHA2 环境变量中指定的密码哈希
登录到 Graylog 后,配置输入以接收来自容器的日志。
进入 “System” > “Inputs”。
选择 GELF UDP 作为输入类型。
配置输入,选择启动输入,绑定到 0.0.0.0,并使用默认端口 12201。
配置容器日志驱动
指定应用容器配置日志驱动,将日志发送到 Graylog。
docker run -d --name my_nginx \
--log-driver=gelf \
--log-opt gelf-address=udp://127.0.0.1:12201 \
--log-opt tag="nginx" \
nginx
Docker管理工具
portainer单机版
docker run -d -p 9000:9000 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
--name prtainer-test \
docker.io/portainer/portainer
访问方式:http://IP:9000
portainer 远程管理
远程管理使用2375端口,需要开启端口
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock # 原配置文件
修改后,选择其中一种
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H 0.0.0.0:2375
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
docker-machine
docker-machine
base=https://github.com/docker/machine/releases/download/v0.16.0 &&
curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
sudo mv /tmp/docker-machine /usr/local/bin/docker-machine &&
chmod +x /usr/local/bin/docker-machine
docker-compose
docker-compose
curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
配置Docker
修改docker默认的存储位置
docker info | grep 'Docker Root Dir' # 查看现在的存储位置
docker stop $(docker ps -q) # 停止所有容器
systemctl stop docker # 停止docker服务
mv /var/lib/docker /path/to/newdir # 移动原数据到新路径
vim /etc/docker/daemon.json
{
"data-root": "/path/to/newdir"
}
systemctl restart docker # 重启docker
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)