Kyverno安裝

使用 Helmkubectl 安裝和配置 Kyverno 的詳細(xì)信息。

Kyverno 可以使用 Helm 安裝或直接從 YAML 清單進(jìn)行部署。 使用這兩種方法中的任何一種時(shí),都不需要其他步驟來(lái)啟動(dòng)和運(yùn)行 Kyverno。

注意

從 v1.7.0 開(kāi)始,Kyverno 遵循與 Kubernetes 項(xiàng)目相同的支持政策,即 N-2 版本兼容。 盡管以前的版本可能有效,但它們未經(jīng)測(cè)試。

兼容矩陣

Kyverno Version Kubernetes Min Kubernetes Max
1.4.x 1.16 1.21
1.5.x 1.16 1.21
1.6.x 1.16 1.23
1.7.x 1.21 1.23

*由于 Kubernetes 1.23.0-1.23.2 的一個(gè)已知問(wèn)題,對(duì) 1.23 的支持從 1.23.3 開(kāi)始。

使用 Helm 安裝 Kyverno

Kyverno 可以通過(guò) Helm chart 進(jìn)行安裝——這是生產(chǎn)環(huán)境安裝的推薦方法——可通過(guò) Kyverno 倉(cāng)庫(kù)或 ArtifactHub 得到相關(guān) chart。

為了使用 Helm 安裝 Kyverno,首先添加 Kyverno Helm 倉(cāng)庫(kù):

helm repo add kyverno https://kyverno.github.io/kyverno/

掃描倉(cāng)庫(kù)以獲取 chart:

helm repo update

(可選)顯示 Kyverno 的所有可用 chart 版本:

helm search repo kyverno -l

根據(jù)您希望安裝 Kyverno 的方式,請(qǐng)參閱下面的高可用性或獨(dú)立安裝選項(xiàng)。

要安裝 Kyverno Pod 安全標(biāo)準(zhǔn)策略,請(qǐng)?jiān)诎惭b Kyverno 后運(yùn)行以下 Helm 命令:

helm install kyverno-policies kyverno/kyverno-policies -n kyverno

高可用

官方 Helm chart 是以生產(chǎn)級(jí)、高可用的方式安裝 Kyverno 的推薦方法,因?yàn)樗峁┝怂斜匾?Kubernetes 資源和配置來(lái)滿足生產(chǎn)需求。通過(guò)設(shè)置 replicaCount=3,以下將自動(dòng)創(chuàng)建并配置為默認(rèn)值的一部分。這不是一個(gè)詳盡的列表,可能會(huì)發(fā)生變化。 對(duì)于所有默認(rèn)值,請(qǐng)參閱 Helm char README 文件,并牢記發(fā)布分支。您應(yīng)該仔細(xì)檢查所有可用的 chart 值及其默認(rèn)值,以確定哪些需要覆蓋(如果有),以滿足生產(chǎn)環(huán)境的特定需求。

  • Kyverno 以3副本方式運(yùn)行

  • PodDisruptionBudget

  • Pod 反親和配置

  • Kyverno Namespace 排除

注意Kyverno 不支持兩個(gè)副本。 對(duì)于高可用性安裝,只支持三副本。

默認(rèn)情況下,從 Helm chart 的 2.5.0 版本開(kāi)始,將使用配置了不可變標(biāo)簽 kubernetes.io/metadata.name 的 namespaceSelector 排除 Kyverno 命名空間,通過(guò)配置 chart 值可以排除其他命名空間。namespaceSelector 和 objectSelector 都可以用于排除。

另請(qǐng)參閱下面的 Namespace 選擇器部分,尤其是安全性與可操作性部分。

使用 Helm 3.2+ 創(chuàng)建一個(gè)命名空間并安裝 Kyverno:

helm install kyverno kyverno/kyverno -n kyverno --create-namespace --set replicaCount=3

對(duì)于 3.2 之前的 Helm 版本,需要先創(chuàng)建一個(gè) Namespace,然后安裝 Kyverno Helm chart。

kubectl create namespace kyverno
helm install kyverno kyverno/kyverno -n kyverno --create-namespace --set replicaCount=3

從 Kyverno 1.5.0(Helm chart v2.1.0)開(kāi)始,Kyverno Pod 標(biāo)準(zhǔn)安全策略必須在 Kyverno 安裝后單獨(dú)添加:

helm install kyverno-policies kyverno/kyverno-policies -n kyverno

獨(dú)立安裝

Kyverno “獨(dú)立”安裝適用于試驗(yàn)、開(kāi)發(fā)或測(cè)試,或少于3個(gè)節(jié)點(diǎn)的小環(huán)境中。它為 Kyverno 部署配置單個(gè)副本,并省略了許多生產(chǎn)級(jí)組件。

使用 Helm 3.2+ 創(chuàng)建一個(gè)命名空間并安裝 Kyverno:

helm install kyverno kyverno/kyverno -n kyverno --create-namespace --set replicaCount=1

對(duì)于 3.2 之前的 Helm 版本,需要先創(chuàng)建一個(gè) Namespace,然后安裝 Kyverno Helm chart。

kubectl create namespace kyverno
helm install kyverno kyverno/kyverno -n kyverno --create-namespace --set replicaCount=1

要安裝預(yù)發(fā)行版,請(qǐng)將 --devel 開(kāi)關(guān)添加到 Helm。

helm install kyverno kyverno/kyverno -n kyverno --create-namespace --devel

使用 YAML 安裝 Kyverno

Kyverno 也可以使用單個(gè)安裝清單進(jìn)行安裝,但是對(duì)于生產(chǎn)安裝,推薦使用 Helm chart 安裝。

此清單路徑將始終指向最新的主分支,并且不保證穩(wěn)定。

kubectl create -f https://raw.githubusercontent.com/kyverno/kyverno/main/config/install.yaml

您還可以從發(fā)布分支中提取以安裝穩(wěn)定版本,包括候選發(fā)行版本。

kubectl create -f https://raw.githubusercontent.com/kyverno/kyverno/release-1.7/config/release/install.yaml

安全性與可操作性

對(duì)于生產(chǎn)環(huán)境,Kyverno 應(yīng)該以 HA 模式安裝。無(wú)論 Kyverno 使用哪種安裝方法,了解與任何 webhook 相關(guān)的風(fēng)險(xiǎn)以及它如何影響集群操作和安全性都非常重要,尤其是在生產(chǎn)環(huán)境中。Kyverno 默認(rèn)(但可配置)以fail closed 模式配置其資源 webhook。這意味著如果 API Server 在嘗試發(fā)送與策略匹配的資源的 AdmissionReview 請(qǐng)求時(shí)無(wú)法到達(dá) Kyverno,則該請(qǐng)求將失敗。例如,存在一個(gè)驗(yàn)證策略,它檢查所有 Pod 必須以非 root 身份運(yùn)行。向 API Server提交了新的 Pod 創(chuàng)建請(qǐng)求,但API Server 無(wú)法訪問(wèn) Kyverno。 由于無(wú)法評(píng)估策略,因此創(chuàng)建 Pod 的請(qǐng)求將失敗。因此,必須注意確保 Kyverno 始終可用,或者進(jìn)行適當(dāng)配置以排除某些關(guān)鍵命名空間,特別是 Kyverno 的命名空間,以確保它可以接收這些 API 請(qǐng)求。 無(wú)論選擇哪個(gè)選項(xiàng),都需要在默認(rèn)安全性和可操作性之間進(jìn)行權(quán)衡。

如果不排除 Kyverno 命名空間,以下組合可能會(huì)導(dǎo)致集群無(wú)法運(yùn)行:

  • 在 fail closed 模式下(默認(rèn)配置),Pod 匹配到至少一個(gè) Kyverno 規(guī)則。

  • 至少?zèng)]有為 Kyverno 命名空間配置命名空間排除項(xiàng),可能還有其他關(guān)鍵系統(tǒng)命名空間(例如,kube-system)。Helm char 2.5.0 版本中不是默認(rèn)配置。

  • 所有 Kyverno Pod 由于集群完全中斷或節(jié)點(diǎn)擴(kuò)展不當(dāng)(例如,作為自動(dòng)擴(kuò)展操作的一部分而在沒(méi)有首先封鎖和排空 Pod 的情況下,云 PaaS 銷(xiāo)毀節(jié)點(diǎn)組中的太多節(jié)點(diǎn))而變得不可用。

如果出現(xiàn)這種情況,恢復(fù)的唯一方法是手動(dòng)刪除 ValidatingWebhookConfigurations,從而允許新的 Kyverno Pod 啟動(dòng)。 故障排除部分提供了恢復(fù)步驟。

注意
Kubernetes 不會(huì)將 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration 對(duì)象發(fā)送到準(zhǔn)入控制器,因此無(wú)法使用 Kyverno 策略來(lái)驗(yàn)證或改變這些對(duì)象。

相比之下,這些可操作性問(wèn)題可以通過(guò)做出一些安全讓步來(lái)緩解。 具體來(lái)說(shuō),通過(guò)在安裝過(guò)程中排除 Kyverno 和其他系統(tǒng)命名空間,如果出現(xiàn)上述故障情況,Kyverno 應(yīng)該能夠自行恢復(fù)而無(wú)需人工干預(yù)。這是 Helm chart 2.5.0 版的默認(rèn)行為。但是,配置這些排除項(xiàng)意味著后續(xù)策略將無(wú)法對(duì)發(fā)往這些命名空間的資源采取行動(dòng),因?yàn)?API Server 已被告知不要為它們發(fā)送 AdmissionReview 請(qǐng)求。因此,為這些命名空間提供控制取決于集群管理員的操作,例如,Kubernetes RBAC 可限制哪些人或哪些操作可以在這些被排查的命名空間中執(zhí)行。

注意
命名空間和/或命名空間中的對(duì)象可以通過(guò)多種方式排除,包括命名空間選擇器和對(duì)象選擇器。 Helm chart 為兩者提供了選項(xiàng),但默認(rèn)情況下,Kyverno 命名空間將被排除在外。

注意
使用 objectSelector 時(shí),如果用戶發(fā)現(xiàn) webhook 的配置方式,他們可能會(huì)通過(guò)配置 webhook 的相同標(biāo)簽鍵/值來(lái)欺騙 webhook,從而允許資源繞過(guò)策略檢測(cè)。 因此,建議使用使用 kubernetes.io/metadata.name 不可變標(biāo)簽的 namespaceSelector。

因此,這些選擇及其影響是:

  • 在安裝過(guò)程時(shí)不排除系統(tǒng)命名空間,包括 Kyverno 的(非默認(rèn)),這會(huì)使默認(rèn)情況下更加安全,但在某些中斷情況下可能需要手動(dòng)恢復(fù)。這是默認(rèn)行為,除非被覆蓋。

  • 在安裝過(guò)程中排除系統(tǒng)命名空間(默認(rèn))可以更輕松地恢復(fù)集群,但可能需要其他方法來(lái)保護(hù)這些命名空間,例如使用 Kubernetes RBAC。

您應(yīng)該根據(jù)您的風(fēng)險(xiǎn)規(guī)避、需求和操作實(shí)踐選擇最佳選項(xiàng)。

注意
如果您選擇不排除 Kyverno 或系統(tǒng)命名空間/對(duì)象并打算用策略覆蓋它們,您可能需要修改 ConfigMap 中的 Kyverno resourceFilters 配置以刪除這些條目。

自定義安裝Kyverno

下圖顯示了典型的 Kyverno 安裝:

[圖片上傳失敗...(image-1da32d-1663730295834)]

如果您希望自定義 Kyverno 的安裝以使證書(shū)由內(nèi)部或受信任的 CA 簽名,或者以其他方式了解組件如何協(xié)同工作,請(qǐng)遵循以下指南。

安裝特定版本

要安裝特定版本,請(qǐng)下載 install.yaml并修改鏡像tag:

例如,將鏡像 tag 從 latest 更改為特定標(biāo)簽 v1.3.0

spec:
  containers:
    - name: kyverno
      # image: ghcr.io/kyverno/kyverno:latest
      image: ghcr.io/kyverno/kyverno:v1.3.0

要在特定命名空間中安裝,請(qǐng)將命名空間“kyverno”替換為您的命名空間。

例如:

apiVersion: v1
kind: Namespace
metadata:
  name: <namespace>
apiVersion: v1
kind: Service
metadata:
  labels:
    app: kyverno
  name: kyverno-svc
  namespace: <namespace>

以及其他提到命名空間的地方(ServiceAccount、ClusterRoles、ClusterRoleBindings、ConfigMaps、Service、Deployment)。

ConfigMap Flags

以下標(biāo)志用于控制 Kyverno 的行為,必須在 Kyverno ConfigMap 中設(shè)置。

  1. excludeGroupRole:excludeGroupRole 字符串,以逗號(hào)分隔的 group role。它將從用戶請(qǐng)求中排除所有組角色。默認(rèn)使用 system:serviceaccounts:kube-system,system:nodes,system:kube-scheduler。

  2. excludeUsername:excludeUsername 字符串,以逗號(hào)分隔的 kubernetes 用戶名。在生成請(qǐng)求中,如果用戶在生成策略中啟用同步,則只有 kyverno 可以更新/刪除生成的資源,但管理員可以排除特定用戶名,使其有權(quán)刪除/更新生成的資源。

  3. resourceFilters:不由 admission webhook 策略評(píng)估的Kubernetes 資源,格式為“[kind,namespace,name]”。 例如 –filterKind “[Deployment, kyverno, kyverno]” –filterKind “[Deployment, kyverno, kyverno],[Events, *, *]”。

  4. generateSuccessEvents:指定是否 (true/false) 生成成功事件。 默認(rèn)設(shè)置為“false”。

  5. webhooks:指定要在 Kyverno 管理的 webhook 中配置排除的命名空間或?qū)ο蟆?/p>

Container Flags

以下標(biāo)志也可用于控制 Kyverno 的高級(jí)行為,并且必須以參數(shù)的形式在 kyverno 主容器上設(shè)置。

  1. -v:設(shè)置 Kyverno 日志輸出的詳細(xì)級(jí)別。 取一個(gè)從 1 到 6 的整數(shù),其中 6 是最詳細(xì)的。 級(jí)別 4 顯示變量替換消息。

  2. profile:將此標(biāo)志設(shè)置為“true”將啟用分析。

  3. profilePort:指定端口以啟用分析,默認(rèn)為 6060。

  4. metricsPort:指定暴露 prometheus 指標(biāo)的端口,默認(rèn)為 8000 端口。

  5. genWorkers:并行處理生成策略的 worker 數(shù)量,默認(rèn)是10。

  6. disableMetrics:指定是否 (true/false) 啟用公開(kāi)指標(biāo)。 默認(rèn)為“false”。

  7. backgroundScan:后臺(tái)處理的時(shí)間間隔(如 30s、15m、12h)。 默認(rèn)為 1h。

  8. imagePullSecrets:指定 image registry 訪問(wèn)憑證的 secret 資源名稱(chēng)。

  9. allowInsecureRegistry: 允許 Kyverno 使用不安全的 image registry(即繞過(guò)證書(shū)檢查),使用 verifyImages 規(guī)則或來(lái)自 image registry 的變量。僅用于測(cè)試目的。 不得用于生產(chǎn)環(huán)境。

  10. autoUpdateWebhooks: 將此標(biāo)志設(shè)置為“false”以禁用 webhook 的自動(dòng)配置。 禁用此功能后,Kyverno 會(huì)創(chuàng)建一個(gè)默認(rèn)的 webhook 配置(匹配所有類(lèi)型的資源),因此,通過(guò) configmap 的 webhook 配置將被忽略。 但是,用戶仍然可以通過(guò)手動(dòng)修補(bǔ) webhook 資源來(lái)修改它。 默認(rèn)為“true”。

  11. imageSignatureRepository:指定鏡像簽名的備用存儲(chǔ)庫(kù)。 可以根據(jù)規(guī)則覆蓋以驗(yàn)證 Images.Repository。

  12. webhookRegistrationTimeout:指定 Kyverno 嘗試向 API Server 注冊(cè) webhook 的時(shí)間長(zhǎng)度。 默認(rèn)為 120 秒。

  13. clientRateLimitQPS:配置從 Kyverno 到控制平面的最大 QPS。 如果為零,則使用客戶端默認(rèn)值。 示例:20

  14. clientRateLimitBurst:配置限制的最大突發(fā)流量。 如果為零,則使用客戶端默認(rèn)值。 示例:50

  15. webhookTimeout:指定 webhook 的超時(shí)時(shí)間。 超時(shí)后,根據(jù)失敗策略,Webhook 調(diào)用將被忽略或 API 調(diào)用失敗。超時(shí)值必須在 1 到 30 秒之間,默認(rèn)為 10 秒。

  16. autogenInternals:Kyverno 1.7.0 中新增的。此標(biāo)志激活(當(dāng)前為測(cè)試版)自動(dòng)生成規(guī)則計(jì)算,以不寫(xiě)入 Kyverno 策略的 .spec 字段。 這是正在建設(shè)中,行為將在未來(lái)發(fā)生變化。 默認(rèn)設(shè)置為false。 設(shè)置為 true 以激活此能力。

