<返回目录     Powered by claude/xia兄

第9课: 容器通信

容器通信方式

Docker容器间通信有多种方式:

通过容器名通信

# 创建自定义网络
docker network create mynet

# 启动MySQL容器
docker run -d \
  --name mysql-server \
  --network mynet \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:8.0

# 启动应用容器,通过容器名访问MySQL
docker run -d \
  --name webapp \
  --network mynet \
  -e DB_HOST=mysql-server \
  -e DB_PORT=3306 \
  myapp:latest

# 在webapp容器中测试连接
docker exec webapp ping mysql-server
docker exec webapp curl http://mysql-server:3306
注意:只有在自定义网络中,容器名才能被DNS解析。默认bridge网络不支持容器名解析。

实战:三层架构应用

# 创建网络
docker network create app-tier

# 1. 数据库层
docker run -d \
  --name postgres-db \
  --network app-tier \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=myapp \
  postgres:14

# 2. 后端API层
docker run -d \
  --name api-server \
  --network app-tier \
  -e DATABASE_URL=postgresql://postgres:secret@postgres-db:5432/myapp \
  -e REDIS_URL=redis://redis-cache:6379 \
  myapi:latest

# 3. Redis缓存层
docker run -d \
  --name redis-cache \
  --network app-tier \
  redis:alpine

# 4. 前端层
docker run -d \
  --name frontend \
  --network app-tier \
  -p 80:80 \
  -e API_URL=http://api-server:8000 \
  myfrontend:latest

网络别名实现负载均衡

# 创建网络
docker network create lb-net

# 启动多个后端服务,使用相同别名
docker run -d --name api1 --network lb-net --network-alias api nginx
docker run -d --name api2 --network lb-net --network-alias api nginx
docker run -d --name api3 --network lb-net --network-alias api nginx

# 启动客户端容器
docker run -it --rm --network lb-net alpine sh

# 在客户端容器中测试(会轮询到不同的后端)
# nslookup api
# wget -qO- http://api

容器连接到多个网络

# 创建前端和后端网络
docker network create frontend
docker network create backend

# 数据库只在后端网络
docker run -d --name db --network backend mysql

# API服务器连接两个网络
docker run -d --name api --network backend myapi
docker network connect frontend api

# Web服务器只在前端网络
docker run -d --name web --network frontend -p 80:80 nginx

# 现在:web可以访问api,api可以访问db,但web不能直接访问db

使用Docker Compose管理通信

version: '3.8'

services:
  # 前端
  frontend:
    image: nginx:alpine
    ports:
      - "80:80"
    networks:
      - frontend
    depends_on:
      - backend

  # 后端API
  backend:
    image: myapi:latest
    environment:
      - DB_HOST=database
      - CACHE_HOST=cache
    networks:
      - frontend
      - backend
    depends_on:
      - database
      - cache

  # 数据库
  database:
    image: postgres:14
    environment:
      - POSTGRES_PASSWORD=secret
    networks:
      - backend
    volumes:
      - db-data:/var/lib/postgresql/data

  # 缓存
  cache:
    image: redis:alpine
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # 内部网络,不能访问外网

volumes:
  db-data:

服务发现

# Docker内置DNS服务器
# 容器启动时自动注册到DNS
# 其他容器可以通过名称解析

# 查看容器DNS配置
docker exec mycontainer cat /etc/resolv.conf

# 测试DNS解析
docker exec mycontainer nslookup other-container
docker exec mycontainer dig other-container

跨主机通信(Overlay网络)

# 在管理节点初始化Swarm
docker swarm init --advertise-addr 192.168.1.100

# 创建overlay网络
docker network create \
  --driver overlay \
  --attachable \
  my-overlay-net

# 在任意节点运行容器
docker run -d --name app1 --network my-overlay-net myapp
docker run -d --name app2 --network my-overlay-net myapp

# app1和app2可以跨主机通信

容器与主机通信

# 容器访问主机服务
# Linux: 使用host.docker.internal(需要添加extra_hosts)
docker run --add-host=host.docker.internal:host-gateway myapp

# macOS/Windows: 直接使用host.docker.internal
docker run myapp
# 在容器中访问:curl http://host.docker.internal:8080

# 主机访问容器
# 方法1: 端口映射
docker run -p 8080:80 nginx

# 方法2: 使用容器IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mycontainer

网络隔离与安全

# 创建隔离的内部网络
docker network create --internal secure-net

# 内部网络的容器无法访问外网
docker run -d --name secure-app --network secure-net myapp

# 创建网络时指定子网
docker network create \
  --subnet=172.18.0.0/16 \
  --gateway=172.18.0.1 \
  custom-net

调试容器通信

# 测试容器间连通性
docker exec container1 ping container2

# 查看容器网络配置
docker exec container1 ip addr
docker exec container1 ip route

# 使用netshoot工具容器调试
docker run -it --rm --network container:myapp nicolaka/netshoot

# 在netshoot中可以使用:
# - ping, curl, wget
# - tcpdump, netstat, ss
# - nslookup, dig
# - traceroute, mtr

性能优化

最佳实践

实践练习

  1. 创建前后端分离的网络架构
  2. 配置三层架构:前端、API、数据库
  3. 使用网络别名部署多个API实例
  4. 测试容器间的DNS解析和连通性
  5. 使用netshoot工具排查网络问题