一.系统环境

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

服务器版本 docker软件版本 Kubernetes(k8s)集群版本 kube-bench版本 CPU架构
Ubuntu 18.04.5 LTS Docker version 20.10.14 v1.22.2 0.6.7 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节点

二.前言

在现代的云计算环境中,安全是每个开发者和运维人员必须关注的问题。尤其是在运行容器的环境中,如何确保容器之间以及容器与宿主机之间的安全隔离,防止恶意行为对系统造成破坏,是一个非常重要的课题。本文将介绍如何使用 AppArmor 来限制容器对资源的访问,提高系统的安全性。

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

三.AppArmor简介

AppArmor 是一种 Linux 内核模块,用于提供强制访问控制(MAC)功能。它允许管理员为每个进程定义详细的访问控制策略,从而限制进程对文件、目录、网络接口等资源的访问。通过使用 AppArmor,我们可以有效地防止恶意软件或错误配置的应用程序对系统资源造成不必要的影响。

AppArmor 的规则文件通常位于 /etc/apparmor.d/ 目录下。每个规则文件对应一个应用或服务,文件名通常以路径开头,后面跟着应用的名称。例如,对于 Nginx 服务器,其规则文件名为 /etc/apparmor.d/usr.sbin.nginx

AppArmor 规则由一系列的匹配语句组成,每条语句表示一个访问控制规则。规则的基本结构如下:

<profile> <options> <match> <permissions> <files> <paths> <commands> </profile>

其中:

  • <profile>:指定规则所属的 profile,可以是预定义的 profile(如 usr.sbin.nginx),也可以是自定义的 profile。
  • <options>:可选字段,用于指定 profile 的行为选项,如是否启用日志记录等。
  • <match>:必选字段,用于指定规则适用的条件,如进程名称、用户等。
  • <permissions>:必选字段,用于指定允许或拒绝的操作类型,如读、写、执行等。
  • <files>:可选字段,用于指定规则适用的文件类型,如普通文件、目录、设备文件等。
  • <paths>:可选字段,用于指定规则适用的文件路径模式。
  • <commands>:可选字段,用于指定规则适用的命令名称。

四.AppArmor和SELinux的区别

虽然 AppArmor 和 SELinux 都是 Linux 上的访问控制工具,但它们之间存在一些区别:

  • 设计理念:AppArmor 的设计目标是简单易用,而 SELinux 则更注重细粒度的控制。因此,AppArmor 的策略配置文件通常比 SELinux 更简洁。
  • 配置方式:AppArmor 的策略配置文件采用一种类似于 DSL(领域特定语言)的语法,易于阅读和编写;而 SELinux 的策略配置文件则采用一种更复杂的布尔表达式语法。
  • 社区支持:由于 AppArmor 的配置相对简单,因此在社区中得到了更广泛的支持和应用。

五.使用AppArmor限制nginx程序访问目录

5.1 安装nginx

创建目录存放文件。

root@k8scludes1:~# mkdir systemsafe   

root@k8scludes1:~# cd systemsafe/

安装nginx。

root@k8scludes1:~/systemsafe# apt-get install nginx

root@k8scludes1:~/systemsafe# which nginx
/usr/sbin/nginx

nginx安装好之后就可以访问nginx了。

root@k8scludes1:~/systemsafe# curl 192.168.110.128
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
......
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p>
</body>
</html>

5.2 修改nginx的默认主页

创建一个safe目录和一个unsafe目录。

root@k8scludes1:~/systemsafe# mkdir -p /data/www/safe /data/www/unsafe

在safe目录写入index.html。

root@k8scludes1:~/systemsafe# vim /data/www/safe/index.html

root@k8scludes1:~/systemsafe# cat /data/www/safe/index.html
<html>
<b>Hello! Accessing this file is allowed.</b>
</html>

在unsafe目录写入index.html。

root@k8scludes1:~/systemsafe# vim /data/www/unsafe/index.html

root@k8scludes1:~/systemsafe# cat /data/www/unsafe/index.html
<html>
<b>Hello! Accessing this file is forbidden.</b>
</html>

