1. 程式人生 > >Kubernetes 服務入口管理與 Nginx Ingress Controller

Kubernetes 服務入口管理與 Nginx Ingress Controller

Kubernetes 具有強大的副本,動態擴容等特性,每一次 Pod 的變化 IP 地址都會發生變化,所以 Kubernetes 引進了 Service 的概念。Kubernetes 中使用 Service 物件抽象出來的機制來管理同一組標籤的 Pod ,而不需要關心 Pod 發生了什麼變化併為其分配了一個虛擬的 IP,當外界需要訪問 Pod 裡的容器提供的功能時,不直接使用 Pod 的 IP 地址和埠,而是訪問 Service 的這個虛擬 IP 和埠,由 Service 把請求轉發給它背後的 Pod。

Service 暴露服務型別

通常情況下,我們會定義一個 Service 來管理一組 Pod 暴露相關的服務,如果要對外暴露服務的話,只需要定義相應的埠即可(NodePort模式),但如果定義了很多 Service 物件並暴露服務的話就需要配置很多埠,後續維護起來就會變的很複雜,所以 Kubernetes 中還使用了 Ingress 的機制,比如使用 Nginx 繫結一個固定埠 80,後續的請求通過轉發到 Service 即可。這樣如果每次新增服務的話,還需要修改 Nginx 的配置,為了解決這個問題 Kubernetes 中還使用了 Ingress Controller 元件。簡單理解就是原先需要修改 Nginx 配置,然後配置不同的轉發規則到 Service 這個過程抽象出來變成一個 Ingress 物件,後續 Nginx 的變更再通過 Ingress Controoler 與 Kubernetes API 互動,動態的去感知叢集中 Ingress 規則變化,再寫到 Nginx Pod 裡。

kind: Service
apiVersion: v1
metadata:
  name: test-service
spec:
  selector:
    app: test—-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

由於 Service 中的服務僅可以在容器內部中通訊,如果需要外部能訪問到,還需要暴露 Service , 如下 :

    internet
        |
  ------------
  [ Services ]

kubernetes 中定義瞭如下的一些服務型別:

Proxy

使用 Kubernetes 代理來訪問服務,一般內網檢視 dashboard,除錯遠端檢視時可能會用到。

