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

K8s in Action 閱讀筆記——【13】Securing cluster nodes and the network

這篇具有很好參考價(jià)值的文章主要介紹了K8s in Action 閱讀筆記——【13】Securing cluster nodes and the network。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

K8s in Action 閱讀筆記——【13】Securing cluster nodes and the network

13.1 Using the host node’s namespaces in a pod

Pod中的容器通常在不同的Linux名稱空間下運(yùn)行,這使得它們的進(jìn)程與其他容器或節(jié)點(diǎn)默認(rèn)名稱空間下運(yùn)行的進(jìn)程隔離開(kāi)來(lái)。

例如,我們學(xué)習(xí)到每個(gè)Pod都擁有自己的IP和端口空間,因?yàn)樗褂闷渥约旱木W(wǎng)絡(luò)名稱空間。同樣,每個(gè)Pod也擁有自己的進(jìn)程樹(shù),因?yàn)樗凶约旱腜ID名稱空間,并且它還使用自己的IPC名稱空間,只允許在同一Pod中的進(jìn)程通過(guò)IPC(Inter-Process Communication)機(jī)制相互通信。

13.1.1 Using the node’s network namespace in a pod

某些Pod(通常是系統(tǒng)Pod)需要在主機(jī)的默認(rèn)名稱空間中運(yùn)行,允許它們查看和操作節(jié)點(diǎn)級(jí)別的資源和設(shè)備。例如,一個(gè)Pod可能需要使用節(jié)點(diǎn)的網(wǎng)絡(luò)適配器而不是自己的虛擬網(wǎng)絡(luò)適配器。可以通過(guò)將Pod規(guī)范中的hostNetwork屬性設(shè)置為true來(lái)實(shí)現(xiàn)這一點(diǎn)。

在這種情況下,Pod使用節(jié)點(diǎn)的網(wǎng)絡(luò)接口而不是它自己的網(wǎng)絡(luò)接口,如圖13.1所示。這意味著Pod不會(huì)獲得自己的IP地址,如果它運(yùn)行綁定端口的進(jìn)程,該進(jìn)程將綁定到節(jié)點(diǎn)的端口。

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-eVGECMzg-1686405749288)(https://note-image-1307786938.cos.ap-beijing.myqcloud.com/typora/image-20230610150830900.png)]

運(yùn)行Pod后,可以使用以下命令查看其確實(shí)使用主機(jī)的網(wǎng)絡(luò)名稱空間(例如,它可以看到所有主機(jī)的網(wǎng)絡(luò)適配器)。

kubectl exec pod-with-host-network -- ifconfig
cni0      Link encap:Ethernet  HWaddr 0E:DB:96:27:9A:29  
         ......

docker0   Link encap:Ethernet  HWaddr 02:42:5D:5E:AE:54  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
         ......

ens3      Link encap:Ethernet  HWaddr 1E:00:49:00:00:59  
          inet addr:33.33.33.108  Bcast:33.33.33.255  Mask:255.255.255.0
         ......

flannel.1 Link encap:Ethernet  HWaddr FA:36:23:30:02:19  
          inet addr:10.244.1.0  Bcast:0.0.0.0  Mask:255.255.255.255
         ......

ifb0      Link encap:Ethernet  HWaddr A6:98:4B:6B:61:AB  
          inet6 addr: fe80::a498:4bff:fe6b:61ab/64 Scope:Link
         ......

lo        Link encap:Local Loopback  
         ......

tunl0     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
         ......

veth3d45ae3c Link encap:Ethernet  HWaddr 92:E5:55:02:3D:36  
         ......

當(dāng)Kubernetes控制面組件作為Pod部署時(shí),會(huì)發(fā)現(xiàn)這些Pod使用了hostNetwork選項(xiàng),讓它們表現(xiàn)得好像它們沒(méi)有運(yùn)行在Pod中一樣。

13.1.2 Binding to a host port without using the host’s network namespace

允許Pod綁定到節(jié)點(diǎn)的默認(rèn)名稱空間中的端口,但仍具有自己的網(wǎng)絡(luò)名稱空間。這是通過(guò)在Pod規(guī)范的spec.containers.ports字段中使用容器端口(hostPort)屬性來(lái)實(shí)現(xiàn)的。

不要將使用hostPort的Pod與通過(guò)NodePort服務(wù)暴露的Pod混淆。它們是兩個(gè)不同的東西,如下圖所示:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-KFL4zOlz-1686405749290)(https://note-image-1307786938.cos.ap-beijing.myqcloud.com/typora/image-20230610152136088.png)]

首先,在圖中你會(huì)注意到,當(dāng)一個(gè)Pod使用hostPort時(shí),連接到節(jié)點(diǎn)的端口直接轉(zhuǎn)發(fā)到在該節(jié)點(diǎn)上運(yùn)行的Pod上,而使用NodePort服務(wù)時(shí),連接到節(jié)點(diǎn)的端口將被轉(zhuǎn)發(fā)到一個(gè)隨機(jī)選擇的Pod上(可能在另一個(gè)節(jié)點(diǎn)上)。另一個(gè)區(qū)別是,使用hostPort的Pod只會(huì)在運(yùn)行此類Pod的節(jié)點(diǎn)上綁定節(jié)點(diǎn)的端口,而NodePort服務(wù)會(huì)在所有節(jié)點(diǎn)上綁定端口,即使在不運(yùn)行此類Pod的節(jié)點(diǎn)上(如圖13.2中的節(jié)點(diǎn)3上)也會(huì)綁定端口。

重要的是要理解,如果一個(gè)Pod使用特定的hostPort,每個(gè)節(jié)點(diǎn)只能安排一個(gè)該P(yáng)od的實(shí)例,因?yàn)閮蓚€(gè)進(jìn)程不能綁定到同一個(gè)host端口。調(diào)度器在調(diào)度Pod時(shí)會(huì)考慮到這一點(diǎn),因此不會(huì)將多個(gè)Pod調(diào)度到同一節(jié)點(diǎn)上,如圖13.3所示。如果有三個(gè)節(jié)點(diǎn)并想要部署四個(gè)Pod副本,則只會(huì)安排三個(gè)Pod(一個(gè)Pod將保持掛起狀態(tài))。

