k8s--Ingress 介绍、ingress-nginx(一)

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: k8s--Ingress 介绍、ingress-nginx

Ingress 介绍


在前面我们已经知道,Service 对集群之外暴露服务的主要方式有两种:NodePort 和 LoadBalance,但是这两种方式,都有一定的缺点

  • NodePort 方式的缺点是会占用很多集群机器的端口,那么当集群服务变多的时候,这个缺点就更加明显
  • LoadBalance 的缺点是每个 Service 需要一个 LoadBalance,浪费、麻烦,并且需要 kubernetes 之外设备的支持

基于这种现状,kubernetes 提供了 ingress 资源对象,ingress 只需要一个 NodePort 或者一个 LoadBalance 就可以满足暴露多个 Service 的需要,工作机制大致如下图所示:

实际上,Ingress 相当于一个 7 层的负载均衡器,是 kubernetes 对反向代理的一个抽象,它的工作原理类似于 Nginx,可以理解成在 Ingress 里建立诸多映射规则,Ingress Controller 通过监听这些配置规则并转化成 Nginx 的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:

  • ingress:kubernetes 中的一个对象,作用是定义请求如何转发到 service 的规则
  • ingress controller:具体实现反向代理及负载均衡的程序,对 ingress 定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如 Nginx, Contour, Haproxy 等等

Ingress(以Nginx为例)的工作原理如下:

  1. 用户编写 Ingress 规则,说明哪个域名对应 kubernetes 集群中的哪个 Service
  2. Ingress 控制器动态感知 Ingress 服务规则的变化,然后生成一段对应的 Nginx 反向代理配置
  3. Ingress 控制器会将生成的 Nginx 配置写入到一个运行着的 Nginx 服务中,并动态更新
  4. 到此为止,其实真正在工作的就是一个 Nginx 了,内部配置了用户定义的请求转发规则

lngress-nginx可解决的问题

  • 动态配置服务:如果按照传统方式, 当新增加一个服务时, 我们可能需要在流量入口加一个反向代理指向我们新的 k8s 服务. 而如果用了 Ingress-nginx, 只需要配置好这个服务, 当服务启动时, 会自动注册到 Ingress 的中, 不需要额外的操作
  • 减少不必要的端口映射:配置过 k8s 的都清楚, 第一步是要关闭防火墙的, 主要原因是 k8s 的很多服务会以 NodePort 方式映射出去, 这样就相当于给宿主机打了很多孔, 既不安全也不优雅. 而 Ingress 可以避免这个问题, 除了 Ingress 自身服务可能需要映射出去, 其他服务都不要用 NodePort 方式


ingress-nginx 实战


官网:https://kubernetes.github.io/ingress-nginx/

创建一个命名空间 zouzou

# 创建命名空间 zouzou
kubectl create ns zouzou
创建 httpd 服务、Service 资源对象

创建一个 httpd-01.yaml 的文件,内容如下

apiVersion: apps/v1
kind: Deployment  # 类型为 Deployment
metadata:
  name: web01  # Deployment 的名称
  namespace: zouzou  # ns
spec:
  replicas: 3  # 3 个副本数
  selector:  # 标签选择器
    matchLabels:
      app: httpd01
  template:
    metadata:
      labels:
        app: httpd01
    spec:
      containers:
      - name: httpd
        image: httpd:2.4  # 镜像
---
apiVersion: v1
kind: Service  # 类型为 Service
metadata:
  name: httpd-svc  # svc 的名称
  namespace: zouzou
spec:
  selector:
    app: httpd01  # 选择标签为 app=httpd01 的 pod,也就是上面的
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

运行 yaml 文件

# 创建 Deployment 和 Service
[root@dce-10-6-215-215 tmp]# kubectl apply -f httpd-01.yaml
deployment.apps/web01 created
service/httpd-svc created

运行完等会查看是否正常启动

# 查看 pod、svc、deployment
[root@dce-10-6-215-215 tmp]# kubectl get pod,svc,deploy -n zouzou
NAME                         READY   STATUS    RESTARTS   AGE
pod/web01-7445cbbd94-hrb2p   1/1     Running   0          7m9s
pod/web01-7445cbbd94-qx6np   1/1     Running   0          7m9s
pod/web01-7445cbbd94-s5z9v   1/1     Running   0          7m10s
NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/httpd-svc   ClusterIP   172.31.63.225   <none>        80/TCP    7m9s
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web01   3/3     3            3           7m10s
创建 tomcat 服务及 service

创建一个 tomcat-01.yaml 文件,内容如下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web02  # deployment 的名称
  namespace: zouzou
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat01
  template:
    metadata:
      labels:
        app: tomcat01  # label
    spec:
      containers:
      - name: tomcat
        image: tomcat:8-jdk8  # 镜像
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc  # svc 名称
  namespace: zouzou
spec:
  selector:
    app: tomcat01  # 匹配 app=tomcat01 的 pod
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080

运行 yaml 文件

# 创建 deployment 和 svc
[root@dce-10-6-215-215 tmp]# kubectl apply -f tomcat-01.yaml
deployment.apps/web02 created
service/tomcat-svc created

在来查看 pod 和 svc 是否都正常

# 查看 pod,svc,deployment
[root@dce-10-6-215-215 tmp]# kubectl get pod,svc,deploy -n zouzou
NAME                         READY   STATUS    RESTARTS   AGE
pod/web01-7445cbbd94-hrb2p   1/1     Running   0          22m
pod/web01-7445cbbd94-qx6np   1/1     Running   0          22m
pod/web01-7445cbbd94-s5z9v   1/1     Running   0          22m
pod/web02-fff958574-9j7cl    1/1     Running   0          57s
pod/web02-fff958574-c9hz9    1/1     Running   0          57s
pod/web02-fff958574-v77cc    1/1     Running   0          57s
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/httpd-svc    ClusterIP   172.31.63.225   <none>        80/TCP     22m
service/tomcat-svc   ClusterIP   172.31.116.87   <none>        8080/TCP   57s
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web01   3/3     3            3           22m
deployment.apps/web02   3/3     3            3           57s

使用 cluster-ip 访问 pod 看能否访问成功

# 访问 httpd
[root@dce-10-6-215-215 tmp]# curl 172.31.63.225
<html><body><h1>It works!</h1></body></html>
# 访问 tomcat,因为没有页面,所以是 404
[root@dce-10-6-215-215 tmp]# curl 172.31.116.87:8080
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/8.5.73</h3></body></html>[root@dce-10-6-215-215 tmp]#
创建 Ingress-nginx 资源对象

创建文件夹 ingress-controller 存放 ingress-nginx 的 yaml 文件

# 创建文件夹
[root@dce-10-6-215-215 tmp]# mkdir ingress-controller
# 进入到文件夹里面
[root@dce-10-6-215-215 tmp]# cd ingress-controller/
[root@dce-10-6-215-215 ingress-controller]#

获取 ingress-nginx,本次案例使用的是0.30版本

# 获取 ingress-nginx,本次案例使用的是0.30版本
[root@dce-10-6-215-215 ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
[root@dce-10-6-215-215 ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml

下载完成之后查看

[root@dce-10-6-215-215 ingress-controller]# ls
mandatory.yaml  service-nodeport.yaml

修改 mandatory.yaml 文件中的代码

关于上面 yaml 文件中写入的 “hostNetwork: true” 具体解释:如果使用此网络参数,那么 pod 中运行的应用程序可以直接使用 Node 节点端口,这样 node 节点主机所在的网络的其他主机,都可以通过访问到此应用程序。

修改完成之后运行 mandatory.yaml 文件

[root@dce-10-6-215-215 ingress-controller]# kubectl apply -f mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
limitrange/ingress-nginx created

确定 Ingress-nginx 容器运行正常

# 确定 Ingress-nginx 容器运行正常,注意,namespace 是在 ingress-nginx 下
[root@dce-10-6-215-215 ingress-controller]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-5fc65f5fd7-tcskb   1/1     Running   0          29m

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
Kubernetes 应用服务中间件 nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
|
2月前
|
Kubernetes 监控 测试技术
k8s学习--基于Ingress-nginx实现灰度发布系统
k8s学习--基于Ingress-nginx实现灰度发布系统
113 2
k8s学习--基于Ingress-nginx实现灰度发布系统
|
2月前
|
Kubernetes 负载均衡 应用服务中间件
k8s学习--ingress详细解释与应用(nginx ingress controller))
k8s学习--ingress详细解释与应用(nginx ingress controller))
223 0
|
2月前
|
Kubernetes 应用服务中间件 nginx
k8s基础使用--使用k8s部署nginx服务
本文介绍了Kubernetes中核心概念Deployment、Pod与Service的基本原理及应用。Pod作为最小调度单元,用于管理容器及其共享资源;Deployment则负责控制Pod副本数量,确保其符合预期状态;Service通过标签选择器实现Pod服务的负载均衡与暴露。此外,还提供了具体操作步骤,如通过`kubectl`命令创建Deployment和Service,以及如何验证其功能。实验环境包括一台master节点和两台worker节点,均已部署k8s-1.27。
203 1
|
4月前
|
缓存 Kubernetes 应用服务中间件
使用Kubernetes中的Nginx来改善第三方服务的可靠性和延迟
使用Kubernetes中的Nginx来改善第三方服务的可靠性和延迟
33 3
|
5月前
|
Kubernetes Java 应用服务中间件
Kubernetes 上搭建一个 Nginx 的 Pod,并确保传入的 API 请求被均匀地分发到两个 Java 业务 Pod 上
Kubernetes 上搭建一个 Nginx 的 Pod,并确保传入的 API 请求被均匀地分发到两个 Java 业务 Pod 上
84 0
|
7月前
|
Kubernetes 搜索推荐 应用服务中间件
通过keepalived+nginx实现 k8s apiserver节点高可用
通过keepalived+nginx实现 k8s apiserver节点高可用
409 17
|
7月前
|
弹性计算 应用服务中间件 文件存储
容器服务ACK+容器网络文件系统CNFS快速搭建NGINX网站
本文介绍如何在半小时内,通过阿里云容器ACK服务和CNFS容器网络文件系统服务搭建一个简单的弹性、高可用NGINX网站。在完成本文的所有操作后,您将获得一个单网页的网站,用户的请求将会被打散到多个容器节点上,并且根据业务负载自动扩缩容,即使某个容器节点宕机也不会影响用户访问。另外您还可以将本地编辑的网页快速更新到网站上。
210 0
容器服务ACK+容器网络文件系统CNFS快速搭建NGINX网站
|
13天前
|
Kubernetes 监控 Cloud Native
Kubernetes集群的高可用性与伸缩性实践
Kubernetes集群的高可用性与伸缩性实践
46 1
|
2月前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景