{
  "kind": "Service",
  "apiVersion": "v1",
  "metadata": {
    "name": "kubernetes",
    "namespace": "default",
    "selfLink": "/api/v1/namespaces/default/services/kubernetes",
    "uid": "f594405b-dc19-11e8-90ea-0050569f4a19",
    "resourceVersion
": "6", "creationTimestamp": "2018-10-30T08:01:08Z", "labels": { "component": "apiserver", "provider": "kubernetes" } }, "spec": { "ports": [ { "name": "https", "protocol": "TCP", "port": 443, "targetPort": 6443 } ], "clusterIP": "10.96.0.1", "type": "ClusterIP", "sessionAffinity": "None" }, "status": { "loadBalancer": {} } }

NodePort Service

指定服務型別為 NodePort 是將外部流量直接傳送給服務最原始的方式,需要在 Node 服務節點主機上開放特定的埠,通過繫結主機的某個埠,然後進行 Pod 的請求轉發和負載均衡,但這種方式下缺陷是 Service 可能有很多個,如果每個都繫結一個 Node 主機埠的話,主機需要開放外圍一堆的埠進行服務呼叫,管理混亂,並且只能使用 30000-32767 之間的埠,適用與臨時暴露某一個服務的埠演示的場景。

{
  "kind": "Service",
  "apiVersion": "v1",
  "metadata": {
    "name": "kubernetes-dashboard",
    "namespace": "kube-system",
    "selfLink": "/api/v1/namespaces/kube-system/services/kubernetes-dashboard",
    "uid": "edd78318-dc1a-11e8-90ea-0050569f4a19",
    "resourceVersion": "1076",
    "creationTimestamp": "2018-10-30T08:08:05Z",
    "labels": {
      "k8s-app": "kubernetes-dashboard"
    }
  },
  "spec": {
    "ports": [
      {
        "protocol": "TCP",
        "port": 443,
        "targetPort": 8443,
        "nodePort": 32151
      }
    ],
    "selector": {
      "k8s-app": "kubernetes-dashboard"
    },
    "clusterIP": "10.103.60.159",
    "type": "NodePort",
    "sessionAffinity": "None",
    "externalTrafficPolicy": "Cluster"
  },
  "status": {
    "loadBalancer": {}
  }
}

LoadBlancer Service

一般配合公用雲使用,指定的埠上的所有流量都將轉發到該服務,使用 LoadBlancer Service 暴露服務時實際上是向雲平臺申請建立一個負載均衡器來向外暴露服務,可能需要支付額外的費用。

Nginx Ingress Controller

Nginx Ingress Controller 是由 Nginx 與 Ingress Controller 兩部分組成。

Ingress

與上述的幾種型別不同,Ingress 實際上不是一種服務。它是位於多前面服務的不同,可以轉發不同的域名請求到叢集中不同的服務上,簡單的理解,Ingress 就是從 Kubernetes 叢集外訪問叢集的入口,將使用者的URL請求轉發到不同的 Service 上。Ingress 相當於 Nginx、Apache 等負載均衡方向代理伺服器,其中還包括規則定義,即 URL 的路由資訊,路由資訊得的重新整理由 Ingress controller 來提供。

Ingress controller

Ingress Controller 通過不斷地跟 kubernetes API 打交道,實時的感知後端 service、pod 等變化,比如新增和減少 pod,service 增加與減少等;當得到這些變化資訊後,Ingress Controller 再結合下文的 Ingress 生成配置,然後更新反向代理負載均衡器,並重新整理其配置,達到服務發現的作用。對於 Ingress controller 來說,建立一個 Ingress 相當於在 nginx.conf 中新增一個 server 入口,並 nginx -s reload 重新生效。。

比如想要通過負載均衡器實現不同子域名到不同服務的訪問:

foo.bar.com --|                 |-> foo.bar.com s1:80
              | 178.91.123.132  |
bar.foo.com --|                 |-> bar.foo.com s2:80

定義 Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: s1
          servicePort: 80
  - host: bar.foo.com
    http:
      paths:
      - backend:
          serviceName: s2
          servicePort: 80

Ingress本身並不會自動建立負載均衡器,需要執行一個 Ingress controller 來根據 Ingress 的定義來管理負載均衡器。為了 Ingress 正常工作,叢集中必須執行 Ingress controller ,支援 Ingress 的型別的 kube-controller 有如下幾種:

dia-FM-2018-06-06-NGINX-Ingress-Controller_1037x541-640x334

安裝 nginx-ingress-controller (host network 模式根據 Node 數量設定副本數,取決於部署的方式 Deployment or DaemonSet)

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
$ kubectl -n ingress-nginx get pod -o wide
NAME                                        READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE
nginx-ingress-controller-5bdbdc5657-bcn2f   1/1     Running   0          74m   10.38.0.1   kubernetes-node-2   <none>
nginx-ingress-controller-5bdbdc5657-mmtph   1/1     Running   0          79m   10.40.0.1   kubernetes-node-1   <none>
$ kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx --watch
NAMESPACE       NAME                                        READY   STATUS    RESTARTS   AGE
ingress-nginx   nginx-ingress-controller-6457d975c8-6twqf   1/1     Running   0          78m
ingress-nginx   nginx-ingress-controller-5bdbdc5657-mmtph   1/1     Running   0          83m

$ kubectl describe pod nginx-ingress-controller-6457d975c8-6twqf -n ingress-nginx
Name:               nginx-ingress-controller-6457d975c8-6twqf
Namespace:          ingress-nginx
Priority:           0
PriorityClassName:  <none>
Node:               kubernetes-node-2/172.23.216.50
Start Time:         Wed, 31 Oct 2018 20:04:44 +0800
Labels:             app.kubernetes.io/name=ingress-nginx
                    app.kubernetes.io/part-of=ingress-nginx
                    pod-template-hash=6457d975c8
Annotations:        prometheus.io/port: 10254
                    prometheus.io/scrape: true
Status:             Running
IP:                 172.23.216.50
Controlled By:      ReplicaSet/nginx-ingress-controller-6457d975c8
Containers:
  nginx-ingress-controller:
    Container ID:  docker://f4d5b69cf579752799d6d7e92c547ed9a5a0ba9154b3683c4956079ea9e77304
    Image:         quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.20.0
    Image ID:      docker-pullable://quay.io/kubernetes-ingress-controller/[email protected]:f6180c5397d2361c317aff1314dc192ab0f9f515346a5319422cdc264f05d2d9
    Ports:         80/TCP, 443/TCP
    Host Ports:    80/TCP, 443/TCP
    Args:
      /nginx-ingress-controller
      --configmap=$(POD_NAMESPACE)/nginx-configuration
      --publish-service=$(POD_NAMESPACE)/ingress-nginx
      --annotations-prefix=nginx.ingress.kubernetes.io
    State:          Running
      Started:      Wed, 31 Oct 2018 20:04:45 +0800
    Ready:          True
    Restart Count:  0
    Liveness:       http-get http://:10254/healthz delay=10s timeout=1s period=10s #success=1 #failure=3
    Readiness:      http-get http://:10254/healthz delay=0s timeout=1s period=10s #success=1 #failure=3
    Environment:
      POD_NAME:       nginx-ingress-controller-6457d975c8-6twqf (v1:metadata.name)
      POD_NAMESPACE:  ingress-nginx (v1:metadata.namespace)
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from nginx-ingress-serviceaccount-token-rhpsb (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  nginx-ingress-serviceaccount-token-rhpsb:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  nginx-ingress-serviceaccount-token-rhpsb
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason            Age                From                        Message
  ----     ------            ----               ----                        -------
  Warning  FailedScheduling  49m (x3 over 49m)  default-scheduler           0/3 nodes are available: 1 node(s) had taints that the pod didn't tolerate, 2 node(s) didn't have free ports for the requested pod ports.
  Normal   Scheduled         49m                default-scheduler           Successfully assigned ingress-nginx/nginx-ingress-controller-6457d975c8-6twqf to kubernetes-node-2
  Normal   Pulled            48m                kubelet, kubernetes-node-2  Container image "quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.20.0" already present on machine
  Normal   Created           48m                kubelet, kubernetes-node-2  Created container
  Normal   Started           48m                kubelet, kubernetes-node-2  Started container

檢視安裝的版本

POD_NAMESPACE=ingress-nginx
POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app.kubernetes.io/name=ingress-nginx -o jsonpath='{.items[0].metadata.name}')
kubectl exec -it $POD_NAME -n $POD_NAMESPACE -- /nginx-ingress-controller --version

-------------------------------------------------------------------------------
NGINX Ingress controller
  Release:    0.20.0
  Build:      git-e8d8103
  Repository: https://github.com/kubernetes/ingress-nginx.git
-------------------------------------------------------------------------------

根據不同的網路環境與場景,需要選擇不同的策略,具體可以參考官方的文件,如下列舉常用的幾種:

Cloud environments 模式

如果是使用公有云,可以使用公有云的負載到 Node 節點即可,需要支付額外費用。

image

NodePort Service 模式(臨時測試,一般不建議使用)

image

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
# nodePort: 30000
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

執行

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
$ kubectl -n ingress-nginx get svc
NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.98.42.64   <none>        80:31460/TCP,443:31200/TCP   6m50s

host network 模式

image

修改 hostNetwork: true

vi nginx-ingress-controller.yaml

apiVersion: extensions/v1beta1
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: 2
  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
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.20.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            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

---

$ kubectl apply -f nginx-ingress-controller.yaml

檢視 ingress-nginx

$ kubectl -n ingress-nginx get pod -o wide
NAME                                        READY   STATUS    RESTARTS   AGE    IP              NODE                NOMINATED NODE
nginx-ingress-controller-6457d975c8-6twqf   1/1     Running   0          3m7s   172.23.216.50   kubernetes-node-2   <none>
nginx-ingress-controller-6457d975c8-smjsv   1/1     Running   0          3m7s   172.23.216.49   kubernetes-node-1   <none>

測試訪問

$ curl -D- 172.23.216.50
HTTP/1.1 404 Not Found
Server: nginx/1.15.5
Date: Wed, 31 Oct 2018 12:08:40 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive

<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.15.5</center>
</body>
</html>

建立 kubernetes-dashboard-ingress(預設 https ,annotations 頭必須設定

vi kubernetes-dashboard-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard-ingress
  namespace: kube-system
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/secure-backends: "true"

spec:
#  tls:
#   - secretName: k8s-dashboard-secret
  rules:
   - http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
      - path: /test
        backend:
          serviceName: test-nginx
          servicePort: 80
執行
$ kubectl apply -f kubernetes-dashboard-ingress.yaml
$ kubectl get ingress -o wide --all-namespaces      
NAMESPACE     NAME                           HOSTS   ADDRESS   PORTS   AGE
kube-system   kubernetes-dashboard-ingress   *                 80      3h53m

image
備註:其他功能參考官方文件:
其他命令
#刪除 Ingress Controller 名稱空間
$ kubectl delete namespace nginx-ingress
#安裝網路元件
$ yum install net-tools
#檢視開放的埠
$ netstat -ntlp

相關推薦

Kubernetes 服務入口管理 Nginx Ingress Controller

Kubernetes 具有強大的副本,動態擴容等特性,每一次 Pod 的變化 IP 地址都會發生變化,所以 Kubernetes 引進了 Service 的概念。Kubernetes 中使用 Service 物件抽象出來的機制來管理同一組標籤的 Pod ,而不需要關心 Pod 發生了什麼變化併為其分配了一個虛

Kubernetes 服務入口管理 Traefik Ingress Controller

前面部署了 kubernetes/ingress-nginx 作為 Ingress Controller,使用 Nginx 反向代理與負載,通過 Ingress Controller 不斷的跟 Kubernetes API 互動,實時獲取後端 Service、Pod 等的變化,然後動態更新 Nginx 配

kubernetes nginx ingress controller部署

test nta notice bus ast 請求 count ren pes Kubernetes nginx ingress controller部署 1.下載kubernetes nginx的yaml文件 Wget https://raw.githu

Kubernetes的負載均衡問題(Nginx Ingress)

targe yaml gen vim bsp 曾經 pla val icc Kubernetes關於服務的暴露主要是通過NodePort方式,通過綁定minion主機的某個端口,然後進行pod的請求轉發和負載均衡,但這種方式下缺陷是 Service可能有很多個,如果每個都

Linux服務管理啟停

firewalld Linux7 Linux 一、RHEL/OEL7.X前service 命令用於對系統服務進行管理,比如啟動(start),停止(stop),重啟(restart),查看狀態(status)等。chkconfig 用於查看、設置服務的運行級別。ntsysv 用於直觀方便的設置各個

網絡操作系統 第九章 DHCP 服務管理配置

onf www 存在 protoc protocol 內存 開始 計算機 協議 習題 1.DHCP的主要用途是什麽? DHCP(Dynamic Host Configuration Protocol,動態主機配置協議) 通過在網絡中配置DHCP服務器,可以為網絡內的計算機自

網絡操作系統 第十章 DNS服務管理配置

ip地址 targe 相互 一次 baidu 頂級 light main 能夠 習題 1、什麽是域名系統?描述域名解析的過程。 1)域名系統:Domain Name System縮寫DNS,是因特網的一項核心服務域名系統作為可以將域名和IP地址相互映射的一個分布式數據庫,能

Kubernetes服務發現ingress & ingress controller

Service雖然解決了服務發現和負載均衡的問題,但它在使用上還是有一些限制: 只支援4層負載均衡,沒有7層功能 對外訪問時,NodePort型別需要在外部搭建額外的負載均衡,而LoadBalancer要求kubernetes必須跑在支援的cloud prov

使用 NGINXNGINX Plus 的 Ingress Controller 進行 Kubernetes 的負載均衡

執行和管理跨機器叢集的大規模的容器微服務應用是一個極具挑戰的任務。Kubernetes 提供了一個強大的容器編排解決方案,從而幫助我們迎接這個挑戰。它包含了一些重要特性,比如容錯,自動伸縮,滾動升級,儲存,服務發現,以及負載均衡。 本文講解了如何使用開源 NGINX 軟體或者 NGINX Plus,以及 I

Samba服務Nginx服務

logs 如果 star smb tro 解析 glibc edt devel Samba服務: 1 準備環境 =====>part1: iptables -F 清楚防火墻配置 #systemctl disable firewalld #開機默認關閉 #syst

Linux基礎系列:常用命令(5)_nfs服務nginx服務

ash .com access emctl 磁盤 keepalive roo inux iptable 介紹:   NFS 是Network File System的縮寫,即網絡文件系統。一種使用於分散式文件系統的協定,由Sun公司開發,於1984年向外公布。功能是通過

centOS 6 服務管理服務腳本

很多 相關 技術 must 問題: -- 信息 rest 默認 服務管理與服務腳本 linux服務 服務管理與服務腳本 linux服務 服務啟動過程詳解 chkconfig命令 非獨立服務與xinetd進程 一個特殊的服務腳本 服務啟動過程詳解

centOS7服務管理啟動流程

當前 接下來 提示 設置 內存 ios 名稱 .gz 還要 centOS7服務管理與啟動流程 centOS7啟動流程 systemd簡介 unit對象 unit類型 特性 service unit文件格式 serv

kubernetes nginx ingress 使用記錄

uber doc 修改 tro aml 需要 端口 end 直接 前言 ingress是一種可以暴露k8s集群內部service的方式,用戶編輯配置文件定義一個ingress資源即可實現外部網絡訪問內網service。 ingress controller是來管理所有的In

nginxnginx-rtmp-module搭建流媒體服務

vedio sans nginx配置 mark dir pen isp 自己 需要 轉載自my student 克明zhang 現在,一起學習一下如何自己搭建一個流媒體服務器吧! 本次搭建流媒體使用的環境是centos 7.0+nginx; 讓我們一起開始奇妙的流媒體之

Kubernetes實戰[2]: 服務發現機制Cluster DNS的安裝(無CA認證版)

服務發現機制與Cluster DNS的安 服務發現機制Kubernetes提供了兩種發現Service的方法: 1.環境變量 當Pod運行的時候,Kubernetes會將之前存在的Service的信息通過環境變量寫到Pod中。 這種方法要求Pod必須要在Service之後啟動。

ansible 自動化編譯安裝nginx服務管理配置文件

lease root 嚴格 f2c 重啟 handlers nginx fig items 圖解: 說明: 系統版本:CentOS Linux release 7.4.1708 (Core) 需要先在一臺機上先裝好nginx,再配置ansible服務 1、將替換的文件放入

Kubernetes使用Nginx Ingress暴露Dashboard

strong ann 學會 itl 環境 kubectl back sys erro Kubernetes使用Nginx Ingress暴露Dashboard [TOC] 1. 環境說明 可用的kubernetes集群 可用的nginx ingress controlle

HashiCorp Consul Kubernetes 服務目錄同步

key meta lec htm etc sting gist tegra -m SEP 26 2018?MITCHELL HASHIMOTO We‘re releasing a new feature from the?HashiCorp Consul + Kuberne

服務器搭建管理(8)

host hugepage tran dir enable roo pro uri RoCE 1.服務器: 192.168.9.103 cluster-1 192.168.9.104 cluster-2 192.168.9.105 cluster-3 2.部署mongodb