K8s in Action 閱讀筆記——【13】Securing cluster nodes and the network

讓我們看看如何在Pod的YAML定義中定義hostPort。下面的示例顯示了運(yùn)行的kubia Pod并將其綁定到節(jié)點(diǎn)的端口9000的YAML:

# pod-with-host-network.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-host-network
spec:
  hostNetwork: true
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]

創(chuàng)建此Pod后,可以通過(guò)該P(yáng)od調(diào)度的節(jié)點(diǎn)的9000端口訪問(wèn)它。如果有多個(gè)節(jié)點(diǎn),則會(huì)看到在其他節(jié)點(diǎn)上無(wú)法通過(guò)該端口訪問(wèn)Pod。

$ curl http://yjq-k8s4:9000
You've hit kubia-hostport

hostPort功能主要用于公開(kāi)系統(tǒng)服務(wù),這些服務(wù)使用DaemonSet部署到每個(gè)節(jié)點(diǎn)。

13.1.3 Using the node’s PID and IPC namespaces

hostNetwork選項(xiàng)類似的是hostPIDhostIPC Pod規(guī)范屬性。當(dāng)你將它們?cè)O(shè)置為true時(shí),Pod的容器將使用節(jié)點(diǎn)的PID和IPC名稱空間,分別允許在容器中運(yùn)行的進(jìn)程查看節(jié)點(diǎn)上的所有其他進(jìn)程或通過(guò)IPC與它們通信。參見(jiàn)以下示例。

#  pod-with-host-pid-and-ipc.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-host-pid-and-ipc
spec:
  hostPID: true
  hostIPC: true
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]

你應(yīng)該還記得,Pod通常只能看到它們自己的進(jìn)程,但是如果你運(yùn)行此Pod,然后在容器內(nèi)列出進(jìn)程,你會(huì)看到運(yùn)行在主機(jī)節(jié)點(diǎn)上的所有進(jìn)程,而不僅僅是在容器中運(yùn)行的進(jìn)程,如以下示例所示。

#  kubectl exec pod-with-host-pid-and-ipc --  ps aux | head -10
PID   USER     TIME  COMMAND
    1 root      5h43 {systemd} /sbin/init
    2 root      0:06 [kthreadd]
    3 root      0:00 [rcu_gp]
    4 root      0:00 [rcu_par_gp]
    6 root      0:00 [kworker/0:0H-kb]
    8 root      0:00 [mm_percpu_wq]
    9 root      3:22 [ksoftirqd/0]
   10 root     52:55 [rcu_sched]
   11 root      0:56 [migration/0]

通過(guò)將hostIPC屬性設(shè)置為true,Pod的容器中的進(jìn)程也可以通過(guò)Inter-Process Communication與運(yùn)行在節(jié)點(diǎn)上的所有其他進(jìn)程通信。

13.2 Configuring the container’s security context

除了允許Pod使用主機(jī)的Linux名稱空間之外,還可以通過(guò)securityContext屬性在Pod及其容器上配置其他安全相關(guān)功能,可以直接在Pod規(guī)范下指定,也可以在各個(gè)容器的規(guī)范中指定。

配置安全上下文允許你執(zhí)行各種操作:

  • 指定容器中的進(jìn)程將以哪個(gè)用戶(用戶ID)身份運(yùn)行。
  • 防止容器以root用戶身份運(yùn)行(容器默認(rèn)以容器鏡像中定義的用戶身份運(yùn)行,因此可能希望防止容器以root用戶身份運(yùn)行)。
  • 以特權(quán)模式運(yùn)行容器,使其對(duì)節(jié)點(diǎn)的內(nèi)核具有完全訪問(wèn)權(quán)限。
  • 通過(guò)添加或刪除權(quán)限,配置細(xì)粒度的權(quán)限,與在特權(quán)模式下給予容器所有可能權(quán)限的方式相反。
  • 設(shè)置SELinux(安全增強(qiáng)Linux)選項(xiàng),以對(duì)容器進(jìn)行強(qiáng)制鎖定。
  • 防止進(jìn)程寫入容器的文件系統(tǒng)。