訪問(wèn)策略報(bào)告

安裝 Kyverno 時(shí),會(huì)生成一個(gè) ClusterRole kyverno:admin-policyreport,它有權(quán)對(duì) policyreportclusterpolicyreport 資源執(zhí)行所有操作。要授予對(duì)命名空間管理員權(quán)限,請(qǐng)配置以下 YAML 文件,然后將其應(yīng)用于集群。

  • metadata.namespace 替換為管理員的命名空間

  • 配置 subjects 字段,綁定管理員角色到 ClusterRole policyviolation

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: policyviolation
  # change namespace below to create rolebinding for the namespace admin
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kyverno:admin-policyreport
subjects:
# configure below to access policy violation for the namespace admin
- kind: ServiceAccount
  name: default
  namespace: default
# - apiGroup: rbac.authorization.k8s.io
#   kind: User
#   name:
# - apiGroup: rbac.authorization.k8s.io
#   kind: Group
#   name:

Webhooks

從 Kyverno 1.5.0 版本開(kāi)始,通過(guò)配置策略來(lái)實(shí)現(xiàn)對(duì) mutatingWebhookConfigurationvalidatingWebhookConfiguration 資源的動(dòng)態(tài)注冊(cè)和管理。在 1.5.0 之前,Kyverno 使用通配符 webhook,允許它接收所有資源的準(zhǔn)入請(qǐng)求。借助 webhook 自動(dòng)配置功能,Kyverno 現(xiàn)在只接收選定資源的準(zhǔn)入請(qǐng)求,從而防止將不必要的準(zhǔn)入請(qǐng)求轉(zhuǎn)發(fā)給 Kyverno。

另外,failurePolicywebhookTimeoutSeconds 策略配置選項(xiàng)允許對(duì) webhook 設(shè)置進(jìn)行精細(xì)控制。默認(rèn)情況下,策略會(huì)被配置為“fail-closed”(即如果 webhook 調(diào)用出現(xiàn)意外錯(cuò)誤或超時(shí),準(zhǔn)入請(qǐng)求將失敗),除非 failurePolicy 被設(shè)置為 Ignore。

這個(gè)特性在 1.5.0+ 默認(rèn)啟用,可以通過(guò)--autoUpdateWebhooks=false 標(biāo)志來(lái)關(guān)閉。如果禁用,Kyverno 會(huì)創(chuàng)建默認(rèn)的 webhook 配置來(lái)轉(zhuǎn)發(fā)所有資源的準(zhǔn)入請(qǐng)求,并將 FailurePolicy 設(shè)置為 Ignore。

spec.failurePolicyspec.webhookTimeoutSeconds策略配置字段允許自動(dòng)聚合并用于注冊(cè)所需的 webhook 配置集的每個(gè)策略設(shè)置。

在 1.5.0 之前,默認(rèn)情況下,Kyverno webhook 將處理所有命名空間的所有 API Server請(qǐng)求,并且使用下面討論的資源過(guò)濾器和命名空間選擇器過(guò)濾策略應(yīng)用程序。

資源過(guò)濾器

資源過(guò)濾器是一種指示 Kyverno 忽略 API Server發(fā)送的 AdmissionReview 請(qǐng)求的方法。這與配置 webhook 的能力不同。可以通過(guò)在 Namespace kyverno 中添加 ConfigMap 并在 data.resourceFilters 下指定要過(guò)濾的資源來(lái)過(guò)濾策略應(yīng)該忽略的 Kubernetes 種類(lèi)。

Namespace 過(guò)濾器

