07-kubernetes Ingress 原理 和 Ingress-nginx 案例


Service 類型

  1. ClusterIP 只在集群內部訪問,無法跨越集群邊界
  2. NodePort 提供集群外部流量進入到集群內部
  3. LoadBalancer 集群部署在公有雲或私有雲之上,提供給公有雲或私有雲的負載均衡中間使用
  4. ExternelName 把集群外部的服務映射給集群內部使用, 是一個FQDN的名稱,一個CNAME名稱,這個CNAM指向公網的FQDN

No ClusterIP 成為 Headless Sercie

ServiceName -> PodIP

Service 是一個四層調度器

也就是說,當請求為HTTPS請求的時候,則無法卸載證書。

namespace 名稱空間


創建 namespace 如下:

[root@master manifests]# kubectl create namespace dev
namespace/dev created
[root@master manifests]# kubectl get ns
NAME              STATUS   AGE
default           Active   20d
dev               Active   4s       # 新創建的namespace
kube-node-lease   Active   20d
kube-public       Active   20d
kube-system       Active   20d

刪除 namespace 如下:

[root@master manifests]# kubectl delete ns/dev
namespace "dev" deleted
[root@master manifests]# kubectl get ns
NAME              STATUS   AGE
default           Active   20d
kube-node-lease   Active   20d
kube-public       Active   20d
kube-system       Active   20d

Ingress Controller

舉例

當kubernetes集群有上千甚至跟多個節點的時候,此時需要特有的web七層代理
如在集群其中的四個節點上打上污點,這四個節點上只運行web七層代理所對應的Pod
由此Pod來代理集群內部的Service,Service再把流量轉發給集群內部對應的Pod。

這就叫做 Ingress Controller

Ingress Controller 是基於 DaemonSet 控制器來實現。

DaemonSet 是實現保證集群內部每個節點上都運行一個指定的Pod。

Kubernetes 中三種常用七層代理:

  1. Nginx # 常規代理
  2. Traefik # 微服務前段負載均衡
  3. Envoy # 微服務代理負載均衡,使用的多

Ingress

IngressIngress Controller 是兩回事。

Ingress 原理

Ingress 啟動一個獨立的Pod來運行七層代理,可以是 NginxTraefik 或者是 Envoy,此時 ingress Pod 會直接代理 后端運行服務的 Pod,為了能監聽后端Pod的變化,需要一個 無頭Service Headless Sercie 通過標簽選擇器來選擇后端指定的Pod,並收集到后端Pod 對應的IP,而此Service不會被使用,它主要是用於被Ingress Pod 來監聽后端Pod的變化,而一旦后端Pod產生變化,無頭Service 會知道,此時被Ingress Pod 發現后,會自動根據變化來更改配置文件,並重載。

如果此時使用的是 Nginx 類型的 Ingress Pod ,則每次變化后修改配置文件后都會自動重新 reload。
但如果使用 Traefik 或者是 Envoy 天生就是為微服務開發的,更友好的支持。

Ingress

Ingress-nginx 進行測試

可以在 GitHub 上找到Ingress-nginx

本次使用的是相對簡單部署 ingress-nginx 的配置清單。

ingress-nginx 單獨的詳情頁面

因為是直接在物理機上直接安裝的kubernetes集群,所以需要兩個配置清單。

[root@master ingress]#  kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created

還需要一個Ingress-name名稱空間中創建的NodePort Service,以便引入集群外流量

需要根據實際情況修改一下:

