本連載では、エンタープライズシステムでコンテナやKubernetesを活用した業務システムを開発・運用するエンジニアに向けて、知っておくべきKubernetesセキュリティの基礎知識、Microsoftが提供するパブリッククラウド「Azure」を使ったクラウドでのKubernetesセキュリティ対策のポイント、気を付けておきたい注意点などの実践的なノウハウを紹介します。
今回も引き続き、コンテナセキュリティの基礎となるコンテナ技術について説明します。前回と前前回は、コンテナの基礎になっているLinuxカーネルの機能「namespace」「cgroup」「Capability」について説明しました。
コンテナ技術の基礎の最終回である第3回では、これらの技術がKubernetesとどのような関係があるのかを説明していきます。
Kubeneresとnamespace
まずは、Kubeneresのノードの中にどのようなnamespaceがあるのかを見てみます。ノードの中を探索するための特権を持ったDaemonSetをデプロイします。DaemonSetのイメージの素になるDockerfileは以下にしました。
FROM ubuntu:20.04
ENTRYPOINT ["tail","-f", "/etc/profile"]
DaemonSetを定義するyamlは以下です。securityContextで特権を与えており、hostPIDとhostNetworkをtrueにし、hostPathのルートをマウントする極めて危険なものです。この中にkubectl exec -it root-daemon-xxxxx -- bashで入り、ノードの中を探索します。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: root-daemon
spec:
selector:
matchLabels:
app: root-daemon
template:
metadata:
labels:
app: root-daemon
spec:
hostPID: true
hostNetwork: true
containers:
- name: network-collect
image: xxxxxxxxxxxxxxxxxx.azurecr.io/root-daemon:v0.0.1
securityContext:
privileged: true
resources:
limits:
cpu: 50m
memory: 50Mi
requests:
cpu: 50m
memory: 50Mi
volumeMounts:
- mountPath: /hostroot
name: hostroot
volumes:
- name: hostroot
hostPath:
path: /
ベーシックなnginxのDeploymentも適用してみます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-seccomp
spec:
selector:
matchLabels:
app: nginx-seccomp
replicas: 2
template:
metadata:
labels:
app: nginx-seccomp
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 125Mi
requests:
cpu: 90m
memory: 115Mi
kubectl exec -it root-daemon-xxxxx -- bashでノードの中を探索する前に、同じノードのnginxのContainer IDを確認しておきます。今回は、f66dd3c1e442f0da10aaf0d6954fcafa4d3533da5f3bb597ca7003c66bbb437dがContainer IDです。
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-seccomp-55449744c7-g4zp9 1/1 Running 0 124m 10.240.0.104 aks-agentpool-23069546-vmss000000
nginx-deployment-seccomp-55449744c7-z2zd5 1/1 Running 0 124m 10.240.0.200 aks-agentpool-23069546-vmss000002
root-daemon-gzcrq 1/1 Running 0 149m 10.240.0.115 aks-agentpool-23069546-vmss000002
root-daemon-jbzcd 1/1 Running 0 149m 10.240.0.4 aks-agentpool-23069546-vmss000000
$ kubectl describe pod nginx-deployment-seccomp-55449744c7-z2zd5 | grep "Container ID"
Container ID: containerd://f66dd3c1e442f0da10aaf0d6954fcafa4d3533da5f3bb597ca7003c66bbb437d
次に、nginxのnamespaceがどうなっているのかを確認してみます。
# ls -l /proc/14611/ns
lrwxrwxrwx 1 root root 0 Nov 30 01:57 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Nov 30 01:57 ipc -> 'ipc:[4026532474]'
lrwxrwxrwx 1 root root 0 Nov 30 01:57 mnt -> 'mnt:[4026532476]'
lrwxrwxrwx 1 root root 0 Nov 30 01:57 net -> 'net:[4026532402]'
lrwxrwxrwx 1 root root 0 Nov 30 01:57 pid -> 'pid:[4026532477]'
lrwxrwxrwx 1 root root 0 Nov 30 01:57 pid_for_children -> 'pid:[4026532477]'
lrwxrwxrwx 1 root root 0 Nov 30 01:57 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Nov 30 01:57 uts -> 'uts:[4026532473]'