11 Ingress

理论基础

Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:

使用Ingress的重要原因是,每个service如果希望暴露给集群外部都需要一个负载均衡器以及一个独有的公网IP地址,而Ingress只需要一个公网IP地址就能为许多服务提供访问。如下图所示:
在这里插入图片描述
使用Ingress的重要原因是,每个service如果希望暴露给集群外部都需要一个负载均衡器以及一个独有的公网IP地址,而Ingress只需要一个公网IP地址就能为许多服务提供访问。如下图所示:
在这里插入图片描述
要使用Ingress,必须要有Ingress控制器,K8S支持多种Ingress控制器,常用的有HAProxy 与 Nginx控制器。

安装Ingress 控制器

方法一)

参考文档:
helm安装: https://github.com/kubernetes/ingress-nginx

  1. 公网安装最新版本,需要从k8s.gcr.io下载镜像:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm show values ingress-nginx/ingress-nginx >ingress-values.yaml

helm install myingress ingress-nginx/ingress-nginx --values ingress-values.yaml -n ingress-nginx
  1. K8S 1.22版本,按照以下方式安装。镜像已经预先下载,配置文件使用Daemonset方式安装,指定service类型为LoadBalancer:
kubectl create ns ingress-nginx
cp /resources/helm/helm /bin/
helm install ingress-nginx /resources/helm/ingress-nginx/ -n ingress-nginx
kubectl get all -n ingress-nginx
  1. K8S 1.20版本按照以下方式安装:
kubectl create ns ingress-nginx
cp /resources/helm/helm /bin/
helm install ingress-nginx /resources/helm/ingress-nginx-3.15.2.tgz -n ingress-nginx
kubectl get all -n ingress-nginx

方法二)

yaml:
https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-manifests/
(不支持defaultBackend语法)
1) 安装

$ kubectl apply -f ns-and-sa.yaml
$ kubectl apply -f rbac.yaml
$ kubectl apply -f default-server-secret.yaml
$ kubectl apply -f nginx-config.yaml
$ kubectl apply -f ingress-class.yaml
$ kubectl apply -f nginx-ingress-daemonset.yaml

If you created a daemonset, ports 80 and 443 of the Ingress controller container are mapped to the same ports of the node where the container is running. To access the Ingress controller, use those ports and an IP address of any node of the cluster where the Ingress controller is running.
If you created a deployment, below are two options for accessing the Ingress controller pods.
2) 验证

[root@clientvm ~]# kubectl get all -n nginx-ingress
NAME                      READY   STATUS    RESTARTS   AGE
pod/nginx-ingress-4njn9   1/1     Running   0          44m
pod/nginx-ingress-6htv2   1/1     Running   0          44m
pod/nginx-ingress-8nd6w   1/1     Running   0          44m

NAME                           DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/nginx-ingress   3         3         3       3            3           <none>          44m

Ingress使用范例

1)创建两个测试用的Pod

[root@clientvm ~]# kubectl run nginx1 --image=nginx --image-pull-policy='IfNotPresent'
pod/nginx1 created
[root@clientvm ~]# kubectl run nginx2 --image=nginx --image-pull-policy='IfNotPresent'
pod/nginx2 created


[root@clientvm service]# kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
nginx1           1/1     Running   0          81m
nginx2           1/1     Running   0          81m
nginx3-default   1/1     Running   0          3m19s

[root@clientvm ~]# kubectl expose pod nginx1 --port=80 --target-port=80
service/nginx1 exposed
[root@clientvm ~]# kubectl expose pod nginx2 --port=80 --target-port=80
service/nginx2 exposed


[root@clientvm service]# kubectl get svc
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP   128m
nginx1           ClusterIP   10.107.202.107   <none>        80/TCP    81m
nginx2           ClusterIP   10.100.175.93    <none>        80/TCP    81m

2) 修改Nginx Web页面

[root@clientvm ~]# kubectl exec nginx1 -it -- bash
root@nginx1:/# echo AAAAAA >/usr/share/nginx/html/index.html
root@nginx1:/# exit
exit
[root@clientvm ~]# kubectl exec nginx2 -it -- bash
root@nginx2:/# echo BBBBBB >/usr/share/nginx/html/index.html
root@nginx2:/# exit
exit

到Master或worker主机上验证

[root@master ~]# curl 10.105.82.83
AAAAAA
[root@master ~]# curl 10.103.158.125
BBBBBB

3) 创建Ingress

在这里插入图片描述

3.1 虚拟主机

[root@clientvm service]# cat ingress-multi-hosts.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  ingressClassName: nginx
  defaultBackend:
    service:
      name: nginx1
      port:
        number: 80
  rules:
  - host: nginx1.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx1
            port:
              number: 80
  - host: nginx2.example.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nginx2
            port:
              number: 80
[root@clientvm service]# kubectl apply -f ingress-multi-hosts.yaml

[root@clientvm service]# kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME                        CLASS   HOSTS                                   ADDRESS   PORTS   AGE
name-virtual-host-ingress   nginx   nginx1.example.com,nginx2.example.com             80      15m

测试:
在clientvm上使用vi修改LB的文件,使用ingress 的service的HostPort替换以下的80端口:

[root@clientvm ~]# setenforce 0
[root@clientvm service]# tail -4 /etc/haproxy/haproxy.cfg
    balance roundrobin
    server worker1 worker1:80 check
    server worker2 worker2:80 check
[root@clientvm service]# systemctl restart haproxy.service

到worker1修改/etc/hosts,增加一行

[root@worker1 ~]# cat /etc/hosts
......
192.168.241.134 clientvm.example.com clientvm nginx1.example.com nginx2.example.com

验证:

[root@worker1 ~]# curl http://nginx1.example.com/
AAAAAA
[root@worker1 ~]# curl http://nginx2.example.com/
BBBBBB

3.2 基于Path的虚拟主机

[root@clientvm service]# cat ingress-service-path.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  ingressClassName: nginx
  rules:
  - host: clientvm.example.com
    http:
      paths:
      - path: /nginx1
        pathType: Prefix
        backend:
          service:
            name: nginx1
            port:
              number: 80
      - path: /nginx2
        pathType: Prefix
        backend:
          service:
            name: nginx2
            port:
              number: 80

[root@clientvm service]# kubectl apply -f ingress-service-path.yaml
ingress.networking.k8s.io/simple-fanout-example created

[root@clientvm service]# kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME                    CLASS   HOSTS                  ADDRESS   PORTS   AGE
simple-fanout-example   nginx   clientvm.example.com             80      6s

如果配置的Ingress使用如下声明,则不需要再每一个Pod中创建匹配的目录

  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /

验证:
分别在两个Pod上创建目录

[root@clientvm service]# kubectl  exec nginx1 -it -- bash
root@nginx1:/# cd /usr/share/nginx/html
root@nginx1:/usr/share/nginx/html# mkdir nginx1
root@nginx1:/usr/share/nginx/html# echo AAAAAAAAAAAAAAAA >nginx1/index.html
root@nginx1:/usr/share/nginx/html# exit
exit

[root@clientvm service]# kubectl  exec nginx2 -it -- bash
root@nginx2:/# cd /usr/share/nginx/html/
root@nginx2:/usr/share/nginx/html# mkdir nginx2
root@nginx2:/usr/share/nginx/html# echo BBBBBBBBBB >nginx2/index.html
root@nginx2:/usr/share/nginx/html# exit
exit
[root@worker1 ~]# curl clientvm.example.com/nginx1/
AAAAAAAAAAAAAAAA
[root@worker1 ~]# curl clientvm.example.com/nginx2/
BBBBBBBBBB

annotations的作用

Ingress 经常使用注解(annotations)来配置一些选项,具体取决于 Ingress 控制器,例如 重写目标注解。 不同的 Ingress 控制器 支持不同的注解。查看文档以供你选择 Ingress 控制器,以了解支持哪些注解。
参考:https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md
范例 1:
ingress-nginx Version 0.22.0版本以后

  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
......
spec:
  rules:
  - host: rewrite.bar.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /something(/|$)(.*)

.*)捕获的任何字符都将被分配给占位符$2,然后将其作为重写目标注释中的参数使用
上面的输入定义将导致以下重写:

  • rewrite.bar.com/something rewrites to rewrite.bar.com/
  • rewrite.bar.com/something/ rewrites to rewrite.bar.com/
  • rewrite.bar.com/something/new rewrites to rewrite.bar.com/new
  • rewrite.bar.com/ 将会匹配错误,因为没有匹配上预定义path /something

范例 2:
在上例的基础上增加如下

  annotations:
    nginx.ingress.kubernetes.io/app-root: /something/

任何对http://rewrite.bar.com/ 的访问都定向到http://rewrite.bar.com/something/

范例 3:

  annotations:
    kubernetes.io/ingress.class: "nginx"

使用ingress class: nginx
此功能在1.22版本上已经废弃,被替换为

spec:
  ingressClassName: nginx
根据提供的引用内容,可以得知当前使用的是`quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.31.0`版本。如果想查看Ingress Controller的历史版本,可以通过以下步骤实现: 1. 执行以下命令查看Ingress Controller的Deployment历史版本: ```shell kubectl rollout history deployment nginx-ingress-controller -n ingress-nginx ``` 输出结果类似如下: ``` deployment.apps/nginx-ingress-controller REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 <none> 4 <none> 5 <none> 6 <none> 7 <none> 8 <none> 9 <none> 10 <none> 11 <none> 12 <none> 13 <none> 14 <none> 15 <none> 16 <none> 17 <none> 18 <none> 19 <none> 20 <none> 21 <none> 22 <none> 23 <none> 24 <none> 25 <none> 26 <none> 27 <none> 28 <none> 29 <none> 30 <none> 31 <none> ``` 2. 执行以下命令查看指定版本的Ingress Controller镜像: ```shell kubectl describe deployment nginx-ingress-controller -n ingress-nginx | grep -A 1 "Image:" | tail -n 1 ``` 将命令中的`nginx-ingress-controller`替换为需要查看的版本的Deployment名称,例如要查看第5个版本的Deployment,则将命令中的`nginx-ingress-controller`替换为`nginx-ingress-controller-5`。输出结果类似如下: ``` Image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 ``` 3. 如果想回滚到指定版本,可以执行以下命令: ```shell kubectl rollout undo deployment nginx-ingress-controller -n ingress-nginx --to-revision=<revision_number> ``` 将命令中的`<revision_number>`替换为需要回滚到的版本号,例如要回滚到第5个版本,则将`<revision_number>`替换为`5`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值