apiVersion: v1
data:
  resourceFilters: '[Event,*,*][*,kube-system,*][*,kube-public,*][*,kube-node-lease,*][Node,*,*][APIService,*,*][TokenReview,*,*][SubjectAccessReview,*,*][SelfSubjectAccessReview,*,*][*,kyverno,*][Binding,*,*][ReplicaSet,*,*][ReportChangeRequest,*,*][ClusterReportChangeRequest,*,*]'
  webhooks: '[{"namespaceSelector":{"matchExpressions":[{"key":"kubernetes.io/metadata.name","operator":"NotIn","values":["kyverno"]}]}}]'
kind: ConfigMap
metadata:
  name: kyverno
  namespace: kyverno

升級(jí)Kyverno

升級(jí) Kyverno 就像應(yīng)用新的 YAML 清單一樣簡(jiǎn)單,或者根據(jù)安裝方式使用 Helm。

使用 YAML 清單升級(jí) Kyverno

在現(xiàn)有安裝上應(yīng)用新清單。

kubectl apply -f https://raw.githubusercontent.com/kyverno/kyverno/main/config/install.yaml

使用 Helm 升級(jí) Kyverno

Kyverno 可以像任何其他 Helm Chat一樣升級(jí)。

掃描您的 Helm 存儲(chǔ)庫(kù)以獲取更新的 Chart。

helm repo update

顯示可用的 Kyverno chart版本。 要查看預(yù)發(fā)布chart,請(qǐng)將 --devel 標(biāo)志添加到 helm 命令。

helm search repo kyverno

運(yùn)行升級(jí)命令以選擇目標(biāo)版本。

helm upgrade kyverno kyverno/kyverno --namespace kyverno --version <version_number>

注意
從 1.4.2 到 1.4.3(Helm chart >=v2.0.2 <v2.1.0)之間的版本升級(jí)到 Kyverno 1.5.0+(Helm chart v2.1.0)需要額外的步驟。 刪除 CRD 的步驟將導(dǎo)致所有 Kyverno 策略被刪除,因此必須對(duì) Helm 未添加的策略進(jìn)行備份。

以下是將 Kyverno 從 1.4.3 升級(jí)到 1.5.0 的步驟。 升級(jí)到 1.5.0+ 需要首先刪除舊的 CRDs 圖表。

首先備份所有非 Helm 添加的集群策略:

kubectl get clusterpolicy -l app.kubernetes.io/managed-by!=Helm -A -o yaml > kyverno-policies.yaml

執(zhí)行升級(jí):

helm uninstall kyverno --namespace kyverno
helm uninstall kyverno-crds --namespace kyverno
helm install kyverno kyverno/kyverno --namespace kyverno --version <version_number>

恢復(fù) Kyverno 集群策略:

kubectl apply -f kyverno-policies.yaml

卸載 Kyverno

要卸載 Kyverno,請(qǐng)使用原始 YAML 清單或 Helm。 Kyverno Deployment、RBAC 資源和所有 CRD 將被刪除,包括任何報(bào)告。

選項(xiàng) 1 - 使用 YAML 清單卸載 Kyverno

kubectl delete -f https://raw.githubusercontent.com/kyverno/kyverno/main/config/install.yaml

選項(xiàng) 2 - 使用 Helm 卸載 Kyverno

helm uninstall kyverno kyverno/kyverno --namespace kyverno

清理 Webhook 配置

默認(rèn)情況下,Kyverno 將在終止時(shí)嘗試清理其所有 webhook 配置。 但如果首先刪除其 RBAC 資源,它將失去正確執(zhí)行此操作的權(quán)限。

無(wú)論選擇哪種卸載方法,最后一步(根據(jù)譯者實(shí)踐,建議第一步就刪除 webhook,否則可能導(dǎo)致 API Server 請(qǐng)求超時(shí))都需要手動(dòng)刪除 webhook。 使用以下命令刪除這些 webhook 配置。

kubectl delete mutatingwebhookconfigurations kyverno-policy-mutating-webhook-cfg kyverno-resource-mutating-webhook-cfg kyverno-verify-mutating-webhook-cfg

kubectl delete validatingwebhookconfigurations kyverno-policy-validating-webhook-cfg kyverno-resource-validating-webhook-cfg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

推薦閱讀更多精彩內(nèi)容