在 Kubernetes 叢集中,Ingress是授權入站串連到達叢集服務的規則集合,為您提供七層負載平衡能力。您可以給 Ingress 配置提供外部可訪問的 URL、負載平衡、SSL、基於名稱的虛擬機器主機等。

前置條件

為了測試複雜路由服務,本例中建立一個 nginx 的樣本應用,您需要事先建立 nginx 的 deployment,然後建立多個 Service,用來觀察路由的效果。實際測試請替換成自己的服務。

root@master # kubectl run nginx --image=registry.cn-hangzhou.aliyuncs.com/acs/netdia:latest

root@master # kubectl expose deploy nginx --name=http-svc --port=80 --target-port=80
root@master # kubectl expose deploy nginx --name=http-svc1 --port=80 --target-port=80
root@master # kubectl expose deploy nginx --name=http-svc2 --port=80 --target-port=80
root@master # kubectl expose deploy nginx --name=http-svc3 --port=80 --target-port=80

簡單的路由服務

通過以下命令建立一個簡單的 Ingress,所有對 /svc 路徑的訪問都會被路由到名為 http-svc 的服務。nginx.ingress.kubernetes.io/rewrite-target: /會將/svc路徑重新導向到後端服務能夠識別的/路徑上面。

root@master # cat <<EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: simple
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /svc
        backend:
          serviceName: http-svc
          servicePort: 80
EOF
root@master # kubectl get ing
NAME            HOSTS         ADDRESS          PORTS     AGE
simple          *             101.37.192.211   80        11s

現在訪問 http://101.37.192.211/svc 即可訪問到 Nginx 服務。

基於網域名稱的簡單扇出路由

如果您有多個網域名稱對外提供不同的服務,您可以產生如下的配置達到一個簡單的基於網域名稱的扇出效果。

root@master # cat <<EOF | kubectl create -f - 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: simple-fanout
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: http-svc1
          servicePort: 80
      - path: /bar
        backend:
          serviceName: http-svc2
          servicePort: 80
  - host: foo.example.com
    http:
      paths:
      - path: /film
        backend:
          serviceName: http-svc3
          servicePort: 80    
EOF
root@master # kubectl get ing
NAME            HOSTS         ADDRESS          PORTS     AGE
simple-fanout   *             101.37.192.211   80        11s

這時您可以通過 http://foo.bar.com/foo 訪問到 http-svc1 服務;通過 http://foo.bar.com/bar 訪問到 http-svc2 服務;通過 http://foo.example.com/film 訪問到 http-svc3 服務。

说明
  • 如果是生產環境,您需要將您的這個網域名稱指向上面返回的 ADDRESS 101.37.192.211
  • 如果是測試環境測試,您可以修改 hosts 檔案添加一條網域名稱映射規則。
    101.37.192.211 foo.bar.com
    101.37.192.211 foo.example.com

簡單路由預設網域名稱

如果您沒有網域名稱地址也沒有關係,Container Service為 Ingress 服務綁定了一個預設網域名稱,您可以通過這個網域名稱來訪問服務。網域名稱的格式如下:*.[cluster-id].[region-id].alicontainer.com。您可以直接在控制台叢集基本資料頁擷取到該地址。

您可以通過下面的配置藉助該預設網域名稱暴露兩個服務。

root@master # cat <<EOF | kubectl create -f - 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: shared-dns
spec:
  rules:
  - host: foo.[cluster-id].[region-id].alicontainer.com  ##替換為您叢集預設的服務訪問網域名稱
    http:
      paths:
      - path: /
        backend:
          serviceName: http-svc1
          servicePort: 80
  - host: bar.[cluster-id].[region-id].alicontainer.com  ##替換為您叢集預設的服務訪問網域名稱
    http:
      paths:
      - path: /
        backend:
          serviceName: http-svc2
          servicePort: 80    
EOF
root@master # kubectl get ing
NAME            HOSTS         ADDRESS          PORTS     AGE
shared-dns   foo.[cluster-id].[region-id].alicontainer.com,bar.[cluster-id].[region-id].alicontainer.com             47.95.160.171   80        40m

這時您可以通過 http://foo.[cluster-id].[region-id].alicontainer.com/ 訪問到 http-svc1 服務;通過 http://bar.[cluster-id].[region-id].alicontainer.com 訪問到 http-svc2 服務。

配置安全的路由服務

支援多認證管理,為您的服務提供安全防護。

  1. 準備您的服務憑證。

    如果沒有認證,可以通過下面的方法產生測試認證。

    说明 網域名稱與您的 Ingress 配置要一致。
    root@master # openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=foo.bar.com/O=foo.bar.com"

    上面命令會產生一個認證檔案 tls.crt、一個私密金鑰檔案tls.key

    然後用該認證和私密金鑰建立一個名為foo.bar 的 Kubernetes Secret。建立 Ingress 時需要引用這個 Secret。

    root@master # kubectl create secret tls foo.bar --key tls.key --cert tls.crt
  2. 建立一個安全的 Ingress 服務。
    root@master # cat <<EOF | kubectl create -f - 
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: tls-fanout
    spec:
      tls:
      - hosts:
        - foo.bar.com
        secretName: foo.bar
      rules:
      - host: foo.bar.com
        http:
          paths:
          - path: /foo
            backend:
              serviceName: http-svc1
              servicePort: 80
          - path: /bar
            backend:
              serviceName: http-svc2
              servicePort: 80
    EOF
    root@master # kubectl get ing
    NAME            HOSTS         ADDRESS          PORTS     AGE
    tls-fanout      *             101.37.192.211   80        11s
  3. 按照 基於網域名稱的簡單扇出路由 中的注意事項,配置 hosts 檔案或者設定網域名稱來訪問該 tls 服務。

    您可以通過 http://foo.bar.com/foo 訪問到 http-svc1 服務;通過 http://foo.bar.com/bar 訪問到 http-svc2 服務。

    您也可以通過 HTTP 的方式訪問該 HTTPS 的服務。Ingress 預設對配置了 HTTPS 的 HTTP 訪問重新導向到 HTTPS 上面。所以訪問 http://foo.bar.com/foo 會被自動重新導向到 https://foo.bar.com/foo

通過 Kubernetes Dashboard 部署 Ingress

  1. 將下面的 yml code 儲存到 nginx-ingress.yml 檔案中。
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: simple
    spec:
      rules:
      - http:
          paths:
          - path: /svc
            backend:
              serviceName: http-svc
              servicePort: 80
  2. 登入Container Service管理主控台,在 Kubernetes 菜單下,在叢集列表頁面中,單擊目的地組群右側的控制台,進入 Kubernetes Dashboard 頁面。
  3. 單擊建立,開始建立應用。


  4. 單擊使用檔案建立。選擇剛才儲存的 nginx-ingress.yml 檔案。
  5. 單擊上傳

    這樣就建立了一個 Ingress 的七層代理路由到 http-svc 服務上。

  6. 在 Kubernetes Dashboard 上定位到 default 命名空間,選擇訪問權
    可以看到您剛剛建立的 Ingress 資源及其訪問地址 http://118.178.174.161/svc


  7. 開啟瀏覽器輸入該地址即可訪問前面建立的 http-svc 服務。