经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Kubernetes » 查看文章
在kubernetes里使用seccomp限制容器的系统调用
来源:cnblogs  作者:人生的哲理  时间:2024/5/31 9:23:31  对本文有异议

一.系统环境

本文主要基于Kubernetes1.22.2和Linux操作系统Ubuntu 18.04。

服务器版本 docker软件版本 Kubernetes(k8s)集群版本 CPU架构
Ubuntu 18.04.5 LTS Docker version 20.10.14 v1.22.2 x86_64

Kubernetes集群架构:k8scludes1作为master节点,k8scludes2,k8scludes3作为worker节点。

服务器 操作系统版本 CPU架构 进程 功能描述
k8scludes1/192.168.110.128 Ubuntu 18.04.5 LTS x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master节点
k8scludes2/192.168.110.129 Ubuntu 18.04.5 LTS x86_64 docker,kubelet,kube-proxy,calico k8s worker节点
k8scludes3/192.168.110.130 Ubuntu 18.04.5 LTS x86_64 docker,kubelet,kube-proxy,calico k8s worker节点

二.前言

随着容器化技术的普及,应用程序的部署和运行变得越来越便捷。然而,容器的安全性也成为了一个日益重要的问题。在Kubernetes中,Seccomp(Secure Computing Mode)提供了一种强大的机制来限制容器可以执行的系统调用,从而提高系统的安全性。

使用seccomp限制容器的系统调用的前提是已经有一套可以正常运行的Kubernetes集群,关于Kubernetes(k8s)集群的安装部署,可以查看博客《Ubuntu 安装部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/17632858.html。

三.系统调用简介

系统调用是应用程序请求操作系统提供服务的一种方式。攻击者可能会利用应用程序的系统调用权限执行恶意操作,例如创建新的进程、访问敏感文件等。通过限制容器可以使用的系统调用,我们可以降低攻击者的利用面,提高系统的安全性。

Seccomp 代表安全计算(Secure Computing)模式,自 2.6.12 版本以来,一直是 Linux 内核的一个特性。 它可以用来沙箱化进程的权限,限制进程从用户态到内核态的调用。 Kubernetes 能使你自动将加载到节点上的 seccomp 配置文件应用到你的 Pod 和容器。

四.使用seccomp限制docker容器系统调用

创建目录存放文件。

  1. root@k8scludes1:~# mkdir systemsafe
  2. root@k8scludes1:~# cd systemsafe/

当我们执行一个命令的时候,会存在各种系统调用syscall,strace 跟踪程式执行时的系统调用和所接收的信号,strace是追踪工具,执行strace -fqc cat /etc/hosts 可以查看执行cat /etc/hosts 的时候执行了哪些系统调用。

  1. root@k8scludes1:~/systemsafe# strace -fqc cat /etc/hosts
  2. 127.0.0.1 localhost
  3. 127.0.1.1 tom
  4. 192.168.110.128 k8scludes1
  5. 192.168.110.129 k8scludes2
  6. 192.168.110.130 k8scludes3
  7. # The following lines are desirable for IPv6 capable hosts
  8. ::1 localhost ip6-localhost ip6-loopback
  9. ff02::1 ip6-allnodes
  10. ff02::2 ip6-allrouters
  11. % time seconds usecs/call calls errors syscall
  12. ------ ----------- ----------- --------- --------- ----------------
  13. 34.67 0.000095 14 7 mmap
  14. 14.23 0.000039 10 4 mprotect
  15. 13.14 0.000036 9 4 openat
  16. 10.22 0.000028 14 2 munmap
  17. 6.57 0.000018 6 3 read
  18. 5.11 0.000014 14 1 write
  19. 4.74 0.000013 2 6 close
  20. 4.38 0.000012 2 5 fstat
  21. 3.65 0.000010 3 3 3 access
  22. 2.19 0.000006 2 3 brk
  23. 0.73 0.000002 2 1 fadvise64
  24. 0.36 0.000001 1 1 arch_prctl
  25. 0.00 0.000000 0 1 execve
  26. ------ ----------- ----------- --------- --------- ----------------
  27. 100.00 0.000274 41 3 total

