容器的持续部署、交付与日志监控
发布时间: 2025-08-15 00:20:09 订阅数: 1 


Docker容器技术与实践指南
# 容器的持续部署、交付与日志监控
## 1. 持续部署与交付
### 1.1 持续交付与持续部署的概念
持续交付是持续集成向生产环境的延伸。工程师在开发环境做出更改后,经过测试,只需点击按钮即可将更改部署到生产环境。而持续部署更进一步,它会自动将通过测试的更改推送到生产环境进行部署。
### 1.2 从持续集成到持续部署的实现
可以通过将镜像推送到生产镜像仓库,并将运行中的容器迁移到新镜像来实现从持续集成到持续部署的扩展。在不中断服务的情况下迁移镜像,需要先启动新容器,重新路由流量,再停止旧容器。安全实现这一过程的方法有蓝绿部署和渐进式部署等。实现这些技术通常会使用内部工具,不过像 Kubernetes 这样的框架也提供了内置解决方案,未来市场上可能还会出现专业工具。
### 1.3 容器生产部署的选择
容器托管有多种生产级别的选择,最佳选择取决于系统的规模、复杂性以及在部署和维护上愿意投入的精力和资金。小型部署可以简单地在云虚拟机上运行 Docker 引擎,但大规模部署时维护负担较大。可以使用 Kubernetes 和 Mesos 等系统,或者选择 Giant Swarm、Triton 或 ECS 等专业托管服务来减轻负担。
## 2. 日志与监控
### 2.1 日志与监控的重要性
对于任何非平凡系统的正常运行和有效调试,对运行中的容器进行有效的监控和日志记录至关重要。在微服务架构中,由于机器数量增加,日志和监控变得更加重要。考虑到容器的短暂性,调试问题时容器可能已不存在,因此集中式日志是不可或缺的工具。
### 2.2 代码获取
相关代码可在 GitHub 上获取。可以使用 v0 标签检出本章开始时的代码:
```bash
$ git clone -b v0 \
https://github.com/using-docker/logging/
```
后续标签代表代码在本章中的进展,也可以从 GitHub 项目的 Releases 页面下载任何标签的代码。
### 2.3 Docker 默认日志记录
如果不指定任何参数或安装任何日志记录软件,Docker 会记录发送到 STDOUT 和 STDERR 的所有内容。可以使用 `docker logs` 命令检索日志,例如:
```bash
$ docker run --name logtest debian sh -c 'echo "stdout"; echo "stderr" >>2'
stderr
stdout
$ docker logs logtest
stderr
stdout
```
使用 `-t` 参数可以获取时间戳:
```bash
$ docker logs -t logtest
2015-04-27T10:30:54.002057314Z stderr
2015-04-27T10:30:54.005335068Z stdout
```
使用 `-f` 参数可以流式传输运行中容器的日志:
```bash
$ docker run -d --name streamtest debian \
sh -c 'while true; do echo "tick"; sleep 1; done;'
13aa6ee6406a998350781f994b23ce69ed6c38daa69c2c83263c863337a38ef9
$ docker logs -f streamtest
tick
tick
tick
tick
tick
tick
...
```
还可以通过 Docker 远程 API 实现相同功能。如果使用 Docker Machine,可以执行以下操作:
```bash
$ curl -i --cacert ~/.docker/machine/certs/ca.pem \
--cert ~/.docker/machine/certs/ca.pem \
--key ~/.docker/machine/certs/key.pem \
"https://$(docker-machine ip default):2376/containers/\
$(docker ps -lq)/logs?stderr=1&stdout=1"
tick
tick
tick
...
```
需要注意的是,Mac OS 上 `curl` 的使用略有不同,可能需要创建包含 `ca.pem` 和 `key.pem` 信息的单个证书。
### 2.4 Docker 默认日志记录的缺点
默认日志记录只能处理 STDOUT 和 STDERR,如果应用程序只记录到文件,就会出现问题。而且没有日志轮转功能,如果使用像 `yes` 这样的应用程序让容器持续运行,容器会很快耗尽磁盘空间,例如:
```bash
$ docker run -d debian yes
ba054389b7266da0aa4e42300d46e9ce529e05fc4146fea2dff92cf6027ed0c7
```
### 2.5 其他日志记录方法
可以使用 `docker run` 的 `--log-driver` 参数启动其他日志记录方法,启动 Docker 守护进程时传递 `--log-driver` 参数可以更改默认日志记录器。日志记录器的可能值如下表所示:
| 日志记录器 | 说明 |
| --- | --- |
| json-file | 前面介绍的默认日志记录方式 |
| syslog | syslog 驱动,稍后会详细介绍 |
| journald | systemd 日志的驱动 |
| gelf | Graylog 扩展日志格式(GELF)驱动 |
| fluentd | 将日志消息转发到 fluentd |
| none | 关闭日志记录 |
关闭日志记录在某些情况下很有用,例如上述 `yes` 命令的示例。
### 2.6 聚合日志
无论使用哪种日志记录驱动,都只能提供部分解决方案,尤其是在多主机系统中。我们希望将所有日志(可能跨主机)聚合到一个位置,以便运行分析和监控工具。有两种基本方法:
1. 在所有容器内运行一个辅助进程作为代理,将日志转发到聚合服务。
2. 在主机上或单独的独立容器中收集日志,并转发到聚合服务。
第一种方法虽然可行,但会使镜像变大,不必要地增加运行进程的数量,因此这里只考虑第二种方法。从主机访问容器日志有以下几种方式:
1. 使用 Docker API 以编程方式访问日志,这种方法的优点是官方支持,但使用 HTTP 连接会有一些开销。下一节将介绍使用 Logspout 实现的示例。
2. 如果使用 syslog 驱动,可以使用 syslog 功能自动转发日志。
3. 直接从 Docker 目录访问日志文件。
如果应用程序坚持将日志记录到文件而不是 STDOUT 或 STDERR,可以参考“处理记录到文件的应用程序”部分的解决方法。
### 2.7 使用 ELK 进行日志记录
为 identidock 应用程序添加日志记录功能,将使用 ELK 栈,即 Elasticsearch、Logstash 和 Kibana:
- **Elasticsearch**:一个具有近实时搜索功能的文本搜索引擎,设计用于轻松跨节点扩展以处理大量数据,非常适合搜索大量日志数据。
- **Logstash**:用于读取原始日志,进行解析和过滤,然后将其发送到其他服务(如索引或存储,这里将转发到 Elasticsearch)。它支持多种输入和输出类型,以及各种应用程序日志的预定义解析器。
- **Kibana**:基于 JavaScript 的 Elasticsearch 图形界面,可用于运行 Elasticsearch 查询并以各种图表形式可视化结果,还可以设置仪表盘以快速了解系统状态。
#### 2.7.1 搭建 ELK 栈
基于上一章的 `prod.yml` 在本地运行 ELK 栈。理想情况下,应将 ELK 容器移动到单独的主机以保持关注点分离,但为了简单起见,本章将所有内容放在一个主机上。
首先创建一个新文件 `prod-with-logging.yml`,内容如下:
```yaml
proxy:
image: amouat/proxy:1.0
links:
- identidock
ports:
- "80:80"
environment:
- NGINX_HOST=45.55.251.164
- NGINX_PROXY=http://identidock:9090
identidock:
image: amouat/identidock:1.0
links:
- dnmonster
- redis
environment:
ENV: PROD
dnmonster:
image: amouat/dnmonster
redis:
image: redis
logspout:
image: amouat/logspout-logstash
volumes:
- /var/run/docker.sock:/tmp/docker.sock
ports:
- "8000:80"
```
需要将 IP 地址替换为自己主机的 IP,也可以将
0
0
相关推荐









