国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

K8S初級入門系列之十一-安全

這篇具有很好參考價值的文章主要介紹了K8S初級入門系列之十一-安全。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、前言

? ? 安全是K8S重要的特性,在K8S初級入門系列之四-Namespace/ConfigMap/Secret章節(jié),我們已經(jīng)已經(jīng)了解了Namespace,Secret與安全相關(guān)的知識。本篇將梳理K8S在安全方面的策略。主要包括兩個方面,API安全訪問策略以及Pod安全策略。

二、用戶/用戶組

在介紹安全前,我們先了解下用戶和用戶組的概念。

?1、用戶

在K8S中,用戶分為兩種:

  • 真實的用戶,即User,如K8S的管理員,開發(fā)者等。
  • Pod的賬號,即Service Account,是給運行在Pod里面的進程提供必要的身份證明,通過其來限制Pod的訪問權(quán)限。

? ? ? ?這里重點看下Service Account,每個命名空間(namespace)都有一個默認的Service Account。如果Pod不指定ServiceAccount,則使用該空間中默認的。

[root@k8s-master ~]# kubectl get sa
NAME                     SECRETS   AGE
default                  1         203d

(1)自定義ServiceAccount

當然,我們也可以自定義一個ServiceAccount,其yaml如下:

[root@k8s-master yaml]# cat my-serviceaccount.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-servicesaccount
  namespace: default

創(chuàng)建完成后,查看詳情

[root@k8s-master yaml]# kubectl describe sa my-servicesaccount
Name:                my-servicesaccount
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   my-servicesaccount-token-cz8kp
Tokens:              my-servicesaccount-token-cz8kp
Events:              <none>

? ?可以看到 mountable secret和tokens都關(guān)聯(lián)了一個名為my-servicesaccount-token-cz8kp的secret,我們查看其secret的詳情

[root@k8s-master yaml]# kubectl describe secret my-servicesaccount-token-cz8kp
Name:         my-servicesaccount-token-cz8kp
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: my-servicesaccount
              kubernetes.io/service-account.uid: 1f493157-13e7-4d43-9f0b-b8779dfe84ae

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1099 bytes
namespace:  7 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6ImpoSnJ...

? ? ? 其data包含ca.crt,namespace,token密鑰三部分,其中ca.crt即頒發(fā)的CA證書,namespace即命名空間,token文件中存放的密鑰。這三部分的用途我們待會講到。

(2)將ServiceAccount分配給Pod

? ?創(chuàng)建Pod,將上面的serviceAccount分配給Pod,其yaml內(nèi)容如下:

[root@k8s-master yaml]# cat pod-read.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-read
spec:
  serviceAccount: my-servicesaccount
  containers:
  - name: netshoot
    image: nicolaka/netshoot
    imagePullPolicy: IfNotPresent
    command: ["sleep","3600"]

? ? ? ? ?該Pod中定義serviceAccount屬性,并設(shè)置為剛創(chuàng)建的my-servicesaccount。我們進入該pod,查看下/var/run/secrets/kubernetes.io/serviceaccount目錄。

[root@k8s-master ~]#  kubectl exec -it pod-read sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
~ # cd /var/run/secrets/kubernetes.io/serviceaccount
/run/secrets/kubernetes.io/serviceaccount # ls
ca.crt     namespace  token
/run/secrets/kubernetes.io/serviceaccount # cat token
eyJhbGciOiJSUzI1NiIsImtpZCI6ImpoSnJ

? ? ? 該目錄下,包含了my-servicesaccount的secret的三個文件。實際上,ServiceAcccount分配給Pod,就是將serviceAccount的secret作為volume掛載到pod的的固定目錄下(即/var/run/secrets/kubernetes.io/serviceaccount ),后續(xù)Pod將通過這三個文件協(xié)同完成身份驗證。

2、用戶組

? ? ?多個用戶可以屬于一個或者多個用戶組,用戶組可以一次給多個用戶賦予權(quán)限。K8S系統(tǒng)內(nèi)置了一些組,如:

  • system:unauthenticated組用于所有認證插件都不會認證客戶端身份的請求。
  • system:authenticated組會自動分配給一個成功通過認證的用戶。
  • system:serviceaccounts組包含所有在系統(tǒng)中的 ServiceAccount
  • system:serviceaccounts:<namespace>組包含了所有在特定命名空間中的ServiceAccount。

三、API? Server安全訪問策略

? ? ? 在K8S初級入門系列之一-概述章節(jié)的K8S架構(gòu)中,我們形象的比喻過,API Server就像是辦事大廳,對外對內(nèi)提供統(tǒng)一的訪問接口,所以API Server訪問安全策略至關(guān)重要。先來看下官方上的圖。

K8S初級入門系列之十一-安全,K8S,k8s,ServiceAccount,認證,鑒權(quán),安全策略

? ? ?當訪問API Server時,需要經(jīng)過三層關(guān)卡,分別是認證(Authentication),鑒權(quán)(Authorization)和準入控制(Admission Control)。

1、認證

