在容器上内嵌了containers
字段,额外还定义了hostPort
,就意味着可以像docker
一样,让pod
运行的那个主机打开一个DNAT
的端口映射,把宿主机的某个请求做地址转换后转发至内部的容器之上。而hostNetwork
所提供的功能是让pod
直接共享了它所在的宿主机的网路名称空间。
以上的两个操作都属于特权操作,正常情况下,一个多租户的K8S
,使用以上两种方式来让外部的流量进入k8s
将会造成隔离级的开放。而k8s为了安全运行pod
级容器专门设计了一种叫安全上下文的概念(SecurityContext
)。
SecuritContext
:安全上下文主要是允许用户和管理员定义容器或Pod的特权或访问控制机制,以配置容器、主机以及主机之上的其他容器之间的隔离方式或隔离级别。安全上下文就是一组决定容器如何创建和运行的约束条件,他们代表创建和运行容器时使用的运行时参数。
SecurityContext级别 Pod
上的SecurityContext
有两个级别:
Pod级别:对Pod内的所有容器生效
容器级别:只对Pod内的单个容器生效
安全上下文相关资源定义 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 apiVersion: v1 kind: Pod metadata: {…} spec: securityContext: runAsUser <integer > runAsGroup <integer > supplementalGroups <[]integer > fsGroup <integer > runAsNonRoot <boolean> seLinuxOptions <Object> sysctls <[]Object> windowsOptions <Object> containers: - name: … image: … securityContext: runAsUser <integer > runAsGroup <integer > runAsNonRoot <boolean> allowPrivilegeEscalation <boolean> capabilities <Object> add <[]string> drop <[]string> privileged <boolean> procMount <string> readOnlyRootFilesystem <boolean> seLinuxOptions <Object> windowsOptions <Object>
SecurityContext示例 以普通用户运行容器 1.创建配置清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 root@k8s-master01:~/yaml/chapter04 apiVersion: v1 kind: Pod metadata: name: securitycontext-runasuser-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent env: - name: PORT value: "8080" securityContext: runAsUser: 1001 runAsGroup: 1001
2.应用配置文件
1 2 root@k8s-master01:~/yaml/chapter04 pod/securitycontext-runasuser-demo created
3.验证pod是否运行为普通用户
1 2 3 4 5 root@k8s-master01:~/yaml/chapter04 PID USER TIME COMMAND 1 1001 0:00 python3 /usr/local /bin/demo.py 14 1001 0:00 ps aux
设定容器级capabilities 可设定的capabilities
有以下:
CAP_CHOWN
:改变文件UID和GID
CAP_MKNOD
:能使用mknod(),创建设备文件;
CAP_NET_ADMIN
:网络管理权限。
CAP_SYS_ADMIN
:大部分管理权限
CAP_SYS_TIME
:管理内核时钟
CAP_SYS_MODULE
:装卸载内核模块
CAP_NET_BIND_SERVICE
:是否允许能够将绑定1024以内端口
设定网络管理权限能力 1.编写配置清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 root@k8s-master01:~/yaml/chapter04 apiVersion: v1 kind: Pod metadata: name: securitycontext-capabilities-demo namespace: default spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 command : ["/bin/sh" ,"-c" ] args: ["/sbin/iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 && /usr/bin/python3 /usr/local/bin/demo.py" ] securityContext: capabilities: add: ['NET_ADMIN' ] drop: ['CHOWN' ]
2.引用容器清单
1 2 3 4 5 6 root@k8s-master01:~/yaml/chapter04 pod/securitycontext-capabilities-demo created root@k8s-master01:~/yaml/chapter04 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES securitycontext-capabilities-demo 1/1 Running 0 49s 10.244.2.18 k8s-node02 <none> <none>
3.验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 root@k8s-master01:~/yaml/chapter04 iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: securitycontext-capabilities-demo, ServerIP: 10.244.2.18! root@k8s-master01:~/yaml/chapter04 Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1 60 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 redir ports 80 Chain INPUT (policy ACCEPT 1 packets, 60 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination root@k8s-master01:~/yaml/chapter04 chown: /etc/fstab: Operation not permitted command terminated with exit code 1
设定容器内sysctls的参数 我们还可以改变pod内部的网络名称空间的内核参数,而事实上目前在容器能安全允许pod修改的参数只有三个,并且其作用并非很大。如果要启用其他非安全参数,则需要在k8s启动时,允许非安全参数也能在pod内进行设定。
pod内可安全设定的内核参数 k8s默认允许设定的安全的内核参数有以下三个:
kernel.shm_rmid_forced
net.ipv4.ip_local_port_range
net.ipv4.tcp_syncookies
除此之外都不允许设定,如要设定需要修改k8s启动参数。
非安全参数设定方法示例 1.修改/etc/default/kubelet
文件,加入需要启用的非安全参数,如果没有此文件可以自己创建,kubelet
会自动读取
1 2 3 4 5 root@k8s-master01:~/yaml/chapter04 KUBELET_EXTRA_ARGS='--allowed-unsafe-sysctls=net.core.somaxconn,net.ipv4.ip_unprivileged_port_start'
2.重启kubelet
1 root@k8s-master01:~/yaml/chapter04
注意:以上操作所有节点都需要修改,因为pod调度到那个节点上是未知的。
参数设定示例 1.创建配置清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 root@k8s-master01:~/yaml/chapter04 apiVersion: v1 kind: Pod metadata: name: securitycontext-sysctls-demo namespace: default spec: securityContext: sysctls: - name: kernel.shm_rmid_forced value: "0" - name: net.ipv4.ip_unprivileged_port_start value: "0" containers: - name: demoapp image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent securityContext: runAsUser: 1001 runAsGroup: 1001
2.在所有节点修改/etc/default/kubelet
文件,加入允许设定的非安全参数,并重启kubelet
1 2 3 4 5 6 root@k8s-master01:~/yaml/chapter04 KUBELET_EXTRA_ARGS='--allowed-unsafe-sysctls=net.ipv4.ip_unprivileged_port_start' root@k8s-master01:~/yaml/chapter04
3.引用配置清单创建pod
1 2 3 4 5 root@k8s-master01:~/yaml/chapter04 pod/securitycontext-sysctls-demo created root@k8s-master01:~/yaml/chapter04 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES securitycontext-sysctls-demo 1/1 Running 0 15s 10.244.3.18 k8s-node03 <none> <none>
4.验证用户及监听
1 2 3 4 5 6 7 8 9 10 11 root@k8s-master01:~/yaml/chapter04 State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:80 0.0.0.0:* root@k8s-master01:~/yaml/chapter04 PID USER TIME COMMAND 1 1001 0:00 python3 /usr/local /bin/demo.py 15 1001 0:00 ps aux