[root@master ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
[root@master ingress]# cat service-nodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
      nodePort: 30080       # 手動指定node對外的http端口
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
      nodePort: 30443       # 手動指定node對外的https端口
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

[root@master ingress]#kubectl apply -f service-nodeport.yaml
service/ingress-nginx created

查看創建的ingress-nginx Pod

[root@master ingress]# kubectl get pods -n ingress-nginx -o wide
NAME                                        READY   STATUS    RESTARTS   AGE   IP            NODE                NOMINATED NODE   READINESS GATES
nginx-ingress-controller-7995bd9c47-b4fzh   1/1     Running   0          34s   10.244.1.27   node03.kubernetes   <none>           <none>
[root@master ingress]# kubectl get svc -n ingress-nginx     # 這里是第二次執行在Ingress-name名稱空間中創建的NodePort Service,以便引入集群外流量
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.111.201.108   <none>        80:30080/TCP,443:30443/TCP   44s

創建對應的后端Pod和Service

查看創建的ingress-myapp

[root@master ingress]# cat myapp-deplay.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp       # Service 名稱
  namespace: default
spec:
  selector:
    app: myapp
    release: canary
  ports:
  - name: http
    targetPort: 80      # 指定容器端口
    port: 80            # Service 自己開房的端口
    
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
        - name: http
          containerPort: 80
[root@master ingress]# kubectl apply -f myapp-deplay.yaml 
service/myapp created
deployment.apps/myapp-deploy unchanged

查看

[root@master ingress]# kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
myapp-deploy-55b78d8548-b4c2c   1/1     Running   0          42h
myapp-deploy-55b78d8548-gpdw8   1/1     Running   0          42h
myapp-deploy-55b78d8548-hr6vx   1/1     Running   0          42h
[root@master ingress]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   22d
myapp        ClusterIP   10.111.44.7   <none>        80/TCP    6s

創建 Ingress

[root@master ingress]# cat ingress-myapp.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-myapp
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"        # 自動生成 nginx 相關的匹配和修改規則
spec:
  rules:
  - host: myapp.sijiayong.com       # 使用 host 主機模式來訪問
    http:
      paths:
      - path:
        backend:
          serviceName: myapp        # 這里指定剛剛創建的后端Pod對應的Service名稱
          servicePort: 80
[root@master ingress]# kubectl apply -f ingress-myapp.yaml 
ingress.extensions/ingress-myapp created
[root@master ingress]# kubectl get ing
NAME            HOSTS                 ADDRESS   PORTS   AGE
ingress-myapp   myapp.sijiayong.com             80      6s

查看 Ingress-controller 對應的Pod配置信息

上面一系列都配置完成之后,此時在看查看 Ingress-controller 的Pod中nginx的配置信息包含如下:

[root@master ingress]# kubectl exec -n ingress-nginx -it nginx-ingress-controller-7995bd9c47-b4fzh -- /bin/sh
	server {
		server_name myapp.sijiayong.com ;
		listen 80;
		
		set $proxy_upstream_name "-";
		set $pass_access_scheme $scheme;
		set $pass_server_port $server_port;
		set $best_http_host $http_host;
		set $pass_port $pass_server_port;
		location / {
			
			set $namespace      "default";
			set $ingress_name   "ingress-myapp";
			set $service_name   "myapp";
			set $service_port   "80";
			set $location_path  "/";

... ...
... ...

訪問測試

此時在集群外部訪問測試:

注意,臨時測試,上面使用的host模式來訪問,所以在測試的集群外部機器上手動添加hosts記錄

[root@xinguan-test-node1 ~]# grep myapp /etc/hosts
10.0.20.20 myapp.sijiayong.com
[root@xinguan-test-node1 ~]# curl myapp.sijiayong.com:30080
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@xinguan-test-node1 ~]# curl myapp.sijiayong.com:30080/hostname.html
myapp-deploy-55b78d8548-hr6vx

模擬測試 Ingress 后端 Tomcat 訪問

還是基於上面的配置,一切都不動,增加tomcat后端Pod和Service 以及 Ingress

創建 tomcat 的 Pod 和Service

[root@master ingress]# cat tomcat-deploy.yaml 
apiVersion: v1
kind: Service
metadata:
  name: tomcat
  namespace: default
spec:
  selector:
    app: tomcat
    release: canary
  ports:
  - name: http
    targetPort: 8080
    port: 8080
  - name: ajp
    targetPort: 8009
    port: 8009
    
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-depoly
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat
      release: canary
  template:
    metadata:
      labels:
        app: tomcat
        release: canary
    spec:
      containers:
      - name: tomcat
        image: tomcat:8.5.32-jre8-alpine
        ports:
        - name: http
          containerPort: 8080
        - name: ajp
          containerPort: 8009

創建和查看

[root@master ingress]# kubectl apply -f tomcat-deploy.yaml 
service/tomcat created
deployment.apps/tomcat-depoly created
[root@master ingress]# kubectl get pods -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP            NODE                NOMINATED NODE   READINESS GATES
myapp-deploy-55b78d8548-b4c2c    1/1     Running   0          43h   10.244.3.29   node01.kubernetes   <none>           <none>
myapp-deploy-55b78d8548-gpdw8    1/1     Running   0          43h   10.244.1.26   node03.kubernetes   <none>           <none>
myapp-deploy-55b78d8548-hr6vx    1/1     Running   0          43h   10.244.2.22   node02.kubernetes   <none>           <none>
tomcat-depoly-579d97b849-66wrh   1/1     Running   0          7s    10.244.3.30   node01.kubernetes   <none>           <none>
tomcat-depoly-579d97b849-rh5r6   1/1     Running   0          7s    10.244.1.28   node03.kubernetes   <none>           <none>
tomcat-depoly-579d97b849-sd49w   1/1     Running   0          7s    10.244.2.23   node02.kubernetes   <none>           <none>
[root@master ingress]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP             22d
myapp        ClusterIP   10.111.44.7    <none>        80/TCP              76m
tomcat       ClusterIP   10.106.39.78   <none>        8080/TCP,8009/TCP   3m18s

創建 tomcat-ingress

[root@master ingress]# cat ingress-tomcat.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tomcat
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: tomcat.sijiayong.com
    http:
      paths:
      - path:
        backend:
          serviceName: tomcat
          servicePort: 8080

創建和查看

[root@master ingress]# kubectl apply -f ingress-tomcat.yaml 
ingress.extensions/ingress-tomcat created
[root@master ingress]# kubectl get ing
NAME             HOSTS                  ADDRESS   PORTS   AGE
ingress-myapp    myapp.sijiayong.com              80      53m
ingress-tomcat   tomcat.sijiayong.com             80      4s

測試訪問 tomcat

注意,同樣寫Hosts 之后進行測試

[root@xinguan-test-node1 ~]# grep tomcat /etc/hosts
10.0.20.20 myapp.sijiayong.com tomcat.sijiayong.com
[root@xinguan-test-node1 ~]# curl tomcat.sijiayong.com:30080



<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.32</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>

    <body>
        <div id="wrapper">
            <div id="navigation" class="curved container">
                <span id="nav-home"><a href="http://tomcat.apache.org/">Home</a></span>
                <span id="nav-hosts"><a href="/docs/">Documentation</a></span>
                <span id="nav-config"><a href="/docs/config/">Configuration</a></span>
                <span id="nav-examples"><a href="/examples/">Examples</a></span>
                <span id="nav-wiki"><a href="http://wiki.apache.org/tomcat/FrontPage">Wiki</a></span>
                <span id="nav-lists"><a href="http://tomcat.apache.org/lists.html">Mailing Lists</a></span>
                <span id="nav-help"><a href="http://tomcat.apache.org/findhelp.html">Find Help</a></span>
                <br class="separator" />
            </div>
            <div id="asf-box">
                <h1>Apache Tomcat/8.5.32</h1>
            </div>
... ...
... ...

模擬測試 Https

模擬測試 通過Ingress 的七層代理,訪問Https,通過Ingress卸載證書后訪問后端

所有先需要手動自簽SSL證書

自簽SSL證書

[root@master https]# openssl genrsa -out tls.key 2048 
Generating RSA private key, 2048 bit long modulus
...............................+++
.....................................................................................................................................+++
e is 65537 (0x10001)
[root@master https]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=BeiJing/L=BeiJing/O=DefOps/CN=tomcat.sijiayong.com
[root@master https]# ll
total 8
-rw-r--r-- 1 root root 1302 Aug  1 11:33 tls.crt
-rw-r--r-- 1 root root 1675 Aug  1 11:31 tls.key

自簽證書完成

創建secret

注意,此證書不能直接帖進去,需要先創建成secret,才能應用到Ingress中

[root@master https]# kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key 
secret/tomcat-ingress-secret created
[root@master https]# kubectl get secret
NAME                    TYPE                                  DATA   AGE
default-token-bc86p     kubernetes.io/service-account-token   3      22d
tomcat-ingress-secret   kubernetes.io/tls                     2      10s
[root@master https]# kubectl describe secret tomcat-ingress-secret
Name:         tomcat-ingress-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.key:  1675 bytes
tls.crt:  1302 bytes

創建tls的https清單文件

[root@master https]# cat ingress-tomcat-tls.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tomcat-tls
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - tomcat.sijiayong.com
    secretName: tomcat-ingress-secret       # 這里指定剛剛創建的secret名稱
  rules:
  - host: tomcat.sijiayong.com
    http:
      paths:
      - path:
        backend:
          serviceName: tomcat
          servicePort: 8080

創建和查看

[root@master https]# kubectl apply -f ingress-tomcat-tls.yaml 
ingress.extensions/ingress-tomcat-tls created
[root@master https]# kubectl get ing
NAME                 HOSTS                  ADDRESS   PORTS     AGE
ingress-myapp        myapp.sijiayong.com              80        174m
ingress-tomcat       tomcat.sijiayong.com             80        121m
ingress-tomcat-tls   tomcat.sijiayong.com             80, 443   4s          # 這里看到被創建成功
[root@master https]# kubectl describe ingres-tomcat-tls
error: the server doesn't have a resource type "ingres-tomcat-tls"
[root@master https]# kubectl describe ingress ingress-tomcat-tls
Name:             ingress-tomcat-tls
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<none>)
TLS:
  tomcat-ingress-secret terminates tomcat.sijiayong.com
Rules:
  Host                  Path  Backends
  ----                  ----  --------
  tomcat.sijiayong.com  
                           tomcat:8080 (10.244.1.28:8080,10.244.2.23:8080,10.244.3.30:8080)
Annotations:
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-tomcat-tls","namespace":"default"},"spec":{"rules":[{"host":"tomcat.sijiayong.com","http":{"paths":[{"backend":{"serviceName":"tomcat","servicePort":8080},"path":null}]}}],"tls":[{"hosts":["tomcat.sijiayong.com"],"secretName":"tomcat-ingress-secret"}]}}

  kubernetes.io/ingress.class:  nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  26s   nginx-ingress-controller  Ingress default/ingress-tomcat-tls

測試訪問

此時就已經完成,可以測試訪問

因前面測試hosts已經寫好

tomcat https訪問測試


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM