Ingress

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: Ingress

屏幕截图 2023-08-28 163846.png

一、Ingress 简介

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

   NodePort

    LoadBalancer(负载均衡)

    Ingress(入口)

-----------------------------------------

Ingress 组成:ingress controller、ingress服务

ingress controller:

 将新加入的Ingress转化成Nginx的配置文件并使之生效

ingress服务:

 将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可

Ingress 工作原理

1. ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化,

2. 然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置

3. 再写到nginx-ingress-control的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中

4. 然后reload一下使配置生效。以此达到域名分配置和动态更新的问题。

Ingress参考网站:

  https://github.com/kubernetes/ingress-nginx

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

--------------------------------------------------

Ingress 可以解决什么问题

1.动态配置服务

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

2.减少不必要的端口暴露

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

-------------------------------------------

实验需求:

创建2个Deployment,

   第一个: nginx镜像,replicas:3  

   第二个: httpd镜像,replicas:4

创建2个SVC资源,

   第一个和第一个Deploy绑定。

   第二个和第二个Deploy绑定。

//这里是deploy1,deploy2的yaml文件。

```yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: deploy1
spec:
 selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
```yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: deploy2
spec:
  selector:
    matchLabels:
      app: httpd
  replicas: 4
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd
        imagePullPolicy: IfNotPresent

//创建对应的SVC资源,并与上述Deployment相互关联。

```yaml
kind: Service
apiVersion: v1
metadata:
  name: svc1
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
```yaml
kind: Service
apiVersion: v1
metadata:
  name: svc2
spec:
  selector:
    app: httpd
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

二、部署Ingress

//部署Ingress-controller.可以在GitHub:https://github.com/kubernetes/ingress-nginx上找到,这里我们部署的是Ingress:0.35.0版本

//这里我们可以先保存Ingress的yaml文件,可以查看都做了什么,也方便我们后期管理

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.35.0/deploy/static/provider/baremetal/deploy.yaml

//这里使用的镜像,是国外的镜像,需要提前下载获得。

#docker pull pollyduan/ingress-nginx-controller:v0.35.0

#docker tag pollyduan/ingress-nginx-controller:v0.35.0 k8s.gcr.io/ingress-nginx/controller:v0.35.0

//复制并编辑这个文件deploy.yaml。启用hostNetwork网络,添加 hostNetwork: true即可。 如果在Pod中使用hostNetwork:true配置网络,那么Pod中运行的应用程序可以直 接使用node节点的端口,这样node节点主机所在网络的其他主机,都可以通过该端 口访问到此应用程序。

[root@master ingress]# vim deploy.yaml
... ...
330       hostNetwork: true               #添加本行
331       dnsPolicy: ClusterFirst
332       containers:
333         - name: controller
334           image: k8s.gcr.io/ingress-nginx/controller:v0.35.0    #修改本行
335           imagePullPolicy: IfNotPresent
... ...

PS: 添加hostNetwork: true,和更改可用镜像

kubectl apply -f deploy.yaml

//确保Pod正常运行。

[root@master ingress]# kubectl get po -n ingress-nginx  -o wide
NAME                                        READY   STATUS      RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
ingress-nginx-admission-create-qp6jq        0/1     Completed   0          20s   10.244.1.62   node01              
ingress-nginx-admission-patch-qzkfc         0/1     Completed   1          20s   10.244.2.98   node02              
ingress-nginx-controller-6995cf966b-c5mvd   1/1     Running     0          20s   10.244.1.63   node01              
[root@master ingress]# kubectl get svc -n ingress-nginx 
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.109.23.90            80:30105/TCP,443:32457/TCP   3m33s
ingress-nginx-controller-admission   ClusterIP   10.104.13.179           443/TCP                      3m33s
```

//注意:Ingress-controller服务运行之后,还有一个manatora-svc.yaml文件,这个文件,是将

Ingress-controller的Deployment资源对象关联在一起了,也就是说,访问mandatora-svc就能否访问Ingress-controller的Depoyment资源的Pod的了。

//查看其yaml文件,发现它暴露的是NodePort类型。

```yaml
[root@master ingress]# vim mandatory-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
  - name: https
    port: 443
    targetPort: 443
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

//查看Ingress-nginx-controller容器内部详情:可以看到,它现在已经有一个模板,用来描述Ingress资源能够收集到的信息了。

