Kubernetes之Ingress服务

2022年 9月 30日 23.1k 0

我们一起学习 Kubernetes 的 Ingress 服务发现吧!

Kubernetes 中为了实现服务实例间的负载均衡和不同服务间的服务发现,创造了 Service 对象,同时又为从集群外部访问集群创建了 Ingress 对象。
Kubernetes之Ingress服务
Kubernetes之Ingress服务

1. 原理介绍

介绍关于 K8S 中 Ingress 的基本知识和要点!

我们都知道传统的 SVC 只支持四层上面的代码,而对于七层上的代码而无能为力。比如:我们使用 K8S 集群对外提供 HTTPS 的服务,为了方便和便捷,我们需要在对外的 Nginx 服务上面配置 SSL 加密,但是将请求发送给后端服务的时候,进行证书卸载的操作,后续都是用 HTTP 的协议进行处理。而面对此问题,K8S 中给出了使用 Ingress (K8S在1.11版本中推出了)来进行处理。

Kubernetes之Ingress服务 - 请求流程
Kubernetes之Ingress服务 - Nginx协程的工作方案

Kubernetes                                                  Workstation
+---------------------------------------------------+     +------------------+
|                                                   |     |                  |
|  +-----------+   apiserver        +------------+  |     |  +------------+  |
|  |           |   proxy            |            |  |     |  |            |  |
|  | apiserver |                    |  ingress   |  |     |  |  ingress   |  |
|  |           |                    | controller |  |     |  | controller |  |
|  |           |                    |            |  |     |  |            |  |
|  |           |                    |            |  |     |  |            |  |
|  |           |  service account/  |            |  |     |  |            |  |
|  |           |  kubeconfig        |            |  |     |  |            |  |
|  |           +<-------------------+            |  |     |  |            |  |
|  |           |                    |            |  |     |  |            |  |
|  +------+----+      kubeconfig    +------+-----+  |     |  +------+-----+  |
|         |<--------------------------------------------------------|        |
|                                                   |     |                  |
+---------------------------------------------------+     +------------------+

2. 服务安装

介绍关于 Ingress 服务的安装方式!

安装 Ingress-Nginx 首先需要在官网下载对应的安装 yaml 文件,如果你也是 Mac 用户的话,可以使用该 下载文件 进行安装。
安装的过程中,根据部署文件其会自行定义一个名为 ingress-nginx 的名称空间,由来保存其对应的 Pod 和内容。而 Deployments 中会自动部署一个名为 nginx-ingress-controller 的服务,用于管理和控制 Ingress 服务。当然,还有对应 Deployment 的 ingress-nginx 的 SVC 也会一同创建的。同时,还有相关的角色、ConfigMap 等等。

# 直接运行即可安装
$ kubectl apply -f deploy.yaml

可以看到其底层的暴露类型就是 NodePort 模式,会在每个 Node 节点上面开放的 80 端口和 443 端口映射的地址。

# 查看对应SVC服务
$ kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.97.243.161   <none>        80:31345/TCP,443:31802/TCP   22s

# 查看对应POD服务
$ kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-761212d12f-11864   1/1     Running   0          54s

3. 配置 HTTP 代理

配置关于 Ingress 服务的 HTTP 代理访问!

  • Deployment/Service/Ingress
    • 我们这里可以使用 kubectl apply -f ingress-http.yml 来直接部署服务。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: escape/nginx:v1
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80

---
apiVersion: apps/v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    name: nginx
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP

---
apiVersion: apps/v1
kind: Ingress
metadata:
  name: nginx-test
spec:
  rules:
    - host: test.escape.com
      http:
        paths:
          - path: /
            backend:
              serviceName: nginx-svc
              servicePort: 80
  • 测试效果
    • 如果我们没有自己的独立域名的话,可以通过修改 Hosts 配置文件来访问。
    • 然后通过域名进行访问,但是需要使用 Ingress 的服务端口,比如 31345 端口。
# /etc/hosts
192.168.66.10    test.escape.com

# 查看对应SVC服务
$ kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.97.243.161   <none>        80:31345/TCP,443:31802/TCP   3m

# 为后续测试而删除服务
$ kubectl delete svc nginx-svc
$ kubectl delete svc nginx-test
$ kubectl delete pod nginx-app

4. 配置 HTTP 代理

根据不同的域名实现访问对应的虚拟主机!

  • 服务配置图示

Kubernetes之Ingress服务 - 配置HTTP代理示例

  • 网站 1:Deployment/Service/Ingress
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx-1
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx-1
    spec:
      containers:
        - name: nginx-1
          image: escape/nginx:v2
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80

---
apiVersion: apps/v1
kind: Service
metadata:
  name: svc-nginx-1
spec:
  selector:
    name: nginx-1
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP

---
apiVersion: apps/v1
kind: Ingress
metadata:
  name: nginx-web1