修改nginx配置文件,修改nginx的默认主页目录为/data/www。

root@k8scludes1:~/systemsafe# vim /etc/nginx/nginx.conf 

root@k8scludes1:~/systemsafe# grep -A10 sites-enabled /etc/nginx/nginx.conf
#include /etc/nginx/sites-enabled/*; server {
listen 8080;
location / {
#root /data/www; 改变nginx的默认主页
root /data/www;
}
}
}

重启nginx。

root@k8scludes1:~/systemsafe# systemctl restart nginx

访问nginx目录,现在safe和unsafe都可以访问。

root@k8scludes1:~/systemsafe# curl 192.168.110.128:8080/safe/
<html>
<b>Hello! Accessing this file is allowed.</b>
</html> root@k8scludes1:~/systemsafe# curl 192.168.110.128:8080/unsafe/
<html>
<b>Hello! Accessing this file is forbidden.</b>
</html>

我们需要配置AppArmor,使nginx可以访问/data/www/safe/目录,不可以访问/data/www/unsafe/目录,保护敏感数据。

5.3 安装AppArmor实用工具

查看系统有没有安装AppArmor。

root@k8scludes1:~/systemsafe# dpkg -l | grep apparmor
ii apparmor 2.12-4ubuntu5.1 amd64 user-space parser utility for AppArmor
ii libapparmor1:amd64 2.12-4ubuntu5.1 amd64 changehat AppArmor library

更新软件源。

root@k8scludes1:~/systemsafe# apt-get update

安装apparmor-utils ,apparmor-profiles, apparmor-profiles-extra。

apparmor-utils 是一组用户空间的命令行实用工具,可以帮助我们很好的管理 AppArmor 。

apparmor-profiles, apparmor-profiles-extra是一些预先配置的配置文件,这些配置文件一般来说是比较完善的,但是也需要根据实际需要进行修改。

root@k8scludes1:~# apt-get install apparmor-utils apparmor-profiles apparmor-profiles-extra -y

查看apparmor软件包,现在apparmor工具包就安装好了。

root@k8scludes1:~# cd systemsafe/

root@k8scludes1:~/systemsafe# dpkg -l | grep apparmor
ii apparmor 2.12-4ubuntu5.1 amd64 user-space parser utility for AppArmor
ii apparmor-profiles 2.12-4ubuntu5.1 all experimental profiles for AppArmor security policies
ii apparmor-profiles-extra 1.19 all Extra profiles for AppArmor Security policies
ii apparmor-utils 2.12-4ubuntu5.1 amd64 utilities for controlling AppArmor
ii libapparmor1:amd64 2.12-4ubuntu5.1 amd64 changehat AppArmor library
ii python3-apparmor 2.12-4ubuntu5.1 amd64 AppArmor Python3 utility library
ii python3-libapparmor 2.12-4ubuntu5.1 amd64 AppArmor library Python3 bindings

查看apparmor是否开启。

root@k8scludes1:~/systemsafe# aa-enabled
Yes

apparmor的配置文件在/etc/apparmor.d目录下。

root@k8scludes1:~/systemsafe# cd /etc/apparmor.d/

root@k8scludes1:/etc/apparmor.d# pwd
/etc/apparmor.d

usr.bin.man表示 /usr/bin/man的man程序。

