Ingress

Ingress

在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,在Kubernetes中目前提供了以下几种方案:

NodePort

LoadBalancer

Ingress

NodePort:简单的来说就是通过Service资源对象,为后端的Pod提供一个统一的访问入口,然后将Service的统一访问接口映射到集群节点上,最终实现client通过映射到集群节点上的端口访问到后端Pod提供的服务

但是,这种方法有个弊端,就是当新生成一个pod服务就需要创建对应的service将其映射到节点端口,当运行的pod过多时,我们节点暴露给client端的端口也会随之增加,这样我们整个k8s群集的危险系数就会增加,因为我们在搭建群集之处,官方明确指出,必须关闭firewalld防火墙及清空iptables规则,现在我们又暴露了那么多端口给client,安全系数可想而知

Ingress就解决了这个弊端:

简单的理解:原先暴露的service,现在给定一个统一的访问入口

Ingress资源对象的组成:

Ingress-nginx-controller:

将新加入的Ingress转化为反向代理服务器的配置文件,并使之生效(动态的感知k8s集群内Ingress资源的变化,通过lua脚本实现)

Ingress:

将反向代理服务器抽象成一个Ingress对象,每添加一个新的服务,只需要写一个新的Ingress的yaml文件即可,或修改已经存在的Ingress规则的yaml

在k8s集群前边部署一个反向代理服务器,这个服务器代理着k8s集群内部的service资源

Ingress-nginx可以解决什么问题:

动态的配置服务

​ 如果按照传统方式, 当新增加一个服务时, 我们可能需要在流量入口加一个反向代理指向我们新的k8s服务. 而如果用了Ingress-nginx, 只需要配置好这个服务, 当服务启动时, 会自动注册到Ingress的中, 不需要而外的操作

减少不必要的端口暴露

​ 配置过k8s的都清楚, 第一步是要关闭防火墙的, 主要原因是k8s的很多服务会以NodePort方式映射出去, 这样就相当于给宿主机打了很多孔, 既不安全也不优雅. 而Ingress可以避免这个问题, 除了Ingress自身服务可能需要映射出去, 其他服务都不要用NodePort方式

Ingress-nginx工作原理:

1)Ingress controller通过和kubernetes api交互,动态的去感知集群中Ingress规则变化,
2)然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置,
3)再写到nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,
4)然后reload一下使配置生效。以此达到域名分别配置和动态更新的问题

基于Nginx的Ingress controller根据不同的开发公司,又分为两种:

k8s社区版的:Ingress-nginx

nginx公司自己开发的:nginx-ingress

Ingress-nginx配置实例:

1)创建一个web服务,用deployment资源,用httpd奖项,然后创建一个service资源与之关联

[root@master ~]# vim  deploy_1.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: bdqn-ns
  labels:
    name: bdqn-ns

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: httpd-deploy
  namespace:  bdqn-ns
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app:  bdqn-ns
    spec:
      containers:
      - name: httpd
        image:  httpd

---
apiVersion: v1
kind: Service
metadata:
  name: httpd-svc
  namespace:  bdqn-ns
spec:
  type: NodePort
  selector:
    app:  bdqn-ns
  ports:
  - name: httpd-port
    port: 80
    targetPort: 80   
    nodePort: 31033
[root@master ~]# kubectl  apply  -f  deploy_1.yaml 
namespace/bdqn-ns created
deployment.extensions/httpd-deploy created
service/httpd-svc created
[root@master ~]# kubectl  get svc  -n bdqn-ns 
NAME        TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
httpd-svc   NodePort   10.97.86.190   <none>        80:31033/TCP   3m31s
[root@master ~]# kubectl  get pod  -n bdqn-ns 
NAME                           READY   STATUS    RESTARTS   AGE
httpd-deploy-966699d76-25wkn   1/1     Running   0          3m33s
httpd-deploy-966699d76-6cdwf   1/1     Running   0          3m34s
[root@master ~]# kubectl  get deployments. -n bdqn-ns 
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
httpd-deploy   2/2     2            2           3m37s
[root@master ~]# kubectl  describe svc  -n bdqn-ns
Selector:                 app=bdqn-ns
Type:                     NodePort
IP:                       10.97.86.190
Port:                     httpd-port  80/TCP
TargetPort:               80/TCP
NodePort:                 httpd-port  31033/TCP
Endpoints:                10.244.1.2:80,10.244.2.2:80
Session Affinity:         None
External Traffic Policy:  Cluster