首先,運(yùn)行一個(gè)默認(rèn)的安全上下文選項(xiàng)的Pod(完全不指定它們),這樣你就可以看到與自定義安全上下文的Pod相比它的行為如何:

$ kubectl run pod-with-defaults --image alpine --restart Never -- /bin/sleep 999999
pod/pod-with-defaults created

現(xiàn)在讓我們看看容器運(yùn)行的用戶和組ID,以及它所屬的組。你可以通過(guò)在容器內(nèi)運(yùn)行id命令來(lái)查看:

$ kubectl exec pod-with-defaults -- id
uid=0(root) gid=0(root) groups=0(root), 1(bin), 2(daemon), 3(sys), 4(adm), 6(disk), 10(wheel), 11(floppy),20(dialout),26(tape),27(video)

容器以用戶ID(uid)0,也就是root,和組ID(gid)0(也是root)運(yùn)行。它還是多個(gè)其他組的成員。

容器運(yùn)行的用戶是指定在容器鏡像中的。在一個(gè)Dockerfile中,使用USER指令來(lái)實(shí)現(xiàn)這一點(diǎn)。如果省略了這一指令,則容器以root身份運(yùn)行。

現(xiàn)在,將運(yùn)行一個(gè)容器以不同用戶身份運(yùn)行的Pod。

13.2.1 Running a container as a specific user

要在容器鏡像中內(nèi)嵌的用戶ID不同的情況下運(yùn)行pod,需要設(shè)置pod的securityContext.runAsUser屬性。通過(guò)如下的示例,你可以將容器運(yùn)行為用戶名為guest 的用戶,該用戶在alpine容器鏡像中的用戶ID為405。

# pod-as-user-guest.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-as-user-guest
spec:
  containers:
    - name: main
      image: alpine
      command: ["/bin/sleep", "999999"]
      securityContext:
        runAsUser: 405

現(xiàn)在,為了查看runAsUser屬性的效果,在這個(gè)新的pod中運(yùn)行id命令,就像之前那樣:

$ kubectl exec pod-as-user-guest -- id
uid=405(guest) gid=100(users) groups=100(users)

可以看到,容器正在以guest用戶身份運(yùn)行。

13.2.2 Preventing a container from running as root

假設(shè)你不關(guān)心容器以哪個(gè)用戶身份運(yùn)行,但你仍然希望防止其以root身份運(yùn)行,該怎么辦呢?

假設(shè)你部署了一個(gè)pod,其中包含了一個(gè)使用了Dockerfile中的USER daemon指令的容器鏡像,它使得容器在daemon用戶下運(yùn)行。那如果一個(gè)攻擊者可以訪問(wèn)你的鏡像注冊(cè)表并在相同標(biāo)簽下推送一個(gè)不同的鏡像會(huì)怎么樣呢?攻擊者的鏡像被配置為root用戶下運(yùn)行。當(dāng)Kubernetes調(diào)度了一個(gè)你的pod的新實(shí)例后,Kubelet會(huì)下載攻擊者的鏡像,并運(yùn)行其中的所有代碼。

盡管容器大多數(shù)情況下與主機(jī)系統(tǒng)相互隔離,但以root身份運(yùn)行容器的進(jìn)程仍然被認(rèn)為是一種糟糕的做法。例如,當(dāng)主機(jī)目錄被掛載到容器中時(shí),如果在容器中運(yùn)行的進(jìn)程以root身份運(yùn)行,它將完全訪問(wèn)掛載的目錄,但如果以非root身份運(yùn)行,則不會(huì)。

為了防止前面描述的攻擊場(chǎng)景,你可以指定pod的容器需要以非root身份運(yùn)行,如下所示:

# pod-run-as-non-root.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-run-as-non-root
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      runAsNonRoot: true # 不允許以root身份運(yùn)行

如果你部署這個(gè)pod,它將會(huì)被調(diào)度但不被允許運(yùn)行:

$ kubectl get pod pod-run-as-non-root
NAME                  READY   STATUS                       RESTARTS   AGE
pod-run-as-non-root   0/1     CreateContainerConfigError   0          92s
# Error: container has runAsNonRoot and image will run as root

13.2.3 Running pods in privileged mode

有時(shí)候,pod需要能夠執(zhí)行其所在節(jié)點(diǎn)的所有操作,例如使用受保護(hù)的系統(tǒng)設(shè)備或其他內(nèi)核特性,這是常規(guī)容器無(wú)法訪問(wèn)的。

其中一個(gè)這樣的pod的例子是kube-proxy pod,它需要修改節(jié)點(diǎn)的iptables規(guī)則以使服務(wù)正常工作。

為了完全訪問(wèn)節(jié)點(diǎn)的內(nèi)核,pod的容器運(yùn)行在特權(quán)模式下。這可以通過(guò)將容器的securityContext屬性中的privileged權(quán)限設(shè)置為true來(lái)實(shí)現(xiàn)。你可以使用下面清單中的YAML創(chuàng)建一個(gè)特權(quán)的pod:

# pod-privileged.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-privileged
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      privileged: true

現(xiàn)在,你可以部署這個(gè)pod并與之前運(yùn)行的非特權(quán)pod進(jìn)行比較。

如果你熟悉Linux,你可能知道它有一個(gè)特殊的文件目錄稱為/dev,它包含了系統(tǒng)上所有設(shè)備的設(shè)備文件。這些不是磁盤上的常規(guī)文件,而是用于與設(shè)備通信的特殊文件。現(xiàn)在,我們通過(guò)列出非特權(quán)容器在它的/dev目錄中可見(jiàn)的文件來(lái)查看哪些設(shè)備可見(jiàn),如下:

$ kubectl exec -it pod-with-defaults -- ls /dev
core             null             shm              termination-log
fd               ptmx             stderr           tty
full             pts              stdin            urandom
mqueue           random           stdout           zero

該清單顯示了所有設(shè)備。設(shè)備列表相當(dāng)短?,F(xiàn)在,將其與下面的清單進(jìn)行比較,該清單顯示了特權(quán)pod可以看到的設(shè)備文件:

$ kubectl exec -it pod-privileged --  ls /dev
autofs           snapshot         tty45            ttyS30
bsg              snd              tty46            ttyS31
btrfs-control    sr0              tty47            ttyS4
bus              stderr           tty48            ttyS5
core             stdin            tty49            ttyS6
cpu              stdout           tty5             ttyS7
cpu_dma_latency  termination-log  tty50            ttyS8
cuse             tty              tty51            ttyS9
dri              tty0             tty52            ttyprintk
ecryptfs         tty1             tty53            udmabuf
fb0              tty10            tty54            uhid
fd               tty11            tty55            uinput
full             tty12            tty56            urandom
fuse             tty13            tty57            userio
hidraw0          tty14            tty58            vcs
hpet             tty15            tty59            vcs1
hwrng            tty16            tty6             vcs2
i2c-0            tty17            tty60            vcs3
input            tty18            tty61            vcs4
......

可以看到設(shè)備列表比之前長(zhǎng)得多。事實(shí)上,特權(quán)容器可以看到主機(jī)節(jié)點(diǎn)的所有設(shè)備。這意味著它可以自由地使用任何設(shè)備。

13.2.4 Adding individual kernel capabilities to a container

與讓一個(gè)容器擁有特權(quán)和無(wú)限權(quán)限相比,從安全的角度來(lái)看,更為安全的方法是僅賦予它訪問(wèn)它實(shí)際需要的內(nèi)核功能。Kubernetes允許你為每個(gè)容器添加能力或刪除其中的一部分,這使你可以微調(diào)容器的權(quán)限并限制攻擊者潛在入侵的影響。

例如,通常情況下容器無(wú)法更改系統(tǒng)時(shí)間(硬件時(shí)鐘的時(shí)間)。你可以通過(guò)嘗試在pod-withdefaults pod中設(shè)置時(shí)間來(lái)確認(rèn)這一點(diǎn):

$ kubectl exec -it pod-with-defaults -- date +%T -s "12:00:00"
date: can't set date: Operation not permitted
12:00:00

如果你想允許容器更改系統(tǒng)時(shí)間,可以在容器能力列表中添加一個(gè)稱為CAP_SYS_TIME的能力,如下所示:

# pod-add-settime-capability.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-add-settime-capability
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      capabilities:
        add:
        - SYS_TIME

在這個(gè)新創(chuàng)建的pod的容器中運(yùn)行相同的命令,系統(tǒng)時(shí)間會(huì)被成功更改。

像這樣添加能力要比使用privileged:true給容器賦予完全的特權(quán)要好得多。但是這需要你了解每個(gè)能力的作用。

Linux內(nèi)核能力的列表可以在Linux手冊(cè)中找到。

13.2.5 Dropping capabilities from a container

之前你已經(jīng)了解如何添加能力,但你也可以取消容器的某些可能存在的能力。例如,默認(rèn)賦予容器的能力之一是CAP_CHOWN能力,它允許進(jìn)程更改文件系統(tǒng)中的文件所有權(quán)。

你可以通過(guò)將pod-with-defaults pod中/tmp目錄的所有權(quán)更改為guest用戶來(lái)驗(yàn)證這一點(diǎn),例如:

# pod-drop-chown-capability.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-drop-chown-capability
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      capabilities:
        drop:
        - CHOWN

為了防止容器這樣做,你需要通過(guò)在容器的securityContext.capabilities.drop屬性下列出該能力,如下例所示,來(lái)撤銷該能力:

$ kubectl exec pod-drop-chown-capability -- chown guest /tmp
chown: /tmp: Operation not permitted
command terminated with exit code 1

通過(guò)刪除CHOWN能力,你不允許在此pod中更改/tmp目錄的所有者。

13.2.6 Preventing processes from writing to the container’s filesystem

防止容器向其文件系統(tǒng)中寫入數(shù)據(jù),通過(guò)將容器的securityContext.readOnlyRootFilesystem屬性設(shè)置為true可以實(shí)現(xiàn)點(diǎn),如下例所示:

# pod-with-readonly-filesystem.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-readonly-filesystem
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      readOnlyRootFilesystem: true
    volumeMounts:
    - name: my-volume
      mountPath: /volume
      readOnly: false
  volumes:
  - name: my-volume
    emptyDir:

當(dāng)你部署這個(gè)pod時(shí),容器是作為root用戶運(yùn)行的,具有寫入根目錄的權(quán)限,但嘗試在根目錄中寫入文件會(huì)失敗:

$ kubectl exec -it pod-with-readonly-filesystem -- touch /new-file
touch: /new-file: Read-only file system

另一方面,允許向掛載的卷中寫入數(shù)據(jù):

$ kubectl exec -it pod-with-readonly-filesystem  -- touch /volume/newfile

$ kubectl exec -it pod-with-readonly-filesystem -- ls -la /volume/newfile
-rw-r--r--    1 root     root             0 Jun 10 12:58 /volume/newfile

當(dāng)你將容器文件系統(tǒng)設(shè)置為只讀時(shí),你可能需要在應(yīng)用程序?qū)懭氲拿總€(gè)目錄中都掛載一個(gè)卷(例如,日志、磁盤緩存等)。

為了增強(qiáng)安全性,在生產(chǎn)環(huán)境中運(yùn)行pod時(shí),請(qǐng)將容器的readOnlyRootFilesystem屬性設(shè)置為true。

13.2.7 Sharing volumes when containers run as different users

在第6章中,我們解釋了如何使用卷在pod的容器之間共享數(shù)據(jù)。你可以在一個(gè)容器中寫入文件并在另一個(gè)容器中讀取文件,沒(méi)有任何問(wèn)題。

但這僅僅是因?yàn)閮蓚€(gè)容器都作為root用戶運(yùn)行,它們可以完全訪問(wèn)卷中的所有文件?,F(xiàn)在想象一下使用我們之前解釋過(guò)的runAsUser選項(xiàng)。你可能需要將這兩個(gè)容器作為兩個(gè)不同的用戶運(yùn)行(也許你正在使用兩個(gè)來(lái)自第三方容器鏡像的容器,每個(gè)容器都在自己特定的用戶下運(yùn)行其進(jìn)程)。如果這兩個(gè)容器使用卷來(lái)共享文件,它們可能無(wú)法讀取或?qū)懭氡舜说奈募?/p>

這就是Kubernetes允許你為在容器中運(yùn)行的所有pod指定補(bǔ)充組的原因,使它們可以共享文件,而不受它們運(yùn)行的用戶ID的影響。這可以使用以下兩個(gè)屬性來(lái)完成:fsGroupsupplementalGroups。

讓我們看看如何在一個(gè)pod中使用它們,然后再看看它們的效果如何。下面的示例描述了一個(gè)有兩個(gè)容器共享同一個(gè)卷的pod:

# pod-with-shared-volume-fsgroup.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-shared-volume-fsgroup
spec:
  #  在pod級(jí)別定義
  securityContext:
    fsGroup: 555
    supplementalGroups: [666, 777]
  containers:
  - name: first
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      # 第一個(gè)容器的用戶id
      runAsUser: 1111
    volumeMounts:
    - name: shared-volume
      mountPath: /volume
      readOnly: false
  - name: second
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      # 第二個(gè)容器的用戶id
      runAsUser: 2222
    volumeMounts:
    - name: shared-volume
      mountPath: /volume
      readOnly: false
  # 兩個(gè)容器共享一個(gè)卷
  volumes:
  - name: shared-volume
    emptyDir:

創(chuàng)建這個(gè)pod后,在第一個(gè)容器中運(yùn)行一個(gè)shell,并查看容器運(yùn)行的用戶和組ID:

$ kubectl exec -it pod-with-shared-volume-fsgroup -c first -- sh
/ $ id
uid=1111 gid=0(root) groups=0(root),555,666,777

id命令顯示該容器正在以1111用戶ID運(yùn)行,正如在pod定義中指定的一樣。有效的組ID是0(root),但群組ID 555、666和777也與該用戶相關(guān)聯(lián)。

在pod定義中,你將fsGroup設(shè)置為555。因此,掛載的卷將由組ID為555擁有,如下所示:

ls -l / | grep volume
drwxrwsrwx    2 root     555           4096 Jun 10 13:08 volume

如果你在掛載的卷的目錄中創(chuàng)建一個(gè)文件,該文件的所有者是用戶ID 1111(這是容器正在運(yùn)行的用戶ID)和組ID 555:

/ $ echo foo > /volume/foo
/ $ ls -l /volume
total 4
-rw-r--r--    1 1111     555              4 Jun 10 13:12 foo

這與其他情況下新創(chuàng)建的文件的所有權(quán)設(shè)置不同。通常,當(dāng)一個(gè)用戶創(chuàng)建文件時(shí),使用的是用戶的有效群組ID(在你的情況下為0)。你可以通過(guò)在容器的文件系統(tǒng)中創(chuàng)建文件而不是在卷中來(lái)查看這一點(diǎn):

/ $ echo foo > /tmp/foo
/ $ ls -l /tmp
total 4
-rw-r--r--    1 1111     root             4 Jun 10 13:13 foo

正如你所看到的,當(dāng)進(jìn)程在一個(gè)卷中創(chuàng)建文件時(shí),會(huì)使用fsGroup安全上下文屬性(但這取決于使用的卷插件),而supplementalGroups屬性定義了用戶關(guān)聯(lián)的附加組ID列表。

這就結(jié)束了關(guān)于容器安全上下文配置的部分。接下來(lái),我們將看到集群管理員如何限制用戶這樣做。

13.3 Restricting the use of security-related features in pods

集群管理員可以通過(guò)創(chuàng)建一個(gè)或多個(gè)PodSecurityPolicy資源來(lái)限制先前介紹的與安全相關(guān)的功能的使用。

13.3.1 Introducing the PodSecurityPolicy resource

PodSecurityPolicy是一個(gè)集群級(jí)別的(非namespaced)資源,它定義了用戶可以或不能在他們的pod中使用的安全相關(guān)功能。維護(hù)PodSecurityPolicy資源中配置的策略的工作是由運(yùn)行在API服務(wù)器中的PodSecurityPolicy admission控制插件執(zhí)行的。

PodSecurityPolicy admission控制插件可能沒(méi)有在你的集群中啟用。在運(yùn)行以下示例之前,請(qǐng)確保已啟用該插件。

當(dāng)有人向API服務(wù)器提交一個(gè)pod資源時(shí),PodSecurityPolicy admission控制插件根據(jù)配置的PodSecurityPolicies驗(yàn)證pod定義。如果pod符合集群的策略,它被接受并存儲(chǔ)到etcd中;否則它會(huì)被立即拒絕。插件還可以根據(jù)策略中配置的默認(rèn)值修改pod資源。

13.4 Isolating the pod network

在本章的其余部分,我們將探討如何通過(guò)限制哪些Pod可以連接到哪些Pod來(lái)保護(hù)Pod之間的網(wǎng)絡(luò)

這取決于在群集中使用的容器網(wǎng)絡(luò)插件是否提供了相應(yīng)的配置。如果網(wǎng)絡(luò)插件支持,可以通過(guò)創(chuàng)建NetworkPolicy資源來(lái)配置網(wǎng)絡(luò)隔離。

NetworkPolicy適用于匹配其標(biāo)簽選擇器的Pod,并指定可以訪問(wèn)匹配Pod的源或可從匹配Pod訪問(wèn)的目標(biāo)。這是通過(guò)分別設(shè)置入口規(guī)則和出口規(guī)則來(lái)配置的。兩種類型的規(guī)則都可以匹配滿足Pod選擇器的Pod,滿足Namespace選擇器的所有具有標(biāo)簽的命名空間中的所有Pod,或使用無(wú)類域間路由(CIDR)表示法指定的網(wǎng)絡(luò)IP塊(例如,192.168.1.0/24)。

我們將探討入口和出口規(guī)則以及所有三種匹配選項(xiàng)。

13.4.1 Enabling network isolation in a namespace

默認(rèn)情況下,給定命名空間中的Pod可以被任何人訪問(wèn)。首先,你需要更改此設(shè)置。你將創(chuàng)建一個(gè)名為default-deny NetworkPolicy,這將防止所有客戶端連接到你的命名空間中的任何Pod。NetworkPolicy定義如下:

# network-policy-default-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  # 適用于default命名空間下所有pod
  podSelector:
    

當(dāng)你在某個(gè)命名空間中創(chuàng)建此網(wǎng)絡(luò)策略時(shí),任何人都無(wú)法連接到該命名空間中的任何Pod。

在集群中使用的CNI插件或其他類型的網(wǎng)絡(luò)解決方案必須支持NetworkPolicy,否則對(duì)Pod之間的連接性將沒(méi)有任何影響

13.4.2 Allowing only some pods in the namespace to connect to a server pod

現(xiàn)在,要允許客戶端連接到命名空間中的Pod,你必須明確表明誰(shuí)可以連接到這些Pod,也就是說(shuō),哪些Pod。讓我們通過(guò)一個(gè)例子來(lái)探討如何實(shí)現(xiàn)這一點(diǎn)。

假設(shè)在名為foo的命名空間中有一個(gè)正在運(yùn)行的PostgreSQL數(shù)據(jù)庫(kù)Pod和一個(gè)使用該數(shù)據(jù)庫(kù)的Web服務(wù)器Pod。還有其他Pod也在該命名空間中,你不希望它們連接到數(shù)據(jù)庫(kù)。為了保護(hù)網(wǎng)絡(luò),你需要在與數(shù)據(jù)庫(kù)Pod相同的命名空間中創(chuàng)建以下清單中顯示的NetworkPolicy資源:

# network-policy-postgres.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: postgres-netpolicy
spec:
  podSelector:
    matchLabels:
      app: database
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: webserver
    ports:
    - port: 5432

此示例NetworkPolicy允許具有app=webserver標(biāo)簽的Pod連接到具有app=database標(biāo)簽的Pod,并且只能使用端口5432。其他Pod無(wú)法連接到數(shù)據(jù)庫(kù)Pod,而且除了數(shù)據(jù)庫(kù)Pod的端口5432之外,沒(méi)有人(甚至是Web服務(wù)器Pod)可以連接到其他任何端口。圖13.4顯示了這一點(diǎn)。

K8s in Action 閱讀筆記——【13】Securing cluster nodes and the network

客戶端Pod通常通過(guò)Service與Server Pod連接而不是直接連接到Pod,但這并不會(huì)改變什么。在通過(guò)Service連接時(shí),NetworkPolicy也會(huì)得到執(zhí)行。

13.4.3 Isolating the network between Kubernetes namespaces

現(xiàn)在,讓我們看另一個(gè)例子,在這個(gè)例子中,多個(gè)租戶正在使用同一個(gè)Kubernetes集群。每個(gè)租戶可以使用多個(gè)命名空間,每個(gè)命名空間都有一個(gè)標(biāo)簽指定它所屬的租戶。例如,其中一個(gè)租戶是Manning。他們的所有命名空間都已標(biāo)記為tenant:manning。在他們的某個(gè)命名空間中,他們運(yùn)行一個(gè)購(gòu)物車微服務(wù),需要對(duì)他們?nèi)魏蚊臻g中運(yùn)行的所有Pod都可用。顯然,他們不希望其他租戶訪問(wèn)他們的微服務(wù)。

為了保護(hù)他們的微服務(wù),他們創(chuàng)建以下清單中顯示的NetworkPolicy資源。

# network-policy-cart.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: shoppingcart-netpolicy
spec:
  podSelector:
    matchLabels:
      app: shopping-cart 
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          tenant: manning
    ports:
    - port: 80

該NetworkPolicy確保只有運(yùn)行在標(biāo)記為tenant:manning的命名空間中的Pod可以訪問(wèn)他們的購(gòu)物車微服務(wù),如圖13.5所示。

K8s in Action 閱讀筆記——【13】Securing cluster nodes and the network

如果購(gòu)物車提供商還想向其他租戶(也許是他們的合作伙伴公司之一)提供訪問(wèn)權(quán)限,他們可以創(chuàng)建一個(gè)額外的NetworkPolicy資源或向其現(xiàn)有的NetworkPolicy添加一個(gè)額外的ingress規(guī)則。

在多租戶的Kubernetes集群中,租戶通常不能自己添加標(biāo)簽(或注釋)到他們的命名空間。如果他們這樣做,他們將能夠規(guī)避基于namespaceSelector的ingress規(guī)則。

13.4.4 Isolating using CIDR notation

你可以使用CIDR表示法中的IP塊來(lái)指定哪些可以訪問(wèn)NetworkPolicy中目標(biāo)Pod。與其指定Pod或命名空間選擇器不同。例如,要允許先前部分中的購(gòu)物車Pod僅從192.168.1.1到255范圍內(nèi)的IP訪問(wèn),可以如此指定:

ingress: 
- from: 
	- ipBlock: 
		cidr: 192.168.1.0/24

13.4.5 Limiting the outbound traffic of a set of pods

在所有先前的例子中,你一直使用ingress規(guī)則限制匹配NetworkPolicy的Pod選擇器的入站流量,但你也可以通過(guò)egress規(guī)則限制它們的出站流量。如下所示:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-500711.html

# network-policy-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-net-policy
spec:
  podSelector:
    matchLabels:
      app: webserver
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - port: 5432

到了這里,關(guān)于K8s in Action 閱讀筆記——【13】Securing cluster nodes and the network的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【實(shí)戰(zhàn)】K8S Helm部署Redis Cluster & Redisinsight

    【實(shí)戰(zhàn)】K8S Helm部署Redis Cluster & Redisinsight

    在Web服務(wù)的開(kāi)發(fā)過(guò)程中,Redis一直以來(lái)都有著舉足輕重的作用?;旧纤械暮蠖朔?wù)都會(huì)用這個(gè)中間件實(shí)現(xiàn)具體的業(yè)務(wù)場(chǎng)景,比如常作為系統(tǒng)緩存、分布式鎖,也可以實(shí)現(xiàn)排名、定位以及發(fā)布訂閱隊(duì)列等等。當(dāng)然,在k8s平臺(tái)我們也能夠部署Redis集群,今天就以Helm快速部署R

    2024年02月05日
    瀏覽(40)
  • k8s實(shí)戰(zhàn)案例之部署redis單機(jī)和redis cluster

    k8s實(shí)戰(zhàn)案例之部署redis單機(jī)和redis cluster

    redis是一款基于BSD協(xié)議,開(kāi)源的非關(guān)系型數(shù)據(jù)庫(kù)(nosql數(shù)據(jù)庫(kù)),作者是意大利開(kāi)發(fā)者Salvatore Sanfilippo在2009年發(fā)布,使用C語(yǔ)言編寫;redis是基于內(nèi)存存儲(chǔ),而且是目前比較流行的鍵值數(shù)據(jù)庫(kù)(key-value database),它提供將內(nèi)存通過(guò)網(wǎng)絡(luò)遠(yuǎn)程共享的一種服務(wù),提供類似功能的還有

    2024年02月08日
    瀏覽(21)
  • K8S cluster with multi-masters on Azure VM

    K8S cluster with multi-masters on Azure VM

    在 Azure VM 實(shí)例上部署 KubeSphere 基礎(chǔ)模板 需要修改 IP 地址和 VM Image的可以在模板中修改。 可以修改 master 和 node 的名字前綴、部署區(qū)域、數(shù)量和 VM 類型 ssh 22 對(duì)外由 LB 配置 NAT 端口實(shí)現(xiàn),如配置文件中 50200 → master-0 已經(jīng)包含的規(guī)則轉(zhuǎn)換(不含 30880) 服務(wù) 協(xié)議 規(guī)則 后端端口

    2024年02月11日
    瀏覽(15)
  • k8s-調(diào)度 13

    k8s-調(diào)度 13

    調(diào)度器通過(guò) kubernetes 的 watch 機(jī)制 來(lái)發(fā)現(xiàn)集群中新創(chuàng)建且尚未被調(diào)度到 Node 上的 Pod。調(diào)度器會(huì)將發(fā)現(xiàn)的每一個(gè)未調(diào)度的 Pod 調(diào)度到一個(gè)合適的 Node 上來(lái)運(yùn)行。 kube-scheduler 是 Kubernetes 集群的默認(rèn)調(diào)度器,并且是集群控制面的一部分。 如果你真的希望或者有這方面的需求,kube-

    2024年02月02日
    瀏覽(15)
  • 【k8s】Unable to restart cluster, will reset it: apiserver healthz異常

    問(wèn)題描述 該問(wèn)題在執(zhí)行 minikube start 命令后出現(xiàn)的無(wú)法啟動(dòng)的異常 完整異常描述: 翻譯:無(wú)法重新啟動(dòng)群集,將重置它:apiserver healthz:apiserver進(jìn)程從未出現(xiàn) 問(wèn)題解決辦法 問(wèn)題分析:未構(gòu)建成功服務(wù),并由于存在國(guó)內(nèi)墻的困擾,哪怕指定了阿里云的鏡像庫(kù)依舊失敗,這可能是由

    2023年04月10日
    瀏覽(23)
  • k8s源碼閱讀環(huán)境配置

    k8s源碼閱讀環(huán)境配置

    ? k8s代碼的閱讀可以讓我們更加深刻的理解k8s各組件的工作原理,同時(shí)提升我們Go編程能力。 ? IDE使用Goland,代碼閱讀環(huán)境需要進(jìn)行如下配置: 從github上下載代碼:https://github.com/kubernetes/kubernetes 在GOPATH目錄下新建文件夾:$GOPATH/src/k8s.io/kubernetes 將下載的zip包解壓后,將kub

    2024年01月21日
    瀏覽(22)
  • ConfigMaps in K8s

    ConfigMaps是Kubernetes(K8s)中用于存儲(chǔ)應(yīng)用程序配置信息的一種資源對(duì)象。它將key-value對(duì)存儲(chǔ)為Kubernetes集群中的一個(gè)資源,并可以在Pod中以卷或環(huán)境變量的形式使用。 ConfigMaps的設(shè)計(jì)目的是將應(yīng)用程序配置與應(yīng)用程序本身解耦。它可以存儲(chǔ)應(yīng)用程序所需的任何配置信息,例如數(shù)

    2024年02月09日
    瀏覽(14)
  • CronJob in K8s

    CronJob的設(shè)計(jì)思想是基于Cron工具的,Cron是一種在Unix和類Unix系統(tǒng)中用于自動(dòng)執(zhí)行任務(wù)的工具。CronJob的設(shè)計(jì)思想是將Cron的功能引入到Kubernetes中,以便在集群中自動(dòng)化和調(diào)度任務(wù)的執(zhí)行。 CronJob的設(shè)計(jì)思想包括以下幾個(gè)方面: 基于時(shí)間的調(diào)度:CronJob根據(jù)時(shí)間表來(lái)周期性地調(diào)度任

    2024年02月09日
    瀏覽(19)
  • ClusterIP in K8s

    ClusterIP is a type of Service in Kubernetes that is designed to provide internal network connectivity to a group of pods. The main purpose of ClusterIP is to create a stable, virtual IP address that represents a set of pods and allows other components within the cluster to access them. ClusterIP works by creating a virtual IP address for the Service, which

    2024年02月11日
    瀏覽(17)
  • StatefulSets In K8s

    StatefulSets是Kubernetes的一種資源對(duì)象,用于管理有狀態(tài)應(yīng)用程序的部署。與Deployment不同,StatefulSets保證應(yīng)用程序的有序部署和有狀態(tài)的維護(hù),確保每個(gè)Pod都有唯一的標(biāo)識(shí)和穩(wěn)定的網(wǎng)絡(luò)標(biāo)識(shí)。這些特性使得StatefulSets非常適合部署需要穩(wěn)定標(biāo)識(shí)和有序存儲(chǔ)的應(yīng)用程序,如數(shù)據(jù)庫(kù)服

    2024年02月09日
    瀏覽(13)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包