全部產品
Search
文件中心

Alibaba Cloud Service Mesh:為工作負載設定存取原則

更新時間:Jun 30, 2024

預設情況下,Service Mesh內的工作負載可以互相訪問。當您需要對叢集中的工作負載進行存取控制和許可權管理時,可以使用授權原則設定工作負載的訪問條件(例如限制請求路徑、方法和用戶端IP等),確保只有符合要求的請求才能訪問對應工作負載,提高網格安全和資源保護。

前提條件

已添加叢集到ASM執行個體

功能介紹

授權策略支援CUSTOM(自訂)、DENY(拒絕)和ALLOW(允許)策略類型。規則的判斷存在優先順序關係,當CUSTOM、DENY和ALLOW策略同時用於同一個工作負載時,將首先驗證CUSTOM策略,然後驗證DENY策略,最後驗證ALLOW策略,並且存在以下關係:

  • 如果任何一個CUSTOM策略匹配了請求並驗證結果為拒絕,則拒絕此請求。

  • 如果任何一個DENY策略匹配了請求並驗證結果為拒絕,則拒絕此請求。

  • 如果此工作負載上沒有配置ALLOW策略,允許此請求(預設允許)。

  • 如果該工作負載配置了ALLOW策略,並且ALLOW策略匹配此請求,允許此請求。

  • 如果都不滿足以上要求,則拒絕此請求。

本文提供以下四個樣本,協助您快速瞭解和使用授權策略。

樣本一:限制訪問工作負載的請求路徑

本樣本中,foo命名空間下的應用可以訪問本命名空間下的httpbin應用的/headers路徑,訪問其他路徑都將失敗;其它命名空間下的應用無法訪問httpbin應用。

步驟一:為default和foo命名空間注入Sidecar代理

  1. 建立default和foo命名空間。具體操作,請參見建立命名空間

  2. 為default和foo命名空間注入Sidecar代理。具體操作,請參見啟用自動注入

步驟二:部署測試應用

  1. 在default和foo命名空間部署sleep應用。

    1. 使用以下內容,建立sleep.yaml

      展開查看sleep.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
      ---
    2. 執行以下命令,在default命名空間部署sleep應用。

      kubectl apply -f sleep.yaml -n default
    3. 執行以下命令,在foo命名空間部署sleep應用。

      kubectl apply -f sleep.yaml -n foo
  2. 在foo命名空間部署httpbin應用。

    1. 使用以下內容,建立httpbin.yaml

      展開查看httpbin.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: httpbin
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: httpbin
        labels:
          app: httpbin
          service: httpbin
      spec:
        ports:
        - name: http
          port: 8000
          targetPort: 80
        selector:
          app: httpbin
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: httpbin
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: httpbin
            version: v1
        template:
          metadata:
            labels:
              app: httpbin
              version: v1
          spec:
            serviceAccountName: httpbin
            containers:
            - image: docker.io/kennethreitz/httpbin
              imagePullPolicy: IfNotPresent
              name: httpbin
              ports:
              - containerPort: 80
    2. 執行以下命令,在foo命名空間部署httpbin應用。

      kubectl apply -f httpbin.yaml -n foo

步驟三:建立授權策略

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略,然後單擊建立

  3. 建立頁面,配置相關資訊,然後單擊建立

    配置項

    說明

    名稱

    自訂授權策略名稱稱。

    策略類型

    設定為允許

    命名空間

    工作負載生效頁簽,設定命名空間foo

    生效範圍

    選擇Service

    工作負載

    選擇httpbin

    請求匹配規則

    1. 添加請求來源地區,開啟命名空間(Namespaces)開關,設定值為foo,使foo命名空間下的應用都能訪問httpbin應用。

    2. 添加請求目標地區,開啟HTTP路徑(Paths)開關,設定值為/headers,使所有命名空間下的應用僅支援訪問foo命名空間下的httpbin應用的/headers路徑。

步驟四:驗證限制訪問請求路徑是否成功

  1. 使用default命名空間下的sleep應用訪問foo命名空間下的httpbin應用。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 容器組

    3. 容器組頁面頂部,設定命名空間default,在操作列,單擊sleep容器對應的終端 > sleep

    4. 在sleep容器終端中執行以下命令,訪問httpbin應用的/headers路徑。

      curl httpbin.foo.svc.cluster.local:8000/headers

      返回403,提示訪問被拒絕。

    5. 在sleep容器終端中執行以下命令,訪問httpbin應用的/ip路徑。

      curl httpbin.foo.svc.cluster.local:8000/ip

      返回403,提示訪問被拒絕。

  2. 使用foo命名空間下的sleep應用訪問foo命名空間下的httpbin應用。

    1. 在叢集管理頁左側導覽列,選擇工作負載 > 容器組

    2. 容器組頁面頂部設定命名空間foo,在操作列,單擊sleep容器對應的終端 > sleep

    3. 在sleep容器終端中執行以下命令,訪問httpbin應用的/headers路徑。

      curl httpbin.foo.svc.cluster.local:8000/headers

      預期輸出:

      {
        "headers": {
          "Accept": "*/*",
          "Host": "httpbin.foo.svc.cluster.local:8000",
          "User-Agent": "curl/7.82.0-DEV",
          "X-Envoy-Attempt-Count": "1",
          "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=f7ab4985563b5b1986314d5a36c6e46819213e2f38301f534f00afb7cd4b9164;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
        }
      }
    4. 在sleep容器終端中執行以下命令,訪問httpbin應用的/ip路徑。

      curl httpbin.foo.svc.cluster.local:8000/ip

      返回403,提示訪問被拒絕。

    可以看到default命名空間中的應用無法訪問foo命名空間下的httpbin應用的任何路徑,foo命名空間中的應用可以訪問httpbin的/headers路徑。

樣本二:限制訪問工作負載的請求路徑和方法

本樣本中,所有命名空間下的應用僅支援通過GET請求訪問foo命名空間下的httpbin應用的/status路徑,訪問其他路徑或使用其他要求方法都將失敗。

步驟一:為default和foo命名空間注入Sidecar代理

  1. 建立default和foo命名空間。具體操作,請參見建立命名空間

  2. 為default和foo命名空間注入Sidecar代理。具體操作,請參見啟用自動注入

步驟二:部署測試應用

  1. 在default和foo命名空間部署sleep應用。

    1. 使用以下內容,建立sleep.yaml

      展開查看sleep.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
      ---
    2. 執行以下命令,在default命名空間部署sleep應用。

      kubectl apply -f sleep.yaml -n default
    3. 執行以下命令,在foo命名空間部署sleep應用。

      kubectl apply -f sleep.yaml -n foo
  2. 在foo命名空間部署httpbin應用。

    1. 使用以下內容,建立httpbin.yaml

      展開查看httpbin.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: httpbin
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: httpbin
        labels:
          app: httpbin
          service: httpbin
      spec:
        ports:
        - name: http
          port: 8000
          targetPort: 80
        selector:
          app: httpbin
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: httpbin
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: httpbin
            version: v1
        template:
          metadata:
            labels:
              app: httpbin
              version: v1
          spec:
            serviceAccountName: httpbin
            containers:
            - image: docker.io/kennethreitz/httpbin
              imagePullPolicy: IfNotPresent
              name: httpbin
              ports:
              - containerPort: 80
    2. 執行以下命令,在foo命名空間部署httpbin應用。

      kubectl apply -f httpbin.yaml -n foo

