---
# System prepended metadata

title: 第四题 AppArmor
tags: [真题讲解]

---

# 第四题 AppArmor
###### tags: `真题讲解`
切换集群kubectl config use-context k8s

**Context**
AppArmor is enabled on the cluster's worker node. An AppArmor profile is prepared, but not enforced yet.
You may use your browser to open one additional tab to access the AppArmor documentation.

**Task**
On the cluster's worker node, enforce the prepared AppArmor profile located at /etc/apparmor.d/nginx_apparmor.
Edit the prepared manifest file located at /cks/4/pod1.yaml to apply the AppArmor profile. Finally, apply the manifest file and create the pod specified in it.

## 解法
[官方参考链接: k8s.io/apparmor](https://kubernetes.io/docs/tutorials/clusters/apparmor/)

SSH 到apparmor文件所在的Node, 进入所在文件夹:
```
cd /etc/apparmor.d/
root@ubuk8s-vm02:/etc/apparmor.d# ls
abstractions  disable         local  lxc-containers  sbin.dhclient  usr.bin.lxc-start  usr.bin.ubuntu-core-launcher     usr.sbin.rsyslogd
cache         force-complain  lxc    nginx_apparmor  tunables       usr.bin.man        usr.lib.snapd.snap-confine.real  usr.sbin.tcpdump
```
查看该apparmor文件, 发现该Pofile名为nginx-profile-1, 记住它, 省的待会回来找.
```
cat nginx_apparmor
#include <tunables/global>
profile nginx-profile-1 flags=(attach_disconnected) {
  #include <abstractions/base>
  file,
  # Deny all file writes.
  deny /** w,
}
```
加载该Profile, Ubuntu中输入app + TAB可以找到该命令, 无需背.
```
apparmor_parser nginx_apparmor
```
校验是否加载为执行模式, 看到nginx-profile-1已在Node2上加载.
```
root@ubuk8s-vm02:/etc/apparmor.d# apparmor_status
apparmor module is loaded.
18 profiles are loaded.
18 profiles are in enforce mode.
   /sbin/dhclient
   /usr/bin/lxc-start
   /usr/bin/man
   /usr/bin/ubuntu-core-launcher
   /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
   nginx-profile-1
   ...
   ...
```

返回跳板机, 修改YAML, 指定Pod启动在Node2上, 指定调用该Apparmor Profile.
三处注意事项:
* 通过nodeName指定Pod运行在Node2上
* 通过注释指定Apparmor Profile, 该Profile针对Container生效, 非整个Pod, 所以注意YAML中的Container name.
* localhost/nginx-profile-1, 即为目标Node本地的nginx-profile-1, 之前记住这个名字就不会回去找了.
```
apiVersion: v1
kind: Pod
metadata:
  name: apparmor-demo
  labels:
    app: net-tools
  annotations:
    container.apparmor.security.beta.kubernetes.io/apparmor-c1: localhost/nginx-profile-1
spec:
  nodeName: ubuk8s-vm02
  containers:
  - name: apparmor-c1
    image: net-tools:v2
    command: [ "sh", "-c", "sleep 1h" ]
```

## 校验

登录Pod, 尝试在/tmp中写入文件, 被apparmor拒绝.
```
kubectl exec -it apparmor-demo bash

root@apparmor-demo:/# cd /tmp/
root@apparmor-demo:/tmp# ls
root@apparmor-demo:/tmp# touch file
touch: cannot touch 'file': Permission denied
```

Tips: 如果Profile加载错误, 可以在描述Pod时发现, 比如说你写错了Profile的名字. 输出会提示你Cannot enforce AppArmor: profile "nginx-profile-2" is not loaded, Pod会被禁止启动
```
kubectl describe pod apparmor-demo
Name:         apparmor-demo
Namespace:    default
Priority:     0
Node:         ubuk8s-vm02/10.79.230.10
Start Time:   Sun, 02 May 2021 16:42:44 +0800
Labels:       app=net-tools
Annotations:  container.apparmor.security.beta.kubernetes.io/apparmor-c1: localhost/nginx-profile-2
Status:       Pending
Reason:       AppArmor
Message:      Cannot enforce AppArmor: profile "nginx-profile-2" is not loaded
```
```
kubectl get pod                   
NAME            READY   STATUS    RESTARTS   AGE
apparmor-demo   0/1     Blocked   0          116s
```