2)创建一个web服务,用deployment资源,用tomcat镜像,然后创建一个service资源与之关联

[root@master ~]# vim  deploy_2.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: tomcat-deploy
  namespace:  bdqn-ns
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app:  bdqn-tomcat
    spec:
      containers:
      - name: tomcat
        image:  tomcat:8.5.45

---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
  namespace:  bdqn-ns
spec:
  type: NodePort
  selector:
    app:  bdqn-tomcat
  ports:
  - name: tomcat-port
    port: 8080
    targetPort: 8080   
    nodePort: 32033
[root@master ~]# kubectl  apply  -f  deploy_2.yaml 
deployment.extensions/tomcat-deploy created
service/tomcat-svc created
[root@master ~]# kubectl  get deployments. -n bdqn-ns 
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
httpd-deploy    2/2     2            2           9m58s
tomcat-deploy   2/2     2            2           58s
[root@master ~]# kubectl  get pod -n bdqn-ns 
NAME                             READY   STATUS    RESTARTS   AGE
httpd-deploy-966699d76-25wkn     1/1     Running   0          10m
httpd-deploy-966699d76-6cdwf     1/1     Running   0          10m
tomcat-deploy-759dc8c885-9wgqw   1/1     Running   0          70s
tomcat-deploy-759dc8c885-9xmhj   1/1     Running   0          70s
[root@master ~]# kubectl  get svc -n bdqn-ns 
NAME         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
httpd-svc    NodePort   10.97.86.190   <none>        80:31033/TCP     10m
tomcat-svc   NodePort   10.98.122.36   <none>        8080:32033/TCP   75s

3)创建Ingress -nginx-controller

[root@master ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.29.0/deploy/static/mandatory.yaml
//将yaml文件下载下来
在yaml文件中添加:hostNetwork: true
    spec:    //在212行的spec字段下添加
      hostNetwork:  true   //添加这行就行
      # wait up to five minutes for the drain of connections
[root@master ~]# kubectl  apply  -f  mandatory.yaml
[root@master ~]# kubectl  get pod -n  ingress-nginx 
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-5954d475b6-xtzbc   1/1     Running   0          16m

hostNetwork: true

在deployment资源中,如果添加了此字段,意味着Pod中运行的应用可以直接使用node节点的端口,这样node节点主机所在网络的其他主机,就可以通过访问该端口访问此应用。(类似于docker映射到宿主机的端口)

4)创建Ingress资源:(定义Ingress规则)

[root@master ~]# vim  ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: bdqn-ingress
  namespace:  bdqn-ns
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target:  / #这个千万不要写错,不然后面无法访问
spec:
  rules:
  - host: ingress.bdqn.com
    http:
      paths:
      - path: /
        backend:
          serviceName:  httpd-svc
          servicePort:  80
      - path: /tomcat
        backend:
          serviceName:  tomcat-svc
          servicePort:  8080
[root@master ~]# kubectl  apply  -f  ingress.yaml 
ingress.extensions/bdqn-ingress created
[root@master ~]# kubectl  describe  ingresses. -n bdqn-ns  bdqn-ingress
Rules:
  Host              Path  Backends
  ----              ----  --------
  ingress.bdqn.com  
                    /         httpd-svc:80 (10.244.1.5:80,10.244.2.4:80)
                    /tomcat   httpd-tomcat:8080 (10.244.1.4:8080,10.244.2.5:8080)
