认证


开启 TLS时,所有的请求都需要首先认证。Kubernetes支持多种认证机制,并支持同时开启多个认证插件(只要有一个认证通过即可)。

如果认证成功,则用户的 username 会传入授权模块做进一步授权验证,而对于认证失败的请求则返回 HTTP 401。

当apiserver启动的时候,其实有两个和安全相关的配置,一个叫insecure-port,一个叫secure-port,早期大家很习惯的将insecure-port打开,经过insecure-port端口所有的请求其实是没有做任何的安全校验的,也就是认证,鉴权这些逻辑是不走的,这样就面临着一个危险,所有的request是没有认证的,不管是谁发的,它有没有权限,它都会被接受,这很可能就会有一些恶意的请求。

所以现在在非生产环境也会将insecure端口关掉。

另外一个是secure port,secure-port设置之后所有的认证,鉴权这些逻辑都要走。

[root@k8s-master cfg]# vim kube-apiserver.conf
--secure-port=6443 \

认证插件


针对开放式的框架,它一定会支持很多很多的认证方式。

X509 证书

  • 使用X509客户端证书只需要 API Server启动时配置--client-ca-file=SOMEFILE。在证书认证时,其CN 域用作用户名,而组织机构域则用作 group 名。

证书一般会有key和cert,cert在签发的时候是发给什么机构,哪个人的。这样你带着一个证书来访问apiserver的时候,它有签发你证书的ca文件,它就能够解析出来你的certificates,它就能够知道你是谁。

CN 是请求用户的用户名  O:是请求用户的组名

cat > ca-csr.json <<EOF
{"CN": "Kubernetes","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "China","O": "Kubernetes","OU": "CA","ST": "Zhejiang"}]
}
EOF

静态Token 文件

  • 使用静态 Token 文件认证只需要 API Server启动时配置--token-auth-file=SOMEFILE。
  • 该文件为 csv格式,每行至少包括三列 token,username,userid,token,user,uid,"group1,group2,group3"

apiserver启动的时候要配置一个token-auth-file,在这个csv文件里面配置用户名,用户id,以及对应的token,和用户属于哪些组配置在这个scv文件里面,它有点像简化的数据库,其实也即是将用户名和对应的token发到这里面,然后在apiserver启动的时候加载这个文件,那apiserver就知道我这个集群可以接受哪些用户请求,你带着用户token过来,它就能够判断这个token是不是合法的,如果合法就知道对应的user是谁,它就可以将这个请求接受掉了。

  • 为了支持平滑地启动引导新的集群,Kubernetes 包含了一种动态管理的持有者令牌类型,称作启动引导令牌(Bootstrap Token)。
  • 这些令牌以 Secret 的形式保存在kube-system名字空间中,可以被动态管理和创建。
  • 控制器管理器包含的 TokenCleaner控制器能够在启动引导令牌过期时将其删除。
  • 在使用kubeadm 部署Kubernetes 时,可通过 kubeadm token list 命令查询。

在k8s启动的时候有bootstrap token,它也是可以做认证的。

静态密码文件

  • 需要API Server 启动时配置--basic-auth-file=SOMEFILE,文件格式为cSV,每行至少三列 password,user,uid,后面是可选的group名 password,user,uid,"group1,group2,group3"。(和静态token类似,只不过文件里面存放着密码)

OpenID

OAuth 2.0的认证机制

ServiceAccount

ServiceAccount是 Kubernetes 自动生成的,并会自动挂载到容器的/run/secrets/kubernetes.io/serviceaccount 目录中。

当你去建立任何的namespace的时候,k8s就有一个控制器,它看见namespace创建了,它就会去建立sa,它会生成token,这个token签发的内容其实就是代表了这个token签发给哪个namespace的,哪个serviceaccount的,这个token是apiserver签发的,所以你带着token去访问apiserver的时候,它就知道这个token合法还是非法,代表的是哪个namespace,哪个serviceaccount。

静态token 示例


https://github.com/cncamp

https://github.com/cncamp/101/tree/master/module6/basic-auth

[root@master ~]# mkdir -p /etc/kubernetes/auth[root@master auth]# cat static-token
cncamp-token,cncamp,1000,"group1,group2,group3"

