K8S通过Ingress和外部负载均衡暴露服务

一. 背景知识

Kubernetes 通过 Ingress 暴露服务有两种方案:

  1. 将服务的域名直接指向到其中一台 worker 节点上. 这种方式将流量集中到这一台 worker 节点上, 容易引起单点故障, 故只适用于开发, 测试, 和Demo环境. 示意图如下:image.png
  2. 将服务的域名指向独立负载均衡服务到所有 worker 节点, 而 Ingress 会监听所有 worker 节点上的流量并进行相应的分发, 从而保证正确的服务.
    在这种方案下, 即便我们不是所有的节点都启动了该服务的容器, Ingress也会正确分发. 比如我们我们有 3 个 worker 节点: ttg12 / ttg13 / ttg14, 而服务对应的 Deployment 中设置的 replica=2, 也就是只启动2个副本. 假设这2个容器启动在 ttg12 和 ttg13 上. 这时候, 负载均衡服务器上转发的流量也会打到 ttg14 上, 虽然这个节点本身并没有对应的 pod, 但通过 Ingress, 也能正常地提供服务. 示意图如下:
    image.png

二. 部署

本文示例部署一个 lb-tomcat9.faceless.cn 的域名指向 负载均衡服务器, 并通过 Ingress 提供服务.

2.1 部署 Deployment 和 Service

本地新建文件 lb-tomcat9-svc.yaml:

apiVersion: apps/v1
kind: Deployment 
metadata: 
  name: tomcat9-dev-dpl
  labels:
    app: tomcat9
    env: dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: tomcat9
      env: dev
  template:
    metadata:
      labels:
        app: tomcat9
        env: dev
    spec:
      containers:
      - name: tomcat9
        image: tomcat:9.0.37-jdk8-openjdk
        ports:
        - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: tomcat9-dev-svc
  labels:
    app: tomcat9
    env: dev
spec:
  selector:
    app: tomcat9
    env: dev
  ports:
  - name: nginx-port
    protocol: TCP
    port: 8080
    targetPort: 8080

应用本配置文件:

kubectl apply -f lb-tomcat9-svc.yaml

输出:

deployment.apps/tomcat9-dev-dpl created
service/tomcat9-dev-svc created

2.2 部署 Ingress

在本地新建 Ingress 配置 lb-tomcat9-ingress.yaml, 将 lb-tomcat9.faceless.cn 域名下的所有流量分发给 tomcat9-dev-svc 服务:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: lb-tomcat9-ingress
spec:
  rules:
  - host: lb-tomcat9.faceless.cn
    # Ingress 的 `http` 端口为 80, 对应在负载均衡配置文件中 **upstream** 模块下配置的端口
    http:
      paths: 
      - path: /
        backend:
          serviceName: tomcat9-dev-svc
          servicePort: 8080

应用本配置文件:

kubectl apply -f lb-tomcat9-ingress.yaml

输出:

ingress.networking.k8s.io/lb-tomcat9-ingress configured

注意 Ingress 除了部署资源之外, 还需要对应的 Ingress Controller. 本文使用 Nignx 出厂的 nginx/nginx-ingress 控制器. 可使用 Kuboard 教程中的配置脚本安装:

kubectl apply -f https://kuboard.cn/install-script/v1.18.x/nginx-ingress.yaml

具体请参考: https://kuboard.cn/install/install-k8s.html#安装-ingress-controller.

另外关于 Nginx Ingress 的两种不同实现, 请参考我的另一篇博文: K8S Ingress控制器两个实现版本(kubernetes-ingress 和 ingress-nginx)的区别.

2.3 验证是否生效

先通过 kubectl get pods | grep tomcat9-dev-dpl 确认 2 个 pods 的状态都已为 Running.

然后在本地通过 /etc/hostslb-tomcat9.faceless.cn 域名分别执行 ttg12 / ttg13 / ttg14 对应的 IP, 并访问 http://lb-tomcat9.faceless.cn, 查看这3个IP是否都能正常返回.

2.4 部署 负载均衡

本文负载均衡 (Load Balancer) 使用 Nginx 实现, 对应的配置文件为:

# 这里定义了一个名称为`lb_tomcat9_server`的`上游`, 即负载均衡的目标站点清单
upstream lb_tomcat9_server {
  server ttg12:80;
  server ttg13:80;
  server ttg14:80;
}
# 下面定义`lb-tomcat9.faceless.cn`站点, 将所有流量转发到`lb_tomcat9_server`
server {
    listen       80;
    listen  [::]:80;
    server_name  lb-tomcat9.faceless.cn;

    location / {
    
        proxy_set_header  Host  $http_host;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;


        proxy_pass http://lb_tomcat9_server;
    }

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

更多细节可参考笔记: Docker 容器部署 Nginx 实现负载均衡

阅读 179

推荐阅读