【kubernetes】Ingress和Ingress-Controller介绍,高可用应用案例

一,Ingress介绍

Ingress是k8s中一种重要的资源对象,它主要用于定义从集群外部到集群内部服务的HTTP(S)路由规则。用于管理代理 Ingress-Controller的配置文件。

python 复制代码
kubectl explain ingress

二,Ingress-Controller介绍

Ingress Controller 是 Kubernetes 集群中的一个组件,是一个七层的负载均衡调度器,它负责实现 Ingress 资源对象中定义的路由规则。

Ingress Controller 的具体实现可以多种多样,包括但不限于 Nginx、HAProxy、Traefik、Istio 等。每种 Ingress Controller 都有其独特的特性和优势,但它们的共同目标都是根据 Ingress 资源中的定义来管理外部到集群内部服务的 HTTP(S) 流量。

三,Ingress和Ingress Controller

1,共同作用

Ingress Controller结合Ingress 定义的规则生成配置,然后动态更新ingress-controller里的Nginx 或者trafik负载均衡器,并刷新使配置生效,来达到服务自动发现的作用。

Ingress 则是定义规则,通过它定义某个域名的请求过来之后转发到集群中指定的 Service。它可以通过 Yaml 文件定义,可以给一个或多个 Service 定义一个或多个 Ingress 规则。

2,使用Ingress Controller代理步骤

(1)部署Ingress controller(以nginx为例部署)。

(2)创建Pod应用,可以通过控制器(DeploymentStatefulset等)创建pod。

(3)创建Service,用selector来分组pod。

(4)创建Ingress http/https,测试通过 http/https 访问应用。

四,高可用

根据Deployment+ nodeSeletor+pod反亲和性方式部署在k8s指定的两个work节点,然后通过keepalive+nginx实现nginx-ingress-controller高可用(框架如下图所示)。

1,安装ingress-controller

下载镜像及yaml文件安装:ingress-nginx-controller.v1.1.1.tar.gz

python 复制代码
# 安装
kubectl apply -f ingress-deploy.yaml

【如果报错】:

【解决办法】

执行一下命令,然后再次尝试创建内容!

python 复制代码
kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission

至此,两个ingress-controller的pod,由于采用反亲和性,分别部署到两个节点上。

2,安装 配置keeplived+nginx

实现前端虚拟IP(VIP),两节点node机器上相互"漂移"。

(1)两台node节点分别安装
python 复制代码
yum install  epel-release  nginx keepalived nginx-mod-stream  -y
(2)更改nginx.conf
python 复制代码
# cat /etc/nginx/nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

# 增加一下内容:为两台apiserver组件提供负载均衡
stream {

    log_format  main  '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';

    access_log  /var/log/nginx/k8s-access.log  main;

    upstream k8s-ingress-controller {
       server 192.168.40.181:80 weight=5 max_fails=3 fail_timeout=30s;   # node1的IP:PORT
       server 192.168.40.182:80 weight=5 max_fails=3 fail_timeout=30s;   # node2 的IP:PORT
    }
    
    server {
       listen 30080; # 该监听端口需要大于30000-32000左右
       proxy_pass k8s-ingress-controller;
    }
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    
}

【备注】:

  • server 反向服务地址和端口
  • weight 主机权重
  • max_fails 最大失败次数,达到该数值,则认为主机已挂掉,踢出
  • fail_timeout 踢出后重新探测时间
  • nginx监听端口变成大于30000的端口,才能代理ingress-controller。(比方说30080,问域名:30080)
(3)keepalive配置

主节点 和 备节点服务器的配置不同。

python 复制代码
# cat /etc/keepalived/keepalived.conf 

global_defs { 
   notification_email { 
     acassen@firewall.loc 
     failover@firewall.loc 
     sysadmin@firewall.loc 
   } 
   notification_email_from Alexandre.Cassen@firewall.loc  
   smtp_server 127.0.0.1 
   smtp_connect_timeout 30 
   router_id NGINX_MASTER
} 

vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
}

vrrp_instance VI_1 { 
    state MASTER 
    interface ens33      # 修改为实际网卡名
    virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的 
    priority 100         # 优先级,备服务器设置 90 
    advert_int 1         # 指定VRRP 心跳包通告间隔时间,默认1秒 
    authentication { 
        auth_type PASS      
        auth_pass 1111 
    }  
    # 虚拟IP
    virtual_ipaddress { 
        192.168.40.199/24  # 该网段需和物理机ip为同一个网段
    } 
    track_script {
        check_nginx
    } 
}

【注意】:

  • vrrp_script:指定检查nginx工作状态脚本(根据nginx状态判断是否故障转移)
  • virtual_ipaddress:
    • 虚拟IP(VIP)
    • 192.168.40.199/24 # 该网段需和物理机ip为同一个网段
    • 该ip地址不能被占用,需要ping一下查看

【主/备配置参数区别】:

主服务(node01) 备服务(node02)
state MASTER BACKUP
priority 100 90
(4)配置检测脚本check_nginx.sh
powershell 复制代码
# cat check_nginx.sh