root@k8scludes1:/etc/apparmor.d# ls
abstractions local tunables usr.bin.totem-previewers usr.lib.dovecot.dovecot-lda usr.lib.dovecot.pop3 usr.sbin.dovecot usr.sbin.smbldap-useradd
apache2.d lxc usr.bin.chromium-browser usr.lib.dovecot.anvil usr.lib.dovecot.imap usr.lib.dovecot.pop3-login usr.sbin.identd usr.sbin.tcpdump
bin.ping lxc-containers usr.bin.irssi usr.lib.dovecot.auth usr.lib.dovecot.imap-login usr.lib.dovecot.ssl-params usr.sbin.mdnsd usr.sbin.traceroute
cache sbin.dhclient usr.bin.lxc-start usr.lib.dovecot.config usr.lib.dovecot.lmtp usr.lib.snapd.snap-confine.real usr.sbin.nmbd
disable sbin.klogd usr.bin.man usr.lib.dovecot.deliver usr.lib.dovecot.log usr.sbin.apt-cacher-ng usr.sbin.nscd
force-complain sbin.syslogd usr.bin.pidgin usr.lib.dovecot.dict usr.lib.dovecot.managesieve usr.sbin.avahi-daemon usr.sbin.rsyslogd
gst_plugin_scanner sbin.syslog-ng usr.bin.totem usr.lib.dovecot.dovecot-auth usr.lib.dovecot.managesieve-login usr.sbin.dnsmasq usr.sbin.smbd

5.4 AppArmor规则解释

aa-autodep生成nginx进程的apparmor配置文件,aa-autodep nginx自动给nginx生成一套规则。

root@k8scludes1:/etc/apparmor.d# aa-autodep nginx
Writing updated profile for /usr/sbin/nginx. root@k8scludes1:/etc/apparmor.d# pwd
/etc/apparmor.d root@k8scludes1:/etc/apparmor.d# ls usr.sbin.nginx
usr.sbin.nginx

查看自动生成的规则文件。

apparmor涉及两种模式,每个配置文件都可以在强制(enforcing)模式(阻止访问不允许的资源)或投诉(complain)模式 (仅报告冲突)下运行:

  1. complain模式(即使没有满足条件也放行) ;
  2. enforce模式(必须满足条件)。

/usr/sbin/nginx flags=(complain)表示启用的是complain模式。

root@k8scludes1:/etc/apparmor.d# vim usr.sbin.nginx

root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Thu May 12 16:12:18 2022
#include <tunables/global> /usr/sbin/nginx flags=(complain) {
#include <abstractions/base> /lib/x86_64-linux-gnu/ld-*.so mr,
/usr/sbin/nginx mr, }

把usr.sbin.nginx的模式变为enforce模式。

root@k8scludes1:/etc/apparmor.d# aa-enforce nginx
Setting /usr/sbin/nginx to enforce mode.

现在usr.sbin.nginx就是enforce模式。

root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Thu May 12 16:12:18 2022
#include <tunables/global> /usr/sbin/nginx {
#include <abstractions/base> /lib/x86_64-linux-gnu/ld-*.so mr,
/usr/sbin/nginx mr, }

查看apparmor权限帮助。

root@k8scludes1:/etc/apparmor.d# man 5 apparmor.d

