溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何解析K8S中Service 的Ingress意義與部署

發(fā)布時間:2021-12-16 09:19:01 來源:億速云 閱讀:131 作者:柒染 欄目:云計算

這篇文章給大家介紹如何解析K8S中Service 的Ingress意義與部署,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

前言

ingress 可以理解為 Service 的 Service,即在現(xiàn)有 Service 的前面再搭建一層 Service,作為外部流量的統(tǒng)一入口,進(jìn)行請求路由的轉(zhuǎn)發(fā)。

說白了就是在前端搭建一個 nginx或者h(yuǎn)aproxy,將不同 host 或 url 轉(zhuǎn)發(fā)到對應(yīng)的后端 Service,再由 Service 轉(zhuǎn)給 Pod。只不過 ingress 對 nginx/haproxy 進(jìn)行了一些解耦和抽象。

Ingress 的意義

ingress 彌補(bǔ)了默認(rèn) Service 暴露外網(wǎng)訪問時候的一些缺陷,如不能進(jìn)行統(tǒng)一入口處的7層 URL 規(guī)則,如一個默認(rèn) Service 只能對應(yīng)一種后端服務(wù)。

通常說的 ingress 包含 ingress-controller 和 ingress 對象兩部分。

ingress-controller 對應(yīng) nginx/haproxy 程序,以 Pod 形式運行。

ingress 對象 對應(yīng) nginx/haproxy 配置文件。

ingress-controller 使用 ingress 對象中描述的信息修改自身 Pod 中 nginx/haproxy 的規(guī)則。

部署 ingress

準(zhǔn)備測試資源

部署2個服務(wù),
訪問服務(wù)1,返回 Version 1
訪問服務(wù)2,返回 Version 2

兩個服務(wù)的程序配置

# cat deployment.yaml 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-v1.0
spec:
  selector:
    matchLabels:
      app: v1.0
  replicas: 3
  template:
    metadata:
      labels:
        app: v1.0
    spec:
      containers:
      - name: hello-v1
        image: anjia0532/google-samples.hello-app:1.0
        ports:
        - containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-v2.0
spec:
  selector:
    matchLabels:
      app: v2.0
  replicas: 3
  template:
    metadata:
      labels:
        app: v2.0
    spec:
      containers:
      - name: hello-v2
        image: anjia0532/google-samples.hello-app:2.0
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: service-v1
spec:
  selector:
    app: v1.0
  ports:
  - port: 8081
    targetPort: 8080
    protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: service-v2
spec:
  selector:
    app: v2.0
  ports:
  - port: 8081
    targetPort: 8080
    protocol: TCP

讓容器運行在 8080 上,service 運行在 8081 上。

啟動兩個服務(wù)和對應(yīng)的 Pod

# kubectl apply -f deployment.yaml    
deployment.apps/hello-v1.0 created
deployment.apps/hello-v2.0 created
service/service-v1 created
service/service-v2 created

查看啟動情況,每個服務(wù)對應(yīng)3個 Pod

# kubectl get pod,service -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
pod/hello-v1.0-6594bd8499-lt6nn   1/1     Running   0          37s   192.10.205.234   work01   <none>           <none>
pod/hello-v1.0-6594bd8499-q58cw   1/1     Running   0          37s   192.10.137.190   work03   <none>           <none>
pod/hello-v1.0-6594bd8499-zcmf4   1/1     Running   0          37s   192.10.137.189   work03   <none>           <none>
pod/hello-v2.0-6bd99fb9cd-9wr65   1/1     Running   0          37s   192.10.75.89     work02   <none>           <none>
pod/hello-v2.0-6bd99fb9cd-pnhr8   1/1     Running   0          37s   192.10.75.91     work02   <none>           <none>
pod/hello-v2.0-6bd99fb9cd-sx949   1/1     Running   0          37s   192.10.205.236   work01   <none>           <none>

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE   SELECTOR
service/service-v1   ClusterIP   192.20.92.221   <none>        8081/TCP   37s   app=v1.0
service/service-v2   ClusterIP   192.20.255.0    <none>        8081/TCP   36s   app=v2.0

查看 Service 后端 Pod 掛載情況

[root@master01 ~]# kubectl get ep service-v1
NAME         ENDPOINTS                                                     AGE
service-v1   192.10.137.189:8080,192.10.137.190:8080,192.10.205.234:8080   113s
[root@master01 ~]# kubectl get ep service-v2
NAME         ENDPOINTS                                                 AGE
service-v2   192.10.205.236:8080,192.10.75.89:8080,192.10.75.91:8080   113s

可以看到兩個服務(wù)均成功掛載了對應(yīng)的 Pod。

下面部署前端 ingress-controller。

首先指定 work01/work02 兩臺服務(wù)器運行 ingress-controller

kubectl label nodes work01 ingress-ready=true
kubectl label nodes work02 ingress-ready=true

ingress-controller 使用官方 nginx 版本

wget -O ingress-controller.yaml https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml

修改為啟動 2 個 ingress-controller

# vim ingress-controller.yaml