查看执行ping www.baidu.com的时候执行了哪些系统调用。

  1. root@k8scludes1:~/systemsafe# strace -fqc ping www.baidu.com
  2. PING www.a.shifen.com (14.215.177.38) 56(84) bytes of data.
  3. 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=6 ttl=128 time=53.4 ms
  4. 64 bytes from 14.215.177.38 (14.215.177.38): icmp_seq=7 ttl=128 time=31.8 ms
  5. ^C% time seconds usecs/call calls errors syscall
  6. ------ ----------- ----------- --------- --------- ----------------
  7. 11.70 0.001336 167 8 write
  8. 8.91 0.001018 54 19 read
  9. 8.54 0.000976 108 9 sendto
  10. 7.52 0.000859 86 10 recvmsg
  11. 7.41 0.000847 61 14 1 poll
  12. ......
  13. 0.27 0.000031 31 1 uname
  14. 0.27 0.000031 31 1 geteuid
  15. 0.25 0.000028 28 1 rt_sigprocmask
  16. 0.04 0.000005 5 1 arch_prctl
  17. 0.04 0.000004 4 1 setuid
  18. 0.00 0.000000 0 1 execve
  19. ------ ----------- ----------- --------- --------- ----------------
  20. 100.00 0.011423 242 14 total
  21. --- www.a.shifen.com ping statistics ---
  22. 7 packets transmitted, 7 received, 0% packet loss, time 6009ms
  23. rtt min/avg/max/mdev = 31.827/296.919/767.191/313.549 ms

我们可以禁用某个系统调用,比如把read系统调用给禁了,则和read相关的操作都没法执行。

宿主机的操作系统并没有限制系统调用, 如果能执行所有的系统调用,则容器里可以执行所有的操作。

设置容器可以使用哪些系统调用,哪些不能用,可以使用profile文件控制,默认的profile禁用了44个系统调用(总共300多个系统调用),默认的profile可以去https://github.com/moby/moby/blob/master/profiles/seccomp/default.json 查看。

注意:创建seccomp profile配置文件很麻烦,并且很大程度上是基于反复试验,反复测试你需要禁止的系统调用和允许的系统调用。

下载默认的profile文件。

  1. root@k8scludes1:~/systemsafe# wget https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.json
  2. #上面那个网址下载不了的话,使用如下网址
  3. root@k8scludes1:~/systemsafe# wget https://github.com/moby/moby/blob/master/profiles/seccomp/default.json

下载nginx镜像。

  1. root@k8scludes1:~/systemsafe# docker pull nginx
  2. root@k8scludes1:~/systemsafe# docker images | grep nginx
  3. nginx latest 605c77e624dd 4 months ago 141MB

使用docker创建一个nginx容器,关于docker容器的详细操作,请查看博客《一文搞懂docker容器基础:docker镜像管理,docker容器管理》。

  1. root@k8scludes1:~/systemsafe# docker run -dit --name=nginxweb --restart=always nginx
  2. b92aeecb455216a42fdaf9be475ae2fdef197b8d7bfde31407d7acc5d3dd96c4

创建docker 容器的时候没有指定使用哪个seccomp profile,则默认使用默认的seccomp profile。

  1. root@k8scludes1:~/systemsafe# docker ps | grep nginxweb
  2. b92aeecb4552 nginx "/docker-entrypoint.…" 15 seconds ago Up 14 seconds 80/tcp nginxweb

删除docker容器。

  1. root@k8scludes1:~/systemsafe# docker rm -f nginxweb
  2. nginxweb

默认的profile可以去https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.json 或者https://github.com/moby/moby/blob/master/profiles/seccomp/default.json查看。

--security-opt seccomp可以指定docker容器使用哪个seccomp profile文件,nginxweb容器使用刚才下载的default.json作为seccomp profile文件。

  1. root@k8scludes1:~/systemsafe# docker run -dit --name=nginxweb --restart=always --security-opt seccomp=./default.json nginx
  2. 29e9718746acffaa2ce0d435f4f8951773d3df6d18c3bc04035479f1b9a4ef37

