kubernets之节点和网络的安全保障策略
一 在pod中使用宿主节点的命名空间
1.1 在pod中使用宿主的网络命名空间
[root@node01 Chapter13]# cat pod-with-host-network.yml apiVersion: v1 kind: Pod metadata: name: pod-with-host-network spec: hostNetwork: true containers: - name: main image: alpine command: ["/bin/sleep", "999999"]
- 如果需要pod使用节点的网络命名空间的话,仅仅需要在pod的mainifest的定义里面添加 hostNetwork: true
1.2 绑定到宿主机的端口上面而不是宿主机的网络的命名空间
[root@node01 Chapter13]# cat kubia-hostport.yml apiVersion: v1 kind: Pod metadata: name: kubia-hostport spec: containers: - name: kubia image: luksa/kubia ports: - containerPort: 8080 hostPort: 9000
- 在pod的容器spec.containers.ports.hostPort:9000就可以将容器使用主机的端口来访问
- 这个与将pod添加到服务有所不同,这个只有被调度到的主机可以访问
1.3 使用宿主机的PID以及PIC的命名空间
apiVersion: v1 kind: Pod metadata: name: pod-with-host-pid-and-ipc spec: hostPID: true hostIPC: true containers: - name: main image: alpine command: ["/bin/sleep", "999999"]
二 配置容器级别的安全上下文
2.1 使用指定用户运行容器
apiVersion: v1 kind: Pod metadata: name: pod-as-user-guest spec: containers: - name: mian image: alpine command: ["/bin/sleep", "999999"] securityContext: runAsUser: 405
2.2 阻止容器以root用户运行
apiVersion: v1 kind: Pod metadata: name: pod-no-root spec: containers: - name: mian image: alpine command: ["/bin/sleep", "999999"] securityContext: runAsNonRoot: true
2.3 使用特权模式运行pod
apiVersion: v1 kind: Pod metadata: name: pod-root spec: containers: - name: mian image: alpine command: ["/bin/sleep", "999999"] securityContext: privileged: true
- 添加之后,pod就会有可以改变宿主机的权限,例如设置iptables规则等
2.4 在容器内部单独添加内核功能而不是将最大的权限全部交给pod
apiVersion: v1 kind: Pod metadata: name: pod-with-some spec: containers: - name: mian image: alpine command: ["/bin/sleep", "999999"] securityContext: capabilities: add: - SYS_TIME
2.5 关闭容器中某些操作内核的权限
apiVersion: v1 kind: Pod metadata: name: pod-with-drop-some spec: containers: - name: mian image: alpine command: ["/bin/sleep", "999999"] securityContext: capabilities: drop: - SYS_TIME
2.6 禁止容器里面的进程写入容器的文件系统,但是允许其写入挂载的卷里面
apiVersion: v1 kind: Pod metadata: name: pod-with-readonly-filesystem spec: containers: - name: main image: alpine command: ["/bin/sleep","999999"] securityContext: readOnlyRootFilesystem: true volumeMounts: - name: my-volume mountPath: /volume readOnly: false volumes: - name: my-volume emptyDir:
三 限制pod使用安全相关的特性
3.1 PodSecurityPolicy资源介绍
apiVersion: extensions/v1beta1 kind: PodSecurityPolicy metadata: name: default spec: hostIPC: false hostPID: false hostNetwork: false hostPorts: - min: 10000 max: 11000 - min: 13000 max: 14000 privileged: false readOnlyRootFilesystem: true runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny supplementalGroups: rule: RunAsAny seLinux: rule: RunAsAny volumes: - '*'
3.2 如果要对容器内的应用运行时候指定用户名以及用户组需要配置runasuser,fsgroup,supplementalGroup等的属性,其一个示范配置如下
runAsUser: rule: MustRunAs ranges: - min: 2 max: 2 fsGroup: rule: MustRunAs ranges: - min: 2 max: 10 - min:20 max: 30 supplementGroups: rule: MustRunAs ranges: - min: 2 max: 10 - min: 20 max: 30
- 注意一点的是PodsecurityPolicy里面定义的规则不针对集群里面已经存在的pod
- 对于用户推送的pod,如果与策略里面相悖,则无法创建成功,如果创建容器的时候并未对其用户指定,则会使用集群策略里面的条例
- 对于runAsUser而言可以指定mustRunAsNonRoot,如此设置之后必须指定一个非root的用户来运行pod
3.3 更细粒度的内核功能权限划分,被允许添加,默认添加,以及禁止添加的内核功能
apiVersion: extensions/v1beta1 kind: PodSecurityPolicy spec: allowedCapabilities: - SYS_TIME defaultAddCapabilities: - CHOWN requiredDropCapabilities: - SYS_ADMIN - SYS_MODULE
- allowedcapabilities的作用是,允许pod访问docker系统里面的功能
- defaultAddCapabilities作用是,默认添加到pod里面的对系统权限访问功能
- requiredDropCapabilities作用是不允许添加到pod的系统功能,一旦添加,将无法成功的创建pod
3.4 限制pod可以使用存储卷的类型
kind: PodSecurityPolicy spec: volumes: - emptyDir - configMap - secret - downwardAPI - persistentVolumeClaim
- 指定了pod可以使用的存储卷类型
3.5 对不同的用户或者用户组分配不同的PodSecurityPolicy
使用的方法是利用集群角色以及集群角色绑定到不同用户或者用户组,使得,不同用户或者不同用户组里面的用户拥有不同的PodSecurityPolicy的规则,前面提到过,PodSeurityPolicy属于集群资源,但是不可能某个Policy可以对集群里面的所有的pod都能有效果,于是我们可以试图用一个之前已经学过的资源来让PodSecurityPolicy来关联不同的用户以及用户组来让不同的用户组拥有不同的权限
3.5.1 创建1个psp
apiVersion: extensions/v1beta1 kind: PodSecurityPolicy metadata: name: privileged spec: privileged: true runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny supplementalGroups: rule: RunAsAny seLinux: rule: RunAsAny volumes: - '*'
3.5.2 为它创建一个集群角色
k create clusterrole privileged --verb=use --resource=podsecuritypolicies --resource-name=privileged
3.5.3 创建一个集群角色绑定
k create clusterrolebinding psp-bob --clusterrole=privileged --user=wxm
3.5.4 创建这个用户
k config set-credentials wxm --username=wxm --password=password
3.5.5 使用这个用户来创建带有特权的pod
k --user wxm create -f pod-privileged.yml
四 隔离pod网络
4.1 在一个命名空间中启用网络隔离
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metddata: name: default-deny spec: podSelector:
- 在任何一个特定的命名空间里面创建这个Networkpolicy,则任何客户端都无法访问这个命名空间的pod
- 前提是kubernets集群里面的网络插件(cni)支持NetworkPolicy
4.2 允许同一个命名空间的部分pod访问
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: postgres-netpolicy spec: podSelector: matchLabels: app: database ingress: - from: - podSelector: matchLabels: app: webserver ports: - port: 5432
- 这个networkpolicy允许命名空间中标签为database的pod被访问
- 并且只能被标签为webserver的pod访问
- 并且只能访问5432的端口
4.3 允许带有特定标签的命名空间的pod访问某个特定标签的pod
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: shopping-cart-policy spec: podSelector: matchLabels: app: shopping-cart ingress: - from: - namespaceSelector: matchLabels: app: wxm ports: - port: 80
4.4 使用CIDR隔离网络
只能允许特定网端的pod访问指定的pod
ingress: - from: - ipBlock: cidr: 192.168.1.0/24
4.5 限制pod的出流量
spec: podSelector: matchLabels: app: webserver egress: - to: - podSelector: matchLabels: app: database
- webserver标签只能和ddatabase标签访问,其余的任何pod和IP都不能访问