AppArmor允许规则说明:

  • allow /path/file (允许访问/path/file文件) ,allow /path/file 规则也可以写为/path/file ,因为默认是allow规则;
  • allow /path/* (允许访问/path/目录下所有文件,不支持递归) ;
  • allow /path/** (允许访问/path/目录下所有文件,支持递归),对于/path/aa/aa1/aaa1目录,allow /path/*规则能匹配到/path/aa 不能匹配到/path/aa/aa1和/path/aa/aa1/aaa1 ,allow /path/** 规则能匹配 /path/目录下所有文件。

AppArmor拒绝规则说明:

  • deny /path/file
  • deny /path/*
  • deny /path/**

AppArmor权限说明:

  • r: 读;
  • w: 写;
  • m: 存储器映射;
  • k: 文件锁定;
  • l: 创建硬链接;
  • ix: 执行并继承该安全配置;
  • Px: 在清理环境之后,执行并使用其他安全配置;
  • Ux: 在清理环境之后,执行不做限制。

apparmor常用命令:

  • aa-unconfined:用于检测运行在系统上监听网络连接且不受AppArmor保护的应用程序;
  • aa-autodep:用于创建配置文件的基本框架,该模板投入使用前需要完善。生成的配置文件被加载时进入complain模式,报告应用程序中(尚未)被AppArmor规则覆盖的行为。
  • aa-genprof:生成一个基本配置文件。通过执行应用程序会激发一系列事件并记录在日志中,在配置策略时要认真考虑其中存在的问题,进一步细化配置文件。生成并被加载时会进入enforce模式。
  • aa-logprof:当应用程序已生成配置文件并处于complain模式时,其可交互式地扫描和检查由应用程序生成的日志条目,辅助完善配置策略。
  • aa-complain:将AppArmor配置文件从enforce切换为complain模式。不符合配置文件策略的行为会被记录,但不会被拒绝。
  • aa-enforce:将AppArmor配置文件的模式从complain切换到enforce。不符合配置文件策略的行为会被记录,且会被拒绝。

5.5 配置AppArmor规则限制nginx程序访问目录

编写AppArmor规则,deny /data/www/unsafe/** r 表示禁止读/data/www/unsafe/目录下的文件。

root@k8scludes1:/etc/apparmor.d# vim usr.sbin.nginx 

root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Thu May 12 16:12:18 2022
#include <tunables/global> /usr/sbin/nginx {
#include <abstractions/base> deny /data/www/unsafe/** r,
/lib/x86_64-linux-gnu/ld-*.so mr,
/usr/sbin/nginx mr, }

aa-complain nginx将usr.sbin.nginx切换为complain模式。

root@k8scludes1:/etc/apparmor.d# aa-complain nginx
Setting /usr/sbin/nginx to complain mode.

aa-logprof:当应用程序已生成配置文件并处于complain模式时,其可交互式地扫描和检查由应用程序生成的日志条目,辅助完善配置策略。

root@k8scludes1:/etc/apparmor.d# aa-logprof
Reading log entries from /var/log/syslog.
Updating AppArmor profiles in /etc/apparmor.d.
Complain-mode changes: Profile: /usr/sbin/nginx
Capability: dac_override
Severity: 9 [1 - #include <abstractions/lxc/container-base>]
2 - #include <abstractions/lxc/start-container>
3 - capability dac_override,
(A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish
Adding #include <abstractions/lxc/container-base> to profile.
Deleted 5 previous matching profile entries.
Enforce-mode changes: = Changed Local Profiles = The following local profiles were changed. Would you like to save them? [1 - /usr/sbin/nginx]
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t = Changed Local Profiles = The following local profiles were changed. Would you like to save them? [1 - /usr/sbin/nginx]
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
Writing updated profile for /usr/sbin/nginx.

查看新的apparmor规则,拒绝访问/data/www/unsafe/**目录。

  • #include <tunables/global>:这一行包含了一个内核参数,tunables/global 提供了对内核参数的访问,这些参数可以影响AppArmor如何加载和处理规则。
  • /usr/sbin/nginx flags=(complain) {:这行定义了规则集的应用范围。这里是针对位于 /usr/sbin/nginx 的程序(即Nginx服务器)应用这些规则。flags=(complain) 表示这些规则是以complain 模式(complain mode)运行,即AppArmor会记录不允许的操作,但不会阻止它们。
  • #include <abstractions/base>:包含基础抽象规则,这些规则提供了最基本的安全策略,比如禁止写文件系统等。
  • #include <abstractions/lxc/container-base>:包含LXC容器基础抽象规则,这些规则适用于容器环境,提供了与容器相关的安全策略。
  • deny /data/www/unsafe/** r,:这一行表示禁止对 /data/www/unsafe/ 目录及其所有子目录进行读取操作。r 代表读取操作。这意味着Nginx不能访问这个目录或其子目录中的任何文件。这通常用于限制对敏感数据的访问。
#include <abstractions/lxc/container-base> 表示加载默认的规则库
root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Fri May 13 11:37:31 2022
#include <tunables/global> /usr/sbin/nginx flags=(complain) {
#include <abstractions/base>
#include <abstractions/lxc/container-base> deny /data/www/unsafe/** r, }

现在访问nginx,safe目录能访问,unsafe目录访问不了。

root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/safe/
<html>
<b>Hello! Accessing this file is allowed.</b>
</html> root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/unsafe/
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>

切换为enforce模式。

root@k8scludes1:/etc/apparmor.d# aa-enforce nginx
Setting /usr/sbin/nginx to enforce mode. root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Fri May 13 11:37:31 2022
#include <tunables/global> /usr/sbin/nginx {
#include <abstractions/base>
#include <abstractions/lxc/container-base> deny /data/www/unsafe/** r, }

enforce模式下,safe可以访问,unsafe访问不了,满足需求了

root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/safe/
<html>
<b>Hello! Accessing this file is allowed.</b>
</html> root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/unsafe/
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>

现在修改apparmor规则,使safe不能访问,unsafe能访问。

root@k8scludes1:/etc/apparmor.d# vim usr.sbin.nginx 

root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Fri May 13 11:37:31 2022
#include <tunables/global> /usr/sbin/nginx {
#include <abstractions/base>
#include <abstractions/lxc/container-base> deny /data/www/safe/** r, }

重新加载apparmor规则,使配置文件生效。

root@k8scludes1:/etc/apparmor.d# /etc/init.d/apparmor reload
[ ok ] Reloading apparmor configuration (via systemctl): apparmor.service.

重新加载apparmor规则之后,safe不能访问,unsafe能访问。

root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/unsafe/
<html>
<b>Hello! Accessing this file is forbidden.</b>
</html> root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/safe/
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>

六.在kubernetes里使用AppArmor限制容器对资源的访问

6.1 检查环境

在 Kubernetes v1.4 版本中才添加了对 AppArmor 的支持。验证节点的 Kubelet 版本。

root@k8scludes1:~# kubectl get nodes -o=jsonpath={range .items[*]}{@.metadata.name}: {@.status.nodeInfo.kubeletVersion}\n{end}' 

k8scludes1: v1.22.2 

k8scludes2: v1.22.2 

k8scludes3: v1.22.2

查看AppArmor 内核模块是否启用 。

root@k8scludes1:/etc/apparmor.d# cat /sys/module/apparmor/parameters/enabled
Y

现在还没有pod。

root@k8scludes1:/etc/apparmor.d# cd 

root@k8scludes1:~# cd systemsafe/ 

root@k8scludes1:~/systemsafe# kubectl get pod
No resources found in systemsafe namespace.

查看node节点的标签。

root@k8scludes1:~/systemsafe# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
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=
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
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。

root@k8scludes1:~/systemsafe# kubectl label nodes k8scludes3 yy=xx

查看标签为yy=xx的节点,等下创建的pod,我们让其运行在k8scludes3节点。

root@k8scludes1:~/systemsafe# kubectl get node -l yy=xx
NAME STATUS ROLES AGE VERSION
k8scludes3 Ready <none> 30d v1.22.2

6.2 配置AppArmor规则

先在k8scludes3节点设置apparmor规则。

root@k8scludes3:~# cd /etc/apparmor.d/ 

root@k8scludes3:/etc/apparmor.d# ls
abstractions cache disable force-complain local lxc lxc-containers
sbin.dhclient tunables usr.bin.lxc-start usr.bin.man usr.lib.snapd.snap-confine.real
usr.sbin.rsyslogd usr.sbin.tcpdump

查看AppArmor 内核模块是否启用

root@k8scludes3:~# cat /sys/module/apparmor/parameters/enabled
Y

创建一个k8s的apparmor规则文件。

注意:拒绝的优先级高于允许的优先级 。

apparmor的规则为 deny /tmp/aa/** rw 禁止在/tmp/aa/目录下读写 。

k8s-apparmor-profile-deny-write是AppArmor规则的名字。

root@k8scludes3:/etc/apparmor.d# vim k8s-apparmorprofile 

root@k8scludes3:/etc/apparmor.d# cat k8s-apparmorprofile
#include <tunables/global>
profile k8s-apparmor-profile-deny-write flags=(attach_disconnected) {
#include <abstractions/base>
#include <abstractions/lxc/container-base>
#file,
allow /proc/** rw,
allow /usr/bin/sleep rwkix,
allow /bin/* rwkix,
allow /root/** rw,
allow /etc/bash.bashrc rw,
allow /usr/bin/* rwkix,
allow /** rw,
deny /tmp/aa/** rw,
# Deny all file writes.
#deny /** w,
}

apparmor_status查看apparmor启用了哪些规则 。

root@k8scludes3:/etc/apparmor.d# apparmor_status
apparmor module is loaded.
16 profiles are loaded.
16 profiles are in enforce mode.
/sbin/dhclient
/usr/bin/lxc-start
/usr/bin/man
/usr/lib/NetworkManager/nm-dhcp-client.action
/usr/lib/NetworkManager/nm-dhcp-helper
/usr/lib/connman/scripts/dhclient-script
/usr/lib/snapd/snap-confine
/usr/lib/snapd/snap-confine//mount-namespace-capture-helper
/usr/sbin/tcpdump
docker-default
lxc-container-default
lxc-container-default-cgns
lxc-container-default-with-mounting
lxc-container-default-with-nesting
man_filter
man_groff
0 profiles are in complain mode.
23 processes have profiles defined.
23 processes are in enforce mode.
docker-default (2298)
docker-default (2505)
docker-default (3726)
docker-default (3757)
docker-default (3782)
docker-default (4338)
docker-default (4419)
docker-default (4585)
docker-default (4615)
docker-default (4688)
docker-default (5109)
docker-default (5173)
docker-default (5295)
docker-default (5362)
docker-default (5490)
docker-default (5642)
docker-default (5651)
docker-default (5726)
docker-default (5946)
docker-default (5999)
docker-default (6023)
docker-default (6894)
docker-default (7234)
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

我们创建的规则还没有启用 ,apparmor启用的规则里没有k8s-apparmor-profile-deny-write规则 。

root@k8scludes3:/etc/apparmor.d# apparmor_status | grep k8s-apparmor-profile-deny-write

加载规则 。

root@k8scludes3:/etc/apparmor.d# apparmor_parser -q k8s-apparmorprofile

现在k8s-apparmor-profile-deny-write规则就启用了 。

root@k8scludes3:/etc/apparmor.d# apparmor_status | grep k8s-apparmor-profile-deny-write
k8s-apparmor-profile-deny-write

如果想要删除规则 ,apparmor_parser -R 删除规则 ,apparmor_parser -r 是替换规则 。

root@k8scludes3:/etc/apparmor.d# apparmor_parser -R k8s-apparmorprofile 

root@k8scludes3:/etc/apparmor.d# apparmor_status | grep k8s-apparmor-profile-deny-write

重新加载规则。

root@k8scludes3:/etc/apparmor.d# apparmor_parser -q k8s-apparmorprofile 

root@k8scludes3:/etc/apparmor.d# apparmor_status | grep k8s-apparmor-profile-deny-write
k8s-apparmor-profile-deny-write

6.3 使用AppArmor限制容器对资源的访问

k8scludes3节点启用了apparmor规则之后,需要在k8scludes3节点创建pod ,回到k8scludes1节点,创建pod配置文件。

nodeSelector:yy: xx 指定pod在k8scludes3上运行 ,command: ["sh","-c","sleep 100000"] 指定运行sleep进程 。

root@k8scludes1:~/systemsafe# vim pod.yaml 

root@k8scludes1:~/systemsafe# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: podtest
name: podtest
spec:
nodeSelector:
yy: xx
#当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
terminationGracePeriodSeconds: 0
containers:
- image: hub.c.163.com/library/centos:latest
command: ["sh","-c","sleep 100000"]
#imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
imagePullPolicy: IfNotPresent
name: podtest
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

创建pod。

root@k8scludes1:~/systemsafe# kubectl apply -f pod.yaml
pod/podtest created

现在pod运行在k8scludes3节点,pod正常运行,不过我们没有在pod里启用apparmor规则 。

root@k8scludes1:~/systemsafe# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
podtest 1/1 Running 0 8s 10.244.1.121 k8scludes3 <none> <none>

删除pod。

root@k8scludes1:~/systemsafe# kubectl delete pod podtest
pod "podtest" deleted root@k8scludes1:~/systemsafe# kubectl get pod
No resources found in systemsafe namespace.

在pod里启用apparmor规则,添加的注解语法为:annotations:container.apparmor.security.beta.kubernetes.io/容器名字: localhost/apparmor规则名 。

container.apparmor.security.beta.kubernetes.io/podtest: localhost/k8s-apparmor-profile-deny-write里,容器名为podtest,规则名为:k8s-apparmor-profile-deny-write。

root@k8scludes1:~/systemsafe# vim pod.yaml 

root@k8scludes1:~/systemsafe# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: podtest
name: podtest
annotations:
# Tell Kubernetes to apply the AppArmor profile "k8s-apparmor-example-deny-write".
# Note that this is ignored if the Kubernetes node is not running version 1.4 or greater.
container.apparmor.security.beta.kubernetes.io/podtest: localhost/k8s-apparmor-profile-deny-write
spec:
#nodeSelector:yy: xx 指定pod在k8scludes3上运行
nodeSelector:
yy: xx
#当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
terminationGracePeriodSeconds: 0
containers:
- image: hub.c.163.com/library/centos:latest
#command: ["sh","-c","sleep 100000"] 指定运行sleep进程
command: ["sh","-c","sleep 100000"]
#imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
imagePullPolicy: IfNotPresent
name: podtest
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

创建pod,pod正常运行。

root@k8scludes1:~/systemsafe# kubectl apply -f pod.yaml
pod/podtest created root@k8scludes1:~/systemsafe# kubectl get pod
NAME READY STATUS RESTARTS AGE
podtest 1/1 Running 0 5s

进入pod。

root@k8scludes1:~/systemsafe# kubectl exec -it podtest -- bash 

root@podtest:/# ls /tmp 

root@podtest:/# mkdir /tmp/aa /tmp/bb/ 

#apparmor的规则为 deny /tmp/aa/** rw 禁止在/tmp/aa/目录下读写,满足条件
root@podtest:/# touch /tmp/aa/aa1.txt
touch: cannot touch '/tmp/aa/aa1.txt': Permission denied root@podtest:/# touch /tmp/bb/bb1.txt root@podtest:/# ls /tmp/aa root@podtest:/# ls /tmp/bb
bb1.txt #退出pod
root@podtest:/# exit
exit

删除pod。

root@k8scludes1:~/systemsafe# kubectl delete pod podtest
pod "podtest" deleted

七.总结

通过使用 AppArmor,我们可以在不牺牲性能的前提下,为容器提供有效的安全隔离。Kubernetes 的集成使得配置和管理 AppArmor 规则变得更加便捷。通过精确的规则设置,我们可以确保容器只能访问它所需要的资源,从而降低系统的风险暴露。

在kubernetes里使用AppArmor限制容器对资源的访问的更多相关文章

  1. springMvc里的mvc:resources与静态资源的访问

    在进行Spring MVC的配置时,通常我们会配置一个dispatcher servlet用于处理对应的URL.配置如下:   <servlet>   <servlet-name&g ...

  2. Kubernetes pod里一个特殊的容器:pause-amd64

    大家在使用Docker容器或者Kubernetes时,遇到过这个容器么?gcr.io/google_containers/pause-amd64 docker ps的命令返回的结果: [root@k8 ...

  3. Kubernetes — 我的第一个容器化应用

    而在这篇文章中,我们就来扮演一个应用开发者的角色,使用这个 Kubernetes 集群发布第一个容器化应用. 在开始实践之前,我先给你讲解一下 Kubernetes 里面与开发者关系最密切的几个概念. ...

  4. 使用Kubernetes里的job计算圆周率后2000位

    使用Kubernetes里的job(作业),我们可以很方便地执行一些比较耗时的操作. 新建一个job.ymal文件: 定义了一个Kubernetes job,名称为pi,类型为job,容器名称为pi, ...

  5. Kubernetes里的Service是如何工作的

    Service是Kubernetes接入层的一种抽象资源,它为我们提供了一种固定的.统一的访问接口地址和负载均衡能力,这时可能会想到,当时使用docker-compose的时候,不存在Service概 ...

  6. Docker&Kubernetes沙龙干货集锦:容器集群管理利器kubernetes详谈-CSDN.NET

    Docker&Kubernetes沙龙干货集锦:容器集群管理利器kubernetes详谈-CSDN.NET undefined Package - crawler undefined 科学网- ...

  7. 如何使用Kubernetes里的NetworkPolicy

    创建一个类型为NetworkPolicy的Kubernetes对象的yaml文件. 第九行的podSelector指定这个NetworkPolicy施加在哪些pod上,通过label来做pod的过滤. ...

  8. 如何在Kubernetes里创建一个Nginx service

    Jerry之前的文章如何在Kubernetes里创建一个Nginx应用,已经使用kubectl命令行创建了Pod,但是在kubernetes中,Pod的IP地址会随着Pod的重启而变化,因此用Pod的 ...

  9. DataAnnotations里DisplayAttribute和 ValidationAttribute 如何从资源文件读取信息,显示多语言

    这个是我们常见的AccountModel代码 public class ChangePasswordModel { [Required] [DataType(DataType.Password)] [ ...

  10. K8S 容器的资源需求、资源限制

    容器的资源需求,资源限制 requests:需求,最低保障: limits:限制,硬限制: CPU: 1 颗逻辑 CPU 1=1000,millicores 500m=0.5CPU QoS: Gura ...

随机推荐

  1. Centos 8.0 minimal命令行安装图形化界面(超详细)

    Centos 8.0 安装图形化界面(超详细) 开始之前呢,请先查看您的Centos版本和是否有root账户权限. 一.安装Centos 图形化界面并重启 下载安装图形化界面 执行命令 yum gro ...

  2. 收藏 | 超详细的Oracle19c安装步骤-CentOS Linux

    ORACLE学习-DBA数据库工程师 收藏 | 超详细的Oracle19c安装步骤 挨踢-IT人加油 [微思网络]IT培训-思科/华为/红帽/ORACLE... 2 人赞同了该文章 DBA数据库管理必 ...

  3. ORA-29277:invalid SMTP operation

    ORA-29277:invalid SMTP operation 邮件发送的时候出现报错 ORA-29277:invalid SMTP operation 官方解释就很简单 但是实际上重试是不行的,几 ...

  4. 力扣901(java&python)-股票价额跨度(中等)

    题目: 编写一个 StockSpanner 类,它收集某些股票的每日报价,并返回该股票当日价格的跨度. 今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天) ...

  5. 力扣6(java)-Z字形变换(中等)

    题目: 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如 ...

  6. portainer安装,配置,使用

    Portainer安装 Portainer是Docker容器管理可视化界面,主要是可以通过可视化界面创建,管理Dockert容器,并且支持多个节点管理(免费版支持五个节点). Portainer官网地 ...

  7. 科普达人丨一图看懂阿里云ECS

    简介: 建议收藏  原文链接:https://click.aliyun.com/m/1000363154/ 本文为阿里云原创内容,未经允许不得转载.

  8. 3 种发布策略,解决 K8s 中快速交付应用的难题

    作者 | 郝树伟(流生)阿里云高级研发工程师 前言 软件技术更新换代很快,但我们追求的目标是一直不变的,那就是在安全稳定的前提下,增加应用的部署频率,缩短产品功能的迭代周期,这样的好处就是企业可以在更 ...

  9. 如何高效学习 Kubernetes 知识图谱?

    ​简介: Kubernetes 知识图谱遵循云原生人才学习路径搭建课程体系框架,及人才发展路线设置不同阶段,由浅入深,帮助云原生人才学习容器基础.Kuternetes 网络.存储.资源对象.服务发现. ...

  10. WPF 修复引用库报错 所使用的 PresentationFramework 6

    本文记录一个 WPF 构建的坑,这是 WPF 仓库的运维管理大意挖的坑.将会在大家使用低版本的 dotnet 6 如 6.0.1 版本时,引用其他人使用高 dotnet 6 版本,如 dotnet 6 ...