一、安全机制

1.kubernetes的安全框架
2.传输安全,认证,授权,准入控制
3.使用RBAC授权

1)kubernetes安全框架

在这里插入图片描述

流程:kubectl先请求api资源,然后是过三关,第一关是认证(Authentication),第二关是授权(Authorization),第三关是准入控制(Admission Control),只有通过这三关才可能会被k8s创建资源。
K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。
普通用户若要安全访问集群API Server,往往需要证书、Token 或者用户名+密码;Pod访问,需要ServiceAccount

第一步:对客户端访问进行认证操作,确认是否具有访问k8s权限
token(共享秘钥)
SSL(双向SSL认证)
通过任何一个认证即表示认证通过,进入下一步
第二步:授权检查,确认是否对资源具有相关的权限
ABAC(基于属性的访问控制)
RBAC(基于角色的访问控制)
NODE(基于节点的访问控制)
WEB HOOK(自定义HTTP回调方法的访问控制)
第三步:准入控制(对操作资源相关联的其他资源是否有权限操作)

(一)、Service Account详解

https://github.com/kubernetes/kubernetes/blob/release-1.0/examples/cassandra/java/src/io/k8s/cassandra/KubernetesSeedProvider.java#L101

Service Account 是 Kubernetes 用于集群内运行的程序,进行服务发现时调用 API 的帐号,帐号的 token 会直接挂载到 Pod 中,可以供程序直接使用。
Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同
  1.User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
  2.User account是跨namespace的,而service account则是仅局限它所在的namespace;
  3.每个namespace都会自动创建一个default service account
  4.Token controller检测service account的创建,并为它们创建secret
  5.开启ServiceAccount Admission Controller后
1.每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccout)
    2.验证Pod引用的service account已经存在,否则拒绝创建
    3.如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
    4.每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/

(二)、apiserver使用的是token认证

[root@localhost demo]# ps aux | grep apiserver
...
--token-auth-file=/opt/kubernetes/cfg/token.csv 
...

//可以通过ServiceAccount在pod中去访问apiserver

[root@localhost demo]# kubectl get sa
NAME      SECRETS   AGE
default   1         22d

传输安全:告别8080,迎接6443
//默认8080监听本地(是通过master及其他组件连接使用)

[root@localhost demo]# netstat -natp | grep 8080 | grep LISTEN
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      831/kube-apiserver  

//对外提供服务端口是6443

[root@localhost demo]# netstat -natp | grep 6443 | grep LISTEN
tcp        0      0 192.168.195.149:6443    0.0.0.0:*               LISTEN      831/kube-apiserver  

二、第一模块:认证

三种客户端身份认证:
HTTPS 证书认证:基于CA证书签名的数字证书认证
HTTP Token认证:通过一个Token来识别用户(生产环境中使用广泛)
HTTP Base认证:用户名+密码的方式认证

(一)、https证书认证

[root@localhost demo]# cat /root/k8s/k8s-cert/k8s-cert.sh 
{
    "CN": "kubernetes",
    "hosts": [
      "10.0.0.1",
      "127.0.0.1",
      "192.168.195.148",
      "192.168.195.149",
      "192.168.195.100",
      "192.168.195.140",
      "192.168.195.141",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}

(二)、httpd的token认证

[root@localhost demo]# cat /opt/kubernetes/cfg/token.csv 
6351d652249951f79c33acdab329e4c4,kubelet-bootstrap,10001,"system:kubelet-bootstrap"

三、第二模块:授权

RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。
在这里插入图片描述

四、第三模块:准入控制

Adminssion Control实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控制器 插件的检查,检查不通过,则拒绝请求。

[root@localhost demo]# ps aux | grep apiserver
...
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction
...

NamespaceLifecycle: 命令空间回收
LimitRanger:配额管理
ServiceAccount: 每个pod中导入方便访问apiserver
ResourceQuota: 基于命名空间的高级配额管理
NodeRestriction: Node加入到k8s群集中以最小权限运行
以下是官方推荐插件
1.11版本以上推荐使用的插件:
–enable-admission-plugins= \ NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds, ResourceQuota
//使用RBAC授权
RBAC(Role-Based Access Control,基于角色的访问控制),允许通过Kubernetes API动态配置策略。
在这里插入图片描述

角色
Role:授权特定命名空间的访问权限
ClusterRole:授权所有命名空间的访问权限

角色绑定
RoleBinding:将角色绑定到主体(即subject)
ClusterRoleBinding:将集群角色绑定到主体

主体(subject)
User:用户
Group:用户组
ServiceAccount:服务账号
https://kubernetes.io/docs/reference/access-authn-authz/rbac/

//创建命名空间

[root@localhost demo]# kubectl create ns kgc
namespace/kgc created
[root@localhost demo]# kubectl get ns
NAME          STATUS   AGE
default       Active   22d
kgc           Active   5s
kube-public   Active   22d
kube-system   Active   22d

//创建nginx的pod

[root@localhost demo]# kubectl run nginx --image=nginx -n kgc
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx created

//扩容成3个副本

[root@localhost demo]# kubectl scale deploy/nginx --replicas=3 -n kgc
deployment.extensions/nginx scaled

//查看

[root@localhost demo]# kubectl get pods -n kgc
NAME                    READY   STATUS    RESTARTS   AGE
nginx-dbddb74b8-22gp7   1/1     Running   0          109s
nginx-dbddb74b8-pzxz6   1/1     Running   0          33s
nginx-dbddb74b8-vwndx   1/1     Running   0          33s

//官方模板
在这里插入图片描述

//创建role

[root@localhost demo]# vim rbac-role.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: kgc
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

[root@localhost demo]# kubectl apply -f rbac-role.yaml 
role.rbac.authorization.k8s.io/pod-reader created
[root@localhost demo]# kubectl get role -n kgc
NAME         AGE
pod-reader   48s

//创建rolebinding
在这里插入图片描述

[root@localhost demo]# vim rbac-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: kgc
subjects:
- kind: User
  name: zhangsan
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role   
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

[root@localhost demo]# kubectl apply -f rbac-rolebinding.yaml 
rolebinding.rbac.authorization.k8s.io/read-pods created
[root@localhost demo]# kubectl get role,rolebinding -n kgc
NAME                                        AGE
role.rbac.authorization.k8s.io/pod-reader   9m22s

NAME                                              AGE
rolebinding.rbac.authorization.k8s.io/read-pods   39s

//拷贝rbac.yaml和rbac-user.sh文件到/root/demo中

[root@localhost demo]# mkdir zhangsan
[root@localhost demo]# mv rbac-user.sh zhangsan/

//证书拷贝到zhangsan目录

[root@localhost zhangsan]# cp /root/k8s/k8s-cert/ca* ./

//修改地址为apiserver访问地址(负载均衡VIP)

[root@localhost zhangsan]# vim rbac-user.sh 
kubectl config set-cluster kubernetes \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --server=https://192.168.195.100:6443 \
  --kubeconfig=zhangsan-kubeconfig

//安装格式化工具

[root@localhost zhangsan]# yum install dos2unix -y

//格式化

[root@localhost zhangsan]# dos2unix rbac-user.sh 
dos2unix: converting file rbac-user.sh to Unix format ...
[root@localhost zhangsan]# bash rbac-user.sh 
2020/02/21 13:08:40 [INFO] generate received request
2020/02/21 13:08:40 [INFO] received CSR
2020/02/21 13:08:40 [INFO] generating key: rsa-2048
2020/02/21 13:08:41 [INFO] encoded CSR
2020/02/21 13:08:41 [INFO] signed certificate with serial number 165410289803504337012351191503921866329251297724
2020/02/21 13:08:41 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
Cluster "kubernetes" set.
User "zhangsan" set.
Context "default" created.
Switched to context "default".

//查看证书

[root@localhost zhangsan]# cat zhangsan-kubeconfig 

//使用zhangsan-kubeconfig访问pod资源

[root@localhost zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get pods -n kgc
NAME                    READY   STATUS    RESTARTS   AGE
nginx-dbddb74b8-22gp7   1/1     Running   0          23h
nginx-dbddb74b8-pzxz6   1/1     Running   0          23h
nginx-dbddb74b8-vwndx   1/1     Running   0          23h

//使用zhangsan-kubeconfig访问 svc资源就会被拒绝

[root@localhost zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get svc -n kgc
Error from server (Forbidden): services is forbidden: User "zhangsan" cannot list resource "services" in API group "" in the namespace "kgc"

//也无法访问默认的命名空间

[root@localhost zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get svc 
Error from server (Forbidden): services is forbidden: User "zhangsan" cannot list resource "services" in API group "" in the namespace "default"

//UI访问控制

[root@localhost zhangsan]# kubectl get svc -n kube-system
NAME                   TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns               ClusterIP   10.0.0.2     <none>        53/UDP,53/TCP   4d13h
kubernetes-dashboard   NodePort    10.0.0.243   <none>        443:30001/TCP   15d

//访问地址https://192.168.195.150:30001/
//查看令牌

[root@localhost zhangsan]# kubectl describe secret dashboard-admin-token-qctfr -n kube-system

[root@localhost zhangsan]# vim sa.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-reader
  namespace: kgc

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: sa-read-pods
  namespace: kgc
subjects:
- kind: ServiceAccount
  name: pod-reader
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

[root@localhost zhangsan]# kubectl apply -f sa.yaml 
serviceaccount/pod-reader created
rolebinding.rbac.authorization.k8s.io/sa-read-pods created
[root@localhost zhangsan]# kubectl get sa -n kgc
NAME         SECRETS   AGE
default      1         24h
pod-reader   1         38s

//查看token

[root@localhost zhangsan]# kubectl describe secret pod-reader -n kgc
Name:         pod-reader-token-2cpjb
Namespace:    kgc
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: pod-reader
              kubernetes.io/service-account.uid: f4b4c256-546a-11ea-895a-000c297a15fb

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1359 bytes
namespace:  3 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrZ2MiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoicG9kLXJlYWRlci10b2tlbi0yY3BqYiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJwb2QtcmVhZGVyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZjRiNGMyNTYtNTQ2YS0xMWVhLTg5NWEtMDAwYzI5N2ExNWZiIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmtnYzpwb2QtcmVhZGVyIn0.uRNQcjjk7mhW86H3tziJgeEmLkA2H_NL45LZ8VV5JFfUQOluVLR_CrpiHMn97Afla2P9rBkbldEF9nNGt0WnFMPV3AMK0L_UzydVm97eIn_0t_6np8XI5luvmtt8Xavs3-jpkeXdtoSlbGQNNrerndmAh5tvzfJGJkI8-upV_NMVqw8mT27a9G038Qtqk7CEEIyoHbo05cILx_O5Nr9jnZUl3HTdTjuJOr3O0yAcfpnoZSTMUcotuy8FNaadLOCcn2VxY9f9MTMMtFdFsDWDhl6w5CMBGSSg6vFVwbJrr5nn1Z83MyYuQJhId_724J4axHnz__1sLjarSmJxDbDxLw

//登录成功界面
在这里插入图片描述

//只有权限看到容器

在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