k8s部署(单点或)高可用consul集群

在 Kubernetes 集群上部署一个高可用的 Consul 集群,确保一个节点挂了之后不会影响已注册到 Consul 的服务。利用 StatefulSet 和无头服务 HeadLess 的选举机制来实现 Consul 集群的高可用性,数据持久化方式选择HostPath,通过 nodeSelector 节点选择器将 Pod 调度到指定的三台机器(10.10.100.44,10.10.50.71,10.10.50.72)上运行,这样可以避免集群整体故障导致的数据丢失。

1. 准备工作

1.确定要创建的目录:

在我们的配置文件中,我们指定了/data/consul 作为 hostPath 的挂载目录,因此我们需要在三个节点(10.10.100.44,10.10.50.71,10.10.50.72)上创建此目录。

2.创建目录的命令:

bash 复制代码
mkdir -p /data/consul
chmod -R 755 /data/consul  

登陆节点    10.10.100.44
ssh root@10.10.100.44
mkdir -p /data/consul
chmod -R 755 /data/consul

登陆节点    10.10.50.71
ssh root@10.10.50.71
mkdir -p /data/consul
chmod -R 755 /data/consul

登陆节点    10.10.50.72
ssh root@110.10.50.72
mkdir -p /data/consul
chmod -R 755 /data/consul

3.为要固定consul_pod的node节点打标签:

bash 复制代码
➜  ~ kubectl label nodes 10.10.100.44  nodeType=consul
node/10.10.100.44 labeled
➜  ~ kubectl label nodes 10.10.50.71 nodeType=consul
node/10.10.50.71 labeled
➜  ~ kubectl label nodes 10.10.50.72  nodeType=consul
node/10.10.50.72 labeled

4.创建 Consul Namespace

为 Consul 创建一个命名空间:

bash 复制代码
kubectl create namespace consul

2.consul yaml文件编排

1.创建无头服务Service(Headless Service) :

无头服务将帮助我们识别集群中的所有Consul server节点:

bash 复制代码
# 新建consul-server-service.yaml

touch consul-server-service.yaml
XML 复制代码
apiVersion: v1
kind: Service
metadata:
  name: consul
  namespace: consul
  labels:
    name: consul
spec:
  selector:
    name: consul
  ports:
    - name: http
      port: 8500
      targetPort: 8500
    - name: https
      port: 8443
      targetPort: 8443
    - name: rpc
      port: 8400
      targetPort: 8400
    - name: serf-lan-tcp
      protocol: "TCP"
      port: 8301
      targetPort: 8301
    - name: serf-lan-udp
      protocol: "UDP"
      port: 8301
      targetPort: 8301
    - name: serf-wan-tcp
      protocol: "TCP"
      port: 8302
      targetPort: 8302
    - name: serf-wan-udp
      protocol: "UDP"
      port: 8302
      targetPort: 8302
    - name: server
      port: 8300
      targetPort: 8300
    - name: consul-dns
      port: 8600
      targetPort: 8600

保存为consul-server-service.yaml,并运行:

XML 复制代码
kubectl create -f consul-server-service.yaml

2.创建pod控制器StatefulSet:

XML 复制代码
# 新建consul-server-statefulset.yaml

touch consul-server-statefulset.yaml
XML 复制代码
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: consul
  namespace: consul
  labels:
    name: consul
spec:
  serviceName: consul
  selector:
    matchLabels:
      name: consul
  replicas: 3
  template:
    metadata:
      labels:
        name: consul
    spec:
      terminationGracePeriodSeconds: 10
      nodeSelector:
        nodeType: consul
      containers:
        - name: consul
          image: hashicorp/consul:1.17.3
          imagePullPolicy: IfNotPresent
          args:
            - "agent"
            - "-server"
            - "-bootstrap-expect=3"
            - "-ui"
            - "-data-dir=/consul/data"
            - "-bind=0.0.0.0"
            - "-client=0.0.0.0"
            - "-advertise=$(POD_IP)"
            - "-retry-join=consul-0.consul.$(NAMESPACE).svc.cluster.local"
            - "-retry-join=consul-1.consul.$(NAMESPACE).svc.cluster.local"
            - "-retry-join=consul-2.consul.$(NAMESPACE).svc.cluster.local"
            - "-domain=cluster.local"
            - "-disable-host-node-id"
          env:
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - containerPort: 8500
              name: http
            - containerPort: 8400
              name: rpc
            - containerPort: 8443
              name: https-port
            - containerPort: 8301
              name: serf-lan
            - containerPort: 8302
              name: serf-wan
            - containerPort: 8600
              name: consul-dns
            - containerPort: 8300
              name: server
          volumeMounts:
            - name: data-volume
              mountPath: /consul/data
      volumes:
        - name: data-volume
          hostPath:
            path: /data/consul