? ? ? 認證就是識別用戶的身份,對于Pod來說,在訪問API Server時,攜帶其Service Account的token密鑰(前面介紹的),由API Service進行認證,這種方式類似JWT token驗證。過程如下:

?(1)、Pod關(guān)聯(lián)ServiceAccount,并掛載了ServiceAccount的secret。

(2)、通過HTTPS方式與API Server建立連接后,會用Pod里CA證書(文件名為ca.crt)驗證API Server發(fā)來的證書,驗證是否為CA證書簽名的合法證書。

(3)、API Server收到Token后,采用自身私鑰對Token進行合法性驗證。

? ? ? ?整個認證過程,需要用到上面介紹的var/run/secrets/kubernetes.io/serviceaccount下三個文件。我們來實驗下,從Pod內(nèi)部,通過curl訪問Api Server的接口。其命令如下:

# 指向內(nèi)部 API 服務(wù)器的主機名,一般為kubernetes.default.svc,也可以通過env查看
APISERVER=https://kubernetes.default.svc

# 服務(wù)賬號令牌的路徑
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount

# 讀取 Pod 的名字空間
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)

# 讀取服務(wù)賬號的持有者令牌
TOKEN=$(cat ${SERVICEACCOUNT}/token)

# 引用內(nèi)部證書機構(gòu)(CA)
CACERT=${SERVICEACCOUNT}/ca.crt

# 使用令牌訪問 API?curl --cacert ${CACERT} -H "Authorization: Bearer $TOKEN" -s ?${APISERVER}/api

進入pod內(nèi)部,輸入上述指令

[root@k8s-master ~]# kubectl exec -it pod-read sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
~ # APISERVER=https://kubernetes.default.svc
~ # SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
~ # NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
~ # TOKEN=$(cat ${SERVICEACCOUNT}/token)
~ # CACERT=${SERVICEACCOUNT}/ca.crt
~ # curl --cacert ${CACERT} -H "Authorization: Bearer $TOKEN" -s  ${APISERVER}/api
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "192.168.16.4:6443"
    }
  ]
}

可以看下,HTTPS攜帶相關(guān)認證信息,Api認證成功后,正確的返回了Api的相關(guān)信息。

2、鑒權(quán)

? ? ? 認證是對用戶合法性的認證,但用戶合法,不代表可以做任何操作,而鑒權(quán)是對調(diào)用的API是否合法進行鑒權(quán),授予用戶不同的訪問權(quán)限。先看一個例子,我們進入上述Pod,訪問下pod列表。

 #   curl --cacert ${CACERT} -H "Authorization: Bearer $TOKEN" -X GET  ${APISERVER}/api/v1/namespaces/default/pods
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "default \"pods\" is forbidden: User \"system:serviceaccount:default:default\" cannot get resource \"default\" in API group \"\" at the cluster scope",
  "reason": "Forbidden",
  "details": {
    "name": "pods",
    "kind": "default"
  },
  "code": 403

? ? ? ?鑒權(quán)未通過被拒絕了,說明該Pod使用的ServiceAccount是沒有訪問該資源權(quán)限的。

? ? ? 下面我們來進行授權(quán)訪問,授權(quán)的方式主要包括ABAC(基于屬性授權(quán)),RBAC(基于角色授權(quán)),Webhook(外部REST服務(wù)對用戶授權(quán))等,其中RBAC是最主要,也是API Server默認的方式,我們來重點介紹,其模型如下:

K8S初級入門系列之十一-安全,K8S,k8s,ServiceAccount,認證,鑒權(quán),安全策略

  • ??資源權(quán)限,表示對何種對象,有什么的操作權(quán)限,對象包括核心資源,如Pod,Deployment,job等,也包括非資源端點,如"/healthz"等。
  • ?Role(角色),是資源權(quán)限的集合。
  • RoleBinding(角色綁定),將Role授予給ServiceAccount,User,Group等。

接下來,我們通過案例,實現(xiàn)對于Pod列表的訪問。

(1)Role(角色)

首先創(chuàng)建一個Role的yaml文件,內(nèi)容如下:

[root@k8s-master yaml]# cat pod-read-role.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" 標明 core API 組
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

在rules可以定義多組資源權(quán)限,每組包含三個屬性:

  • apiGoups,即資源對象所在的api組,由于pods是核心對象,所以為"",比如對象為jobs,那么該值就是batch。
  • resources,資源對象組,可以是pods,deploymenets,jobs等等
  • verbs,對資源對象的操作權(quán)限組,包括get,list,watch,create,delete等。

? ? ?該Role命名為pod-reader,并申明對于Pod對象具備get,watch,list相關(guān)權(quán)限(注意,不具備刪除,創(chuàng)建權(quán)限)。執(zhí)行文件,創(chuàng)建role對象,查看狀態(tài)。

[root@k8s-master yaml]# kubectl get role
NAME                                    CREATED AT
pod-reader                              2023-05-28T09:24:06Z

(2)RoleBinding