nginx容器正常运行,因为都是允许了默认的系统调用(其中44个syscall是不被允许的)。

  1. root@k8scludes1:~/systemsafe# docker ps | grep nginxweb
  2. 29e9718746ac nginx "/docker-entrypoint.…" 13 seconds ago Up 11 seconds 80/tcp nginxweb

删除docker容器。

  1. root@k8scludes1:~/systemsafe# docker rm -f nginxweb
  2. nginxweb

创建允许所有系统调用的seccomp配置文件,"defaultAction": "SCMP_ACT_ALLOW" 允许所有的系统调用。

系统调用的Action有如下:

  • SCMP_ACT_KILL:当一个进程进行相应的系统调用时,内核发送一个SIGSYS信号终止该进程,进程不会收到这个信号
  • SCMP_ACT_TRAP:当一个进程进行相应的系统调用时,该进程会收到SIGSYS信号并改变其行为
  • SCMP_ACT_ERRNO:当进程进行相应的系统调用时,系统调用失败,进程会收到errno的返回值
  • SCMP_ACT_TRACE:当一个进程进行相应的系统调用时,该进程将被跟踪
  • SCMP_ACT_ALLOW:允许进程执行相应的系统调用行为
  • SCMP_ACT_LOG:记录所有信息
  1. root@k8scludes1:~/systemsafe# cat allowall.json
  2. {
  3. "defaultAction": "SCMP_ACT_ALLOW"
  4. }

创建禁止所有系统调用的seccomp配置文件,"defaultAction": "SCMP_ACT_ERRNO" 禁止所有系统调用。

  1. root@k8scludes1:~/systemsafe# vim denyall.json
  2. root@k8scludes1:~/systemsafe# cat denyall.json
  3. {
  4. "defaultAction": "SCMP_ACT_ERRNO"
  5. }

创建允许所有系统调用的容器nginxweballow,现在nginxweballow这个容器可以使用所有的系统调用,权限过高,有安全隐患。

注意 --security-opt seccomp=./allowall.json 等价于 --security-opt seccomp:unconfined 。

  1. root@k8scludes1:~/systemsafe# docker run -dit --name=nginxweballow --restart=always --security-opt seccomp=./allowall.json nginx
  2. 1f12060e25a9724c755106b731bf727c4ee0b01a83b9c5c9e179e12198eac954
  3. root@k8scludes1:~/systemsafe# docker ps | grep nginxweballow
  4. 1f12060e25a9 nginx "/docker-entrypoint.…" 12 seconds ago Up 11 seconds 80/tcp nginxweballow

删除nginxweballow。

  1. root@k8scludes1:~/systemsafe# docker rm -f nginxweballow
  2. nginxweballow

创建禁止所有系统调用的容器nginxwebdeny,任何的系统调用都不被允许,容器nginxwebdeny 创建失败。

  1. root@k8scludes1:~/systemsafe# docker run -dit --name=nginxwebdeny --restart=always --security-opt seccomp=./denyall.json nginx
  2. 9154203049da171f3c5d7ae93a1b9be486ca0783b6ea9373dcb8544df1d84ff6
  3. docker: Error response from daemon: cannot start a stopped process: unknown.

查看nginx镜像的历史信息,可以发现,nginx容器需要执行"nginx" "-g" "daemon“守护进程,任何的系统调用都被禁止,nginx进程也启动不了,所以创建容器失败。

  1. root@k8scludes1:~/systemsafe# docker history nginx
  2. IMAGE CREATED CREATED BY SIZE COMMENT
  3. 605c77e624dd 4 months ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
  4. <missing> 4 months ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
  5. <missing> 4 months ago /bin/sh -c #(nop) EXPOSE 80 0B
  6. <missing> 4 months ago /bin/sh -c #(nop) ENTRYPOINT ["/docker-entr… 0B
  7. <missing> 4 months ago /bin/sh -c #(nop) COPY file:09a214a3e07c919a… 4.61kB
  8. <missing> 4 months ago /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7… 1.04kB
  9. <missing> 4 months ago /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0… 1.96kB
  10. <missing> 4 months ago /bin/sh -c #(nop) COPY file:65504f71f5855ca0… 1.2kB
  11. <missing> 4 months ago /bin/sh -c set -x && addgroup --system -… 61.1MB
  12. <missing> 4 months ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~bullseye 0B
  13. <missing> 4 months ago /bin/sh -c #(nop) ENV NJS_VERSION=0.7.1 0B
  14. <missing> 4 months ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.21.5 0B
  15. <missing> 4 months ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
  16. <missing> 4 months ago /bin/sh -c #(nop) CMD ["bash"] 0B
  17. <missing> 4 months ago /bin/sh -c #(nop) ADD file:09675d11695f65c55… 80.4MB

五.在kubernetes里使用seccomp限制容器的系统调用

5.1 配置seccomp允许pod进行所有系统调用

在kubernetes集群里,seccomp的配置文件默认放在/var/lib/kubelet/seccomp/目录下。

  1. root@k8scludes1:~/systemsafe# mkdir -p /var/lib/kubelet/seccomp/profiles
  2. root@k8scludes1:~/systemsafe# cd /var/lib/kubelet/seccomp/profiles

创建允许所有系统调用的seccomp配置文件。

  1. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# vim allowall_syscall
  2. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# cat allowall_syscall
  3. {
  4. "defaultAction": "SCMP_ACT_ALLOW"
  5. }

创建禁止所有系统调用的seccomp配置文件。

  1. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# vim denyall_syscall
  2. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# cat denyall_syscall
  3. {
  4. "defaultAction": "SCMP_ACT_ERRNO"
  5. }

系统调用的Action有如下:

  • SCMP_ACT_KILL:当一个进程进行相应的系统调用时,内核发送一个SIGSYS信号终止该进程,进程不会收到这个信号
  • SCMP_ACT_TRAP:当一个进程进行相应的系统调用时,该进程会收到SIGSYS信号并改变其行为
  • SCMP_ACT_ERRNO:当进程进行相应的系统调用时,系统调用失败,进程会收到errno的返回值
  • SCMP_ACT_TRACE:当一个进程进行相应的系统调用时,该进程将被跟踪
  • SCMP_ACT_ALLOW:允许进程执行相应的系统调用行为
  • SCMP_ACT_LOG:记录所有信息

创建允许50个系统调用的seccomp配置文件,"defaultAction": "SCMP_ACT_ERRNO"表示默认的规则是禁止,syscalls里面的系统调用才是允许的。

  1. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# vim fine-grained_syscall
  2. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# cat fine-grained_syscall
  3. {
  4. "defaultAction": "SCMP_ACT_ERRNO",
  5. "architectures": [
  6. "SCMP_ARCH_X86_64",
  7. "SCMP_ARCH_X86",
  8. "SCMP_ARCH_X32"
  9. ],
  10. "syscalls": [
  11. {
  12. "names": [
  13. "accept4",
  14. "epoll_wait",
  15. "pselect6",
  16. "futex",
  17. "madvise",
  18. "epoll_ctl",
  19. "getsockname",
  20. "setsockopt",
  21. "vfork",
  22. "mmap",
  23. "read",
  24. "write",
  25. "close",
  26. "arch_prctl",
  27. "sched_getaffinity",
  28. "munmap",
  29. "brk",
  30. "rt_sigaction",
  31. "rt_sigprocmask",
  32. "sigaltstack",
  33. "gettid",
  34. "clone",
  35. "bind",
  36. "socket",
  37. "openat",
  38. "readlinkat",
  39. "exit_group",
  40. "epoll_create1",
  41. "listen",
  42. "rt_sigreturn",
  43. "sched_yield",
  44. "clock_gettime",
  45. "connect",
  46. "dup2",
  47. "epoll_pwait",
  48. "execve",
  49. "exit",
  50. "fcntl",
  51. "getpid",
  52. "getuid",
  53. "ioctl",
  54. "mprotect",
  55. "nanosleep",
  56. "open",
  57. "poll",
  58. "recvfrom",
  59. "sendto",
  60. "set_tid_address",
  61. "setitimer",
  62. "writev"
  63. ],
  64. "action": "SCMP_ACT_ALLOW"
  65. }
  66. ]
  67. }

