「10.Security」

  CREATED BY JENKINSBOT

介绍用户可以和应该执行的原则,确保集群的安全运行。内容如下:

服务帐号的角色及使用。

基于角色的访问控制。

定义Pod的安全上下文环境。

10.1. Providing a Unique Identity for an Application

如何赋予应用程序唯一的身份,以便从细节上控制资源的访问?

解决:创建一个服务帐号,并在Pod的Spec中使用。

# kubectl create serviceaccount myappsa

# kubectl describe serviceaccount myappsa

# kubectl describe secret “myappsa-token-rr6jc” # 参数”myappsa-token-rr6jc”是由上一步输出的。

接下来在Pod中使用该ServiceAccount帐号:

kind: Pod
apiVersion: v1
metadata:
  name: myapp
spec:
  serviceAccountName: myappsa
  container:
  - name: main
    image: centos:7
    command:
    - "/bin/sh"
    - "-c"
    -c "whatever"

验证该Pod正常使用了ServiceAccount:kubectl exec myapp -c main cat /var/run/secrte/kubernetes.io/serviceaccount/token

如果正确挂载就会有输出。

# 讨论

「可以识别的实体」是认证和授权的前提条件。从APIServer的角度看,由两种类型的实体:终端用户;应用程序。终端用户不再K8S的管理范围内,但是k8s提供了代表应用程序的以及资源:ServiceAccount;

严格来讲,应用程序的认证由token认证,并保存在本地的/var/run/secrets/kubernetes.io/serviceaccount/token文件中,该文件通过secret自动挂载。ServiceAccount属于Namespace的资源,访问形式如下:

system:serviceaccount:$NAMESPACE:$SERVICEACCOUNT

查看某个命名空间内的ServiceAccount,可以看到类似的信息:

NAME SECRETS AGE

default 1 179d

这里由一个名为defalut的服务帐号,提示自动创建的。

!!!如果不明确为 Pod 指定 ServiceAccount ,则系统会自动在该 Pod 的 Namespace 内为其分配为 default 的 ServiceAccount 。

10.2. Listing and Viewing Access Control Information

如何查看可用的操作?例如更新部署或列举secret?

假如你采用的是RBAC:

# kubectl auth can-i list pod –as=system:serviceaccount:sec:myappsa -n=sec

查看Namespace中的Role列表:

# kubectl get roles -n=kube-system

# kubectl get clusterroles -n kube-system # 查看命名空间内的ClusterRole列表

上述命令显示预定义的Role列表。

进一步查看允许的操作

# kubectl describe clusterroles/view -n kube-system

还可以自定义角色,下面会介绍。

!!!>

激活RBAC后,在很多环境中,当访问Dashboard会看到Forbidden(403)状态码。

如果想要访问仪表盘,必须要赋予kube-system:default帐号必要的权限:

# kubectl create clusterrolebinding admin4kubesystem –clusterrole=cluster=admin –serviceaccount=kube-system:default

该命令会赋予帐号非常多的权限,不建议在生产环境中进行该操作。

<!!!

RBAC授权由以下几部分组成:

实体:指一组、用户或服务帐号。

资源:Pod、服务、加密信息。

角色:定义了访问资源的行为规则。

角色绑定:将角色赋予实体。

资源 <- 角色 <- 角色绑定 -> 实体

一个角色在规则内可以进行的操作包括:

get list watch create update patch delete

角色分为两类:

集群范围内的角色:集群角色和他们相应的集群橘色绑定。

命名空间范围的角色:角色和角色绑定。

下面讨论如何创建用户自定义的规则,并应用到角色和资源。

10.3. Controlling Access to Resources

对于既定的用户或应用程序,如何允许或拒绝特定的操作?

加入要限制一个应用,只允许其查看Pod,即查看Pod列表和Pod的详细信息。

# 定义一个Pod,使用为myappsa的ServiceAccount:

kind: Pod
apiVersion: v1
metadata:
  name: myapp
  namespace: sec
spec:
  serviceAccountName: myappsa
  container:
    - name: main
      image: centos:7

# 定义一个Role,名为podreader,并定义了访问操作:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: podreader
  namespace: sec
rules:
  - apiGroups: [""]
    resources: ["pod"]
    verbs: ["get", "list"]

# 角色绑定

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: podreaderbindging
  namespace: sec
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: podreader
subjects:
  - kind: ServiceAccount
    name: myappsa
    namespace: sec

定义号YAML文件后,就可以直接使用kubectl create -f 命令进行创建。

或者不使用文件,从命令行直接创建:

# kubectl create role podreader –verb=get –verb=list –resource=pods -n sec

# kubectl create rolebinding podreaderbinding –role=sec:podreader –serviceaccount=sec:myappsa –namesepace sec -n sec

上面是命名空间内的访问控制设置,因为上述使用的是角色和角色绑定。对于集群范围的访问控制应该使用clusterrole和clusterrolebinding命令。

何时应该使用集群角色,何时应该使用角色?

在命名空间内,及命名空间内的资源,可以使用角色和角色绑定。

如果想在多个命名空间内重复使用某个角色,那应该使用集群角色和角色绑定定

如果想限制节点等集群范围资源的访问,或限制所有命名空间都有的命名空间资源的访问,那么可以使用集群角色和集群角色绑定。

10.4. Securing Pods

加强Pod的安全?

如何在Pod级别为应用定义安全上下文环境?例如,以非特权进程运行该应用,或者限制该应用可以访问的卷的类别

在Pod的spec中使用securityContext字段。

例如以非root用户运行一个应用:

kind: Pod
apiVersion: v1
metadata:
  name: secpod
spec:
  containers:
  - name: shell
    image: centos:7
    command:
      - "sh"
      - "-c"
      - "whatever"
    securityContext:
      runAsUser: 5000

另外一个加强安全级别的方法是使用更强大的「Pod安全策略」(PSP, Pod Security Policies)。可以定义一系列策略,包括一些与上述类似的操作,以及与存储和网络相关的限制。