apiVersion: apps/v1
kind: Deployment
 。。。。。。
 。。。。。。
  revisionHistoryLimit: 10
  replicas: 2   # 新增該行

修改為國內(nèi)鏡像

# vim ingress-controller.yaml

    spec:
      dnsPolicy: ClusterFirst
      containers:
        - name: controller
          #image: us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.34.1@sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20
          image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.32.0
          imagePullPolicy: IfNotPresent

部署 ingress-controller

kubectl apply -f ingress-controller.yaml

查看運行情況

# kubectl get pod,service -n ingress-nginx -o wide 
NAME                                            READY   STATUS      RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
pod/ingress-nginx-admission-create-ld4nt        0/1     Completed   0          15m   192.10.137.188   work03   <none>           <none>
pod/ingress-nginx-admission-patch-p5jmd         0/1     Completed   1          15m   192.10.75.85     work02   <none>           <none>
pod/ingress-nginx-controller-75f89c4965-vxt4d   1/1     Running     0          15m   192.10.205.233   work01   <none>           <none>
pod/ingress-nginx-controller-75f89c4965-zmjg2   1/1     Running     0          15m   192.10.75.87     work02   <none>           <none>

NAME                                         TYPE        CLUSTER-IP      EXTERNAL-IP                   PORT(S)                      AGE   SELECTOR
service/ingress-nginx-controller             NodePort    192.20.105.10   192.168.10.17,192.168.10.17   80:30698/TCP,443:31303/TCP   15m   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
service/ingress-nginx-controller-admission   ClusterIP   192.20.80.208   <none>                        443/TCP                      15m   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx

可以看到 work01/02 上運行了 ingress-nginx-controller Pod。

編寫訪問請求轉(zhuǎn)發(fā)規(guī)則

# cat ingress.yaml 

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - host: test-v1.com
    http:
      paths:
      - path: /
        backend:
          serviceName: service-v1
          servicePort: 8081
  - host: test-v2.com
    http:
      paths:
      - path: /
        backend:
          serviceName: service-v2
          servicePort: 8081

啟用規(guī)則

# kubectl apply -f ingress.yaml
ingress.networking.k8s.io/nginx-ingress created

可以看到 ingress-controller Pod 里面 nginx 配置已經(jīng)生效了

# kubectl exec ingress-nginx-controller-75f89c4965-vxt4d -n ingress-nginx -- cat /etc/nginx/nginx.conf | grep -A 30 test-v1.com

        server {
                server_name test-v1.com ;
                
                listen 80  ;
                listen 443  ssl http2 ;
                
                set $proxy_upstream_name "-";
                
                ssl_certificate_by_lua_block {
                        certificate.call()
                }
                
                location / {
                        
                        set $namespace      "default";
                        set $ingress_name   "nginx-ingress";
                        set $service_name   "service-v1";
                        set $service_port   "8081";
                        set $location_path  "/";

我們在集群外部訪問測試。

首先解析域名到work01

# cat /etc/hosts
192.168.10.15 test-v1.com
192.168.10.15 test-v2.com

訪問測試

# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-svjnf

# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-zqjtm

# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-www76

# curl test-v2.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2.0-6bd99fb9cd-h8862

# curl test-v2.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2.0-6bd99fb9cd-sn84j

可以看到不同域名的請求去到了正確的 Service 下面的不同 Pod 中。

再請求 work02

# cat /etc/hosts
192.168.10.16 test-v1.com
192.168.10.16 test-v2.com

# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-www76

# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-zqjtm

# curl test-v2.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2.0-6bd99fb9cd-sn84j

# curl test-v2.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2.0-6bd99fb9cd-h8862

也沒問題。

如何高可用

在 work01 / work02 前面再掛2臺 LVS+keepalived 就可以實現(xiàn)對 work01/02 的高可用訪問了。
也可以在 work01 / work02 上直接使用 keepalived 漂一個VIP,不需要額外機(jī)器,這樣節(jié)約成本。

用 Deployment 管理 ingress-controller 的 Pod,使用 NodePort 方式暴露 ingress Service。

查看 ingress service

# kubectl get service -o wide -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP                   PORT(S)                      AGE   SELECTOR
ingress-nginx-controller             NodePort    192.20.105.10   192.168.10.17,192.168.10.17   80:30698/TCP,443:31303/TCP   22m   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx

可以看到對外暴露了 30698 端口,訪問任何節(jié)點的 30698 端口即可訪問到 v1/v2 版本的 Pod。

但該端口是隨機(jī)的,并且重建后會變化,我們可以直接訪問運行 ingress-controller Pod 的 work01/02 的 80 端口。

work01/02前面再弄一套 LVS+keepalived 進(jìn)行高可用負(fù)載。

work01/02 上使用 iptables -t nat -L -n -v 可以看到 80 端口是通過 NAT 模式開放的,高流量會有瓶頸。

可以使用 DaemonSet + HostNetwork 的方式來部署 ingress-controller。

這樣 work01/02 上暴露的 80 端口直接使用宿主機(jī)的網(wǎng)絡(luò),不走NAT映射,可以避免性能問題。

關(guān)于如何解析K8S中Service 的Ingress意義與部署就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI