Kubernetes - - k8s - nginx-ingress

1,簡介

  • Kubernetes 暴露服務的有三種方式,分別爲 LoadBlancer Service、NodePort Service、Ingress。
  • Kubernetes中爲了實現服務實例間的負載均衡和不一樣服務間的服務發現,創造了Serivce對象,同時又爲從集羣外部訪問集羣建立了Ingress對象。

1.1 NodePort 類型

  • 若是設置 type 的值爲 "NodePort",Kubernetes master 將從給定的配置範圍內(默認:30000-32767)分配端口,每一個 Node 將從該端口(每一個 Node 上的同一端口)代理到 Service。該端口將經過 Service 的 spec.ports[*].nodePort 字段被指定。
  • 若是須要指定的端口號,能夠配置 nodePort 的值,系統將分配這個端口,不然調用 API 將會失敗(好比,須要關心端口衝突的可能性)。
  • 這可讓開發人員自由地安裝他們本身的負載均衡器,並配置 Kubernetes 不能徹底支持的環境參數,或者直接暴露一個或多個 Node 的 IP 地址。
  • 須要注意的是,Service 將可以經過 :spec.ports[*].nodePort 和 spec.clusterIp:spec.ports[*].port 而對外可見。
  • NodePort Service 是經過在節點上暴漏端口,而後經過將端口映射到具體某個服務上來實現服務暴漏,比較直觀方便,可是對於集羣來講,隨着 Service 的不斷增長,須要的端口愈來愈多,很容易出現端口衝突,並且不容易管理。固然對於小規模的集羣服務,仍是比較不錯的。

1.2 LoadBalancer 類型

  • LoadBlancer Service 是 Kubernetes 結合雲平臺的組件,如國外 GCE、AWS、國內阿里雲等等,使用它向使用的底層雲平臺申請建立負載均衡器來實現,有侷限性,對於使用雲平臺的集羣比較方便。
  • 使用支持外部負載均衡器的雲提供商的服務,設置 type 的值爲 "LoadBalancer",將爲 Service 提供負載均衡器。 負載均衡器是異步建立的,關於被提供的負載均衡器的信息將會經過 Service 的 status.loadBalancer 字段被髮布出去。
  • 來自外部負載均衡器的流量將直接打到 backend Pod 上,不過實際它們是如何工做的,這要依賴於雲提供商。 在這些狀況下,將根據用戶設置的 loadBalancerIP 來建立負載均衡器。 某些雲提供商容許設置 loadBalancerIP。若是沒有設置 loadBalancerIP,將會給負載均衡器指派一個臨時 IP。 若是設置了 loadBalancerIP,但云提供商並不支持這種特性,那麼設置的 loadBalancerIP 值將會被忽略掉。

1.3 Ingress 解析

  • ingress就是從kubernetes集羣外訪問集羣的入口,將用戶的URL請求轉發到不一樣的service上。Ingress至關於nginx、apache等負載均衡方向代理服務器,其中還包括規則定義,即URL的路由信息,路由信息得的刷新由Ingress controller來提供。
  • 一般狀況下,service和pod的IP僅可在集羣內部訪問。集羣外部的請求須要經過負載均衡轉發到service在Node上暴露的NodePort上,而後再由kube-proxy將其轉發給相關的Pod。
  • Ingress能夠給service提供集羣外部訪問的URL、負載均衡、SSL終止、HTTP路由等。爲了配置這些Ingress規則,集羣管理員須要部署一個Ingress controller,它監聽Ingress和service的變化,並根據規則配置負載均衡並提供訪問入口。
  • Ingress Controller 實質上能夠理解爲是個監視器,Ingress Controller 經過不斷地跟 kubernetes API 打交道,實時的感知後端 service、pod 等變化,好比新增和減小 pod,service 增長與減小等;當獲得這些變化信息後,Ingress Controller 再結合下文的 Ingress 生成配置,而後更新反向代理負載均衡器,並刷新其配置,達到服務發現的做用。

1.3.1 Nginx Ingress

  • nginx-ingress 能夠實現 7/4 層的代理功能(4 層代理基於 ConfigMap;7 層的Nginx反向代理) ,主要負責向外暴露服務,同時提供負載均衡等附加功能
    • 反向代理負載均衡器,一般以Service的Port方式運行,接收並按照ingress定義的規則進行轉發,一般爲nginx,haproxy,traefik等
    • ingress是kubernetes的一個資源對象,用於編寫定義規則,經過它定義某個域名的請求過來以後轉發到集羣中指定的 Service。它能夠經過 Yaml 文件定義,能夠給一個或多個 Service 定義一個或多個 Ingress 規則。
    • Ingress Controller 能夠理解爲控制器,它經過不斷的跟 Kubernetes API 監聽交互,實時獲取後端 Service、Pod 等的變化,好比新增、刪除等,而後結合 Ingress 定義的規則生成配置,而後動態更新上邊的 Nginx 負載均衡器,並刷新使配置生效,來達到服務自動發現的做用。
  • nginx-ingress 模塊在運行時主要包括三個主體:NginxController、Store、SyncQueue。
    • Store 主要負責從 kubernetes APIServer 收集運行時信息,感知各種資源(如 ingress、service等)的變化,並及時將更新事件消息(event)寫入一個環形管道。
    • SyncQueue 協程按期掃描 syncQueue 隊列,發現有任務就執行更新操做,即藉助 Store 完成最新運行數據的拉取,而後根據必定的規則產生新的 nginx 配置,(有些更新必須 reload,就本地寫入新配置,執行 reload),而後執行動態更新操做,即構造 POST 數據,向本地 Nginx Lua 服務模塊發送 post 請求,實現配置更新。
    • NginxController 做爲中間的聯繫者,監聽 updateChannel,一旦收到配置更新事件,就向同步隊列 syncQueue 裏寫入一個更新請求。

2,部署 Nginx ingress

  • 下載地址:https://github.com/kubernetes/ingress-nginx/archive/nginx-0.22.0.tar.gzhtml

  • ingress-nginx文件位於deploy目錄下,各文件的做用:
    • configmap.yaml:提供configmap能夠在線更行nginx的配置,修改L4負載均衡配置的configmap
    • namespace.yaml:建立一個獨立的命名空間 ingress-nginx
    • rbac.yaml:建立對應的role rolebinding 用於rbac
    • with-rbac.yaml:有應用rbac的nginx-ingress-controller組件
    • mandatory.yaml:是其它組件yaml之和

2.1 修改 with-rbac.yaml 或者 mandatory.yaml

  • kind: DaemonSet:官方原始文件使用的是deployment,replicate 爲 1,這樣將會在某一臺節點上啓動對應的nginx-ingress-controller pod。外部流量訪問至該節點,由該節點負載分擔至內部的service。測試環境考慮防止單點故障,改成DaemonSet而後刪掉replicate ,配合親和性部署在制定節點上啓動nginx-ingress-controller pod,確保有多個節點啓動nginx-ingress-controller pod,後續將這些節點加入到外部硬件負載均衡組實現高可用性。
  • hostNetwork: true:添加該字段,暴露nginx-ingress-controller pod的服務端口(80)
  • nodeSelector: 增長親和性部署,有custom/ingress-controller-ready 標籤的節點纔會部署該DaemonSet
# with-rbac.yaml
apiVersion: apps/v1
# kind: Deployment
kind: DeamonSet
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:
      serviceAccountName: nginx-ingress-serviceaccount
      hostNetwork: true
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.22.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 -> 33
            runAsUser: 33
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
      nodeSelector:
        custom/ingress-controller-ready: "true"
---

2.3 爲須要部署nginx-ingress-controller的節點設置lable

kubectl label nodes 192.168.2.101 custom/ingress-controller-ready=true
kubectl label nodes 192.168.2.102 custom/ingress-controller-ready=true
kubectl label nodes 192.168.2.103 custom/ingress-controller-ready=true

2.4 建立 nginx-ingress

kubectl create -f mandatory.yaml
kubectl create -f configmap.yaml
kubectl create -f namespace.yaml
kubectl create -f rbac.yaml
kubectl create -f with-rbac.yaml

3,測試ingress

3.1 建立一個apache的Service

# cat > my-apache.yaml << EOF
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-apache
spec:
  replicas: 2
  template:
    metadata:
      labels:
        run: my-apache
    spec:
      containers:
      - name: my-apache
        image: httpd
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-apache
spec:
  metadata:
    labels:
      run: my-apache
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30002
  selector:
    run: my-apache
EOF

3.2 建立一個 nginx 的Service

# cat > my-nginx.yaml << EOF
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
spec:
  template:
    matadata:
      lables:
        run: my-nginx
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30001
  selector:
    run: my-nginx
EOF

3.3 配置ingress轉發文件

  • host: 對應的域名
  • path: url上下文
  • backend:後向轉發 到對應的 serviceName: servicePort:
# cat > test-ingress.yaml << EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: default
spec:
  rules:
  - host: test.apache.ingress
    http:
      paths:
      - path: /
        backend:
          serviceName: my-apache
          servicePort: 80
  - host: test.nginx.ingress
    http:
      paths:
      - path: /
        backend:
          serviceName: my-nginx
          servicePort: 80