? ? ? ?接下來創(chuàng)建RoleBinding,將上面的Role(pod-reader)與ServiceAccount(my-serviceaccount)綁定。其yaml內(nèi)容如下:

[root@k8s-master yaml]# cat pod-reader-rolebinding.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-rolebinding
  namespace: default
subjects:
# 這里可以指定多個主體,User,ServiceAccount,Group
- kind: ServiceAccount
  name: my-servicesaccount
  namespace: default 
  apiGroup: ""
roleRef:
  # "roleRef" 指定與某 Role 綁定關(guān)系
  kind: Role       
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

rolebinding包含兩個屬性。

  • subjects,即綁定的用戶主體,可以是User,ServiceAccount,Group,能同時綁定多個不同的主體。
  • roleRef,即用戶主體待授予的角色。

將my-servicesaccount賬號與pod-reader角色綁定,執(zhí)行文件,創(chuàng)建rolebinding,查看狀態(tài)

[root@k8s-master yaml]# kubectl get rolebinding
NAME                                    ROLE                                         AGE
pod-reader-rolebinding                  Role/pod-reader                              10h

此時,我們進入Pod,再看下能否獲取pod列表。

[root@k8s-master yaml]# kubectl exec -it pod-read sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
~ # APISERVER=https://kubernetes.default.svc
~ # SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
~ # NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
~ # TOKEN=$(cat ${SERVICEACCOUNT}/token)
~ # CACERT=${SERVICEACCOUNT}/ca.crt
~ # curl --cacert ${CACERT} -H "Authorization: Bearer $TOKEN" -X GET  ${APISERVER}/api/v1/namespaces/default/pods
{
   [
      "metadata": {
        "name": "taint-pod",
        "namespace": "default",
        "uid": "12603b58-86b9-4e95-a6d5-b5d8c86a5e9c",
        "resourceVersion": "4812227",
    ...
   ]
   ...
}

可以看到,能正確的獲取了。我們嘗試刪除其中一個pod

# curl --cacert ${CACERT} -H "Authorization: Bearer $TOKEN" -X DELETE  ${APISERVER}/api/v1/namespaces/default/pods/busybox-pod
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "pods \"busybox-pod\" is forbidden: User \"system:serviceaccount:default:my-servicesaccount\" cannot delete resource \"pods\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "name": "busybox-pod",
    "kind": "pods"
  },
  "code": 403
}

可以看到,由于沒有授予刪除相關(guān)的權(quán)限,刪除指令被拒絕。

(3)ClusterRole和ClusterRoleBinding

? ? ? 由于NameSpace的隔離,對于某個空間的ServiceAccount是無法訪問其他空間的資源對象的。如下圖所示,default空間的my-serviceaccount賬號是無法訪問dev空間的Pod資源列表。

K8S初級入門系列之十一-安全,K8S,k8s,ServiceAccount,認證,鑒權(quán),安全策略

? ? ? 在實際工程中,又需要訪問集群中的其他空間的資源,為了解決這一問題,K8S提供了ClusterRole和ClusterBinding。如下圖所示:

K8S初級入門系列之十一-安全,K8S,k8s,ServiceAccount,認證,鑒權(quán),安全策略

? ? ? ?ClusterRole和ClusterRoleBinding組合與Role以及RoleBinding組合的功能類似,只是它們屬于整個集群,不屬于具體某個命名空間,所以它們可以訪問集群中任何命名空間的資源。接下來,我們來實現(xiàn)下這個例子。

? ? ? ?首先創(chuàng)建一個NameSpace和屬于該NameSpace的Pod,我們使用K8S初級入門系列之四-Namespace/ConfigMap/Secret中創(chuàng)建好的命名空間dev,以及ns-pod的Pod,可以查看下pod狀態(tài)。

[root@k8s-master yaml]# kubectl get pod -n dev
NAME     READY   STATUS    RESTARTS   AGE
ns-pod   1/1     Running   0          8s

? ? ? ?在沒有使用ClusterRole和ClusterRoleBinding之前,我們看下能否從default空間中訪問dev空間的資源。

[root@k8s-master yaml]# kubectl exec -it pod-read sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
~ # APISERVER=https://kubernetes.default.svc
~ # SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
~ # NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
~ # TOKEN=$(cat ${SERVICEACCOUNT}/token)
~ # CACERT=${SERVICEACCOUNT}/ca.crt
~ # curl --cacert ${CACERT} -H "Authorization: Bearer $TOKEN" -X GET  ${APISERVER}/api/v1/namespaces/dev/pods
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "pods is forbidden: User \"system:serviceaccount:default:my-servicesaccount\" cannot list resource \"pods\" in API group \"\" in the namespace \"dev\"",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403

? ? ? 訪問被拒絕了,無法訪問到其他命名空間pod。接下來,創(chuàng)建ClusterRole,命名為pod-reader-clusterrole

[root@k8s-master yaml]# cat pod-read-clusterrole.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader-clusterrole
rules:
- apiGroups: [""] # "" 標明 core API 組
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

? ? ? ?與Role比較,ClusterRole沒有NameSpace屬性。執(zhí)行該文件,創(chuàng)建完成后我們可以看下。

[root@k8s-master yaml]# kubectl get clusterrole
NAME                                                                   CREATED AT
admin                                                                  2022-11-04T15:44:14Z
calico-kube-controllers                                                2022-11-05T03:09:48Z
calico-node                                                            2022-11-05T03:09:48Z
cluster-admin                                                          2022-11-04T15:44:14Z
edit                                                                   2022-11-04T15:44:14Z
ingress-nginx                                                          2023-04-02T10:47:54Z
ingress-nginx-admission                                                2023-04-02T10:47:54Z
kubeadm:get-nodes                                                      2022-11-04T15:44:15Z
kubernetes-dashboard                                                   2022-11-05T09:53:47Z
pod-reader-clusterrole                                                 2023-05-30T15:36:51Z
system:aggregate-to-admin                                              2022-11-04T15:44:14Z
system:aggregate-to-edit                                               2022-11-04T15:44:14Z
...

? ? ? 除了創(chuàng)建的pod-reader-clusterrole外,還可以看到大量的系統(tǒng)預(yù)置的ClusterRole。繼續(xù)創(chuàng)建ClusterRoleBinding,命名為pod-reader-clusterrolebinding。

[root@k8s-master yaml]# cat pod-reader-clusterrolebinding.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-reader-clusterrolebinding
subjects:
# 這里可以指定多個主體,User,ServiceAccount,Group
- kind: ServiceAccount
  name: my-servicesaccount
  namespace: default 
  apiGroup: ""
roleRef:
  # "roleRef" 指定與某 Role 綁定關(guān)系
  kind: ClusterRole       
  name: pod-reader-clusterrole
  apiGroup: rbac.authorization.k8s.io

? ? ? 將my-serviceaccount賬號與新創(chuàng)建的pod-reader-clusterrole角色綁定。

[root@k8s-master yaml]# kubectl get clusterrolebinding
NAME                                                   ROLE                                                                               AGE
...
pod-reader-clusterrolebinding                          ClusterRole/pod-reader-clusterrole                                                 16s
system:controller:attachdetach-controller              ClusterRole/system:controller:attachdetach-controller                              209d
system:controller:certificate-controller               ClusterRole/system:controller:certificate-controller                               209d                         
....

? ? ? 同樣,除了我們創(chuàng)建的pod-reader-clusterrolebinding外,也存在大量的系統(tǒng)預(yù)置ClusterRoleBinding對象。再次進入default空間pod,訪問dev空間的pod列表