```sh
[root@master ingress]# kubectl get po -n ingress-nginx 
NAME                                       READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-9b4479c74-n6trz   1/1     Running   0          9m42
[root@master ingress]#kubectl exec -it ingress-nginx-controller-9b4479c74-n6trz sh -n ingress-nginx 
/etc/nginx $ cat nginx.conf
...
        location / {        
            set $namespace      "";
            set $ingress_name   "";
            set $service_name   "";
            set $service_port   "";
            set $location_path  "/";
...
```
## 基于httpd的访问
//创建对应的Ingress规则
```yaml
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: bdqn-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: ingress.bdqn.com
    http:
      paths:
      - path: /nginx
        backend:
          serviceName: svc1
          servicePort: 80
      - path: /httpd
        backend:
          serviceName: svc2
          servicePort: 80
```

//查看对应规则的详细信息

[root@master ingress]# kubectl describe ingresses. bdqn-ingress 
Name:             bdqn-ingress
Namespace:        default
Address:          10.106.32.255
Default backend:  default-http-backend:80 ()
Rules:
  Host              Path  Backends
  ----              ----  --------
  ingress.bdqn.com  
                    /nginx   svc1:80 (10.244.1.98:80,10.244.1.99:80,10.244.2.104:80)
                    /httpd   svc2:80 (10.244.1.100:80,10.244.1.101:80,10.244.2.105:80 + 1 more...)
```

//查看对应Pod内,也应该能够解析到对应的:SVC信息

[root@master ingress]# kubectl get pod -n ingress-nginx 
NAME                                       READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-9b4479c74-n6trz   1/1     Running   0          59m
[root@master ingress]# kubectl exec -it -n ingress-nginx ingress-nginx-controller-9b4479c74-n6trz sh
/etc/nginx $ vi nginx.conf
...
                location ~* "^/nginx" {                                           
                        set $namespace      "default";                      
                        set $ingress_name   "bdqn-ingress";                   
                        set $service_name   "svc1";                           
                        set $service_port   "80";                             
                        set $location_path  "/nginx";                               
...
                location ~* "^/httpd" {                                              
                        set $namespace      "default";                      
                        set $ingress_name   "bdqn-ingress";                   
                        set $service_name   "svc2";                           
                        set $service_port   "80";                             
                        set $location_path  "/httpd";                               
...
```

//来模拟访问,这里我们用Windows的浏览器直接访问,因为我们是模拟的域名所以,需要我们在hosts文件内写入对应的域名解析。Windows10的域名解析文件地址:C:\Windows\System32\drivers\etc,更改这个文件的时候,需要提供管理员权限。

//添加域名解析内容,当然,如果你的mandatory没有做对应的svc的话,需要解析IP是ingress-nginx-controller这个Pod运行所在的节点,如果运行了mandatory-svc.yaml的话,就可以解析为集群的任何一个节点的IP地址。这里我们解析为集群的master节点的IP(因为上边我们运行了mandatory-svc.yaml文件)

192.168.8.30         ingress.bdqn.com

//然后使用浏览器访问:http://ingress.bdqn.com/nginx

//对应httpd的访问:http://ingress.bdqn.com/httpd

总结: Mandatory-svc,这个SVC,就等于是将nginx-ingress-controller做了一个NodePort类型的SVC,提供了一个统一的访问入口,这样可以避免暴露端口过多的情况。

---------------------------------------------------------

## 基于http实现虚拟机主机的访问

//此实验的前提是: Ingress-nginx-controller服务在集群中,已经完成部署。

[root@master vhost]# kubectl get pod -n ingress-nginx 
NAME                                       READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-9b4479c74-n6trz   1/1     Running   0          21h

//编辑ingress1.bdqn.io域名所需要的Deployment和SVC资源。

```yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: deploy3
spec:
  selector:
    matchLabels:
      app: httpd1
  replicas: 2
  template:
    metadata:
      labels:
        app: httpd1
    spec:
      containers:
      - name: httpd1
        image: httpd
    imagePullPolicy: IfNotPresent
---
kind: Service
apiVersion: v1
metadata:
  name: svc3
spec:
  selector:
    app: httpd1
  ports:
  - port: 80
    targetPort: 80
```

//验证上述资源没有问题之后,可以直接复制其yaml文件,更改相应名称即可得到ingress2.bdqn.io这个域名所依赖的资源。

```yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: deploy4
spec:
  selector:
    matchLabels:
      app: httpd2
  replicas: 2
  template:
    metadata:
      labels:
        app: httpd2
    spec:
      containers:
      - name: httpd2
        image: httpd
    imagePullPolicy: IfNotPresent
---
kind: Service
apiVersion: v1
metadata:
  name: svc4
spec:
  selector:
    app: httpd2
  ports:
  - port: 80
    targetPort: 80
```

//访问各SVC资源的ClusterIP,验证服务

