Kubernetes ingress (nginx-ingress)

1. 概述

Kubernetes關于服務的暴露主要是通過NodePort方式,通過綁定主機的某個端口,然后進行pod的請求轉發和負載均衡,但這種方式下缺陷是

Service可能有很多個,如果每個都綁定一個node主機端口的話,主機需要開放外圍一堆的端口進行服務調用,管理混亂。
無法應用很多公司要求的防火墻規則
理想的方式是通過一個外部的負載均衡器,綁定固定的端口,比如80,然后根據域名或者服務名向后面的Service ip轉發,Nginx很好的解決了這個需求,但問題是如果有新的服務加入,如何去修改Nginx的配置,并且加載這些配置? Kubernetes給出的方案就是Ingress,Ingress包含了兩大主件Ingress Controller和Ingress.

Ingress解決的是新的服務加入后,域名和服務的對應問題,基本上是一個ingress的對象,通過yaml進行創建和更新進行加載。
Ingress Controller是將Ingress這種變化生成一段Nginx的配置,然后將這個配置通過Kubernetes API寫到Nginx的Pod中,然后reload.

2. 配置

2.1 默認路由

生成一個默認的后端,如果遇到解析不到的URL就轉發到默認后端頁面。

[root@k8s-master ingress]# cat default-backend.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: default-http-backend
  labels:
    k8s-app: default-http-backend
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        # Any image is permissable as long as:
        # 1. It serves a 404 page at /
        # 2. It serves 200 on a /healthz endpoint
        image: gcr.io/google_containers/defaultbackend:1.0
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
  namespace: kube-system
  labels:
    k8s-app: default-http-backend
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    k8s-app: default-http-backend

2.2 部署Ingress Controller

具體文件可以參考官方的
https://github.com/kubernetes/ingress/blob/master/examples/daemonset/nginx/nginx-ingress-daemonset.yaml

[root@k8s-master ingress]# cat nginx-ingress-controller.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-ingress-lb
  labels:
    name: nginx-ingress-lb
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: nginx-ingress-lb
      annotations:
        prometheus.io/port: '10254'
        prometheus.io/scrape: 'true'
    spec:
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      containers:
      - image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.7
        name: nginx-ingress-lb
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          timeoutSeconds: 1
        ports:
        - containerPort: 80
          hostPort: 80
        - containerPort: 443
          hostPort: 443
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: KUBERNETES_MASTER
            value: http://192.168.0.105:8080
        args:
        - /nginx-ingress-controller
        - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
        - --apiserver-host=http://192.168.0.105:8080

曾經出現的問題是,啟動后pod總是在CrashLoopBack的狀態,通過logs一看發現nginx-ingress-controller的啟動總是去連接apiserver內部集群ip的443端口,導致因為安全問題不讓啟動,后來在args里面加入

- --apiserver-host=http://192.168.0.105:8080

2.3 配置ingress

[root@k8s-master ingress]# cat dashboard-weblogic.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dashboard-weblogic-ingress
  namespace: kube-system
spec:
  rules:
  - host: helloworld.eric
    http:
      paths:
      - path: /console
        backend:
          serviceName: helloworldsvc 
          servicePort: 7001
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 80

理解如下:

host指虛擬出來的域名,具體地址(我理解應該是Ingress-controller那臺Pod所在的主機的地址)應該加入/etc/hosts中,這樣所有去helloworld.eric的請求都會發到nginx
path:/console匹配后面的應用路徑
servicePort主要是定義服務的時候的端口,不是NodePort.
path:/ 匹配后面dashboard應用的路徑,以前通過訪問master節點8080/ui進入dashboard的,但dashboard其實是部署在minion節點中,實際是通過某個路由語句轉發過去而已。

2.4 部署Dashbaord

[root@k8s-master ~]# cat kubernetes-dashboard.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
# Keep the name in sync with image version and
# gce/coreos/kube-manifests/addons/dashboard counterparts
  name: kubernetes-dashboard-latest
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
        version: latest
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
      - name: kubernetes-dashboard
        image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.5.1
        resources:
          # keep request = limit to keep this container in guaranteed class
          limits:
            cpu: 100m
            memory: 50Mi
          requests:
            cpu: 100m
            memory: 50Mi
        ports:
        - containerPort: 9090
        args:
         -  --apiserver-host=http://192.168.0.105:8080
        livenessProbe:
          httpGet:
            path: /
            port: 9090
          initialDelaySeconds: 30
          timeoutSeconds: 30
---
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  labels:
    k8s-app: kubernetes-dashboard
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    k8s-app: kubernetes-dashboard
  ports:
  - port: 80
    targetPort: 9090

2.5 測試

訪問http://helloworld.eric/console 出現dashboard

3. 轉載

原文鏈接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容