日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
使用Kube-Mgmt將OPA集成到Kubernetes集群中

使用 Kube-Mgmt 將 OPA 集成到 Kubernetes 集群中

作者:陽明 2022-03-24 07:44:41

云計算

云原生 OPA 將策略決策與策略執(zhí)行分離,當(dāng)應(yīng)用需要做出策略決策時,它會查詢 OPA 并提供結(jié)構(gòu)化數(shù)據(jù)(例如 JSON)作為輸入,OPA 接受任意結(jié)構(gòu)化數(shù)據(jù)作為輸入。

成都創(chuàng)新互聯(lián)公司服務(wù)項目包括威遠(yuǎn)網(wǎng)站建設(shè)、威遠(yuǎn)網(wǎng)站制作、威遠(yuǎn)網(wǎng)頁制作以及威遠(yuǎn)網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,威遠(yuǎn)網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到威遠(yuǎn)省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

Open Policy Agent 簡稱 OPA,是一種開源的通用策略代理引擎,是 CNCF 畢業(yè)的項目。OPA 提供了一種高級聲明式語言 Rego,簡化了策略規(guī)則的定義,以減輕程序中策略的決策負(fù)擔(dān)。在微服務(wù)、Kubernetes、CI/CD、API 網(wǎng)關(guān)等場景中均可以使用 OPA 來定義策略。

我們這里主要講解在 Kubernetes 中如何集成 OPA,在 Kubernetes 中 OPA 是通過 Admission Controllers 來實現(xiàn)安全策略的。事實上使用 Pod 安全策略(要廢棄了)來執(zhí)行我們的安全策略并沒有什么問題,然而,根據(jù)定義,PSP 只能應(yīng)用于 pods。它們不能處理其他 Kubernetes 資源,如 Ingresses、Deployments、Services 等,OPA 的強大之處在于它可以應(yīng)用于任何 Kubernetes 資源。OPA 作為一個準(zhǔn)入控制器部署到 Kubernetes,它攔截發(fā)送到 APIServer 的 API 調(diào)用,并驗證和/或修改它們。你可以有一個統(tǒng)一的 OPA 策略,適用于系統(tǒng)的不同組件,而不僅僅是 pods,例如,有一種策略,強制用戶在其服務(wù)中使用公司的域,并確保用戶只從公司的鏡像倉庫中拉取鏡像。

概述

OPA 將策略決策與策略執(zhí)行分離,當(dāng)應(yīng)用需要做出策略決策時,它會查詢 OPA 并提供結(jié)構(gòu)化數(shù)據(jù)(例如 JSON)作為輸入,OPA 接受任意結(jié)構(gòu)化數(shù)據(jù)作為輸入。

OPA 通過評估查詢輸入策略和數(shù)據(jù)來生成策略決策,你可以在你的策略中描述幾乎任何的不變因素,例如:

  • 哪些用戶可以訪問哪些資源。
  • 哪些子網(wǎng)的出口流量被允許。
  • 工作負(fù)載必須部署到哪些集群。
  • 二進制文件可以從哪里下載。
  • 容器可以用哪些操作系統(tǒng)的能力來執(zhí)行。
  • 系統(tǒng)在一天中的哪些時間可以被訪問。

策略決定不限于簡單的是/否或允許/拒絕,與查詢輸入一樣,你的策略可以生成任意結(jié)構(gòu)化數(shù)據(jù)作為輸出。讓我們看一個例子。OPA 的策略是用一種叫做 Rego 的高級聲明性語言來聲明的,Rego 是專門為表達復(fù)雜的分層數(shù)據(jù)結(jié)構(gòu)的策略而設(shè)計的。

在 Kubernetes 中,準(zhǔn)入控制器在創(chuàng)建、更新和刪除操作期間對對象實施策略。準(zhǔn)入控制是 Kubernetes 中策略執(zhí)行的基礎(chǔ)。通過將 OPA 部署為準(zhǔn)入控制器,可以:

  • 要求在所有資源上使用特定標(biāo)簽。
  • 要求容器鏡像來自企業(yè)鏡像倉庫。
  • 要求所有 Pod 指定資源請求和限制。
  • 防止創(chuàng)建沖突的 Ingress 對象。
  • ......

Kubernetes APIServer 配置為在創(chuàng)建、更新或刪除對象時查詢 OPA 以獲取準(zhǔn)入控制策略。APIServer 將 webhook 請求中的整個對象發(fā)送給 OPA,OPA 使用準(zhǔn)入審查作為輸入來評估它已加載的策略。這個其實和我們自己去實現(xiàn)一個準(zhǔn)入控制器是類似的,只是不需要我們?nèi)ゾ帉懘a,只需要編寫策略規(guī)則,OPA 就可以根據(jù)我們的規(guī)則去對輸入的對象進行驗證。

部署

接下來我們介紹下如何在 Kubernetes 集群中集成 OPA,由于 Kubernetes 中是通過準(zhǔn)入控制器來集成 OPA 的,所以我們必須在集群中啟用 ValidatingAdmissionWebhook 這個準(zhǔn)入控制器。

首先創(chuàng)建一個名為 opa 的命名空間,可以讓 OPA 從該命名空間中的 ConfigMap 去加載策略:

 kubectl create namespace opa

并將上下文更改為 opa 命名空間:

 kubectl config current-context
kubernetes-admin@kubernetes
content kubectl config set-context kubernetes-admin@kubernetes --namespace=opa
Context "kubernetes-admin@kubernetes" modified.
kubectl get pods
No resources found in opa namespace.

為了保護 APIServer 和 OPA 之間的通信,我們需要配置 TLS 證書。

創(chuàng)建證書頒發(fā)機構(gòu)和密鑰:

 openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -days 100000 -out ca.crt -subj "/CN=admission_ca"

為 OPA 生成密鑰和證書:

cat >server.conf <[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = opa.opa.svc
EOF
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/CN=opa.opa.svc" -config server.conf
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 100000 -extensions v3_req -extfile server.conf

創(chuàng)建一個 Kubernetes TLS Secret 來存儲我們的 OPA 憑證:

 kubectl create secret tls opa-server --cert=server.crt --key=server.key

證書準(zhǔn)備好后就可以部署準(zhǔn)入控制器了,對應(yīng)的資源清單文件如下所示:

# opa-admission-controller.yaml
# Grant OPA/kube-mgmt read-only access to resources. This lets kube-mgmt
# replicate resources into OPA so they can be used in policies.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: opa-viewer
roleRef:
kind: ClusterRole
name: view
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts:opa
apiGroup: rbac.authorization.k8s.io
---
# Define role for OPA/kube-mgmt to update configmaps with policy status.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: opa
name: configmap-modifier
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["update", "patch"]
---
# Grant OPA/kube-mgmt role defined above.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: opa
name: opa-configmap-modifier
roleRef:
kind: Role
name: configmap-modifier
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts:opa
apiGroup: rbac.authorization.k8s.io
---
kind: Service
apiVersion: v1
metadata:
name: opa
namespace: opa
spec:
selector:
app: opa
ports:
- name: https
port: 443
targetPort: 443
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: opa-viewer
roleRef:
kind: ClusterRole
name: view
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts:opa
apiGroup: rbac.authorization.k8s.io
---
# Define role for OPA/kube-mgmt to update configmaps with policy status.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: opa
name: configmap-modifier
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["update", "patch"]
---
# Grant OPA/kube-mgmt role defined above.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: opa
name: opa-configmap-modifier
roleRef:
kind: Role
name: configmap-modifier
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts:opa
apiGroup: rbac.authorization.k8s.io
---
kind: Service
apiVersion: v1
metadata:
name: opa
namespace: opa
spec:
selector:
app: opa
ports:
- name: https
protocol: TCP
port: 443
targetPort: 443
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: opa
namespace: opa
spec:
selector:
matchLabels:
app: opa
template:
metadata:
labels:
app: opa
spec:
containers:
- name: opa
image: openpolicyagent/opa:latest
args:
- "run"
- "--server"
- "--tls-cert-file=/certs/tls.crt"
- "--tls-private-key-file=/certs/tls.key"
- "--addr=0.0.0.0:443"
- "--addr=http://127.0.0.1:8181"
- "--log-level=debug"
- "--log-format=json-pretty"
volumeMounts:
- readOnly: true
mountPath: /certs
name: opa-server
readinessProbe:
httpGet:
path: /health
scheme: HTTPS
port: 443
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
scheme: HTTPS
port: 443
initialDelaySeconds: 10
periodSeconds: 15
- name: kube-mgmt
image: openpolicyagent/kube-mgmt:4.0.0
args:
- --replicate-cluster=v1/namespaces
- --replicate=networking.k8s.io/v1/ingresses
- --opa-url=http://127.0.0.1:8181/v1
- --enable-data=true
- --enable-policies=true
- --policies=opa
- --require-policy-label=true
volumes:
- name: opa-server
secret:
secretName: opa-server
---
kind: ConfigMap
apiVersion: v1
metadata:
name: opa-default-system-main
namespace: opa
labels:
openpolicyagent.org/policy: rego
data:
main: |
package system
import data.kubernetes.admission
main = {
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": response,
}
default uid = ""
uid = input.request.uid
response = {
"allowed": false,
"uid": uid,
"status": {
"message": reason,
},
} {
reason = concat(", ", admission.deny)
reason != ""
}
else = {"allowed": true, "uid": uid}

上面的資源清單中我們添加了一個 kube-mgmt 的 Sidecar 容器,該容器可以將 ConfigMap 對象中的策略動態(tài)加載到 OPA 中,kube-mgmt 容器還可以將任何其他 Kubernetes 對象作為 JSON 數(shù)據(jù)加載到 OPA 中。

另外需要注意的是 Service 的名稱(opa)必須與我們證書配置的 CN 匹配,否則 TLS 通信會失敗。在 kube-mgmt 容器中還指定了以下命令行參數(shù):

  • --replicate-cluster=v1/namespaces。
  • --replicate=networking.k8s.io/v1/ingresses。
  • --enable-policies=true。
  • --policies=opa。
  • --require-policy-label=true。

前兩個參數(shù)允許 sidecar 容器復(fù)制命名空間、Ingress 對象,并將它們加載到 OPA 引擎中,enable-policies=true 表示會通過 Configmap 加載 OPA 策略,下面的 --policies=opa 表示從 opa 命名空間中的 Configmap 來加載策略,如果還配置了 --require-policy-label=true 參數(shù),則需要 Configmap 中帶有 openpolicyagent.org/policy=rego 這個標(biāo)簽才會被自動加載。

現(xiàn)在直接應(yīng)用上面的資源清單即可:

 kubectl apply -f opa-admission-controller.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE
opa-6cd68f74f-s9zcv 2/2 Running 0 5m28s

為了讓準(zhǔn)入控制器工作,我們還需要一個準(zhǔn)入 webhook 來接收準(zhǔn)入 HTTP 回調(diào)并執(zhí)行它們,創(chuàng)建如下所示的 webhook 配置文件:

 cat > webhook-configuration.yaml <kind: ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
metadata:
name: opa-validating-webhook
webhooks:
- name: validating-webhook.openpolicyagent.org
admissionReviewVersions: ["v1", "v1beta1"]
namespaceSelector:
matchExpressions:
- key: openpolicyagent.org/webhook
operator: NotIn
values:
- ignore
failurePolicy: Ignore
rules:
- apiGroups:
- '*'
apiVersions:
- '*'
operations:
- '*'
resources:
- '*'
sideEffects: None
clientConfig:
caBundle: $(cat ca.crt | base64 | tr -d '\n')
service:
namespace: opa
name: opa
EOF

上面的 webhook 中配置了以下屬性:

  • 不會監(jiān)聽來自帶有 openpolicyagent.org/webhook=ignore 標(biāo)簽的命名空間的操作。
  • 會監(jiān)聽所有資源的操作。
  • 它使用我們之前創(chuàng)建的 CA 證書,以便能夠與 OPA 通信。

現(xiàn)在,在使用配置之前,我們標(biāo)記 kube-system 和 opa 命名空間,使它們不在 webhook 范圍內(nèi):

 kubectl label ns kube-system openpolicyagent.org/webhook=ignore
kubectl label ns opa openpolicyagent.org/webhook=ignore

然后應(yīng)用上面的配置對象將 OPA 注冊為準(zhǔn)入控制器:

 kubectl apply -f webhook-configuration.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE
opa-6cd68f74f-s9zcv 2/2 Running 0 72m
kubectl get validatingwebhookconfiguration
NAME WEBHOOKS AGE
opa-validating-webhook 1 2m14s

策略示例

OPA 使用 Rego 語言來描述策略,這里我們使用官方文檔中提到的示例來進行說明,創(chuàng)建一個限制 Ingress 可以使用的主機名策略,只允許匹配指定正則表達式的主機名。

創(chuàng)建如下所示名為 ingress-allowlist.rego 的策略文件:

package kubernetes.admission
operations = {"CREATE", "UPDATE"}
deny[msg] {
input.request.kind.kind == "Ingress"
operations[input.request.operation]
host := input.request.object.spec.rules[_].host
not fqdn_matches_any(host, valid_ingress_hosts)
msg := sprintf("invalid ingress host %q", [host])
}
valid_ingress_hosts = {host |
allowlist := namespaces[input.request.namespace].metadata.annotations["ingress-allowlist"]
hosts := split(allowlist, ",")
host := hosts[_]
}
fqdn_matches_any(str, patterns) {
fqdn_matches(str, patterns[_])
}
fqdn_matches(str, pattern) {
pattern_parts := split(pattern, ".")
pattern_parts[0] == "*"
str_parts := split(str, ".")
n_pattern_parts := count(pattern_parts)
n_str_parts := count(str_parts)
n_pattern_parts == n_str_parts
suffix := trim(pattern, "*.")
endswith(str, suffix)
}
fqdn_matches(str, pattern) {
not contains(pattern, "*")
str == pattern
}

如果你是 Rego 新手,上面的代碼看上去可能有點陌生,但 Rego 讓定義策略變得非常容易,我們來分析下這個策略是如何使用白名單中的 Ingress 命名空
本文標(biāo)題:使用Kube-Mgmt將OPA集成到Kubernetes集群中
URL標(biāo)題:http://www.dlmjj.cn/article/djgpooj.html