现在有三个不同的seccomp配置文件。

  1. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# ls
  2. allowall_syscall denyall_syscall fine-grained_syscall

查看node节点的标签。

  1. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# kubectl get nodes --show-labels
  2. NAME STATUS ROLES AGE VERSION LABELS
  3. k8scludes1 Ready control-plane,master 30d v1.22.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8scludes1,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
  4. k8scludes2 Ready <none> 30d v1.22.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8scludes2,kubernetes.io/os=linux
  5. k8scludes3 Ready <none> 30d v1.22.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8scludes3,kubernetes.io/os=linux

给k8scludes3节点设置一个标签yy=xx。

  1. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# kubectl label nodes k8scludes3 yy=xx

查看标签为yy=xx的节点,此次创建pod要运行在k8scludes3节点上。

  1. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# kubectl get node -l yy=xx
  2. NAME STATUS ROLES AGE VERSION
  3. k8scludes3 Ready <none> 30d v1.22.2

在k8scludes3节点上拉取镜像hashicorp/http-echo:0.2.3。

  1. root@k8scludes3:~# docker pull hashicorp/http-echo:0.2.3
  2. 0.2.3: Pulling from hashicorp/http-echo
  3. 86399148984b: Pull complete
  4. Digest: sha256:ba27d460cd1f22a1a4331bdf74f4fccbc025552357e8a3249c40ae216275de96
  5. Status: Downloaded newer image for hashicorp/http-echo:0.2.3
  6. docker.io/hashicorp/http-echo:0.2.3

编辑pod配置文件,在k8scludes3节点上创建pod。

localhostProfile: profiles/allowall_syscall 指定pod使用allowall_syscall这个seccomp配置文件。

使用的镜像为hashicorp/http-echo:0.2.3,需要提前在k8scludes3节点上拉取该镜像。

如果allowall_syscall文件在/var/lib/kubelet/seccomp/profiles目录下,则写为profiles/allowall_syscall,如果allowall_syscall文件在/var/lib/kubelet/seccomp/目录下,则写为allowall_syscall。

  1. root@k8scludes1:/var/lib/kubelet/seccomp/profiles# cd ~/systemsafe/
  2. root@k8scludes1:~/systemsafe# vim pod2.yaml
  3. root@k8scludes1:~/systemsafe# cat pod2.yaml
  4. apiVersion: v1
  5. kind: Pod
  6. metadata:
  7. name: audit-pod
  8. labels:
  9. app: audit-pod
  10. spec:
  11. securityContext:
  12. seccompProfile:
  13. type: Localhost
  14. localhostProfile: profiles/allowall_syscall
  15. #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
  16. terminationGracePeriodSeconds: 0
  17. #nodeSelector:yy: xx 表示pod运行在标签为yy=xx的节点上
  18. nodeSelector:
  19. yy: xx
  20. containers:
  21. - name: test-container
  22. image: hashicorp/http-echo:0.2.3
  23. #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
  24. imagePullPolicy: IfNotPresent
  25. args:
  26. - "-text=just made some syscalls!"
  27. securityContext:
  28. allowPrivilegeEscalation: false

创建pod。

  1. root@k8scludes1:~/systemsafe# kubectl apply -f pod2.yaml
  2. pod/audit-pod created

pod创建失败。

  1. root@k8scludes1:~/systemsafe# kubectl get pod -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. audit-pod 0/1 CreateContainerError 0 10s 10.244.218.138 k8scludes2 <none> <none>

查看日志。

  1. root@k8scludes1:~/systemsafe# kubectl logs audit-pod
  2. Error from server (BadRequest): container "test-container" in pod "audit-pod" is waiting to start: CreateContainerError