步驟三:建立授權策略

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略,然後單擊建立

  3. 建立頁面,配置相關資訊,然後單擊建立

  4. 配置項

    說明

    名稱

    自訂授權策略名稱稱。

    策略類型

    選擇允許

    命名空間

    工作負載生效頁簽,設定命名空間foo

    生效範圍

    選擇Service

    工作負載

    選擇httpbin

    請求匹配規則

    添加請求目標地區,進行如下配置:

    1. 開啟HTTP方法(Methods)開關,設定值為GET

    2. 開啟HTTP路徑(Paths)開關,設定值為/status/*,使所有命名空間下的應用僅支援使用GET方法訪問foo命名空間下的httpbin應用的/status路徑。

步驟四:驗證限制訪問工作負載的請求路徑和方法是否成功

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 容器組

  3. 容器組頁面頂部,設定命名空間default,在操作列,單擊sleep容器對應的終端 > sleep

  4. 在sleep容器終端中執行以下命令,使用POST的方式訪問httpbin應用的/status路徑。

    curl -I -X POST "httpbin.foo.svc.cluster.local:8000/status/200" -H "accept: text/plain"

    返回403,訪問httpbin應用失敗。

  5. 執行以下命令,使用GET的方式訪問httpbin應用的/IP路徑。

    curl -I -X GET "httpbin.foo.svc.cluster.local:8000/IP/200" -H "accept: text/plain"

    返回403,訪問httpbin應用失敗。

  6. 執行以下命令,使用GET的方式訪問httpbin應用的/status路徑。

    curl -I -X GET "httpbin.foo.svc.cluster.local:8000/status/200" -H "accept: text/plain"

    預期輸出:

    HTTP/1.1 200 OK
    server: envoy
    date: Fri, 29 Apr 2022 03:01:16 GMT
    content-type: text/html; charset=utf-8
    access-control-allow-origin: *
    access-control-allow-credentials: true
    content-length: 0
    x-envoy-upstream-service-time: 5

    可以看到default命名空間下的應用只有使用GET方式訪問httpbin應用的/status路徑才能成功,說明限制訪問工作負載的請求路徑和方法成功。

樣本三:限制訪問工作負載的用戶端IP

限制foo命名空間中的httpbin應用只能被許可的用戶端IP訪問。

步驟一:為foo命名空間注入Sidecar代理

  1. 建立foo命名空間。具體操作,請參見管理全域命名空間

  2. 為foo命名空間注入Sidecar代理。具體操作,請參見啟用自動注入

步驟二:建立ASM網關

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇ASM網關 > 入口網關

  3. 入口網關頁面,單擊建立,配置相關資訊,然後單擊建立

    配置項

    說明

    名稱

    自訂網關的名稱。

    部署叢集

    選擇網關部署的叢集。

    負載平衡

    選擇CLB(可以根據需要使用NLB,此處以CLB為例),公網訪問。

    建立負載平衡

    選擇負載平衡,可選:

    • 使用已有負載平衡:從已有負載平衡列表中選擇。

    • 建立負載平衡:單擊建立負載平衡,從下拉式清單中選擇所需的負載平衡規格。

    連接埠映射

    按需選擇協議,輸入服務連接埠

    外部流量策略

    單擊進階選項,設定外部流量策略Local

步驟三:建立虛擬服務和網關規則

  1. 使用以下內容,在foo命名空間中建立虛擬服務。具體操作,請參見管理虛擬服務

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: httpbin
    spec:
      gateways:
        - httpbin-gateway
      hosts:
        - '*'
      http:
        - match:
            - uri:
                prefix: /headers
          route:
            - destination:
                host: httpbin
                port:
                  number: 8000
  2. 使用以下內容,在foo命名空間建立網關規則。具體操作,請參見管理網關規則

    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: httpbin-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
        - hosts:
            - '*'
          port:
            name: http
            number: 80
            protocol: HTTP

步驟四:建立授權策略

  1. 擷取ASM網關IP。具體操作,請參見建立入口網關服務

  2. 擷取用戶端IP。

    在瀏覽器地址欄中輸入http://{ASM網關IP}/headers,擷取X-Envoy-External-Address右側的IP。用戶端IP

  3. 建立授權策略。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略,然後單擊建立

    3. 建立頁面,配置相關資訊,然後單擊建立

      配置項

      說明

      名稱

      自訂授權策略名稱稱。

      策略類型

      選擇拒絕

      命名空間

      工作負載生效頁簽,設定命名空間foo

      生效範圍

      選擇Service

      工作負載

      選擇httpbin

      請求匹配規則

      添加請求來源地區,開啟原始源IP(RemoteIPBlocks)開關,設定值為步驟2擷取的用戶端IP,使用戶端IP將無法訪問httpbin應用。

步驟五:驗證限制訪問工作負載的用戶端IP是否成功

在瀏覽器地址欄中輸入http://{ASM網關IP}/headers,返回RBAC:access denied,訪問httpbin應用失敗,說明限制訪問工作負載的用戶端IP成功。驗證用戶端IP

樣本四:限制跨命名空間的服務訪問

步驟一:為demo-frontend和demo-server命名空間注入Sidecar代理

  1. 建立demo-frontend和demo-server命名空間。具體操作,請參見建立命名空間

  2. 為demo-frontend和demo-server命名空間注入Sidecar代理。具體操作,請參見啟用自動注入

步驟二:部署測試服務

在demo-frontend命名空間下建立發起請求的sleep服務,在demo-server命名空間下建立被訪問的httpbin服務。

  1. 在demo-frontend命名空間下建立sleep服務。

    1. 使用以下內容,建立sleep.yaml。

      展開查看sleep.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
      ---
    2. 在ACK叢集對應的KubeConfig環境下,執行以下命令,建立sleep服務。

      kubectl apply -f sleep.yaml -n demo-frontend
  2. 在demo-server命名空間下建立httpbin服務。

    1. 使用以下內容,建立httpbin.yaml。

      展開查看httpbin.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: httpbin
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: httpbin
        labels:
          app: httpbin
          service: httpbin
      spec:
        ports:
        - name: http
          port: 8000
          targetPort: 80
        selector:
          app: httpbin
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: httpbin
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: httpbin
            version: v1
        template:
          metadata:
            labels:
              app: httpbin
              version: v1
          spec:
            serviceAccountName: httpbin
            containers:
            - image: docker.io/kennethreitz/httpbin
              imagePullPolicy: IfNotPresent
              name: httpbin
              ports:
              - containerPort: 80
    2. 在ACK叢集對應的KubeConfig環境下,執行以下命令,建立httpbin服務。

      kubectl apply -f httpbin.yaml -n demo-server
  3. 驗證測試服務是否成功注入Sidecar。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 容器組

    3. 容器組頁面上方,命名空間選擇demo-frontend,單擊sleep服務的容器組名稱。

      容器頁簽下可以看到istio-proxy容器,說明sleep服務注入Sidecar成功。

    4. 容器組頁面上方,命名空間選擇demo-server,單擊httpbin服務的容器組名稱。

      容器頁簽下可以看到istio-proxy容器,說明httpbin服務注入Sidecar成功。

步驟三:使用授權策略實現對跨命名空間服務訪問的控制

通過修改授權策略的動作,您可以禁止或允許demo-frontend命名空間下的服務訪問demo-server下的服務,實現對跨命名空間服務訪問的控制。

  1. 建立授權策略,禁止來自demo-frontend命名空間的訪問請求。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略,然後單擊建立

    3. 配置授權策略相關資訊,然後單擊建立

      配置項

      說明

      名稱

      輸入授權策略的名稱。

      策略類型

      選擇拒絕

      命名空間

      工作負載生效頁簽,設定命名空間demo-server

      生效範圍

      選擇命名空間生效

      請求匹配規則

      添加請求來源地區,開啟命名空間(Namespaces)開關,設定值為demo-frontend

  2. 訪問httpbin服務。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 容器組

    3. 容器組頁面上方,命名空間選擇demo-frontend,然後在操作列,單擊sleep容器對應的終端 > sleep

    4. 在容器組終端中執行以下命令,訪問httpbin服務。

      curl -I httpbin.demo-server.svc.cluster.local:8000

      預期輸出:

      HTTP/1.1 403 Forbidden
      content-length: 19
      content-type: text/plain
      date: Wed, 11 Oct 2023 08:15:25 GMT
      server: envoy
      x-envoy-upstream-service-time: 4

      返回以上結果,說明demo-frontend命名空間下的服務訪問demo-server下的服務失敗。

  3. 修改授權策略動作為ALLOW,允許來自demo-frontend命名空間的訪問請求。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略

    3. 授權策略頁面,單擊目標策略右側操作列下的查看YAML

    4. 編輯對話方塊,修改action參數值為ALLOW,然後單擊確定

  4. 在sleep容器組終端中執行以下命令,訪問httpbin服務。

    curl -I httpbin.demo-server.svc.cluster.local:8000

    預期輸出:

    HTTP/1.1 200 OK
    server: envoy
    date: Wed, 11 Oct 2023 08:21:40 GMT
    content-type: text/html; charset=utf-8
    content-length: 9593
    access-control-allow-origin: *
    access-control-allow-credentials: true
    x-envoy-upstream-service-time: 13

    返回以上結果,說明demo-frontend命名空間下的服務成功訪問demo-server下的服務。

    可以看到,建立動作Deny的授權策略後,demo-frontend命名空間下的服務訪問demo-server下的服務失敗。修改授權策略的動作ALLOW,demo-frontend命名空間下的服務訪問demo-server下的服務成功,說明通過授權策略控制跨命名空間服務訪問成功。