【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


相关推荐
全能全知者1 小时前
docker快速安装与配置mongoDB
mongodb·docker·容器
为什么这亚子3 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
ZHOU西口4 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
牛角上的男孩5 小时前
Istio Gateway发布服务
云原生·gateway·istio
JuiceFS6 小时前
好未来:多云环境下基于 JuiceFS 建设低运维模型仓库
运维·云原生
景天科技苑7 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge8 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇8 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
川石课堂软件测试10 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
昌sit!16 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes