如何使用宿主节点的命名空间
apiVersion: v1
kind: Pod
metadata:
name: pod-test
spec:
hostNetwork: true # 共用宿主节点的网络命名空间
hostIPC: true # 共用宿主节点的IPC空间
hostPID: true # 共用宿主节点的PID命名空间
containers:
- name: main
image: centos
ports:
- containerPort: 8000
hostPort: 9000 # 可以通过所在节点的9000端口访问
protocol: TCP
hostPort让pod在拥有自己的网络命名空间的同时,将端口绑定到宿主节点的端口上。hostPort和NodePort的区别在于:
- 使用hostPort的pod,到达宿主节点的端口的连接会被直接转发到节点所在的pod的端口;对于NodePort而言,会被转发到随机选取的pod上。
- 对于使用hostPort的pod,仅有运行了这类pod的节点会绑定对应的端口,而NodePort会在所有节点上绑定端口。
hostPort最初用于暴露通过DeamonSet部署在每个节点上的系统服务。
SecurityContext
SecurityContext可以配置与安全相关的特性,可以运用于整个pod,或pod中的容器。其可以配置以下一些事项。
- 使用指定用户运行容器(runAsUser)
- 阻止容器以root用户运行(runAsNonRoot)
- 以特权模式运行。可以做它们宿主节点上能够做的任何事。
- 为容器单独添加/禁用内核功能。
- 阻止对容器根文件系统的写入。
示例如下
apiVersion: v1
kind: Pod
metadata:
name: pod-test
spec:
containers:
- name: main
image: centos
securityContext:
runAsUser: 405 # 指定用户ID
runAsNonRoot: true # 只允许以非root用户运行
privileged: true # pod将在特权模式下运行
readOnlyRootFilesystem: true # 容器的根文件系统不允许写入
capabilities:
add: # 添加内核功能
- SYS_TIME
drop: # 禁用内核功能
- CHOWN
pod级别特有的安全上下文包括fsGroup和supplementalGroups,示例如下
apiVersion: v1
kind: Pod
metadata:
name: pod-test
spec:
securityContext:
fsGroup: 555
supplementalGroups: [666, 777]
fsGroup指定了挂载的卷所属的用户组,supplementalGroups中的用户组会关联到运行容器的用户下,fsGroup指定的用户组也会关联到该用户下。
PodSecurityPolicy
PodSecurityPolicy是一种集群级别的资源,它定义了用户能否在pod中使用各种安全相关的特性。
当向API服务器发送pod资源时,PodSecurityPolicy准入控制插件会将这个pod与已经配置的PodSecurityPolicy进行校验。如果这个pod符合集群中已有安全策略,它会被接受并存入etcd;否则它会立即被拒绝。这个插件也会根据安全策略中配置的默认值对pod进行修改。
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: default
spec:
hostIPC: false
hostPID: false
hostNetwork: false
hostPorts:
- min: 1000
max: 2000
- min: 4000
max: 5000
privileged: false
readOnlyRootFilesystem: true
runAsUser:
rule: MustRunAs
ranges:
- min: 2
max:2
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
allowedCapabilities:
- SYS_TIME
defaultAddCapabilities:
- CHOWN
requiredDropCapabilities:
- SYS_ADMIN
- SYS_MODULE
volumes:
- emptyDir
- configMap
- secret
- runAsUser的MustRunAs规则。当pod中没有指定runAsUser,即使在Dockerfile中指定了user,PodSecurityPolicy也会重写runAsUser。runAsUser可以使用另外一种规则,mustRunAsNonRoot,该规则将阻止用户部署以root运行的容器.
- allowedCapabilities:允许添加哪些内核功能,不在此配置中的功能将不被允许添加到容器中
- defaultAddCapabilities: 会被自动添加到每个容器中
- requiredDropCapabilities: 会在容器的securityContext.capabilities.drop字段中加入这些功能。
对不同的用户与组分配不同的PodSecurityPolicy
这是通过RBAC机制实现的。首先创建需要的PodSecurityPolict资源,然后创建ClusterRole资源并通过PodSecurityPolict名称引用不同的策略,通过创建ClusterRoleBinding将不同的用户或组绑定到这个ClusterRole,以使PodSecurityPolicy资源中的策略对不同的用户或组生效。当PodSecurityPolicy访问控制插件需要决定是否接纳一个pod时,它只会考虑创建pod的用户可以访问到的PodSecurityPolicy中的策略,当没有找到任何策略时则会拒绝创建pod。
可以通过如下命令创建ClusterRole并允许其使用某个特定的policy
kubectl create clusterrole <cluster role name> --verb=use --resource=podsecuritypolicies --resource-name=<podSecurityPolicy name>
隔离pod的网络
NetworkPolicy用于限制pod可以与其他哪些pod通信。一个NetworkPolicy会应用在匹配它的标签选择器的pod上,通过入向规则和出向规则限定源地址和目标地址。但是使用NetworkdPolicy的前提是得到集群中使用的容器网络插件的支持。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-policy
spec:
podSelector: # 当前这个policy应用的pod
matchLabels:
app: kubia
ingress:
- from:
- podSelector: # 匹配该标签的pod可以访问该pod
matchLabels:
app: db
ports:
- port: 80
- from:
- namespaceSelector: # 通过命名空间的标签选择器指定哪些命名空间的pod可以访问该pod
matchLabels:
tenant: manning
ports:
- port: 80
- from:
- ipBlock: # 通过CIDR指定IP地址段
cidr: 192.168.1.0/24
egress: # 出向规则指定
- to:
- podSelector:
matchLabels:
app: database