kubernetes中pod的隔離策略


配置容器級別的安全控制

使用宿主機的網絡模式

可以通過設置pod的spec的hostNetwork參數為true開啟容器的“host”network模式

    spec:
      hostNetwork: true
      containers:
        - name: name
          image: Enter containers image

綁定宿主機的端口

這種方式不需要創建service來做port映射,相當於docker中的-p映射端口的操作

    spec:
      containers:
        - name: name
          image: Enter containers image
          ports:
            # 容器內部的端口
            - containerPort: 8080
              # 映射在宿主機上的端口
              hostPort: 9000
              protocol: TCP

使用宿主機的PID和IPC命名空間

通過開啟pod的spec.hostPID使用宿主機的pid,同樣通過開始hostIPC使用宿主機的ipc

    spec:
      hostPID: true
      hostIPC: true
      containers:
        - name: name
          image: Enter containers image

將hostPID設置為true,pod內就可以看到宿主機上的所有進程pid,同時自己的進程也會有宿主機管理。
將hostIPC設置為true,pod中的進程就可以與宿主機上的其他所有進程進行通信。

配置pod的安全上下文

針對於container級別的控制

指定運行容器的用戶

    spec:
      containers:
        - name: name
          image: Enter containers image
          securityContext:
          # 405為容器中用戶的id,這里僅可以通過id指定運行容器的用戶
            runAsUser: 405

阻止容器以root用戶運行

有的應用在容器中設置了運行用戶,然后可能會有黑客上傳一個以root用戶運行的鏡像到我們的鏡像倉庫。然后在容器中利用root用戶
的權限,這樣是很危險的,所以我們可以禁用容器中的root用戶,讓他不能以root用戶啟動容器

    spec:
      containers:
        - name: name
          image: Enter containers image
          securityContext:
            runAsNonRoot: true

使用特權模式啟動容器

使容器具有宿主機上的所有操作權限,這樣容器中就可以使用宿主機上的設備了

    spec:
      containers:
        - name: name
          image: Enter containers image
          securityContext:
            privileged: true

為容器添加linux內核的功能

使用特權模式啟動的容器被賦予了過大的權限,我們可以根據需求給予容器所需的linux內核的能力。

    spec:
      containers:
        - name: name
          image: Enter containers image
          securityContext:
            # 通過capabilities開啟或者禁用linux的內核功能
            capabilities:
              # 授予容器能力
              add:
                - SYS_TIME
              # 禁用容器能力
              drop:
                - CHOWN

注意:在linux中內核功能通常以CAP_開頭,這里需要省略掉

阻止容器對根目錄的寫入

    spec:
      containers:
        - name: test-container
          image: test-container
          imagePullPolicy: IfNotPresent
          securityContext:
            # 這個容器的根目錄不允許寫入操作
            readOnlyRootFilesystem: true
          volumeMounts:
            # 但是允許向volume目錄寫入,這個目錄是一個掛載卷
            - mountPath: /volume
              name: test-volume
              readOnly: false
      volumes:
        - name: test-volume
          emptyDir: {}

問題:如果不采用掛載的方式,可否將一個目錄釋放出來允許寫入呢?

pod級別的安全上下文

容器使用不同用戶運行時共享存儲卷

當一個pod中的兩個容器都使用root用戶運行時,他們之前可以互相讀取對方的掛載卷。但是,當我們為每個容器配置其他的啟動用戶時,
可以會出現一些訪問權限的問題。
在kubernetes中,可以為pod中的容器指定一個supplemental組,以允許他們無論通過哪個用戶啟動容器都可以共享文件。

    spec:
      securityContext:
        # 用戶組id設置為555,則創建存儲卷時存儲卷屬於用戶ID為555的用戶組
        fsGroup: 555
        # 定義了某個用戶所關聯的額外的用戶組
        supplementalGroups:
          - 666
          - 777
      containers:
        - name: test-A
          image: test-container
          imagePullPolicy: IfNotPresent
          securityContext:
            runAsUser: 01
          volumeMounts:
            - mountPath: /volume
              name: test-volume
              readOnly: false
        - name: test-B
          image: test-container
          imagePullPolicy: IfNotPresent
          securityContext:
            runAsUser: 02
          volumeMounts:
            - mountPath: /volume
              name: test-volume
              readOnly: false
      volumes:
        - name: test-volume
          emptyDir: {}

在pod級別指定fsGroup與supplementalGroups屬性,然后分別指定兩個容器的啟動用戶為01、02。然后在啟動容器,在容器中執行id命令
可以查看容器的用戶和用戶組,然后就可以看到兩個容器雖然用戶不同,但是都屬於“555、666、777”這三個組中。

統一限制pod的安全相關特性 PodSecurityPolicy

PodSecurityPolicy在kubernetes中簡稱為psp,主要定義了用戶能否在pod中使用各種安全相關的特性。
當有人調用api server創建pod時,PodSecurityPolicy會拿到這個pod的信息與自己個規則做比較。如果符合規則,就運行其存入etcd;否則會被拒絕。
因為是在創建pod時校驗的,所以修改psp,不會對已創建的pod采取措施。也可以設置默認值,就是用psp中配置的默認值替換掉pod中的值。
主要提供了以下能力:

  • 是否允許pod使用宿主節點的PID、IPC、網絡命名空間
  • pod允許綁定的宿主節點端口
  • 容器運行時允許使用的用戶ID
  • 是否允許擁有特權模式容器的pod
  • 允許添加哪些內核功能, 默認添加哪些內核功能, 總是禁用哪些內核功能
  • 允許容器使用哪些 SELinux 選項
  • 容器是否允許使用可寫的根文件系統
  • 允許容器在哪些文件系統組下運行
  • 允許pod使用哪些類型的存儲卷
    以下為demo:
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: exporter-node-cluster-monitoring
spec:
  allowPrivilegeEscalation: false
  # 強制使用只讀的根文件系統
  readOnlyRootFilesystem: true
  # 不允許使用特權方式運行容器
  privileged: false
  allowedHostPaths:
    - pathPrefix: /
      readOnly: true
  # 指定容器可以使用的用戶組id范圍
  fsGroup:
    ranges:
      - max: 65535
        min: 1
    rule: MustRunAs
  supplementalGroups:
    ranges:
      - max: 65535
        min: 1
    rule: MustRunAs
  # 允許使用宿主機的網絡命名空間
  hostNetwork: true
  # 允許使用宿主機的PID
  hostPID: true
  # 允許使用宿主機的IPC
  hostIPC: true
  # 只允許綁定宿主機的9796端口,和1000~1080的端口
  hostPorts:
    - max: 9796
      min: 9796
    - max: 1000
      min: 1080
  # 可以使用任意用戶運行
  runAsUser:
    rule: RunAsAny
  # 可以使用seLinux的任意規則
  seLinux:
    rule: RunAsAny
  # 支持的掛載方式
  volumes:
    - configMap
    - emptyDir
    - projected
    - secret
    - downwardAPI
    - persistentVolumeClaim
    - hostPath

配置允許、默認添加、禁用內核功能

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: exporter-node-cluster-monitoring
spec:
  # 允許容器添加SYS_TIME功能
  allowedCapabilities:
    - SYS_TIME
  # 為每個容器添加CHOWN能力
  defaultAddCapabilities:
    - CHOWN
  # 要求容器禁用SYS_ADMIN和SYS_MODULE
  requiredDropCapabilities:
    - SYS_ADMIN
    - SYS_MODULE

利用RBAC分配PodSecurityPolicy

psp屬於集群級別的資源,所以默認是作用於整個集群的。但是我們有時候只需要針對某些應用采用這些設置。可以通過創建一個ClusterRole然后將其
指向一個psp,再通過使用ClusterRoleBinding到不同的用戶,這樣的話這個psp的規則就只作用於這個用戶創建的pod了。

kubectl create clusterrole psp -privileged --verb=use  --resource=podsecuritypolicies --resource-name=privileged

注意:這里的verb采用的是use
然后再將這個clusterrole綁定到用戶或者用戶組上就可以了

pod間的訪問隔離

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: networkPolicy-demo
spec:
  # 允許可以訪問哪些pod
  # 當標簽中為空時,表示不允許任何pod訪問
  podSelector:

配置同一命名空間(foo)下的相互訪問權限

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: networkPolicy-demo
  namespace: foo  
spec:
  # 允許哪些pod可以訪問當前命名空間中的pod
  podSelector:
    matchLabels:
      app: mysql
  ingress:
    - from:
        # 允許哪個pod可以訪問
        - podSelector:
            matchLabels:
              app: service-a
    # 允許被訪問的pod
    - ports:
        - 3306

配置跨命名空間的訪問權限

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: networkPolicy-demo
  namespace: foo
spec:
  # 允許哪些pod可以訪問當前命名空間中的pod
  podSelector:
    matchLabels:
      app: service-b
  ingress:
    - from:
        # 允許帶有標簽為(tenant=service-a)的命名空間中的pod訪問
        - namespaceSelector:
            matchLabels:
              tenant: service-a
    - ports:
        - 80

可以通過網段限制進入的流量

  ingress:
    - from:
        # 值允許來自ip端為192.168.1.0/24的流量
        - ipBlock:
            cidr: 192.168.1.0/24
    - ports:
        - 3306

限制pod流出流量

spec:
  podSelector:
    matchLabels:
      app: service-b
  egress:
    - to:
       # 只允許流量流出到標簽為(app=service-c)的pod
        - podSelector:
            matchLabels:
              app: service-c


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM