Ingress服务

  • 一.Ingress服务简介
  • 二.ingress部署
  • 三.域名访问+ingeress-nginx
  • 四.Ingress TLS 配置
  • 五.用户认证
  • 六.重定向


一.Ingress服务简介

  • 一种全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的Ingress 服务。
  • Ingress由两部分组成:Ingress controller和Ingress服务。
  • Ingress Controller 会根据你定义的 Ingress 对象,提供对应的代理能力。业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已经为Kubernetes 专门维护了对应的 Ingress Controller。
  • ingress服务的使用必须在策略网络中才能实现,如calico网络

ingress的技术架构 ingress controller 原理_ingress的技术架构


ingress相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象。大概的工作原理也确实类似于Nginx,可以理解成在 Ingress 里建立一个个映射规则 , ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置(kubernetes声明式API和控制循环) , 然后对外部提供服务。ingress包括:ingress controller和ingress resources

ingress controller:核心是一个deployment,实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer

ingress resources:这个就是一个类型为Ingress的k8s api对象了,这部分则是面向开发人员。

二.ingress部署

官网下载镜像及安装文件,将镜像上传至集群使用的harbor仓库

ingress的技术架构 ingress controller 原理_kubernetes_02


执行安装脚本

kubectl apply -f deploy.yaml

ingress的技术架构 ingress controller 原理_ingress的技术架构_03


查看ingress服务,部署成功

[root@server1 ingress]# kubectl  -n ingress-nginx  get svc
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.104.84.227    <none>        80:31015/TCP,443:32169/TCP   16h
ingress-nginx-controller-admission   ClusterIP   10.106.177.206   <none>        443/TCP                      16h

三.域名访问+ingeress-nginx

修改ingress-nginx-controller配置
type: LoadBalancer

[root@server1 ingress]# kubectl  -n ingress-nginx  edit svc ingress-nginx-controller
service/ingress-nginx-controller edited

ingress的技术架构 ingress controller 原理_docker_04


可以看到loadbalancer分配ip 172.25.3.10

[root@server1 ingress]# kubectl  -n ingress-nginx  get svc
NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.104.84.227    172.25.3.10   80:31015/TCP,443:32169/TCP   16h
ingress-nginx-controller-admission   ClusterIP      10.106.177.206   <none>        443/TCP                      16h

创建pod:nginx myapp

[root@server1 ~]# cat  deployment.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: myapp:v1
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2

查看pod

[root@server1 ~]# kubectl  get pod
NAME                                READY   STATUS    RESTARTS   AGE
myapp-deployment-67f8c948cf-45h6n   1/1     Running   0          105m
myapp-deployment-67f8c948cf-hq9xg   1/1     Running   0          105m
myapp-deployment-67f8c948cf-rr9bz   1/1     Running   0          105m
nginx-deployment-6456d7c676-8jsrd   1/1     Running   2          19h
nginx-deployment-6456d7c676-bcx9b   1/1     Running   2          19h
nginx-deployment-6456d7c676-kwqfr   1/1     Running   2          19h

创建service

[root@server1 ~]# cat svc.yml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app: myapp

查看service

[root@server1 ~]# kubectl  get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   4d18h
myapp-svc    ClusterIP   10.109.211.64   <none>        80/TCP    124m
nginx-svc    ClusterIP   10.103.119.38   <none>        80/TCP    124m

ingress.yml下赋予域名匹配,用于匹配service

[root@server1 ingress]# cat ingress.yml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx
spec:
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-myapp
spec:
  rules:
  - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myapp-svc
          servicePort: 80

查看ingress信息

[root@server1 ingress]# kubectl  get ingress
NAME            CLASS    HOSTS             ADDRESS      PORTS   AGE
ingress-myapp   <none>   www2.westos.org   172.25.3.2   80      117m
ingress-nginx   <none>   www1.westos.org   172.25.3.2   80      117m

设置本地解析

vim /etc/hosts

172.25.3.10  www1.westos.org www2.westos.org

域名访问测试,访问到对应service

[root@server1 ingress]# curl  www2.westos.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@server1 ingress]# curl  www1.westos.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

负载均衡测试,成功 myapp-svc

[root@server1 ingress]# curl www1.westos.org/hostname.html
nginx-deployment-6456d7c676-8jsrd
[root@server1 ingress]# curl www1.westos.org/hostname.html
nginx-deployment-6456d7c676-8jsrd
[root@server1 ingress]# curl www1.westos.org/hostname.html
nginx-deployment-6456d7c676-bcx9b
[root@server1 ingress]# curl www1.westos.org/hostname.html
nginx-deployment-6456d7c676-kwqfr
[root@server1 ingress]# curl www1.westos.org/hostname.html
nginx-deployment-6456d7c676-bcx9b

查看详细内容,可以看到www2.westos.org 对应 nginx-svc:80,nginx-svc下有三个pod 的ip用于均衡访问

kubectl  describe  ingress ingress-nginx
[root@server1 ingress]#  kubectl  describe  ingress ingress-nginx 
Name:             ingress-nginx
Namespace:        default
Address:          172.25.3.2
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host             Path  Backends
  ----             ----  --------
  www1.westos.org  
                   /   nginx-svc:80 (10.244.179.71:80,10.244.179.72:80,10.244.22.6:80)
Annotations:       <none>
Events:            <none>

四.Ingress TLS 配置

创建证书和密钥

[root@server1 ~]# cd ingress/
[root@server1 ingress]#  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@server1 ingress]# ls
deploy.yaml  ingress.yml  tls.crt  tls.key
[root@server1 ingress]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret/tls-secret created

tls脚本 将http访问转为https

[root@server1 ingress]# kubectl  apply  -f ingress.yml 
Warning: networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.networking.k8s.io/ingress-nginx configured
ingress.networking.k8s.io/ingress-myapp configured
vim ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-https
spec:
  tls:
  - hosts:
    - www1.westos.org
    secretName: tls-secret
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80

访问测试,转换成功

[root@server1 ingress]# curl www1.westos.org -I
HTTP/1.1 308 Permanent Redirect
Date: Fri, 30 Jul 2021 02:58:54 GMT
Content-Type: text/html
Content-Length: 164
Connection: keep-alive
Location: https://www1.westos.org

查看服务信息

[root@server1 ingress]# kubectl  describe  ingress
Name:             ingress-myapp
Namespace:        default
Address:          172.25.3.2
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host             Path  Backends

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

  www2.westos.org  
                   /   myapp-svc:80 (10.244.179.76:80,10.244.179.77:80,10.244.22.11:80)
Annotations:       <none>
Events:            <none>


Name:             ingress-nginx
Namespace:        default
Address:          172.25.3.2
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  tls-secret terminates www1.westos.org
Rules:
  Host             Path  Backends

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

  www1.westos.org  
                   /   nginx-svc:80 (10.244.179.78:80,10.244.179.79:80,10.244.22.9:80)
Annotations:       <none>
Events:
  Type    Reason  Age                 From                      Message

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

  Normal  Sync    13s (x4 over 121m)  nginx-ingress-controller  Scheduled for sync

五.用户认证

安装认证生成插件,生成认证文件

[root@server1 ingress]# yum install -y httpd-tools
[root@server1 ingress]# htpasswd -c auth westos
New password: 
Re-type new password: 
Adding password for user westos
[root@server1 ingress]# ls
auth  deploy.yaml  ingress.yml  tls.crt  tls.key
[root@server1 ingress]# cat auth 
westos:$apr1$lULdJemA$Kuw/dnm4tZ8DkRuR9Lu4x.

创建secrets basic-auth

[root@server1 ingress]# kubectl create secret generic basic-auth --from-file=auth
secret/basic-auth created
[root@server1 ingress]# kubectl  get secrets 
NAME                  TYPE                                  DATA   AGE
basic-auth            Opaque                                1      10s
default-token-t5dst   kubernetes.io/service-account-token   3      5d17h
tls-secret            kubernetes.io/tls                     2      11m

执行脚本

[root@server1 ingress]# vim ingress.yml 
[root@server1 ingress]# kubectl  apply  -f ingress.yml
vim ingress-auth.yaml
 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-with-auth
  annotations:
    # type of authentication
    nginx.ingress.kubernetes.io/auth-type: basic
    # name of the secret that contains the user/password definitions
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    # message to display with an appropriate context why the authentication is required
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - westos'
spec:
  rules:
  - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80

ingress的技术架构 ingress controller 原理_docker_05

测试

[root@server1 ingress]# curl -k -u westos:westos  https://www1.westos.org
<html>

<head><title>302 Found</title></head>

<body>

<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

ingress的技术架构 ingress controller 原理_nginx_06

六.重定向

定向到hostname.htnl

ingress的技术架构 ingress controller 原理_nginx_07

[root@server1 ingress]# curl -I www1.westos.org
HTTP/1.1 302 Moved Temporarily
Date: Fri, 30 Jul 2021 03:14:38 GMT
Content-Type: text/html
Content-Length: 138
Connection: keep-alive
Location: http://www1.westos.org/hostname.html

/westos 定向到/www1.westos.org 默认发布页

#截取第二列输入内容,进行解析
nginx.ingress.kubernetes.io/rewrite-target: /$2

ingress的技术架构 ingress controller 原理_kubernetes_08

[root@server1 ingress]# curl -k -u westos:westos -I https://www1.westos.org/westos/
HTTP/1.1 200 OK
Date: Fri, 30 Jul 2021 03:18:00 GMT
Content-Type: text/html
Content-Length: 65
Connection: keep-alive
Last-Modified: Fri, 02 Mar 2018 03:39:12 GMT
ETag: "5a98c760-41"
Accept-Ranges: bytes
Strict-Transport-Security: max-age=15724800; includeSubDomains
[root@server1 ingress]# curl -k -u westos:westos https://www1.westos.org/westos/
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

修改url ,/westos/hostname.html定向到/hostname.html

ingress的技术架构 ingress controller 原理_ingress_09

[root@server1 ingress]# curl -k -u westos:westos  https://www1.westos.org/ -I
HTTP/1.1 302 Moved Temporarily
Date: Fri, 30 Jul 2021 03:20:45 GMT
Content-Type: text/html
Content-Length: 138
Connection: keep-alive
Location: https://www1.westos.org/westos
[root@server1 ingress]# curl -k -u westos:westos  https://www1.westos.org/westos/hostname.html
nginx-deployment-6456d7c676-bcx9b
[root@server1 ingress]# curl -k -u westos:westos  https://www1.westos.org/westos/hostname.html
nginx-deployment-6456d7c676-kwqfr
[root@server1 ingress]# curl -k -u westos:westos  https://www1.westos.org/westos/hostname.html -I
HTTP/1.1 200 OK
Date: Fri, 30 Jul 2021 03:21:05 GMT
Content-Type: text/html
Content-Length: 34
Connection: keep-alive
Last-Modified: Fri, 30 Jul 2021 00:56:15 GMT
ETag: "61034e2f-22"
Accept-Ranges: bytes
Strict-Transport-Security: max-age=15724800; includeSubDomains