查看pod的描述信息,最后一行表名找不到/var/lib/kubelet/seccomp/allowall_syscall文件,看来需要把seccomp配置文件放到k8scludes3节点的/var/lib/kubelet/seccomp/目录下。

  1. root@k8scludes1:~/systemsafe# kubectl describe pod audit-pod
  2. Name: podtest
  3. Namespace: systemsafe
  4. Priority: 0
  5. Node: k8scludes2/192.168.110.129
  6. ......
  7. Events:
  8. Type Reason Age From Message
  9. ---- ------ ---- ---- -------
  10. Normal Scheduled 83s default-scheduler Successfully assigned systemsafe/podtest to k8scludes2
  11. Normal SandboxChanged 80s kubelet Pod sandbox changed, it will be killed and re-created.
  12. Normal Pulled 0s (x10 over 81s) kubelet Container image "hashicorp/http-echo:0.2.3" already present on machine
  13. Warning Failed 0s (x10 over 81s) kubelet Error: failed to generate security options for container "test-container": failed to generate seccomp security options for container: cannot load seccomp profile "/var/lib/kubelet/seccomp/allowall_syscall": open /var/lib/kubelet/seccomp/allowall_syscall: no such file or directory

删除pod。

  1. root@k8scludes1:~/systemsafe# kubectl delete pod audit-pod
  2. pod "audit-pod" deleted
  3. root@k8scludes1:~/systemsafe# kubectl get pod
  4. No resources found in systemsafe namespace.

在k8scludes3节点创建seccomp配置文件目录/var/lib/kubelet/seccomp/profiles。

  1. root@k8scludes3:~# mkdir -p /var/lib/kubelet/seccomp/profiles
  2. root@k8scludes3:~# cd /var/lib/kubelet/seccomp/profiles
  3. root@k8scludes3:/var/lib/kubelet/seccomp/profiles# pwd
  4. /var/lib/kubelet/seccomp/profiles

还是创建这三个文件。

  1. root@k8scludes3:/var/lib/kubelet/seccomp/profiles# ls
  2. allowall_syscall denyall_syscall fine-grained_syscall

再次创建audit-pod。

  1. root@k8scludes1:~/systemsafe# kubectl apply -f pod2.yaml
  2. pod/audit-pod created

这次pod创建成功。

  1. root@k8scludes1:~/systemsafe# kubectl get pod -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. audit-pod 1/1 Running 0 14s 10.244.1.100 k8scludes3 <none> <none>

创建一个服务,服务类型为NodePort,服务端口为5678,关于服务service的详细操作,请查看博客《Kubernetes(k8s)服务service:service的发现和service的发布》。

  1. root@k8scludes1:~/systemsafe# kubectl expose pod audit-pod --type NodePort --port 5678
  2. service/audit-pod exposed

查看服务,5678端口映射为31163端口。

  1. root@k8scludes1:~/systemsafe# kubectl get svc -o wide
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
  3. audit-pod NodePort 10.107.213.89 <none> 5678:31163/TCP 9s app=audit-pod

访问svc ,访问方式为:物理机IP:端口。

  1. #访问成功
  2. root@k8scludes1:~/systemsafe# curl 192.168.110.128:31163
  3. just made some syscalls!

删除pod。

  1. root@k8scludes1:~/systemsafe# kubectl delete pod audit-pod
  2. pod "audit-pod" deleted
  3. root@k8scludes1:~/systemsafe# kubectl get pod
  4. No resources found in systemsafe namespace.

5.2 配置seccomp禁止pod进行所有系统调用

编辑pod配置文件,在k8scludes3节点上创建pod,这次pod使用denyall_syscall文件。