spec:
  rules:
    - host: web1.escape.com
      http:
        paths:
          - path: /
            backend:
              serviceName: svc-nginx-1
              servicePort: 80
  • 网站 2:Deployment/Service/Ingress
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx-2
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx-2
    spec:
      containers:
        - name: nginx-2
          image: escape/nginx:v2
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80

---
apiVersion: apps/v1
kind: Service
metadata:
  name: svc-nginx-2
spec:
  selector:
    name: nginx-2
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP

---
apiVersion: apps/v1
kind: Ingress
metadata:
  name: nginx-web2
spec:
  rules:
    - host: web2.escape.com
      http:
        paths:
          - path: /
            backend:
              serviceName: svc-nginx-2
              servicePort: 80
  • 测试效果
    • 如果我们没有自己的独立域名的话,可以通过修改 Hosts 配置文件来访问。
    • 然后通过域名进行访问,但是需要使用 Ingress 的服务端口,比如 31345 端口。
# 查看对应POD服务
$ kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-761212d12f-11864   1/1     Running   0          5m

# Ingress容器里面查看Nginx配置
$ kubectl -it exec nginx-ingress-controller-761212d12f-11864 -n ingress-nginx -- /bin/bash

# 查看Ingress规则
$ kubectl get ingress
NAME          HOSTS              ADDRESS    PORTS    AGE
nginx-web1    web1.escape.com               80       9m8s
nginx-web2    web2.escape.com               80       9m10s
# /etc/hosts
192.168.66.10    test.escape.com
192.168.66.10    web1.escape.com
192.168.66.10    web2.escape.com

5. 配置 HTTPS 代理

配置关于 Ingress 服务的 HTTPS 代理访问

  • 创建证书,以及 cert 存储方式。
# 生成自签名证书(365天有效期)
# Key: tls.key  证书: tls.crt
$ 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'

# 在K8S中创建一个名称为tls-secret的secret格式的证书信息
$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret "tls-secret" created
  • Deployment/Service/Ingress
    • 我们这里可以使用 kubectl apply -f ingress-https.yml 来直接部署服务。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx-3
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx-3
    spec:
      containers:
        - name: nginx-3
          image: escape/nginx:v3
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80

---
apiVersion: apps/v1
kind: Service
metadata:
  name: svc-nginx-3
spec:
  selector:
    name: nginx-3
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP

---
apiVersion: apps/v1
kind: Ingress
metadata:
  name: nginx-3
spec:
  tls:
    - hosts:
        - web3.escape.com
      secretName: tls-secret
  rules:
    - host: web3.escape.com
      http:
        paths:
          - path: /
            backend:
              serviceName: svc-nginx-3
              servicePort: 80
  • 测试效果
    • 如果我们没有自己的独立域名的话,可以通过修改 Hosts 配置文件来访问。
    • 然后通过域名进行访问,但是需要使用 Ingress 的服务端口,比如 31802 端口。
# /etc/hosts
192.168.66.10    test.escape.com
192.168.66.10    web1.escape.com
192.168.66.10    web2.escape.com
192.168.66.10    web3.escape.com

# 查看对应SVC服务
$ kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.97.243.161   <none>        80:31345/TCP,443:31802/TCP   3m

6. 基础认证

介绍 Ingress 服务的 BasicAuth 认证方式!

  • 前提准备
# 安装httpd工具
$ yum install -y httpd

# 设置基础认证密码
# 创建文件为auth;用户名为escape;密码连输入两次
$ htpasswd -c auth escape

# k8s配置认证
$ kubectl create secret generic basic-auth --from-file=auth
  • 配置文件
apiVersion: apps/v1
kind: Ingress
metadata:
  name: ingress-with-auth
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: "Authentication Required - escape"
spec:
  rules:
    - host: auth.escape.com
      http:
        paths:
          - path: /
            backend:
              serviceName: nginx-svc
              servicePort: 80
# /etc/hosts
192.168.66.10    test.escape.com
192.168.66.10    web1.escape.com
192.168.66.10    web2.escape.com
192.168.66.10    web3.escape.com
192.168.66.10    auth.escape.com

7. 规则重写

介绍 Ingress 的进行规则重写的方式!

Kubernetes之Ingress服务 - 规则重写

apiVersion: apps/v1
kind: Ingress
metadata:
  name: nginx-test
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: http://web3.escape.com:31802/hostname.html
spec:
  rules:
    - host: web4.escape.com
      http:
        paths:
          - path: /
            backend:
              serviceName: nginx-svc
              servicePort: 80
# /etc/hosts
192.168.66.10    test.escape.com
192.168.66.10    web1.escape.com
192.168.66.10    web2.escape.com
192.168.66.10    web3.escape.com
192.168.66.10    auth.escape.com
192.168.66.10    web4.escape.com

相关文章

KubeSphere 部署向量数据库 Milvus 实战指南
探索 Kubernetes 持久化存储之 Longhorn 初窥门径
征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
那些年在 Terraform 上吃到的糖和踩过的坑
无需 Kubernetes 测试 Kubernetes 网络实现
Kubernetes v1.31 中的移除和主要变更

发布评论