文章目录
一.kubernetes的安全框架
管理kubernetes的有kubectl、api、UI界面
如下是k8s的安全框架图
安全认证流程:kubectl请求api资源,然后通过三层安全机制。
第一层是认证(Authentication),验证身份、用户名和密码或者token;
第二层是授权(Authorization)角色绑定(RBAC),以获得权限;
第三层是准入控制(Admission Control,资源使用限定)。
请求只有通过这三层安全机制,才会被k8s响应请求,创建资源。
- k8s的安全控制框架主要由以上3个阶段进行控制,每一个阶段都支持插件方式,通过APIServer配置来启用插件方式,通过APiserver配置来启用插件。
- 普通用户想要安全的访问集群APIServer,往往需要证书、token或者是用户名+密码
- pod访问需要ServiceAccount
[root@master01 demo]# kubectl get serviceaccount
NAME SECRETS AGE
default 1 5d23h
apiserver内部使用8080端口,默认8080端口监听本地,通过master以及其他组件连接使用
[root@master01 demo]# netstat -napt | grep LISTEN | grep 8080
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 67360/kube-apiserve
apiserver外部使用6443端口
[root@master01 demo]# netstat -napt | grep LISTEN | grep 6443
tcp 0 0 192.168.158.10:6443 0.0.0.0:* LISTEN 67360/kube-apiserve
二.Authentication,认证
认证有三种客户端身份认证
HTTPS 证书认证:基于CA证书签名的数字证书认证
HTTP Token认证:通过一个Token来识别用户(生产环境中使用广泛)
HTTP Base认证:用户名+密码的方式认证
HTTPS证书认证,基于CA证书签名的数字证书认证
CA认证如下
[root@master01 demo]# cat /root/k8s/k8s-cert/server-csr.json
{
"CN": "kubernetes",
"hosts": [
"10.0.0.1",
"127.0.0.1",
"192.168.158.10",
"192.168.158.40",
"192.168.158.100",
"192.168.158.110",
"192.168.158.120",
"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"
}
]
}
HTTP Token认证,通过一个Token来识别用户(生产环境中使用广泛)
httpd的令牌认证如下
[root@master01 ~]# cat /opt/kubernetes/cfg/token.csv
2525e5219c98c6fd3747f969838a0456,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
HTTP Base认证,用户名+密码的方式认证
三.Authorization,授权
RBAC(Role-Based Access Control,基于角色的访问控制),负责完成授权(Authorization)工作。
以下是授权模块的相关概念
user:身份验证期间提供的用户字符串;
user:身份验证期间提供的用户字符串;
group:已验证用户所属的组名列表;
extra:任意字符串键到字符串值得映射,由身份验证层提供;
API:指示请求是否针对API资源;
request path:到其他非资源端点得路径;
api request verb:api动作(get、list、create、update、patch、watch、proxy、redirect、delete和deletecollection)等,用于
资源请求。
http request verb:http动作(get、post和delete用于非资源请求);
resource:正在访问得资源的ID或者名称(仅仅用于资源请求),对于使用get、update、patch和delete谓词的资源请求,必须提供资源名称;
subresource:正在访问的资源(仅仅用于资源请求);
namespace:正在访问的子资源(仅用于资源请求);
api group:被访问的api组(仅用于资源请求),一个空字符串指定核心api组
由于RBAC是基于角色进行控制的,所以首先需要创建角色、然后创建绑定的资源、最后将角色与目标甚至api和请求等绑定。绑定api模式适用于二次开发。
四.admission contorl,准入控制
NamespaceLifecycle:命令空间回收
LimitRanger:配额管理
ServiceAccount:每个pod中导入方便访问apiserver
ResourceQuota:基于命名空间的高级配额管理
NodeRestriction:node加入到k8s群集中以最小的权限运行
以下是官方推荐的插件(用于1.11版本以上)
--enable-admission-plugins= \ NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds, ResourceQuota
五.基于授权机制创建新的用户
使用RBAC(基于角色的访问控制)授权,允许通过kubernetes API动态配置策略
主体:user(用户)、Group(用户组)、ServiceAccount(服务账号)
角色:Role(授权特定命名空间的访问权限)、ClusterRole(授权所有命名空间访问权限)
角色绑定:RoleBinding(将角色绑定到主体,即subject)、ClusterRoleBinding(将集群角色绑定到主体)
创建命名空间
[root@master01 ~]# kubectl create ns tom
namespace/tom created
[root@master01 ~]# kubectl get ns
NAME STATUS AGE
default Active 5d23h
kube-public Active 5d23h
kube-system Active 5d23h
tom Active 9s
创建nginx的pod资源
[root@master01 ~]# kubectl run nginx --image=nginx -n tom
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx created
[root@master01 ~]# kubectl get pods -n tom
NAME READY STATUS RESTARTS AGE
nginx-dbddb74b8-qp7c5 0/1 ContainerCreating 0 2d14h
[root@master01 ~]# kubectl get pods -n tom
NAME READY STATUS RESTARTS AGE
nginx-dbddb74b8-qp7c5 1/1 Running 0 2d14h
扩容成三个副本
[root@master01 ~]# kubectl scale deployment/nginx --replicas=3 -n tom
deployment.extensions/nginx scaled
[root@master01 ~]# kubectl get pods -n tom
NAME READY STATUS RESTARTS AGE
nginx-dbddb74b8-pndsr 1/1 Running 0 2d14h
nginx-dbddb74b8-pnsfd 1/1 Running 0 2d14h
nginx-dbddb74b8-qp7c5 1/1 Running 0 2d14h
[root@master01 ~]# kubectl exec -it nginx-dbddb74b8-pndsr /bin/bash -n tom
root@nginx-dbddb74b8-pndsr:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
创建角色
[root@master01 ~]# vim rbac-role.yaml
[root@master01 ~]# cat rbac-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role #指定控制器为Role
metadata:
namespace: tom
name: pod-reader
rules: ##定义规则
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"] ##定义动作
[root@master01 ~]# kubectl apply -f rbac-role.yaml
role.rbac.authorization.k8s.io/pod-reader created
[root@master01 ~]# kubectl get role -n tom
NAME AGE
pod-reader 3m47s
创建角色绑定
[root@master01 ~]# vim rbac-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: tom
subjects: ##指定主体
- kind: User ##指定主体类型,为用户
name: zhangsan
apiGroup: rbac.authorization.k8s.io ##给定的权限
roleRef:
kind: Role ##指定张三用户对pod-reader的读的权限
name: pod-reader
apiGroup: rbac.authorization.k8s.io
[root@master01 ~]# kubectl create -f rbac-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created
[root@master01 ~]# kubectl get role,rolebinding -n tom
NAME AGE
role.rbac.authorization.k8s.io/pod-reader 4m54s
NAME AGE
rolebinding.rbac.authorization.k8s.io/read-pods 10s
设置张三用户仅可以访问pod资源
#创建zhangsan用户的目录
[root@master demo]# mkdir zhangsan
[root@master demo]# cd zhangsan/
#复制证书到目录下
[root@master zhangsan]# cp /root/k8s/k8s-cert/ca* ./
[root@master zhangsan]# ls
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
[root@master zhangsan]# vim rbac-user.sh
[root@localhost zhangsan]# cat rbac-user.sh
cat > zhangsan-csr.json <<EOF
{
"CN": "zhangsan",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes zhangsan-csr.json | cfssljson -bare zhangsan
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://192.168.158.100:6443 \
--kubeconfig=zhangsan-kubeconfig
kubectl config set-credentials zhangsan \
--client-key=zhangsan-key.pem \
--client-certificate=zhangsan.pem \
--embed-certs=true \
--kubeconfig=zhangsan-kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=zhangsan \
--kubeconfig=zhangsan-kubeconfig
kubectl config use-context default --kubeconfig=zhangsan-kubeconfig
[root@localhost zhangsan]# cat rbac-user.sh
cat > zhangsan-csr.json <<EOF
{
"CN": "zhangsan",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes zhangsan-csr.json | cfssljson -bare zhangsan
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://192.168.158.100:6443 \
--kubeconfig=zhangsan-kubeconfig
kubectl config set-credentials zhangsan \
--client-key=zhangsan-key.pem \
--client-certificate=zhangsan.pem \
--embed-certs=true \
--kubeconfig=zhangsan-kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=zhangsan \
--kubeconfig=zhangsan-kubeconfig
kubectl config use-context default --kubeconfig=zhangsan-kubeconfig
[root@localhost zhangsan]# cat
ca-config.json ca-key.pem rbac.yaml zhangsan-key.pem
ca.csr ca.pem zhangsan.csr zhangsan-kubeconfig
ca-csr.json rbac-user.sh zhangsan-csr.json zhangsan.pem
[root@localhost zhangsan]# cat rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
namespace: default
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sa-read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: pod-reader
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
安装格式化工具
[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
[root@localhost zhangsan]# bash rbac-user.sh
2021/01/30 01:51:00 [INFO] generate received request
2021/01/30 01:51:00 [INFO] received CSR
2021/01/30 01:51:00 [INFO] generating key: rsa-2048
2021/01/30 01:51:00 [INFO] encoded CSR
2021/01/30 01:51:00 [INFO] signed certificate with serial number 321232859891660529703164418849245157146185837478
2021/01/30 01:51:00 [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" modified.
Switched to context "default".
#证书如下
[root@localhost zhangsan]# ll
总用量 52
-rw-r--r--. 1 root root 294 1月 30 01:41 ca-config.json
-rw-r--r--. 1 root root 1001 1月 30 01:41 ca.csr
-rw-r--r--. 1 root root 263 1月 30 01:41 ca-csr.json
-rw-------. 1 root root 1675 1月 30 01:41 ca-key.pem
-rw-r--r--. 1 root root 1359 1月 30 01:41 ca.pem
-rw-r--r--. 1 root root 887 1月 30 01:48 rbac-user.sh
-rw-r--r--. 1 root root 835 1月 8 2020 rbac.yaml
-rw-r--r--. 1 root root 956 1月 30 01:51 zhangsan.csr
-rw-r--r--. 1 root root 181 1月 30 01:51 zhangsan-csr.json
-rw-------. 1 root root 1679 1月 30 01:51 zhangsan-key.pem
-rw-------. 1 root root 6195 1月 30 01:51 zhangsan-kubeconfig
-rw-r--r--. 1 root root 1346 1月 30 01:51 zhangsan.pem
#查看证书
[root@localhost zhangsan]# cat zhangsan-kubeconfig
#使用zhangsan-kubeconfig访问pod资源
[root@localhost zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get pods -n tom
NAME READY STATUS RESTARTS AGE
nginx-dbddb74b8-pndsr 1/1 Running 0 2d15h
nginx-dbddb74b8-pnsfd 1/1 Running 0 2d15h
nginx-dbddb74b8-qp7c5 1/1 Running 0 2d15h
#使用zhangsan-kubeconfig访问 svc资源就会被拒绝
[root@localhost zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get svc -n tom
[root@localhost zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get svc -n tom
Error from server (Forbidden): services is forbidden: User "zhangsan" cannot list resource "services" in API group "" in the namespace "tom"
对于UI界面的访问控制,创建对于kgc的命名空间里的资源才能看见的令牌
[root@localhost zhangsan]# vim sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
namespace: tom
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sa-read-pods
namespace: tom
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 tom
NAME SECRETS AGE
default 1 2d15h
pod-reader 1 7s
[root@localhost zhangsan]# kubectl describe secret pod-reader -n tom
使用令牌登录