Kubernetes之Ingress服务


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

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

Kubernetes之Ingress服务

Kubernetes之Ingress服务


1. 原理介绍

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

我们都知道传统的 SVC 只支持四层上面的代码,而对于七层上的代码而无能为力。比如:我们使用 K8S 集群对外提供 HTTPS 的服务,为了方便和便捷,我们需要在对外的 Nginx 服务上面配置 SSL 加密,但是将请求发送给后端服务的时候,进行证书卸载的操作,后续都是用 HTTP 的协议进行处理。而面对此问题,K8S 中给出了使用 Ingress (K8S1.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 服务。当然,还有对应 Deploymentingress-nginxSVC 也会一同创建的。同时,还有相关的角色、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

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录