#!/bin/bash
#1、判断Nginx是否存活
counter=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$" )
if [ $counter -eq 0 ]; then
    #2、如果不存活则尝试启动Nginx
    service nginx start
    sleep 2
    #3、等待2秒后再次获取一次Nginx状态
    counter=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$" )
    #4、再次进行判断,如Nginx还不存活则停止Keepalived,让地址进行漂移
    if [ $counter -eq 0 ]; then
        service  keepalived stop
    fi
fi

添加授权,拥有可执行权限:chmod +x check_nginx.sh

(5)两台node主机节点按顺序依次启动
python 复制代码
systemctl daemon-reload
systemctl enable nginx keepalived
systemctl start nginx
systemctl start keepalived
(6)测试vip是否绑定成功

查看vip绑定位置:

通过停止keepalived,看看vip的位置,是否"漂移"!!!

3,控制器(deploy)创建pod及service

yaml 复制代码
# cat ingress-service-pod.yaml

apiVersion: v1
kind: Service
metadata:
  name: ingress-service      # 创建service名称
  namespace: ingress-nginx   # 指定命名空间
  labels:
    app: ingress-service     # service自己标签
spec:
  selector: 
    app: ingress-pod         # service 筛选pod标签
    version: v1
  type: ClusterIP
  ports:
  - port: 80                 # service对外暴露的端口
    targetPort: 80           # 指定流量转发pod的目标端口
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-deploy
  labels: 
    app: ingress-deploy-pod
    version: v1
  namespace: ingress-nginx
spec:
  replicas: 3
  revisionHistoryLimit: 8
  selector:
    matchLabels:
      app: ingress-pod
      version: v1
  strategy:
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: ingress-pod
        version: v1
      namespace: ingress-nginx
    spec:
      containers:
      - name: ingress-nginx-pod
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - name: web-port
          containerPort: 80
          protocol: TCP
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"  

4,创建ingress

yaml 复制代码
# cat ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: 
  name: ingress-web
  namespace: ingress-nginx
  labels:
    app: ingress-web
    version: v1
spec:
  ingressClassName: nginx  
  rules:
  - host: mdy.ingressweb.com        # 指定访问的域名
    http:
      paths:
      - backend:
          service:
            name: ingress-service   # 指定之前创建service的名称
            port:        
              number: 80            # 指定service的端口
        path: /                     # 指定访问的路径
        pathType: Prefix            

5,访问域名 http://mdy.ingressweb.com

本地主机host绑定:

python 复制代码
192.168.40.199  mdy.ingressweb.com

6,构建Ingress HTTPS代理访问

HTTPS域名访问,需要购买证书,测试本地自建证书即可!

(1)创建并进入tls目录, 创建域名 mdy.ingressweb2.com证书
python 复制代码
# cd /root/ingress/tls

openssl genrsa -out tls-name.key 2048

# 指定具体域名mdy.ingressweb2.com
openssl req -new -x509 -key tls-name.key -out tls-name.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=mdy.ingressweb2.com
(2)根据域名证书,创建生成secret
python 复制代码
kubectl create secret tls ingress-secret --cert=tls-name.crt --key=tls-name.key

【注意】
kubectl create secret tls:为生产工具(tls为证书类型),固定写法。

(3)基于上面生产的ingress.yaml更改配置
yaml 复制代码
# cat ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-web-https
  namespace: ingress-nginx
  labels:
    app: ingress-web
    version: v1
spec:
  ingressClassName: nginx
  tls:                            # 定义证书
  - hosts:                        # 定义hosts
    - mdy.ingressweb2.com         # 指定域名(已被证书签发)
    secretName: ingress-secret
  rules:
  - host: mdy.ingressweb2.com
    http:
      paths:
      - backend:
          service:
            name: ingress-service
            port:
              number: 80
        path: /
        pathType: Prefix            
(4)访问域名 https://mdy.ingressweb2.com

本地主机host绑定:

python 复制代码
192.168.40.199  mdy.ingressweb2.com


相关推荐
慌糖29 分钟前
微服务介绍
微服务·云原生·架构
高山莫衣6 小时前
Docker Desktop导致存储空间不足时的解决方案
docker·容器·eureka
鹏大师运维6 小时前
在银河麒麟V10 SP1上手动安装与配置高版本Docker的完整指南
linux·运维·docker·容器·麒麟·统信uos·中科方德
Ahlson6 小时前
【fnNAS】docker的nginx配置html
nginx·docker·容器·fnnas
LuckyLay6 小时前
Compose 常用命令详解——AI教你学Docker
docker·容器·eureka
阿里云云原生6 小时前
阿里云可观测 2025 年 6 月产品动态
云原生
阿里云云原生6 小时前
30 秒锁定黑客攻击:SLS SQL 如何从海量乱序日志中“揪”出攻击源
云原生
moppol7 小时前
容器化 vs 虚拟机:什么时候该用 Docker?什么时候必须用 VM?
运维·docker·容器
没有名字的小羊7 小时前
7.可视化的docker界面——portainer
docker·容器·eureka
斯普信专业组8 小时前
K8s环境下基于Nginx WebDAV与TLS/SSL的文件上传下载部署指南
nginx·kubernetes·ssl