聊聊 Linkerd Service Mesh 授權(quán)策略 (Server & ServerAuthorization)
簡(jiǎn)介
Server 和 ServerAuthorization 是 Linkerd 中的兩種策略資源, 用于控制對(duì) mesh 應(yīng)用程序的入站訪問。
在 linkerd 安裝期間,policyController.defaultAllowPolicy 字段用于指定當(dāng)沒有 Server 選擇 pod 時(shí)的默認(rèn)策略。此字段可以是以下之一:
- all-unauthenticated: 允許所有請(qǐng)求。這是默認(rèn)設(shè)置。
- all-authenticated: 允許來自相同或不同集群(使用 multi-cluster)中的 mesh 客戶端的請(qǐng)求。
- cluster-authenticated: 允許來自同一集群中的 mesh 客戶端的請(qǐng)求。
- cluster-unauthenticated: 允許來自同一集群中的 mesh 和非 mesh 客戶端的請(qǐng)求。
- deny: 所有請(qǐng)求都被拒絕。(然后應(yīng)創(chuàng)建 Policy 資源以允許服務(wù)之間的特定通信)。
可以通過在 pod spec 或其命名空間上設(shè)置注釋 config.linkerd.io/default-inbound-policy 來覆蓋此默認(rèn)值。
為 pod & port 配置 Server 后,其默認(rèn)行為是 deny 流量, 并且必須創(chuàng)建 ServerAuthorization 資源以允許 Server 上的流量。
系列
中文手冊(cè)(https://hacker-linner.com)
Server
Server 在與 server 相同的命名空間中的一組 pod 上選擇一個(gè)端口。它通常選擇 pod 上的單個(gè)端口,但在按名稱引用端口時(shí)它可能會(huì)選擇多個(gè)端口(例如 admin-http)。雖然 Server 資源類似于 Kubernetes 的 Service, 但它增加了多個(gè) Server 實(shí)例不能重疊的限制:它們不能選擇相同的 pod/port 對(duì)。 Linkerd 附帶了一個(gè) admission controller,試圖防止創(chuàng)建重疊的 server。
當(dāng)服務(wù)器選擇一個(gè)端口時(shí),默認(rèn)情況下會(huì)拒絕流量, 并且必須使用 ServerAuthorization 來授權(quán) Server 選擇的端口上的流量。
Spec
Server spec 可能包含以下頂級(jí)字段:
field | value |
---|---|
podSelector |
podSelector 選擇相同命名空間中的 pod 。 |
port |
端口名稱或編號(hào)。僅考慮 pod spec 的 ports 中的端口。 |
proxyProtocol |
為入站連接配置協(xié)議發(fā)現(xiàn)。取代 config.linkerd.io/opaque-ports annotation。必須是 unknown 、HTTP/1 、HTTP/2 、gRPC 、opaque 、TLS 之一。如果未設(shè)置,則默認(rèn)為 unknown 。 |
podSelector
這與 Kubernetes 中的 labelSelector 字段相同。屬于此選擇器的所有 pod 都將屬于 Server 組。podSelector 對(duì)象必須恰好包含以下字段之一:
field | value |
---|---|
matchExpressions |
matchExpressions 是 label selector 要求的列表。要求是 AND 組合。 |
matchLabels |
matchLabels 是 {key,value} 對(duì)的映射。 |
有關(guān)更多詳細(xì)信息,請(qǐng)參閱 Kubernetes LabelSelector reference。
- https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/label-selector/#LabelSelector
Server 示例
一個(gè) Server 選擇具有特定標(biāo)簽的 pod,使用 gRPC 作為 proxyProtocol。
- apiVersion: policy.linkerd.io/v1beta1
- kind: Server
- metadata:
- namespace: emojivoto
- name: emoji-grpc
- spec:
- podSelector:
- matchLabels:
- app: emoji-svc
- port: grpc
- proxyProtocol: gRPC
一個(gè) Server 選擇帶有 matchExpressions 的 pod,HTTP/2 作為 proxyProtocol,在端口 8080 上。
- apiVersion: policy.linkerd.io/v1beta1
- kind: Server
- metadata:
- namespace: emojivoto
- name: backend-services
- spec:
- podSelector:
- matchExpressions:
- - {key: app, operator: In, values: [voting-svc, emoji-svc]}
- - {key: environment, operator: NotIn, values: [dev]}
- port: 8080
- proxyProtocol: "HTTP/2"
ServerAuthorization
ServerAuthorization 提供了一種向一個(gè)或多個(gè) Server 授權(quán)流量的方法。
Spec
ServerAuthorization spec 必須包含以下頂級(jí)字段:
field | value |
---|---|
client |
client 描述授權(quán)訪問 server 的客戶端。 |
server |
server 在此授權(quán)適用的同一命名空間中標(biāo)識(shí) Servers 。 |
Server
Server 對(duì)象必須包含以下字段之一:
field | value |
---|---|
name |
按名稱引用 Server 實(shí)例。 |
selector |
selector 選擇在同一命名空間中應(yīng)用此授權(quán)的 server 。 |
selector
這與 Kubernetes 中的 labelSelector 字段相同。屬于此選擇器的所有服務(wù)器都將應(yīng)用此授權(quán)。 selector 對(duì)象必須恰好包含以下字段之一:
field | value |
---|---|
matchExpressions |
matchExpressions 是標(biāo)簽選擇器要求的列表。要求是 AND 組合。 |
matchLabels |
matchLabels 是 {key,value} 對(duì)的映射。 |
client
client 對(duì)象必須包含以下字段之一:
field | value |
---|---|
meshTLS |
meshTLS 用于授權(quán) mesh 客戶端訪問服務(wù)器 |
unauthenticated |
授權(quán)未經(jīng)身份驗(yàn)證的客戶端訪問服務(wù)器的布爾值。 |
或者,它還可以包含 networks 字段:
field | value |
---|---|
networks |
限制此授權(quán)適用的客戶端 IP 地址。如果未設(shè)置,服務(wù)器將選擇默認(rèn)值(通常為所有 IP 或集群的 pod 網(wǎng)絡(luò))。 |
meshTLS
meshTLS 對(duì)象必須恰好包含以下字段之一:
field | value |
---|---|
unauthenticatedTLS |
一個(gè)布爾值,表示通信不需要客戶端身份。這對(duì)于身份控制器非常重要,它必須終止來自尚未擁有證書的客戶端的 TLS 連接。 |
identities |
授權(quán)的代理身份字符串列表(通過 MTLS 提供)。* 前綴可用于匹配域中的所有身份。* 標(biāo)識(shí)字符串表示所有身份驗(yàn)證客戶端都已授權(quán)。 |
serviceAccounts |
授權(quán)客戶端 serviceAccount 的列表(通過 MTLS 提供)。 |
serviceAccount
serviceAccount 字段包含以下頂級(jí)字段:
field | value |
---|---|
name |
ServiceAccount 的名稱。 |
namespace |
ServiceAccount 的命名空間。如果未設(shè)置,則使用授權(quán)的命名空間。 |
ServerAuthorization 示例
一個(gè) ServerAuthorization 允許 mesh 客戶端使用 *.emojivoto.serviceaccount.identity.linkerd.cluster.local 代理身份, 即 emojivoto 命名空間中的所有服務(wù)帳戶。
- apiVersion: policy.linkerd.io/v1beta1
- kind: ServerAuthorization
- metadata:
- namespace: emojivoto
- name: emoji-grpc
- spec:
- # Allow all authenticated clients to access the (read-only) emoji service.
- server:
- selector:
- matchLabels:
- app: emoji-svc
- client:
- meshTLS:
- identities:
- - "*.emojivoto.serviceaccount.identity.linkerd.cluster.local"
一個(gè)允許任何未經(jīng)身份驗(yàn)證的客戶端的 ServerAuthorization。
- apiVersion: policy.linkerd.io/v1beta1
- kind: ServerAuthorization
- metadata:
- namespace: emojivoto
- name: web-public
- spec:
- server:
- name: web-http
- # Allow all clients to access the web HTTP port without regard for
- # authentication. If unauthenticated connections are permitted, there is no
- # need to describe authenticated clients.
- client:
- unauthenticated: true
- networks:
- - cidr: 0.0.0.0/0
- - cidr: ::/0
一個(gè)允許具有特定服務(wù)帳戶的 mesh 客戶端的 ServerAuthorization。
- apiVersion: policy.linkerd.io/v1beta1
- kind: ServerAuthorization
- metadata:
- namespace: emojivoto
- name: prom-prometheus
- spec:
- server:
- name: prom
- client:
- meshTLS:
- serviceAccounts:
- - namespace: linkerd-viz
- name: prometheus