EOF

3.4 查看狀態

# kubectl get ingress
NAME           HOSTS                                    ADDRESS   PORTS   AGE
test-ingress   test.apache.ingress,test.nginx.ingress             80      23s
# kubectl get deploy,pod,svc
NAME                              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/my-apache   2         2         2            1           12s
deployment.extensions/my-nginx    2         2         2            2           12s

NAME                             READY   STATUS              RESTARTS   AGE
pod/my-apache-57874fd49c-dc4vx   1/1     Running             0          12s
pod/my-apache-57874fd49c-lfhld   0/1     ContainerCreating   0          12s
pod/my-nginx-756f645cd7-fvq9d    1/1     Running             0          11s
pod/my-nginx-756f645cd7-ngj99    1/1     Running             0          12s

NAME                               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes                 ClusterIP   10.254.0.1       <none>        443/TCP        10d
service/my-apache                  NodePort    10.254.95.131    <none>        80:30002/TCP   12s
service/my-nginx                   NodePort    10.254.92.19     <none>        80:30001/TCP   11s

3.5 解析域名到ipvs虛擬VIP,訪問測試

3.5.1 經過-H 指定模擬的域名

  • test.apache.ingress
# curl -v http://192.168.2.100 -H 'host: test.apache.ingress'
* About to connect() to 192.168.2.100 port 80 (#0)
*   Trying 192.168.2.100...
* Connected to 192.168.2.100 (192.168.2.100) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> host: test.apache.ingress
>
< HTTP/1.1 200 OK
< Server: nginx/1.15.8
< Date: Fri, 25 Jan 2019 08:24:37 GMT
< Content-Type: text/html
< Content-Length: 45
< Connection: keep-alive
< Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT
< ETag: "2d-432a5e4a73a80"
< Accept-Ranges: bytes
<
<html><body><h1>It works!</h1></body></html>
* Connection #0 to host 192.168.2.100 left intact
  • test.nginx.ingress
# curl -v http://192.168.2.100 -H 'host: test.nginx.ingress'
* About to connect() to 192.168.2.100 port 80 (#0)
*   Trying 192.168.2.100...
* Connected to 192.168.2.100 (192.168.2.100) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> host: test.nginx.ingress
>
< HTTP/1.1 200 OK
< Server: nginx/1.15.8
< Date: Fri, 25 Jan 2019 08:24:53 GMT
< Content-Type: text/html
< Content-Length: 612
< Connection: keep-alive
< Vary: Accept-Encoding
< Last-Modified: Tue, 25 Dec 2018 09:56:47 GMT
< ETag: "5c21fedf-264"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 192.168.2.100 left intact

3.5.2 瀏覽器訪問

4,部署monitoring

4.1 配置 ingress

# cat > monitoring/prometheus-grafana-ingress.yaml << EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: prometheus-grafana-ingress
  namespace: ingress-nginx
spec:
  rules:
  - host: grafana.k8s.ing
    http:
      paths:
      - path: /
        backend:
          serviceName: grafana
          servicePort: 3000
  - host: prometheus.k8s.ing
    http:
      paths:
      - path: /
        backend:
          serviceName: prometheus-server
          servicePort: 9090
EOF

4.2 在ingress-nginx官網deploy/monitoring目錄下載相關yaml文件

# ls monitoring/
configuration.yaml  grafana.yaml  prometheus-grafana-ingress.yaml  prometheus.yaml

4.3 部署服務

# kubectl apply -f monitoring/

4.4 查看狀態

# kubectl get pod,svc,ingress -n ingress-nginx
NAME                                    READY   STATUS    RESTARTS   AGE
pod/grafana-5ccff7668d-7lk6q            1/1     Running   0          2d14h
pod/prometheus-server-7f87788f6-7zcfx   1/1     Running   0          2d14h

NAME                                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/glusterfs-dynamic-pvc-grafana      ClusterIP   10.254.146.102   <none>        1/TCP            2d14h
service/glusterfs-dynamic-pvc-prometheus   ClusterIP   10.254.160.58    <none>        1/TCP            2d14h
service/grafana                            NodePort    10.254.244.77    <none>        3000:30303/TCP   2d14h
service/prometheus-server                  NodePort    10.254.168.143   <none>        9090:32090/TCP   2d14h

NAME                                            HOSTS                                ADDRESS   PORTS   AGE
ingress.extensions/prometheus-grafana-ingress   grafana.k8s.ing,prometheus.k8s.ing             80      2d14h

4.5 配置grafana

  • 導入 json 文件
  • 在ingress-nginx官網deploy/grafana/dashboards目錄下載相關nginx.json文件

相關文章
相關標籤/搜索