//如果没有这个信息说明Ingress创建的有问题 
[root@master ~]# kubectl  exec  -it  -n  ingress-nginx  nginx-ingress-controller-5954d475b6-wkqr2  sh
/etc/nginx $ cat  nginx.conf
//没创建Ingress之前这些值都是空的,这就是动态的感知,然后写入配置文件
		location / {
			
			set $namespace      "bdqn-ns";
			set $ingress_name   "bdqn-ingress";
			set $service_name   "httpd-svc";
			set $service_port   "80";
			set $location_path  "/";
		location ~* "^/tomcat" {
			
			set $namespace      "bdqn-ns";
			set $ingress_name   "bdqn-ingress";
			set $service_name   "tomcat-svc";
			set $service_port   "8080";
			set $location_path  "/tomcat";

因为域名是自定义的,所以要配置域名解析,修改windows的host文件,将IP与域名绑定

//查看Ingress-controller运行在哪个节点,IP 是 ingress-controller  Pod运行所在的节点
[root@master ~]# kubectl get pod -n  ingress-nginx -o wide
NAME                                        READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
nginx-ingress-controller-5954d475b6-wkqr2   1/1     Running   1          44h   192.168.1.50   node01   <none>           <none>
//找到host文件,进行修改
C:\Windows\System32\drivers\etc
192.168.1.50  ingress.bdqn.com

现在已经达到了我们想要的功能,现在可以通过ingress.bdqn.com访问httpd服务,通过ingress.bdqn.com/tomcat访问tomcat服务
在这里插入图片描述
在这里插入图片描述

在上面的访问测试中,虽然访问到了对应的服务,但是有一个弊端,就是在做DNS解析的时候,只能指定Ingress-nginx容器所在的节点IP。而指定k8s集群内部的其他节点IP(包括master)都是不可以访问到的,如果这个节点一旦宕机,Ingress-nginx容器被转移到其他节点上运行(不考虑节点标签的问题,其实保持Ingress-nginx的yaml文件中默认的标签的话,那么每个节点都是有那个标签的)。随之还要我们手动去更改DNS解析的IP(要更改为Ingress-nginx容器所在节点的IP,通过命令“kubectl get pod -n ingress-nginx -o wide”可以查看到其所在节点),很是麻烦

所以就要为ingress资源对象创建一个Service(NodePort),这样在配置DNS解析的时候,就可以通过Ingress.bdqn.com 所有node节点,包括master节点的IP来配置,很方便

5)创建service资源:

[root@master ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.29.0/deploy/static/provider/baremetal/service-nodeport.yaml
[root@master ~]# kubectl  apply  -f  service-nodeport.yaml
[root@master ~]# kubectl  get svc -n ingress-nginx 
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.100.167.12   <none>        80:32756/TCP,443:30501/TCP   2m7s

Service-Nodeport

因为Ingress-nginx-controller运行在了集群内的其中一个节点,为了保证即使这个节点宕机,我们对应的域名仍然能够正常的访问服务,所以我们将Ingress-nginx-controller也暴露为一个service资源

至此,这个域名就可以和集群中任意节点的 32756/30501端口进行绑定了
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ingress 502错误是指在访问Ingress时服务器返回的错误代码。具体表示服务器出现了一些问题,无法提供所请求的页面。 当我们在浏览器访问一个网站时,我们的请求首先会发送到服务器,服务器会进行处理并返回响应给我们的浏览器。在这个过程中,如果服务器在处理我们的请求时遇到了错误,就会返回相应的错误代码。而Ingress 502错误代码则意味着服务器在处理我们的请求时遇到了问题。 Ingress 502错误可能是由于以下几个原因引起的: 1. 服务器过载:服务器处理请求的速度没有跟上请求的速度,导致一些请求无法正常处理,从而返回502错误。 2. 后端服务器故障:服务器上的后端应用程序或数据库等出现了故障,导致服务器无法处理请求。 3. 代理服务器问题:在使用代理服务器时,代理服务器本身出现了问题,无法正常将请求转发到目标服务器。 对于用户而言,遇到Ingress 502错误时,我们建议可以尝试以下几个解决方法: 1. 刷新页面:有时候502错误是暂时的,刷新页面可能会解决问题。 2. 等待一段时间:如果是服务器过载导致的错误,可以等待一段时间后再次尝试访问。 3. 检查网络连接:检查自己的网络连接是否正常,尝试连接其他网站,以确定是否是自己的网络问题。 4. 与网站管理员联系:如果以上方法都无效,可以尝试联系网站管理员报告问题,让其能够及时处理服务器问题。 总的来说,Ingress 502错误代码表示服务器无法正常处理请求,可能是由于服务器过载或故障等原因引起的。需要用户尝试刷新页面、等待一段时间、检查网络连接或与网站管理员联系来解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值