1. 程式人生 > 其它 >k8s部署微服務專案實戰--react前端+springboot/python後端-第四節 前端專案部署總結以及引入ingress解決兩個問題

k8s部署微服務專案實戰--react前端+springboot/python後端-第四節 前端專案部署總結以及引入ingress解決兩個問題

通過前面兩節的學習,我們已經可以將一個簡單的react專案部署到k8s中,總結起來其實就是下面的幾步,但是存在兩個問題,需要配置ingress來解決。

通過前面兩節的學習,我們已經可以將一個簡單的react專案部署到k8s中,總結起來其實就是下面的幾步:

1. 建立react專案

2. 打包生成build資料夾(或者其他命名的資料夾)

3. 上傳到伺服器中(只要是安裝了docker的linux伺服器都可以,推薦上傳到k8s的master節點中)

4. 準備Dockerfile和nginx.conf檔案

5. docker build生成image並且同步到其他節點中(或者上傳到本地或遠端倉庫中)

6. 準備部署檔案即yaml檔案,通常包括deployment.yaml和service.yaml

7. 執行kubectl apply -f xxx.yaml即可。

但同時我們提出了兩個問題:

第一:大部分的前端訪問應該是通過域名的形式訪問,即http://domainName/webgui/smartocr/index.html來訪問。

第二:前端微服務需要訪問後端微服務,如果是通過nodeIP+nodePort的方式訪問也沒有問題,但是,如果是按照serviceName:servicePort的方式訪問(而此種方式正是微服務部署所提倡的),當前的解決方案一定是訪問不通的。

第一個問題好理解,就是要使用域名訪問,跟我們訪問www.baidu.com之類的是一個道理;第二個問題稍微有點不好理解,為什麼通過nodeIP+nodePort的方式訪問沒有問題而通過serviceName:servicePort的方式訪問就不行了呢?這是因為我們在前端傳送類似於http://basemanage-be:8000/smartocr/BaseManage/cases這種serviceName+servicePort的方式呼叫後端微服務,實際上這個url是瀏覽器發出來的,而瀏覽器發出來的這個url是通過這個瀏覽器所在的本機上的dns來解析的,毫無疑問這肯定時解析不了的,因此請求無法傳送給後端微服務。而通過nodeIP+nodePort的方式不需要通過本機的dns解析,因此沒有問題。

好了,問題清楚了,那為什麼可以通過在k8s中配置ingress來解決呢?

首先,ingress本身就可以解決需要對外暴露的微服務的域名訪問問題,通過設定host和hostPath,我們的前端可以使用域名訪問。

其次,對於處理前端請求的這個後端微服務,我們可以將其設定為另一個host和hostPath,這樣所有前端發給後端的請求就類似於http://backend.com/smartocr/BaseManage/cases, 因為配置了ingress,因此該請求會被ingress處理,繼而找到對應的後端服務進行處理。

OK,話不多說,看看怎麼配置ingress,網上配置ingress的文章很多,總結下來就是先建立ingress controller,然後建立ingress rule:

首先建立ingress controller,這裡使用的是nginx-ingress,這個mandatory.yaml檔案我是從網上找的,不需要任何改動,拿過去直接就能用:

mandatory.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "<election-id>-<ingress-class>"
      # Here: "<ingress-controller-leader>-<nginx>"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
      hostNetwork: true
      nodeSelector:
        nginx: "nginx"
      # wait up to five minutes for the drain of connections
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount
      nodeSelector:
        kubernetes.io/os: linux
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            allowPrivilegeEscalation: true
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 101
            runAsUser: 101
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown

---

apiVersion: v1
kind: LimitRange
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  limits:
  - min:
      memory: 90Mi
      cpu: 100m
    type: Container

其次是建立ingress rule,需要注意的一點是Ingress rule的名稱空間一定要和你的微服務的名稱空間相同,負責它找不到你的微服務:

ingress_rule.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-myapp
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - host: smartocr.com
    http:
      paths:
      - path: /webgui/smartocr/
        backend:
          serviceName: service-basemanage
          servicePort: 7070
  - host: backend.com
    http:
      paths:
      - path: /smartocr/BaseManage/
        backend:
          serviceName: service-basemanage-be
          servicePort: 5555

注意看標紅的host: backend.com,這就是處理前端請求的後端微服務service-basemanage-be的域名,所以後續你看到的url應該是類似於下圖:

訪問成功,說明前端的請求正確傳送到了後端。

至此,前端部署完全結束。