如何是单点部署的话,只需要修改consul-statefulset.yaml内容为:

XML 复制代码
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: consul
  namespace: consul
  labels:
    name: consul
spec:
  serviceName: consul
  selector:
    matchLabels:
      name: consul
  replicas: 1
  template:
    metadata:
      labels:
        name: consul
    spec:
      terminationGracePeriodSeconds: 10
      nodeSelector:
        nodeType: consul
      containers:
        - name: consul
          image: hashicorp/consul:1.17.3
          imagePullPolicy: IfNotPresent
          args:
            - "agent"
            - "-server"
            - "-dev" # 启用开发模式,取消选举机制
            - "-ui"
            - "-data-dir=/consul/data"
            - "-bind=0.0.0.0"
            - "-client=0.0.0.0"
            - "-advertise=$(POD_IP)"
            - "-domain=cluster.local"
            - "-disable-host-node-id"
          env:
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - containerPort: 8500
              name: http
            - containerPort: 8400
              name: rpc
            - containerPort: 8443
              name: https-port
            - containerPort: 8301
              name: serf-lan
            - containerPort: 8302
              name: serf-wan
            - containerPort: 8600
              name: consul-dns
            - containerPort: 8300
              name: server
          volumeMounts:
            - name: data-volume
              mountPath: /consul/data
      volumes:
        - name: data-volume
          hostPath:
            path: /data/consul

保存为 consul-server-statefulset.yaml,并运行:

XML 复制代码
kubectl create -f consul-statefulset.yaml

3.创建DNS Service:

Consul Dns Service将负责consul_web的访问入口,服务的注册地址:

bash 复制代码
# 新建consul-server-http.yaml

touch consul-server-http.yaml
bash 复制代码
apiVersion: v1
kind: Service
metadata:
  name: consul-server-http
  namespace: consul   # 添加 namespace 字段并设置为 consul
spec:
  selector:
    name: consul
  type: NodePort
  ports:
    - protocol: TCP
      port: 8500
      targetPort: 8500
      nodePort: 30018
      name: consul-server-tcp

保存为 consul-server-http.yaml,并运行:

bash 复制代码
kubectl create -f consul-server-http.yaml

4.验证部署:

你可以通过检查 Pod 是否在预期的节点上运行来验证部署:

bash 复制代码
kubectl get pods -o wide -n consul

可以看到3个consul server pod已正常启动并绑定到10.10.100.44 10.10.50.72 10.10.50.71 指定节点上:

随便找三台中的一个nodeip+30018端口打开consul_webui确定节点选举机制是否正常,在UI界面的Nodes栏可以看到,选举机制生效

bash 复制代码
在浏览器中访问 http://10.10.100.44:30018

5.服务注册:

k8s集群内部服务需要注册conusl服务只需要在启动参数中添加consul的注册地址端口和具体要注册的服务的key,即可实现服务的配置注册引用:

bash 复制代码
 Args:
      --consul-addr
      consul-server.consul:8500
      --consul-key
      /app/dev/account_module
相关推荐
鹤落晴春9 小时前
【K8s】Pod调度、configMaps
云原生·容器·kubernetes
张忠琳9 小时前
【runc 1.4.2】(Part 2)runc 1.4.2 超深度分析 — CLI层:main.go、命令文件、runner、信号处理、TTY
云原生·kubernetes·runc
Plastic garden15 小时前
K8s知识(3) Pod亲和性,调度
云原生·容器·kubernetes
张忠琳16 小时前
【client-go v0.36.1】(store Part 1)Store 超深度分析 — 模块定位、接口层次、类结构、KeyFunc体系、构造初始化
云原生·kubernetes·informer·store·client-go
眠りたいです18 小时前
LangChainv1:agent快速上手与中间件认识
人工智能·python·中间件·langchain·langgraph
开发者联盟league18 小时前
使用jenkins pipeline将项目打包运行在k8s上报错kubectl: Permission denied
java·kubernetes·jenkins
成为你的宁宁18 小时前
【Prometheus Operator 监控 K8S集群的Calico 与 Ingress-Nginx 组件】
kubernetes·prometheus
Web打印18 小时前
HttpPrinter Web打印中间件 wiki.httpprinter.com 知识库内容总结
前端·中间件
sbjdhjd19 小时前
04 (下) | K8S微服务实战:从 Service 到金丝雀发布
运维·微服务·云原生·kubernetes·开源·云计算·excel