localhostProfile: profiles/denyall_syscall指定pod使用denyall_syscall这个seccomp配置文件。

  1. root@k8scludes1:~/systemsafe# vim pod2.yaml
  2. root@k8scludes1:~/systemsafe# cat pod2.yaml
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: audit-pod
  7. labels:
  8. app: audit-pod
  9. spec:
  10. securityContext:
  11. seccompProfile:
  12. type: Localhost
  13. localhostProfile: profiles/denyall_syscall
  14. #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
  15. terminationGracePeriodSeconds: 0
  16. #nodeSelector:yy: xx 表示pod运行在标签为yy=xx的节点上
  17. nodeSelector:
  18. yy: xx
  19. containers:
  20. - name: test-container
  21. image: hashicorp/http-echo:0.2.3
  22. #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
  23. imagePullPolicy: IfNotPresent
  24. args:
  25. - "-text=just made some syscalls!"
  26. securityContext:
  27. allowPrivilegeEscalation: false

创建pod。

  1. root@k8scludes1:~/systemsafe# kubectl apply -f pod2.yaml
  2. pod/audit-pod created

pod创建失败。

  1. root@k8scludes1:~/systemsafe# kubectl get pod -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. audit-pod 0/1 CrashLoopBackOff 1 (5s ago) 7s 10.244.1.115 k8scludes3 <none> <none>

查看pod日志,因为禁止了所有系统调用,连日志都没有,pod也运行不起来。

  1. root@k8scludes1:~/systemsafe# kubectl logs audit-pod
  2. root@k8scludes1:~/systemsafe# kubectl get pod
  3. NAME READY STATUS RESTARTS AGE
  4. audit-pod 0/1 CrashLoopBackOff 5 (69s ago) 3m59s

删除pod。

  1. root@k8scludes1:~/systemsafe# kubectl delete pod audit-pod
  2. pod "audit-pod" deleted
  3. root@k8scludes1:~/systemsafe# kubectl get pod
  4. No resources found in systemsafe namespace.

5.3 配置seccomp允许pod进行50个系统调用

编辑pod配置文件,在k8scludes3节点上创建pod,这次pod使用fine-grained_syscall文件。

localhostProfile: profiles/fine-grained_syscall指定pod使用fine-grained_syscall这个seccomp配置文件。

fine-grained_syscall这个配置文件允许50个系统调用。

创建pod。

  1. root@k8scludes1:~/systemsafe# vim pod2.yaml
  2. #这次使用fine-grained_syscall文件
  3. root@k8scludes1:~/systemsafe# grep localhostProfile pod2.yaml
  4. localhostProfile: profiles/fine-grained_syscall
  5. root@k8scludes1:~/systemsafe# kubectl apply -f pod2.yaml
  6. pod/audit-pod created

pod创建成功。

  1. root@k8scludes1:~/systemsafe# kubectl get pod -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. audit-pod 1/1 Running 0 6s 10.244.1.107 k8scludes3 <none> <none>

访问svc服务。

  1. root@k8scludes1:~/systemsafe# kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. audit-pod NodePort 10.107.213.89 <none> 5678:31163/TCP 16m
  4. root@k8scludes1:~/systemsafe# curl 192.168.110.128:31163
  5. just made some syscalls!

查看日志。

  1. root@k8scludes1:~/systemsafe# kubectl logs audit-pod
  2. 2022/05/16 10:43:31 Server is listening on :5678
  3. 2022/05/16 10:44:17 192.168.110.128:31163 10.244.9.0:13880 "GET / HTTP/1.1" 200 25 "curl/7.58.0" 36.059μs
  4. root@k8scludes1:~/systemsafe# tail -10f /var/log/syslog | grep 'http-echo'
  5. ^C

删除pod。

  1. root@k8scludes1:~/systemsafe# kubectl delete pod audit-pod
  2. pod "audit-pod" deleted

六.总结

通过使用Seccomp限制容器的系统调用,我们可以显著提高容器的安全性。在这篇博客中,我们学习了如何在Kubernetes环境中应用Seccomp来限制容器的系统调用。通过设置Seccomp配置文件并在Docker容器和Kubernetes Pod中应用该配置,我们可以有效地限制容器的权限,从而保护宿主机的安全。

原文链接:https://www.cnblogs.com/renshengdezheli/p/18222624

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号