Consul部署手册(helm版本)
使用 Helm 部署 Consul 作为统一配置中心与服务发现平台
本文档旨在指导您使用 Helm 在 Kubernetes 集群中部署 Consul,并将其配置为一个专注于统一配置管理和服务发现的平台。此部署将优化服务发现功能,同时保持配置管理的核心能力。
1. 前提条件
- 一个正在运行的 Kubernetes 集群 (版本 >= 1.20 推荐)
kubectl命令行工具已安装并配置好,可以访问您的集群helm(版本 3+) 命令行工具已安装- (可选,但推荐) 用于 Consul UI 的 TLS 证书和私钥 (例如
consultest.crt和consultest.key) - (可选) 一个支持
networking.k8s.io/v1Ingress API 的 Ingress Controller (如 NGINX Ingress Controller) 已部署并运行
2. 添加 HashiCorp Helm 仓库
将 HashiCorp 官方 Helm 仓库添加到您的本地 Helm 客户端:
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
3. 准备配置文件
创建一个名为 consul-values.yaml 的文件,内容如下。请根据您的具体环境修改其中的 consul.XXX.com 域名和存储类名称。
3.1 优化配置说明
此配置专注于以下核心功能:
- 服务发现:通过 DNS 和 gRPC 接口提供服务发现能力
- 配置管理:支持动态配置存储和分发
- 健康检查:内置服务健康检查机制
- 高可用性:多节点集群部署,支持故障转移
# consul-values.yaml - 用于 Consul 统一配置管理和服务发现
# --- 全局设置 ---
global:
# -- 设置所有组件的日志级别
logLevel: "info"
# -- 启用 JSON 格式日志
logJSON: true
# -- Consul Docker 镜像 (请根据需要指定版本)
image: "hashicorp/consul:1.21.2"
# -- Consul K8s Control Plane 镜像 (请根据需要指定版本)
imageK8S: "hashicorp/consul-k8s-control-plane:1.7.2"
# -- Consul 域名 (用于 DNS 查询和服务发现)
domain: "consul"
# -- 启用 ACLs (强烈推荐用于生产环境)
acls:
manageSystemACLs: true
# bootstrapToken: # 如果预创建了引导令牌 Secret,可以在此指定
# secretName: "consul-bootstrap-acl-token"
# secretKey: "token"
# -- 启用 TLS (强烈推荐用于生产环境)
tls:
enabled: false
# enableAutoEncrypt: false # 可选:加密客户端与服务端通信
# caCert: # 如果使用预创建的 CA 证书,可以在此指定
# secretName: "consul-ca-cert"
# caKey: # 如果使用预创建的 CA 密钥,可以在此指定
# secretName: "consul-ca-key"
# -- Gossip 加密 (强烈推荐)
gossipEncryption:
autoGenerate: true
# -- 节点元数据
nodeMeta:
pod-name: ${HOSTNAME}
host-ip: ${HOST_IP}
# --- 服务端配置 ---
server:
enabled: true
replicas: 3 # 推荐用于高可用 (HA)
bootstrapExpect: 3 # 应与 replicas 匹配以实现 HA
storage: "20Gi" # 持久卷大小
storageClass: "nfs" # 指定存储类(如nfs)
# PVC保留策略
persistentVolumeClaimRetentionPolicy:
whenDeleted: Retain
whenScaled: Retain
resources:
requests:
memory: "512Mi"
cpu: "100m"
limits:
memory: "1Gi"
cpu: "500m"
connect: true # 启用服务网格功能(用于服务发现)
extraConfig: | # 自定义配置(可选)
{
"log_level": "INFO",
"disable_update_check": true,
"enable_script_checks": false,
"connect": {
"enabled": true
}
}
# -- 为服务端 Pod 设置反亲和性,防止调度到同一节点
# 使用软性反亲和性(优先分散,但不强制)
affinity: |
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: {{ template "consul.name" . }}
release: "{{ .Release.Name }}"
component: server
topologyKey: kubernetes.io/hostname
#使用硬性反亲和性(强制,推荐使用)
#affinity: |
# podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# - labelSelector:
# matchLabels:
# app: {{ template "consul.name" . }}
# release: "{{ .Release.Name }}"
# component: server
# topologyKey: kubernetes.io/hostname
# --- 客户端配置 ---
client:
enabled: true
grpc: true # 启用 gRPC 端口,用于服务发现和连接
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
# -- 客户端额外配置
extraConfig: |
{
"leave_on_terminate": true,
"skip_leave_on_interrupt": false,
"enable_script_checks": false,
"connect": {
"enabled": true
}
}
# --- UI 配置 (可选,方便查看配置和服务发现状态) ---
ui:
enabled: true
service:
enabled: true
type: "ClusterIP" # 或 LoadBalancer, NodePort
# Ingress配置(对外暴露UI)
ingress:
enabled: true # 启用Ingress
ingressClassName: "nginx" # 指定Ingress Controller类型
pathType: Prefix
annotations: | # 自定义注解(如配置重定向规则)
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
hosts:
- host: "consul.XXX.com" # 访问域名
paths:
- /
tls: # TLS配置(建议生产环境启用)
- hosts:
- consul.XXX.com
# --- DNS 配置 (服务发现核心) ---
dns:
enabled: true # 启用Consul DNS服务
enableRedirection: true # 启用DNS重定向(服务发现需要)
# --- Connect Inject 配置 (服务网格和服务发现) ---
connectInject:
enabled: true # 启用自动sidecar注入
default: false # 默认不注入,需要注解显式启用
replicas: 2 # 注入器副本数(高可用)
transparentProxy:
defaultEnabled: true # 启用透明代理
defaultOverwriteProbes: true # 覆盖健康检查
metrics:
defaultEnabled: true # 启用指标收集
defaultPrometheusScrapePort: 20200
defaultPrometheusScrapePath: "/metrics"
# -- 资源设置
resources:
requests:
memory: "200Mi"
cpu: "50m"
limits:
memory: "200Mi"
cpu: "50m"
# --- 服务目录同步配置 (K8S服务与Consul服务双向同步) ---
syncCatalog:
enabled: true # 启用K8S服务与Consul服务的同步
toConsul: true # 同步K8S服务到Consul
toK8S: true # 同步Consul服务到K8S
default: true # 默认同步所有服务
k8sAllowNamespaces: ["*"] # 允许所有命名空间
k8sDenyNamespaces: ["kube-system", "kube-public"] # 排除系统命名空间
consulNodeName: "k8s-sync" # Consul节点名称
# -- 同步策略
nodePortSyncType: ExternalFirst
syncClusterIPServices: true
syncLoadBalancerEndpoints: false
# -- 资源设置
resources:
requests:
memory: "50Mi"
cpu: "50m"
limits:
memory: "50Mi"
cpu: "50m"
# -- 日志级别
logLevel: "info"
# --- 网关配置 (服务网格) ---
meshGateway:
enabled: false # 禁用网格网关(如不需要可以保持关闭)
ingressGateways:
enabled: false # 禁用入口网关(如不需要可以保持关闭)
terminatingGateways:
enabled: false # 禁用终止网关(如不需要可以保持关闭)
# --- 其他配置 ---
prometheus:
enabled: false # 禁用Prometheus(如需要可以启用)
telemetryCollector:
enabled: false # 禁用遥测收集器(如需要可以启用)
tests:
enabled: false # 禁用测试Pod
# --- 证书管理器 ---
webhookCertManager:
resources:
requests:
memory: "50Mi"
cpu: "100m"
limits:
memory: "50Mi"
cpu: "100m"
# --- 生产环境建议配置 ---
# 1. 启用TLS加密
# 2. 配置适当的资源限制
# 3. 设置Pod反亲和性
# 4. 配置持久化存储
# 5. 启用ACLs
# 6. 监控和日志配置
4. 部署Consul
helm upgrade --install consul \
hashicorp/consul \
-n consul \
--create-namespace \
-f consul-values.yaml \
--version 1.7.2
5. 验证部署
5.1 基本检查
部署后,检查 Pod 和 Service 是否正常运行:
kubectl get pods,svc -n consul
您应该看到 Consul Server Pod (状态为 Running) 和相关的 Service。
5.2 服务发现验证
检查服务发现相关组件:
# 检查服务
kubectl get svc -n consul
5.3 Ingress 验证
检查 Ingress 是否创建:
kubectl get ingress -n consul
6. 服务发现功能验证
6.1 DNS 服务发现测试
# 在集群内部测试DNS解析
kubectl run -it --rm dns-test --image=busybox --restart=Never -- sh -c "nslookup consul-consul-server.consul.svc.cluster.local"
6.2 服务目录同步验证
# 查看同步的Consul服务
kubectl logs -n consul -l app=consul,component=sync-catalog
# 查看Consul中的K8S服务
kubectl exec -n consul -it <consul-server-pod> -- consul catalog services
6.3 Connect 服务验证
# 检查Connect服务状态
kubectl exec -n consul -it <consul-server-pod> -- consul catalog services -connect
7. 访问 Consul UI
- 确保您的 DNS 或 /etc/hosts 文件已将
consul.XXX.com指向您的 Ingress Controller 的 IP 地址 - 在浏览器中访问 http://consul.XXX.com (如果配置了 TLS 且 Secret 存在,则访问 https://consul.XXX.com)
- 如果启用了 ACL (global.acls.manageSystemACLs: true),首次访问 UI 时需要提供 ACL Token。引导令牌可以通过以下方式获取:
kubectl get secret <RELEASE_NAME>-consul-bootstrap-acl-token -n <NAMESPACE> -o jsonpath={.data.token} | base64 --decode
(将 <RELEASE_NAME> 和 <NAMESPACE> 替换为实际值,例如 consul-consul-bootstrap-acl-token 和 consul)
8. 服务发现使用示例
8.1 在应用中使用Consul服务发现
8.1.1 C#应用示例
using Consul;
using System;
using System.Net;
using System.Threading.Tasks;
namespace ConsulServiceDiscovery
{
public class ConsulServiceDiscovery
{
private static readonly string ConsulHost = "consul-consul-server.consul.svc.cluster.local";
private static readonly int ConsulPort = 8500;
public async Task DiscoverServices()
{
// 创建Consul客户端配置
var consulConfig = new
{
Address = $"{ConsulHost}:{ConsulPort}"
};
// 创建Consul客户端
using (var consul = new ConsulClient(config => config.Address = new Uri($"http://{consulConfig.Address}")))
{
try
{
// 获取服务列表
var services = await consul.Catalog.Services();
Console.WriteLine("Available services:");
foreach (var service in services.Response)
{
Console.WriteLine($"- {service.Key}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error discovering services: {ex.Message}");
}
}
}
public async Task DiscoverSpecificService(string serviceName)
{
var consulConfig = new
{
Address = $"{ConsulHost}:{ConsulPort}"
};
using (var consul = new ConsulClient(config => config.Address = new Uri($"http://{consulConfig.Address}")))
{
try
{
// 获取特定服务的健康实例
var healthyServices = await consul.Health.Service(serviceName, "", true);
Console.WriteLine($"Found {healthyServices.Response.Length} healthy instances of {serviceName}:");
foreach (var serviceEntry in healthyServices.Response)
{
var service = serviceEntry.Service;
Console.WriteLine($"- {service.Address}:{service.Port} (ID: {service.ID}, Service: {service.Service})");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error discovering service {serviceName}: {ex.Message}");
}
}
}
public async Task RegisterService()
{
var consulConfig = new
{
Address = $"{ConsulHost}:{ConsulPort}"
};
using (var consul = new ConsulClient(config =>
{
config.Address = new Uri($"http://{consulConfig.Address}");
config.Token = "改为自己的token";
}))
{
try
{
// 注册服务
var registration = new AgentServiceRegistration
{
Name = "my-service",
ID = "my-service-1",
Address = "service-host",
Port = 8080,
Tags = new[] { "web", "api" },
Check = new AgentServiceCheck
{
HTTP = "http://service-host:8080/health",
Interval = TimeSpan.FromSeconds(10),
Timeout = TimeSpan.FromSeconds(5),
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(30)
}
};
await consul.Agent.ServiceRegister(registration);
Console.WriteLine("Service registered successfully");
}
catch (Exception ex)
{
Console.WriteLine($"Error registering service: {ex.Message}");
}
}
}
}
// 使用示例
public class Program
{
public static async Task Main(string[] args)
{
var discovery = new ConsulServiceDiscovery();
// 发现所有服务
await discovery.DiscoverServices();
// 发现特定服务
await discovery.DiscoverSpecificService("database-service");
// 注册服务
await discovery.RegisterService();
}
}
}
9. 监控与运维
9.1 健康检查
# 检查Consul集群状态
kubectl exec -n consul -it <consul-server-pod> -- consul members
# 检查Leader状态
kubectl exec -n consul -it <consul-server-pod> -- consul operator raft list-peers
# 检查服务健康状态
kubectl exec -n consul -it <consul-server-pod> -- consul health checks
9.2 日志监控
# 查看服务端日志
kubectl logs -n consul -l component=server
# 查看客户端日志
kubectl logs -n consul -l component=client
# 查看同步组件日志
kubectl logs -n consul -l app=consul,component=sync-catalog
9.3 性能监控
# 查看Consul性能指标
kubectl exec -n consul -it <consul-server-pod> -- consul monitor
# 查看Prometheus指标
curl http://localhost:8500/v1/agent/metrics
10. 故障排查
10.1 常见问题
10.1.1 服务发现不工作
症状: 应用无法发现其他服务
排查步骤:
- 检查DNS服务是否正常运行
- 检查服务注册是否正确
- 检查网络策略是否允许服务间通信
- 检查ACL配置是否正确
# 检查DNS服务
kubectl get pods -n consul -l component=client
# 测试DNS解析
kubectl run -it --rm dns-test --image=busybox --restart=Never -- sh -c "nslookup consul-consul-server.consul.svc.cluster.local"
# 检查服务注册
kubectl exec -n consul -it <consul-server-pod> -- consul catalog services
10.1.2 配置同步失败
症状: K8S服务无法同步到Consul
排查步骤:
- 检查sync-catalog Pod状态
- 检查日志中的错误信息
- 检查命名空间权限
# 检查sync-catalog日志
kubectl logs -n consul -l app=consul,component=sync-catalog
# 检查K8S服务
kubectl get svc -A | grep my-service
10.2 备份与恢复
10.2.1 数据备份
# 备份Consul数据
kubectl exec -n consul -it <consul-server-pod> -- consul snapshot save consul-backup.snap
# 导出配置
kubectl exec -n consul -it <consul-server-pod> -- consul kv get -recursive > config-backup.txt
10.2.2 数据恢复
# 恢复Consul数据
kubectl exec -n consul -it <consul-server-pod> -- consul snapshot restore consul-backup.snap
# 恢复配置
kubectl exec -n consul -it <consul-server-pod> -- consul kv import @config-backup.txt
11. 最佳实践
11.1 性能优化
- DNS缓存: 启用DNS缓存减少查询延迟
- 服务健康检查: 配置合适的心跳间隔和超时时间
- 资源限制: 为不同组件设置合适的资源限制
- 数据分片: 对于大型集群,考虑数据分片
11.2 安全配置
- 启用TLS: 生产环境必须启用TLS加密
- ACL配置: 配置细粒度的访问控制
- 网络隔离: 使用网络策略限制服务间通信
- 定期轮换密钥: 定期更新加密密钥
11.3 运维建议
- 监控告警: 设置关键指标的监控和告警
- 定期备份: 定期备份Consul数据和配置
- 版本升级: 定期升级Consul版本获取新功能和修复
- 容量规划: 根据业务增长规划集群容量
通过以上配置和优化,Consul将作为一个强大的统一配置中心和服务发现平台,为您的Kubernetes集群提供可靠的服务发现和配置管理能力。

浙公网安备 33010602011771号