在这个scv文件里面创建了用户,token叫做cncamp-token,这个是用户的token。用户名是cncamp,它的uid是1000,然后它放到3个group里面,这就是简单的token文件。

如果我们要去启用静态的token,那么我要去修改apiserver的配置文件,这个就是告诉apiserver说,这个文件里面的内容我是承认的。也即是将主机的文件mount到apiserver的pod里面。

在这个pod的volumes里面定义了一个hostpath的volume

更新完apiserver的yaml文件会去做个重启,如果get pod成功那么说明api-server重启成功。

这里面加了header,这个header加了token,这个token代表了cncamp这个用户,直接发rest

api调用通过curl命令。

[root@master manifests]# curl https://192.168.111.8:6443/api/v1/namespaces/default -H "Authorization: Bearer cncamp-token" -k
{"kind": "Status","apiVersion": "v1","metadata": {},"status": "Failure","message": "namespaces \"default\" is forbidden: User \"cncamp\" cannot get resource \"namespaces\" in API group \"\" in the namespace \"default\"","reason": "Forbidden","details": {"name": "default","kind": "namespaces"},"code": 403
  volumes:- hostPath:path: /etc/kubernetes/authtype: DirectoryOrCreatename: auth-files- mountPath: /etc/kubernetes/authname: auth-files readOnly: true- --token-auth-file=/etc/kubernetes/auth/static-token

可以看到由于权限的问题,它的code是403是鉴权不过的,其实认证是通过的,因为它知道你的token对应的用户是cncamp。

[root@master manifests]# curl https://192.168.111.8:6443/api/v1/namespaces/default -H "Authorization: Bearer cncamp-token" -k
{"kind": "Status","apiVersion": "v1","metadata": {},"status": "Failure","message": "namespaces \"default\" is forbidden: User \"cncamp\" cannot get resource \"namespaces\" in API group \"\" in the namespace \"default\"","reason": "Forbidden","details": {"name": "default","kind": "namespaces"},"code": 403

也就是说带着cncamp的token去访问apiserver,它已经去本地的static token file里面去校验token代表哪个用户了,它查找到了这个用户并且说这个用户没有权限,其实整个的认证就已经过了。

x509证书


如果能够使用kubernetes自己的ca去签发X509证书,那么它是直接可以认的。

   - --client-ca-file=/etc/kubernetes/pki/ca.crt

kubeadm搭建的集群,本身就使用了x509证书

ServiceAccount


当创建任何的serviceaccount的时候,在这个namespace里面,其实k8s会自动的在这个namspace里面创建一个叫default的serviceaccount,所谓的serviceaccount就是系统账号。

每个系统账号会有对应的secret,可以看到有ca文件,还有namespace,这个是base64加密了的,还有一个token,这个其实就是apiserver签发的jwt token,和之前静态token是类似的。

可以看到只要带着这个token去访问apiserver,apiserver就能够认出我是谁,配合权限控制那么就可以根据这个token去访问apiserver里面的任何对象。

如果基于内置的认证方式还不能满足你需求,公司有自己的认证系统,认证方式都在集群之外,那么怎么使得k8s集群和这些认证平台去集成,那么就需要通过webhook,k8s认证也支持webhook。

你可以基于webhook来配置来指向外部的认证服务器,有了这种认证集成的方式之后,那么k8s就可以和任何平台去做集成。

Webhook 令牌身份认证


  • --authentication-token-webhook-config-file  指向一个配置文件,其中描述如何访问远程的Webhook服务。
  • --authentication-token-webhook-cache-ttl   用来设定身份认证决定的缓存时间。默认时长为2分钟。

匿名请求

  • 如果使用AlwaysAllow 以外的认证模式,则匿名请求默认开启,但可用--anonymouSs-auth=false禁止匿名请求。

Kubernetes API准备工作


创建一个NS名称空间, 专用于运行Pod;

kubectl create ns jenkins

创建一个secret关联serviceaccount和role,操作K8s API

# 创建role
kubectl -n jenkins create role jenkinsadmin \
--verb=create,delete,update,list,get,patch \
--resource=pods# 创建服务账户
kubectl -n jenkins create serviceaccount jenkinsadmin# 创建角色绑定
kubectl -n jenkins create rolebinding jenkinsadmin --role=jenkinsadmin --serviceaccount=jenkins:jenkinsadmin# 创建secret
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:name: jenkinsadmin-tokennamespace: jenkinsannotations:kubernetes.io/service-account.name: jenkinsadmin
type: kubernetes.io/service-account-token
EOFwhile ! kubectl -n jenkins describe secret jenkinsadmin-token | grep -E '^token' >/dev/null; doecho "waiting for token..." >&2sleep 1
done# 获取令牌
TOKEN=$(kubectl -n jenkins get secret jenkinsadmin-token -o jsonpath='{.data.token}' | base64 --decode)echo $TOKEN# 获取API
kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'# 使用令牌玩转 API
curl -X GET https://127.0.0.1:35659/api --header "Authorization: Bearer $TOKEN" --insecure
[root@192 ~]# curl -X GET https://127.0.0.1:6443/api --header "Authorization: Bearer $TOKEN" --insecure
{"kind": "APIVersions","versions": ["v1"],"serverAddressByClientCIDRs": [{"clientCIDR": "0.0.0.0/0","serverAddress": "192.168.11.134:6443"}]
}

将token 以secret text类型存储到Jenkins

POD API

//删除POD
def DeletePod(namespace, podName){withCredentials([string(credentialsId: 'f66733bf-ef35-402d-87d1-a79510387d2b', variable: 'CICDTOKEN')]) {sh """curl --location --request DELETE "https://192.168.1.200:6443/api/v1/namespaces/${namespace}/pods/${podName}" \--header "Authorization: Bearer ${CICDTOKEN}" \--insecure >/dev/null"""}
}// 创建POD
def CreatePod(namespace, podYaml){withCredentials([string(credentialsId: 'f66733bf-ef35-402d-87d1-a79510387d2b', variable: 'CICDTOKEN')]) {sh """curl --location --request POST "https://192.168.1.200:6443/api/v1/namespaces/${namespace}/pods" \--header 'Content-Type: application/yaml' \--header "Authorization: Bearer ${CICDTOKEN}" \--data "${podYaml}" --insecure >/dev/null"""}
}
curl --location --request POST "https://192.168.11.134:6443/api/v1/namespaces/jenkins/pods" \
--header 'Content-Type: application/yaml' \
--header "Authorization: Bearer ${TOKEN}" \
--data "${podYaml}" --insecure >/dev/nullcurl --location --request DELETE "https://192.168.11.134:6443/api/v1/namespaces/jenkins/pods/nginx" \
--header "Authorization: Bearer ${TOKEN}" \
--insecure >/dev/null

curl --location --request GET 'https://192.168.11.134:6443/api/v1/namespaces/jenkins/pods' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjBqSWxfOExtSW1pVmpKVkFUVGFQbHp1ZE5TcFo0SjlmOUtjMWFveWtrZGMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJqZW5raW5zIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImplbmtpbnNhZG1pbi10b2tlbi1jbTRsNyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJqZW5raW5zYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjMDAwZTVhMC00Yzg0LTQyZWEtYmJiNy1mZmM5MDBhYzUyMjIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6amVua2luczpqZW5raW5zYWRtaW4ifQ.A-InywzLZZfwx_4-Na9iDDRGsIH0Bjm9Xk92VxKsnP7hflEbOU631EU0eHnewgg0UqAD1kkhW39XupN13oTXrOjHrzWdm_UUMe2cBIYCZD19VIpNnRZ6bBLZ3LFHA2F0gXO14HaVZiUvSYBXgIfyHydetIFQFBPWFtU7091u5iB4pcw_gE-VzGjX6NDHj-81j6Ap2Qr0gIrNvrPVAOpPO9uCSg3PNCgvQMq2ZNrY2te1w7QxmeFPEpOIPiK6VbUkRjhQlHmawULZFol2k5Wwv9z0m1hPQcc2Nten1f1__GR39hUjryWXfltJ8OLpbKWK-AtfBkHx8VqbiKH1vQOrRg' \
--header 'Content-Type: text/plain' \
--data-raw 'abc'

这里请求方法由get换成了delete

Kubernetes API Server 认证机制相关推荐

  1. Kubernetes API Server 之集群安全认证

    文章目录 前言 一.为什么要有 api-server 集群安全认证? 二.安全机制的三个流程 三.HTTP Bearer Token 认证 四.HTTPS 双向证书认证 总结 前言 kubernete ...

  2. 资深专家深度剖析Kubernetes API Server第1章(共3章)

    欢迎来到深入学习Kubernetes API Server的系列文章,在本系列文章中我们将深入的探究Kubernetes API Server的相关实现.如果你对Kubernetes的内部实现机制比较 ...

  3. 深度剖析Kubernetes API Server三部曲 - part 1

    欢迎来到深入学习Kubernetes API Server的系列文章,在本系列文章中我们将深入的探究Kubernetes API Server的相关实现.如果你对Kubernetes 的内部实现机制比 ...

  4. kubernetes API Server 权限管理实践

    2019独角兽企业重金招聘Python工程师标准>>> kubernetes API Server 权限管理实践 API Server权限控制方式介绍 API Server权限控制分 ...

  5. 深度剖析Kubernetes API Server三部曲 - part 2

    欢迎来到深入学习Kubernetes API Server的系列文章的第二部分.在上一部分中我们对APIserver总体,相关术语及request请求流进行探讨说明.在本部分文章中,我们主要聚焦于探究 ...

  6. 资深专家深度剖析Kubernetes API Server第2章(共3章)

    欢迎来到深入学习Kubernetes API Server的系列文章的第二部分.在上一部分中我们对APIserver总体,相关术语及request请求流进行探讨说明.在本部分文章中,我们主要聚焦于探究 ...

  7. Kubernetes API server工作原理

    作为Kubernetes的使用者,每天用得最多的命令就是kubectl XXX了. kubectl其实就是一个控制台,主要提供的功能: 1. 提供Kubernetes集群管理的REST API接口,包 ...

  8. Kubernetes集群安全:Api Server认证

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 kube api serverd 启动参数解析 https://kubernetes.io/docs/reference/command-line-t ...

  9. 深度剖析Kubernetes API Server三部曲 - part 3

    前言 在本系列的前两部分中我们介绍了API Server的总体流程,以及API对象如何存储到etcd中.在本文中我们将探讨如何扩展API资源. 在一开始的时候,扩展API资源的唯一方法是扩展相关API ...

最新文章

  1. 猫=图灵机?4项测试证明,「猫猫计算机」可执行任意计算
  2. 为什么“ npm install”会重写package-lock.json?
  3. Unity中如何计算带minimap的贴图资源的大小
  4. 判断任意控制台输入的十进制数是否为水仙花数
  5. 结对编程:黄金点游戏
  6. SAP系统和微信集成的系列教程之八:100行代码在微信公众号里集成地图搜索功能
  7. 神秘的安全测试思考案例(一)
  8. SQL笔记-使用not in在多个没有外键关联的表中查询
  9. OSS 上传出现异常
  10. mysql装载本地文件及模式匹配
  11. python有趣小程序-知道了这个,你也能写出 Python 趣味小程序
  12. Pandas系列(十三)分层索引MultiIndex
  13. DevOps: 一例高负载多并发服务器连接池满的异常排解过程
  14. 数据分析好学吗_数据分析篇 | 一个虎扑社区数据分析实战
  15. Word域代码实现将形如“图一.1”的题注修改为“图1.1”
  16. electron选mysql的优缺点_大型Electron应用本地数据库技术选型
  17. 肖博数学高考数学快速解题法及秒杀向量问题总结
  18. linux下运行icem脚本,肿么安装linux版的icem
  19. Python脚本把支付宝和微信账单数据转换成随手记APP的excel标准模板导入
  20. AD软件自动添加原理图标注

热门文章

  1. Ubuntu更换阿里源和清华源
  2. 顺丰丰桥下订单、订单查询、路由回调代码总结直接使用
  3. 艺赛旗(RPA)使用 opencv 进行图片颜色识别
  4. 华南农业大学计算机考研资料汇总
  5. 常见的嵌入式处理器对比分析!
  6. 领导想提拔你,这点最真实,可别犯傻不当回事!
  7. Linux /dev/sda1磁盘满了,清理办法。
  8. CVPR2017: Densecap复现记录
  9. 【HDOJ】1006 Tick and Tick_天涯浪子_新浪博客
  10. 麒麟系统下基于卫星的NTP网络授时服务器方案