Shell脚本如何配置容器DNS策略

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器DNS策略

  1. Docker 容器
  2. Podman 容器
  3. Kubernetes Pod
  4. 常见 DNS 策略对比
  5. 调试与验证
  6. 最佳实践

在 Shell 脚本中配置容器的 DNS 策略,通常取决于你使用的容器运行时(如 Docker、Podman、containerd)以及编排工具(如 Kubernetes),以下是常见场景的配置方法:

Docker 容器

使用 --dns 选项(推荐)

#!/bin/bash
docker run -d \
  --name my-container \
  --dns 8.8.8.8 \
  --dns 8.8.4.4 \
  --dns-search example.com \
  --dns-opt timeout:5 \
  nginx:latest

使用 --dns-opt 参数

#!/bin/bash
docker run -d \
  --dns 192.168.1.100 \
  --dns-opt "attempts:3" \
  --dns-opt "rotate" \
  alpine ash -c "ping google.com"

使用 Docker Compose(通过 shell 生成配置)

#!/bin/bash
cat > docker-compose.yml << EOF
version: '3'
services:
  web:
    image: nginx
    dns:
      - 8.8.8.8
      - 8.8.4.4
    dns_search:
      - example.com
    dns_opt:
      - timeout:5
      - attempts:3
      - rotate
EOF
docker-compose up -d

修改系统 DNS 配置(影响所有容器)

#!/bin/bash
# 配置 Docker 守护进程的 DNS(/etc/docker/daemon.json)
cat > /etc/docker/daemon.json << EOF
{
  "dns": ["8.8.8.8", "8.8.4.4"],
  "dns-opts": ["timeout:5", "attempts:3"],
  "dns-search": ["example.com"]
}
EOF
systemctl restart docker

Podman 容器

Podman 支持与 Docker 类似的 --dns 选项:

#!/bin/bash
podman run -d \
  --name my-container \
  --dns 1.1.1.1 \
  --dns-search mycompany.local \
  alpine sleep 3600

Kubernetes Pod

在 Kubernetes 中,DNS 策略通过 YAML 文件的 dnsPolicy 字段配置:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx
  dnsPolicy: "ClusterFirst"  # 可选值:Default, ClusterFirst, ClusterFirstWithHostNet, None
  dnsConfig:  # 当 dnsPolicy 为 None 时必须指定
    nameservers:
      - 8.8.8.8
      - 8.8.4.4
    searches:
      - ns1.svc.cluster.local
      - my.dns.search.suffix
    options:
      - name: ndots
        value: "2"
      - name: edns0

Shell 脚本中动态生成并应用:

#!/bin/bash
kubectl apply -f - << EOF
apiVersion: v1
kind: Pod
metadata:
  name: custom-dns-pod
spec:
  containers:
  - name: app
    image: busybox
    command: ["sleep", "3600"]
  dnsPolicy: "None"
  dnsConfig:
    nameservers:
      - 8.8.8.8
    searches:
      - default.svc.cluster.local
    options:
      - name: attempts
        value: "3"
EOF

常见 DNS 策略对比

策略 描述 使用场景
Default 继承节点 DNS 配置 需要访问外部服务且不想修改
ClusterFirst 使用集群 DNS 优先 需要解析 Service 和 Pod 名称
ClusterFirstWithHostNet 集群 DNS + 主机网络 Pod 使用 hostNetwork 时
None 完全自定义 DNS 需要完全控制 DNS 配置时

调试与验证

配置完成后,在容器内验证:

#!/bin/bash
# 进入容器检查
docker exec -it my-container cat /etc/resolv.conf
# 测试 DNS 解析
docker exec my-container nslookup google.com
docker exec my-container dig example.com
# Kubernetes 中验证
kubectl exec -it dns-pod -- cat /etc/resolv.conf

最佳实践

  1. 避免硬编码:将 DNS 服务器地址定义为脚本变量
  2. 使用环境变量:通过 --env 或 ConfigMap 传递 DNS 配置
  3. 处理不同环境:开发/测试/生产环境使用不同的 DNS 策略
  4. 日志记录:记录 DNS 配置变更以便审计
#!/bin/bash
# 更健壮的实现示例
DNS_SERVER=${DNS_SERVER:-"8.8.8.8"}
DNS_OPTS="timeout:${DNS_TIMEOUT:-5} attempts:${DNS_ATTEMPTS:-2}"
docker run -d \
  --dns "$DNS_SERVER" \
  --dns-opt "$DNS_OPTS" \
  "$@"

根据你的具体使用场景(单一容器、集群编排、还是网络策略需求),选择最适合的方案即可。

抱歉,评论功能暂时关闭!