[root@k8s-master yaml]# kubectl exec -it pod-read sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
~ # APISERVER=https://kubernetes.default.svc
~ # SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
~ # NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
~ # TOKEN=$(cat ${SERVICEACCOUNT}/token)
~ # CACERT=${SERVICEACCOUNT}/ca.crt
~ # curl --cacert ${CACERT} -H "Authorization: Bearer $TOKEN" -X GET  ${APISERVER}/api/v1/namespaces/dev/pods
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "resourceVersion": "31415719"
  },
  "items": [
    {
      "metadata": {
        "name": "ns-pod",
        "namespace": "dev",
        "uid": "31bc247f-6c5a-496a-8805-2631f03e7df2",
        "resourceVersion": "31324908",
        "creationTimestamp": "2023-06-02T01:26:27Z",
        "labels": {
          "app": "nginx-pod"
        },
...

? ? ? 此時可以正確訪問pod列表了。

3、準入

? ? ? ?突破了認證和鑒權(quán)兩層關(guān)卡后,對于API的請求還需要通過"準入"這道關(guān)卡,K8S配備了一個準入控制器的插件列表,發(fā)送給API Server的任何請求都需要通過列表中每個準入控制器的檢查,檢查通不過,則拒絕調(diào)用請求。

? ??準入控制器 是一段代碼,它會在請求通過認證和鑒權(quán)之后、對象被持久化之前攔截到達 API 服務(wù)器的請求,準入控制器又可以分為驗證(Validating)和變更(Mutating),變更(mutating)控制器可以根據(jù)被其接受的請求更改相關(guān)對象,Validating 控制器不會。如果任何一個階段中的任何控制器拒絕了請求,則會立即拒絕整個請求,并將錯誤返回給最終的用戶。

? ?K8S定義了多個準入控制器,可以查看官方文檔準入控制器參考 | Kubernetes,用戶也可以自定義擴展插件。通過如下的命令可以查看K8S默認開啟的準入控制器。

[root@k8s-master ~]# kubectl exec -it kube-apiserver-k8s-master -n kube-system -- kube-apiserver -h | grep enable-admission-plugins
      .....
      --enable-admission-plugins strings       admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, PodSecurity, .....

? ? ?稍后我們專門分析其中的PodSecurity準入控制器。

四、Pod安全策略

? ? ? ?Pod除了對于API Server訪問需要控制,Pod自身的安全策略也非常重要,因為Pod加載的容器鏡像是由開發(fā)者,甚至是三方提供,如果不在Pod層進行安全的控制,這些鏡像運行的代碼就有可能利用漏洞實現(xiàn)非法的操作。

? ? ? ? 有些同學(xué)可能會問,Pod中的容器本來就是和宿主隔離的,就算有影響,也只會影響該容器的環(huán)境,其實不然,在前面的章節(jié),我們了解到容器的目錄是可以掛在到宿主節(jié)點上的,網(wǎng)絡(luò)也可以直接使用宿主的,如果此時容器擁有root權(quán)限,就會隨意篡改宿主節(jié)點的目錄,或者利用宿主機網(wǎng)絡(luò)進行惡意訪問其他主機,從而影響集群安全。

? ? ? 為了解決這些安全問題,K8S對于Pod提供一系列的安全策略方案。

1、安全上下文配置

? ? ? ? 安全上下文即配置securityContext屬性,Pod和Container上都可以配置該屬性,兩者的策略項既有重復(fù)的,也有不同的,對于重復(fù)的部分,Container策略會覆蓋Pod上的。我們先來看下Pod上的配置。

(1)Pod配置

? ? ? ? 我們先看下沒有配置securityContext屬性時,Pod都有哪些權(quán)限。創(chuàng)建security-context-demo.yaml文件

[root@k8s-master yaml]# cat security-context-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo

執(zhí)行文件,Pod創(chuàng)建完成后,進入容器內(nèi)部,看下其默認的進程用戶,組,以及文件目錄屬組。

[root@k8s-master yaml]# kubectl exec -it security-context-demo sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # id
uid=0(root) gid=0(root) groups=0(root),10(wheel)
/ # cd /data
/data # ls -l
total 4
drwxrwxrwx    2 root     root          4096 Jun  4 05:58 demo

? ? ? ?可以看到uid,gid,以及文件目錄的屬主都是root,為了安全起見,我們認為該Pod下的容器不需要root權(quán)限,那么就可以通過Pod級別的securityContext屬性配置。下面我們修改yaml文件。

[root@k8s-master yaml]# cat security-context-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  volumes:
  ...

securityContext屬性中有三項內(nèi)容:

  • runAsUser,指定容器中運行進程的用戶(用戶 ID
  • runAsGroup,指定容器中運行組(組?ID
  • fsGroup,文件屬主組(組ID)

再進入容器看下

[root@k8s-master yaml]# kubectl exec -it security-context-demo sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ $ id
uid=1000 gid=3000 groups=2000,3000
/ $ cd /data
/data $ ls -l
total 4
drwxrwsrwx    2 root     2000          4096 Jun  4 06:30 demo

? ? ? ?可以看到已經(jīng)按照Pod的設(shè)置進行了更變。除了以上的三個配置項,Pod還可以設(shè)置其他的,具體參考:Kubernetes API Reference Docs

(2)容器配置

? ? ? ? 容器中也可以配置securityContext屬性,首先我們看下runAsUser,runAsGroup,fsGroup屬性。我們再來創(chuàng)建一個pod yaml

[root@k8s-master yaml]# cat security-context-demo1.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 1000
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
    securityContext:
      runAsUser: 2000

? ? ? 在container中,增加了securityContext屬性,并配置了runAsUser了,其值和Pod的不同。我們進入Pod內(nèi)部看下。

[root@k8s-master yaml]#  kubectl exec -it security-context-demo1 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ $ id
uid=2000 gid=0(root) groups=0(root)

? ? ? ?可以看到,Container定義的uid=2000覆蓋了Pod定義的uid=1000。

? ? ? ? 默認的情況下,Pod是無法使用宿主內(nèi)核的功能(容器鏡像沒有內(nèi)核),比如修改網(wǎng)絡(luò)接口,修改系統(tǒng)時間等等,如果獲取這些權(quán)限,就需要申請授權(quán)特權(quán)模式。

? ? ? 我們先來看下在沒有授權(quán)特權(quán)模式下,Pod操作內(nèi)核指令的情況。?創(chuàng)建一個新的Pod,其yaml內(nèi)容如下:

[root@k8s-master yaml]# cat security-context-demo2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo2
spec:
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo

? ? ?進入Pod,訪問/dev目錄下的設(shè)備列表,以及修改網(wǎng)絡(luò)接口

[root@k8s-master yaml]# kubectl exec -it security-context-demo2 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /dev
/dev # ls
core             full             null             pts              shm              stdin            termination-log  urandom
fd               mqueue           ptmx             random           stderr           stdout           tty              zero
/dev # ip link add dummy0 type dummy
ip: RTNETLINK answers: Operation not permitted

? ? ? 可以看到修改網(wǎng)絡(luò)接口指令被拒絕了。dev目錄下展示內(nèi)容待會進行比較。接下來,我們修改yaml內(nèi)容,增加特權(quán)配置(?privileged: true)。

[root@k8s-master yaml]# cat security-context-demo2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo2
spec:
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
    securityContext:
      privileged: true

?再次進入Pod,執(zhí)行相關(guān)指令

[root@k8s-master yaml]# kubectl exec -it security-context-demo2 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /dev
/dev # ls
autofs           input            raw              tty12            tty26            tty4             tty53            ttyS0            vcs3             vhci
bsg              kmsg             rtc0             tty13            tty27            tty40            tty54            ttyS1            vcs4             vhost-net
bus              loop-control     sg0              tty14            tty28            tty41            tty55            ttyS2            vcs5             vhost-vsock
core             mapper           shm              tty15            tty29            tty42            tty56            ttyS3            vcs6             watchdog
cpu              mcelog           snapshot         tty16            tty3             ....
/dev # ip link add dummy0 type dummy
/dev # 

? ? ? ?可以看到,/dev下面顯示多個特權(quán)設(shè)備?,也正確的執(zhí)行了網(wǎng)絡(luò)接口修改指令。

? ? ? ?特權(quán)雖然能支持內(nèi)核操作,但是其權(quán)限粒度較大,從Linux內(nèi)核2.2開始,引入了 Capabilities 機制來對 內(nèi)核操作進行了更加細粒度的控制,可以實現(xiàn)按需授權(quán),我們以修改網(wǎng)絡(luò)接口為例。修改yaml文件如下:

[root@k8s-master yaml]# cat security-context-demo2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo2
spec:
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
    securityContext:
       capabilities:
        add: # 添加
        - NET_ADMIN
        drop:  # 刪除
        - KILL

? ? ? 刪除了privileged: true配置,增加了capabilities的列表配置,這里僅需要網(wǎng)絡(luò)權(quán)限,配置NET_ADMIN即可。

[root@k8s-master yaml]# kubectl exec -it security-context-demo2 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # ip link add dummy0 type dummy

? ? 可以正確的修改了網(wǎng)絡(luò)接口配置。

? ? ?容器的securityContext還支持seLinuxOptions,allowPrivilegeEscalation等其他配置項。完整的配置項參見:SecurityContext - Kubernetes指南

2、Pod準入策略

? ? ? Pod一般都是有應(yīng)用開發(fā)者配置和創(chuàng)建的,上面的securityContext配置是否都被允許的呢?比如說容器設(shè)置了特權(quán)模式,擁有了完整的操作內(nèi)核的能力,集群管理員如何進行統(tǒng)一管控?這里就要用到上面介紹的Pod準入策略,其作用是,在Pod創(chuàng)建,進行準入校驗。

? ? ? 在V1.21版本前,通過PodSecurityPolicy統(tǒng)一配置Pod的安全策略,該方式在V1.25中廢棄,代替的是PodSecurity準入控制器。?PodSecurity定義了三種不同的策略,其限制程度逐級提升。

  • Privileged,不受限制的策略,提供最大可能范圍的權(quán)限許可。通常針對由特權(quán)較高、受信任的用戶所管理的系統(tǒng)級或基礎(chǔ)設(shè)施級負載。
  • Baseline,限制性最弱的策略,禁止已知的策略提升。允許使用默認的(規(guī)定最少)Pod 配置。這種策略是最常見的,針對的是應(yīng)用運維人員和非關(guān)鍵性應(yīng)用的開發(fā)人員。其策略內(nèi)容主要有,禁止有特權(quán)容器,禁止打破網(wǎng)絡(luò)隔離等。
  • Restricted,限制性非常強的策略,遵循當前的保護 Pod 的最佳實踐。這類策略會犧牲一些兼容性,主要針對運維人員和安全性很重要的應(yīng)用的開發(fā)人員,以及不太被信任的用戶。其策略內(nèi)容主要有,要求容器以非 root 用戶運行,?容器組必須棄用 ALL capabilities ,并且只允許添加 NET_BIND_SERVICE 能力等。

? ? ?目前PodSecurity僅限于這三種策略,且無法進行擴展的。這些策略需要應(yīng)用于命名空間,實現(xiàn)對命名空間下所有Pod的約束,在命名空間中也可以配置三種模式。

  • enforce,策略違例會導(dǎo)致 Pod 被拒絕
  • audit,策略違例會觸發(fā)審計日志中記錄新事件時添加審計注解;但是 Pod 仍是被接受的。
  • warn,策略違例會觸發(fā)用戶可見的警告信息,但是 Pod 仍是被接受的。

? ? ? 這三種模式配合上述的策略使用,命名空間可以配置多種策略。下面我們來看下案例。創(chuàng)建一個命名空間,設(shè)定安全策略。

[root@k8s-master yaml]# cat pod-level-ns.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: podlevel
  labels: 
    #強制執(zhí)行baseline安全標準,執(zhí)行拒絕。適用于最新的k8s版本
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/enforce-version: latest
    #對restricted的Pod安全標準執(zhí)行警告(warn)和審核(audit),適用于最新的k8s版本
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: latest
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: latest

在命名空間中增加了labels屬性配置,下面是對其設(shè)置的解釋。

# 設(shè)定模式及安全標準策略等級
# MODE必須是 `enforce`, `audit`或`warn`其中之一。
# LEVEL必須是`privileged`, `baseline`或 `restricted`其中之一
pod-security.kubernetes.io/<MODE>: <LEVEL>

# 此選項是非必填的,用來鎖定使用哪個版本的的安全標準
# MODE必須是 `enforce`, `audit`或`warn`其中之一。
# VERSION必須是一個有效的kubernetes minor version(例如v1.23),或者 `latest`
pod-security.kubernetes.io/<MODE>-version: <VERSION>

? ? ?本例中我們設(shè)置了三種模式,對于enforce,配置了baseline策略,也就是違反baseline策略的Pod一律拒絕執(zhí)行;對于warn和audit,配置了restricted策略,也就是違反restricted策略的Pod進行警告和審核。

? ? 接下來,我們創(chuàng)建一個違反restricted策略的Pod。由于它的條件比較苛刻,默認的配置也無法校驗通過。

[root@k8s-master yaml]# cat level-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: level-pod
  namespace: podlevel
spec:
  containers:
    - image: nginx
      name: nginx
      ports:
        - containerPort: 80

? ?執(zhí)行該文件,創(chuàng)建Pod

[root@k8s-master yaml]# kubectl apply -f level-pod.yaml 
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
pod/level-pod created
[root@k8s-master yaml]# kubectl get pod -n podlevel
NAME        READY   STATUS    RESTARTS   AGE
level-pod   1/1     Running   0          78s

? ? 可以看到,違反了restricted策略,對用戶進行了告警提示,但是Pod最終還是創(chuàng)建成功的。我們繼續(xù)修改上面的Pod,讓其違反baseline策略,baseline策略不允許有特權(quán)容器存在。

[root@k8s-master yaml]# cat level-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: level-pod
  namespace: podlevel
spec:
  containers:
    - image: nginx
      name: nginx
      ports:
        - containerPort: 80
      securityContext:
       allowPrivilegeEscalation: true
       privileged: true
       capabilities:
         drop:
         - ALL

執(zhí)行該文件,可以看到,拒絕執(zhí)行Pod創(chuàng)建。

[root@k8s-master yaml]# kubectl apply -f level-pod.yaml 
Error from server (Forbidden): error when creating "level-pod.yaml": pods "level-pod" is forbidden: violates PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)

? ? 綜上所述,Pod安全上下文配置實現(xiàn)了對于容器鏡像的約束,Pod準入策略,實現(xiàn)了Pod的約束。逐級構(gòu)建了安全防護網(wǎng),實現(xiàn)Pod安全。

五、總結(jié)

? ? 本篇我們介紹了K8S的安全相關(guān)內(nèi)容,主要從API安全訪問策略以及Pod安全策略兩個方面。

? ?API安全訪問策略,主要是對API Server的訪問安全控制,其設(shè)置了認證,鑒權(quán),準入三道關(guān)卡。認證是針對用戶的身份合法性驗證,鑒權(quán)是對訪問的API接口合法性驗證,準入是通過一系列的準入控制器進行準入檢查。只有經(jīng)過了這三層關(guān)卡,才能訪問API Server的資源。

? ?Pod安全策略,主要介紹了安全上下文配置和Pod的準入檢查。安全上下文配置是在Pod或者Container中設(shè)置securityContext屬性;Pod的準入檢查通過在命名空間下配置不同的策略,實現(xiàn)Pod創(chuàng)建時準入檢查。

?附:

K8S初級入門系列之一-概述

K8S初級入門系列之二-集群搭建

K8S初級入門系列之三-Pod的基本概念和操作

K8S初級入門系列之四-Namespace/ConfigMap/Secret

K8S初級入門系列之五-Pod的高級特性

K8S初級入門系列之六-控制器(RC/RS/Deployment)

K8S初級入門系列之七-控制器(Job/CronJob/Daemonset)

K8S初級入門系列之八-網(wǎng)絡(luò)

K8S初級入門系列之九-共享存儲

K8S初級入門系列之十-控制器(StatefulSet)

K8S初級入門系列之十一-安全

K8S初級入門系列之十二-計算資源管理文章來源地址http://www.zghlxwxcb.cn/news/detail-600266.html

到了這里,關(guān)于K8S初級入門系列之十一-安全的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Kubernetes(K8s)從入門到精通系列之十四:安裝工具

    Kubernetes 命令行工具 kubectl, 讓你可以對 Kubernetes 集群運行命令。 你可以使用 kubectl 來部署應(yīng)用、監(jiān)測和管理集群資源以及查看日志。 kind 讓你能夠在本地計算機上運行 Kubernetes。 使用這個工具需要你安裝 Docker 或者 Podman。 與 kind 類似,minikube 是一個工具, 能讓你在本地運

    2024年02月14日
    瀏覽(46)
  • Kubernetes(K8s)從入門到精通系列之十三:軟件負載平衡選項

    當設(shè)置具有多個控制平面的集群時,可以通過將 API Server 實例置于負載均衡器后面并在運行 kubeadm init 以便新集群使用它時使用 --control-plane-endpoint 選項來實現(xiàn)更高的可用性。 當然,負載均衡器本身也應(yīng)該具有高可用性。這通常是通過向負載均衡器添加冗余來實現(xiàn)的。為此,

    2024年02月14日
    瀏覽(21)
  • Kubernetes(K8s)從入門到精通系列之十二:安裝和設(shè)置 kubectl

    Kubernetes 命令行工具 kubectl, 讓你可以對 Kubernetes 集群運行命令。 你可以使用 kubectl 來部署應(yīng)用、監(jiān)測和管理集群資源以及查看日志。 kubectl 版本和集群版本之間的差異必須在一個小版本號內(nèi)。 例如:v1.27 版本的客戶端能與 v1.26、 v1.27 和 v1.28 版本的控制面通信。 用最新兼容

    2024年02月14日
    瀏覽(27)
  • K8S初級入門系列之四-Namespace/ConfigMap/Secret

    K8S初級入門系列之四-Namespace/ConfigMap/Secret

    ? ? ?本章節(jié)我們繼續(xù)學(xué)習(xí)Namespace、ConfigMap、Secret基礎(chǔ)概念,了解他們基本用法和操作。NameSpace為命名空間,在同一集群中試下資源隔離。ConfigMap通過key-value的方式實現(xiàn)明文配置數(shù)據(jù)的保存,Secret與ConfigMap類似,不過是采用密文方式保存。 ? ? ?K8S集群可以通過Namespace創(chuàng)建多

    2024年02月15日
    瀏覽(31)
  • K8S初級入門系列之三-Pod的基本概念和操作

    K8S初級入門系列之三-Pod的基本概念和操作

    ? ? ? ?Pod的原意是豌豆莢的意思,一個豆莢里面包含了很多豆子。在K8S中,Pod也是類似的意思,只不過這里的豆子就是容器。在K8S初級入門系列之一-概述中,我們對Pod有個初步的了解。 1、Pod是K8S編排和調(diào)度的最小基礎(chǔ)單元。 ? ? ? ? 了解容器的同學(xué)會知道,容器之間通過

    2024年02月15日
    瀏覽(26)
  • Kubernetes(K8s)從入門到精通系列之十:使用 kubeadm 創(chuàng)建一個高可用 etcd 集群

    Kubernetes(K8s)從入門到精通系列之十:使用 kubeadm 創(chuàng)建一個高可用 etcd 集群

    默認情況下,kubeadm 在每個控制平面節(jié)點上運行一個本地 etcd 實例。也可以使用外部的 etcd 集群,并在不同的主機上提供 etcd 實例。 可以設(shè)置HA集群: 使用堆疊控制控制平面節(jié)點,其中 etcd 節(jié)點與控制平面節(jié)點共存 使用外部 etcd 節(jié)點,其中 etcd 在與控制平面不同的節(jié)點上運行

    2024年02月14日
    瀏覽(34)
  • Kubernetes(K8s)從入門到精通系列之十六:linux服務(wù)器安裝minikube的詳細步驟

    安裝Docker的詳細步驟,可以閱讀博主下面這篇技術(shù)博客文章:

    2024年02月12日
    瀏覽(57)
  • Kubernetes(K8s)從入門到精通系列之七:K8s的基本概念和術(shù)語之安全類

    開發(fā)的Pod應(yīng)用需要通過API Server查詢、創(chuàng)建及管理其他相關(guān)資源對象,所以這類用戶才是K8s的關(guān)鍵用戶。K8s設(shè)計了Service Account這個特殊的資源對象,代表Pod應(yīng)用的賬號,為Pod提供必要的身份驗證。在此基礎(chǔ)上,K8s實現(xiàn)和完善了基于角色的訪問控制權(quán)限系統(tǒng)——RBAC(Role-Based Acce

    2024年02月15日
    瀏覽(92)
  • K8S系列二:實戰(zhàn)入門

    K8S系列二:實戰(zhàn)入門

    本文是K8S系列第二篇,主要面向?qū)8S新手同學(xué),閱讀本文需要讀者對K8S的基本概念,比如Pod、Deployment、Service、Namespace等基礎(chǔ)概念有所了解。尚且不熟悉的同學(xué)推薦先閱讀本系列的第一篇文章:《K8S系列一:概念入門》 本文旨在講述如何通過kubectl(kubernetes命令行工具)操作

    2024年02月13日
    瀏覽(18)
  • 學(xué)習(xí)筆記三十一:k8s安全管理:認證、授權(quán)、準入控制概述SA介紹

    學(xué)習(xí)筆記三十一:k8s安全管理:認證、授權(quán)、準入控制概述SA介紹

    認證基本介紹:kubernetes主要通過APIserver對外提供服務(wù),那么就需要對訪問apiserver的用戶做認證,如果任何人都能訪問apiserver,那么就可以隨意在k8s集群部署資源,這是非常危險的,也容易被黑客攻擊滲透,所以需要我們對訪問k8s系統(tǒng)的apiserver的用戶進行認證,確保是合法的符

    2024年02月06日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包