k8s_day_07_01
一、k8s系统访问控制基础
系统访问控制:
插件化实现了三个功能:
认证 Authn : 用户身份认证 ,以确保仅能被系统所许可的人访问
授权 Authz :虽然都能认证成功 ,但是应该针对不同级别的用户赋予不同权限,实现权限的分配和管理
准入控制 Admission: 审计功能。 执行一些独特的功能 ,体现在以下2方面 检验(Validation) 、变异(?)。检查用户提交数据的规范 是否是apisever 所定义的格式的。 把用户提交的不符合规范的数据范式化(纠正补全)。 只发挥在 用户的“写请求” 上

如图
关于k8s的客户端
在k8s 上 ,认为用户有2类:
- User Account:人类用户,k8s不负责存储和管理这类用户;需要借助外部的组件实现;
- Service Account:由k8s之上运行的Pod中的应用程序在访问API Server时认证使用;是标准的k8s资源类型之一,隶属于名称空间级别;
k8s 用户组
k8s 内建的默认系统组:
- system:unauthenticated:未能通过任何一个授权插件检验的账号的所有未通过认证测试的用户统一隶属的用户组;()
- system:authenticated:认证成功后的用户自动加入的一个专用组,用于快捷引用所有正常通过认证的用户账号;
- system:serviceaccounts:所有名称空间中的所有ServiceAccount对象;
- system:serviceaccounts:<namespace>:特定名称空间内所有的ServiceAccount对象。
k8s 认证方式:
-
X509数字证书认证;
证书中的Subject中的 CommonName, CN 被当作用户名; Orgnization, O:组名; -
引导令牌(Token):
一个令牌 就是代表身份id。==这个身份也背后也隐藏代表了身份权限== 很多时候即代表用户用户名也代表密码。比如kubeam worker 节点加集群时用到的那个
-
静态令牌:
存储于API Server进程可直接加载到的文件中保存的令牌,该文件内容会由API Server缓存于内存中,如果修改了要生效必须重启api; -
静态密码:
存储于API Server进程可直接加载到的文件中保存的账户和密码令牌,该文件内容会由API Server缓存于内存中;类似Linux中的/etc/paasswd -
ServiceAccount令牌:
专门给做ServiceAccount类型应用认证。 和其他类型的令牌认证没有什么区别,只是使用场景不一样
-
OpenID Connect令牌:
OIDC令牌,web认证,第三方集中式认证的常用方式。使用 OAuth 2协议。公有云服务支持这种协议 -
Webhook令牌: 了解
-
代理认证: apiserver 支持从http 请求头部的值识别用户
k8s 授权方式/插件:
- Node: 主要对 kubelet 做访问控制的
- ABAC:Attribution,属性。 基于属性的访问控制 ,可以理解为对k8s资源字段做访问控制。 比较复杂,可使用OPA 开放权限控制管理。
- RBAC: Role-Based AC, 基于角色的访问控制
- Webhook: 基于http回调机制实现外部rest服务检查
准入控制器:
k8s 支持数10中, 不同版本支持的不一样。 具体的必须查文档。 以下常用的3种
-
LimitRanger
限制单个具体pod应用 使用的物理资源配额
-
ResourceQuota:
用于为名称空间设置可用资源上限。比如运行多少个pod
-
PSP: PodSecurityPolicy
在集群级别限制用户使用哪些特权。比如共享宿主机网络
二、ServiceAccount认证 详解
ServiceAccount
简称 sa
[root@master01 ~]# kubectl api-resources|grep sa
serviceaccounts sa v1 true ServiceAccount
[root@master01 ~]#
[root@master01 ~]# kubectl get sa
NAME SECRETS AGE
default 1 11d
[root@master01 ~]#
总结:
K8S自动为每个Pod注入一个ServiceAccount,用于ServiceAccount令牌 认证
在每个名称空间中,会自动存在(由ServiceAccount准入控制器负责)一个默认的 ServiceAccount对象 default ,将被该空间下的每个Pod共享使用。pod 通过挂载==‘default-token’== secret开头存储卷 ,使用sa 信息。
[root@master01 ~]# kubectl get secrets |grep 'default-token'
default-token-wnrlv kubernetes.io/service-account-token 3 11d
[root@master01 ~]# kubectl describe secrets/default-token-wnrlv
Name: default-token-wnrlv
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: 27ee5a19-fc86-4163-868e-56da28b41249
Type: kubernetes.io/service-account-token
Data
====
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjJLZXBTSDdfYThxVkdJNVd1VTVYU3h5VjJvV0V2V3lhU2cyMXZGc3F1OVUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjbt BITJPzFIhubNJ5Pne-AIdQ8JaRpp4GohtD4flHaX_ushhu4vZvs5mkvrUlkz3xzdt3v5P4GedP8ghmRRWwmY0gHompl68fCz0psgkfWYnZukzLOvTAopENBfONLtZYWNXoC4Y-MPYvnYt-srE6LAoSdp-7-xkFnK38qtu9OQ
ca.crt: 1066 bytes
认证令牌保存于该空间下的一个Secret对象中,该对象中共有三个信息:
1、namespace
2、ca.crt
3、token
验证
[root@node01 ~]# kubectl exec -it mypod -- /bin/sh
[root@mypod /]# cd /var/run/secrets/kubernetes.io/serviceaccount
[root@mypod /run/secrets/kubernetes.io/serviceaccount]# ls
ca.crt namespace token
[root@mypod /run/secrets/kubernetes.io/serviceaccount]# cat ca.crt
-----BEGIN CERTIFICATE-----
MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTIxMTIxMzAzNTIxOFoXDTMxMTIxMTAzNTIxOFowFTETMBEGA1UE
AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALgM
F3tdVVHdsHqTm5ifpW77W+XoBCIjWJBf4Qw3Gcs7q3ksU7YEDZnk9B+DysaDdFir
qz6sECKQd7HJ3TAPKFOvqGHr6CiVhRKHvNgVMzjsoRx2gt5M5Ol+dl/1BjNXZiHm
LDXkIE1EZ9tNoP0a6/L1G+OkBVwDRWIjM0HFFJBrG/uviCPdsoNaRwsLHz2THWBQ
axgQSo8mviU5mjbuO1sGLuuvynMgcKauIx+HZ8gxPjwETkKNdUxzE/ekdKKw2bvQ
/mlQWzoakc5a3MkDosN+4VDyQzbUmBmkfpXU0VURci1ssfuPRbs9gi3bP2sLyg5t
CMrOeNryBAqYqu5P2d0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
/wQFMAMBAf8wHQYDVR0OBBYEFEDhztlc7NHyal3QbtwkpI4q7SAMMA0GCSqGSIb3
DQEBCwUAA4IBAQBNVvLrg36ZKVqgoGg+rpAut++1ljDwRe+ALxm72H67eyygmuII
wnPXBvdcUph9iS40/lnn17QOf/7AXoxrr7tRBaN2tkAo9K0ITl1Lz2tTN+XH+8fE
vlxfuFalrmviyvjhCIFVA9EXhGnjyoFlDuY3dlrF3fUd+/AEVV4AdVPmvFPjgUBr
XdEAUKf92/c1Uwxv+goX00enuPE5k79qc7Oz65LWW0RCXYklkxcHZvDx9TpJ8snU
pG4R6xKztyYp+Db+Vei/mZBxfbr0gT1h48hAZi1tCvIplKSv6kBEHgySjVzS3N9O
cjo4RIXr5jPbHdDA20+n2Sq3Apy9DLOCLXGr
-----END CERTIFICATE-----
[root@mypod /run/secrets/kubernetes.io/serviceaccount]# cat namespace
[root@mypod /run/secrets/kubernetes.io/serviceaccount]# cat token
eyJhbGciOiJSUzI1NiIsImtpZCI6IjJLZXBTSDdfYThxVkdJNVd1VTVYU3h5VjJvV0V2V3lhU2cyMXZGc3F1OVUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4td25ybHYiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjI3ZWU1YTE5LWZjODYtNDE2My04NjhlLTU2ZGEyOGI0MTI0OSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.r52XszRDvPUUNqHd7g9ovhmrBV9C9N7lkCEEpnS-I4pIcVfEY0dS_uEtD71M-SCWaR6AunwqZVpLIvXbkRMrvxZ9CwDYpIzb7J6BmI6JLb2AobkvFcy22x_DCYU66d68pUxPVoWUYVxhrL9MfxhNtMVDh1COlHMcR2ktp7EIU9GocyBITJPzFIhubNJ5Pne-AIdQ8JaRpp4GohtD4flHaX_ushhu4vZvs5mkvrUlkz3xzdt3v5P4GedP8ghmRRWwmY0gHompl68fCz0psgkfWYnZukzLOvTAopENBfONLtZYWNXoC4Y-MPYvnYt-srE6LAoSdp-7-xkFnK38qtu9OQ[root@mypod /run/secrets/kubernetes.io/serviceaccount]#
例子1 :命令自定义sa
[root@node01 ~]# kubectl create ns dev
namespace/dev created
[root@node01 ~]# kubectl get sa -n dev
NAME SECRETS AGE
default 1 16s
[root@node01 ~]# kubectl create sa admin -n dev
serviceaccount/admin created
[root@node01 ~]# kubectl get secret -n dev
NAME TYPE DATA AGE
admin-token-tkm7w kubernetes.io/service-account-token 3 14s
default-token-dwmh6 kubernetes.io/service-account-token 3 111s
[root@node01 ~]# kubectl get sa -n dev
NAME SECRETS AGE
admin 1 31s
default 1 2m8s
[root@node01 ~]#
注意: 创建sa 的同时会自动创建对应的 secret
sa 资源格式:
apiVersion: v1 # ServiceAccount所属的API群组及版本
kind: ServiceAccount # 资源类型标识
metadata:
name <string> # 资源名称
namespace <string> # ServiceAccount是名称空间级别的资源
automountServiceAccountToken <boolean> # 是否让Pod自动挂载API令牌
secrets <[]Object> # 以该SA运行的Pod所要使用的Secret对象组成的列表
apiVersion <string> # 引用的Secret对象所属的API群组及版本,可省略
kind <string> # 引用的资源的类型,这里是指Secret,可省略
name <string> # 引用的Secret对象的名称,通常仅给出该字段即可
namespace <string> # 引用的Secret对象所属的名称空间
uid <string> # 引用的Secret对象的标识符;
imagePullSecrets <[]Object> # 引用的用于下载Pod中容器镜像的Secret对象列表
name <string> # docker-registry类型的Secret资源的名称
例子2 :手动创建sa 和 secret
[root@node01 chapter9]# cat serviceaccount-demo.yaml
# serviceaccount/k8sadmin
# Maintainer: MageEdu <mage@magedu.com>
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: namespace-admin
namespace: default
automountServiceAccountToken: true # 这里默认就是true
[root@node01 chapter9]#
[root@node01 chapter9]# cat secret-token.yaml
apiVersion: v1
kind: Secret
metadata:
name: k8sadmin-secret
namespace: default
annotations:
kubernetes.io/service-account.name: k8sadmin # name和上面的sa未保持一致 ,仅仅演示而已
type: kubernetes.io/service-account-token