[root@master vhost]# curl 10.103.181.125

[root@master vhost]# curl 10.110.230.221

//创建对应的Ingress规则,这个是最重要的一环。

```yaml
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress1
spec:
  rules:
    - host: ingress1.bdqn.io
      http:
        paths:
        - path: /
          backend:
            serviceName: svc3
            servicePort: 80
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress2
spec:
  rules:
    - host: ingress2.bdqn.io
      http:
        paths:
        - path: /
          backend:
            serviceName: svc4
            servicePort: 80

//查看对应Ingress规则的相信信息。

[root@master vhost]# kubectl describe ingresses. ingress1 
Name:             ingress1
Namespace:        default
Address:          10.106.32.255
Default backend:  default-http-backend:80 ()
Rules:
  Host              Path  Backends
  ----              ----  --------
  ingress1.bdqn.io  
                    /   svc1:80 (10.244.1.102:80,10.244.2.107:80)
...
[root@master vhost]# kubectl describe ingresses. ingress2
Name:             ingress2
Namespace:        default
Address:          10.106.32.255
Default backend:  default-http-backend:80 ()
Rules:
  Host              Path  Backends
  ----              ----  --------
  ingress2.bdqn.io  
                    /   svc2:80 (10.244.1.103:80,10.244.2.108:80)
...

//在Windows上,做对应的域名解析,用浏览器访问验证。

192.168.8.20         ingress1.bdqn.io

192.168.8.20         ingress2.bdqn.io    

-----------------------------------------------------

基于https的访问

//创建证书

mkdir -p /root/yaml/ingress/https
cd /root/yaml/ingress/https
[root@master https]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
Generating a 2048 bit RSA private key
...............+++
.......................................................................+++
writing new private key to 'tls.key'
-----
[root@master https]# ls
tls.crt  tls.key
```

//创建secret资源,将证书保存到k8s集群中

[root@master https]# kubectl create secret tls tls-secret --key=tls.key --cert tls.crt

//创建新的Deploy5.yaml

```yaml
kind: Deployment
apiVersion:  apps/v1
metadata:
  name: deploy5
spec:
  selector:
    matchLabels:
      app: nginx5
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx5
    spec:
      containers:
      - name: nginx5
        image: nginx
    imagePullPolicy: IfNotPresent
---
kind: Service
apiVersion: v1
metadata:
  name: svc-5
spec:
  selector:
    app: nginx5
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
```

//创建对应Ingress规则。

```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: https
spec:
  tls:
    - hosts:
      - ingress5.bdqn.com
      secretName: tls-secret
  rules:
    - host: ingress5.bdqn.com
      http:
        paths:
        - path: /
          backend:
            serviceName: svc-5
            servicePort: 80
```

//域名访问测试https

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6月前
|
Kubernetes 负载均衡 应用服务中间件
kubernetes—Ingress详解
kubernetes—Ingress详解
127 0
|
6月前
|
Kubernetes 应用服务中间件 nginx
|
3月前
|
Kubernetes 负载均衡 应用服务中间件
在k8S中,ingress是什么?
在k8S中,ingress是什么?
|
6月前
|
Kubernetes 负载均衡 应用服务中间件
Kubernetes的Ingress
Kubernetes的Ingress
117 0
Kubernetes的Ingress
|
Kubernetes 应用服务中间件 调度
kubernetes Ingress、Ingress controller
kubernetes Ingress、Ingress controller
|
负载均衡 网络架构 Docker
Traefik
Traefik 是一款开源的反向代理和负载均衡工具,它可以自动地为容器化的应用程序提供动态路由和负载均衡服务。Traefik 支持多种后端服务,并且可以根据容器的标签和元数据自动发现和配置后端服务。
570 1
|
Kubernetes Cloud Native 中间件
为什么选择 Traefik Ingress ?
何为 Traefik Ingress ? 在解析此概念之前,我们回顾下 Kubernetes 生态组件 Ingress Controller (中文释义:入口控制器)的概念。
130 0
|
Kubernetes 负载均衡 网络协议
Kubernetes Ingress深入解析
基于不同的业务场景中,我们该如何在 Kubernetes 生态集群中规划我们应用程序接口的访问策略呢?
167 0
|
弹性计算 负载均衡 Kubernetes
你所不了解的 Traefik
在之前的文章中,我们简单介绍了关于 Traefik 的相关概念及组件原理机制,具体可参考:为什么选择 Traefik Ingress ?
209 0
|
Kubernetes 负载均衡 算法
一篇搞定K8s Ingress
一篇搞定K8s Ingress
3142 0