客户端请求API Server过程
客户端 --> API Server(识别用户是否有通过api server执行操作的权限)
api Server识别内容:
user: username,uid
group: 用户组
extra: 字段,提供额外信息
客户端请求的API(Request Path):
例如客户端对一个k8s集群中的名为myapp-deploy的deployment的资源发起请求,地址为下,成功的话则可进行增删改查;
http://192.168.133.128:6443/apis/apps/v1/namespaces/default/deployments/myapp-deploy
注释:
192.168.222.100: master地址
6443: API server端口
apis: 固定入口(除核心群组(/api/v1/)外)
apps: app组
v1: 组版本
namespaces: 名称空间级别
default: 名称空间的名称
deployments: 访问deployment资源
myapp-deploy: deployment名称
请求操作(action):
http的方法请求:
get
post
put
delete
k8s请求动作:
增: create
删: delete,deletecollection(删除一个集合)
改: edit,patch
查: get,list,watch(-w)
API Server是整个访问请求进入的网关接口,请求过程中
认证用于实现身份识别;
授权用于实现权限检查,检查用户是否拥有对资源执行各种k8s请求动作;
准入控制机制用来进一步补充授权机制,创建、删除、修改时需要;
k8s集群有两类认证时的认证账号:
1. useraccount
2. serviceaccount
访问API Server的客户端分为以下两类:
1. 集群之外的客户端访问节点地址进行通信;
2. 集群内部的Pod等,使用API Server在集群内的地址(kubectl get svc(kubernetes这个svc),将集群外部地址引入到集群内部供内部组件使用;
# 经过查看某一个Pod的详细信息发现Pod会自动拥有一个Volumes,这个Volumes的名称叫做"default-token-ppzsj"也就是令牌,这就是Pod连接API Server的认证信息,通过secret来定义,并以存储卷的方式关联到Pod上,
使Pod内的运行的应用通过对应的secret中保存的认证信息连接API Server来完成认证的;
$ kubectl describe pod deploy-demo-854b57c687-f7txr .... Volumes: default-token-ppzsj: Type: Secret (a volume populated by a Secret) SecretName: default-token-ppzsj Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s ....
# 经查,发现每个名称空间下都会有一个默认的secret(default-token-ppzsj)
$ kubectl get secret NAME TYPE DATA AGE default-token-ppzsj kubernetes.io/service-account-token 3 26d
创建Pod与API Server通信的serviceaccount(与权限无关,仅认证):
# 首先查看系统上已有的serviceaccount; $ kubectl get serviceaccount NAME SECRETS AGE default 1 26d # 直接使用create创建一个名为admin的sa; $ kubectl create sa admin # 再次查询,发现创建成功; $ kubectl get sa NAME SECRETS AGE admin 1 84s default 1 26d # 查看sa的详细信息,发现了名为"admin-token-pfp5j"的secret; $ kubectl describe sa admin Name: admin Namespace: default Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: admin-token-pfp5j Tokens: admin-token-pfp5j Events: <none> # 查看secret,发现刚创建的sa自动创建了一个"admin-token-pfp5j"secret; $ kubectl get secret NAME TYPE DATA AGE admin-token-pfp5j kubernetes.io/service-account-token 3 2m32s default-token-ppzsj kubernetes.io/service-account-token 3 26d # 创建Pod使用新创建的sa; $ vim pod-sa.yaml apiVersion: v1 kind: Pod metadata: name: pod-sa namespace: default spec: containers: - name: sa-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 # 自定义serviceaccount的名称 serviceAccountName: admin $ kubectl apply -f pod-sa.yaml # 查看详细信息发现默认自带的volumes中的名称变为了"admin-token-pfp5j"也就是我们刚创建sa后,集群自动帮我们创建的secret; $ kubectl describe pods pod-sa .... Volumes: admin-token-pfp5j: Type: Secret (a volume populated by a Secret) SecretName: admin-token-pfp5j Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s ....
配置文件连接API Server:
API Server的客户端在认证时,如果我们要基于配置文件来保存客户端的认证信息,就要配置个配置文件,k8s集群中的所有组件,除API Server外都需要连接至API Server,都需要被API Server认证
每一个组件为了能够连入正确的集群,提供正确的账号、证书、私钥等认证信息,需要将这些信息保存为配置文件(kubeconfig),也就是API Server的客户端连入API Server时使用的认证格式的配置文件;
# 查看配置 $ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://192.168.133.128:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED
注释:
clusters: 集群列表,可以包含多个集群
certificate-authority-data: 认证方式
server: API Server路径
name: 集群名称
users: 用户列表
name: 用户账号名
client-certificate-data: 客户端证书
client-key-data: 客户端私钥
contexts: 上下文列表,一个上下文用来指明哪个账号管理哪个集群;
cluster: 访问哪个集群
user: 使用哪个用户
name: 给上下文取名
current-context: 当前上下文,当前使用哪个账号管理哪个集群;
由于客户端连入API Server要做双向认证,所以可以去"/etc/kubernetes/pki"目录下找到各种key、ca;
创建新账号来连接API Server
# cd /etc/kubernetes/pki # (umask 077; openssl genrsa -out kfree.key 2048) # openssl req -new -key kfree.key -out kfree.csr -subj "/CN=kfree" # openssl x509 -req -in kfree.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out kfree.crt -days 365 # su - kubeadm $ kubectl config set-credentials kfree --client-certificate=/etc/kubernetes/pki/kfree.crt --client-key=/etc/kubernetes/pki/kfree.key $ kubectl config set-context kfree@kubernetes --cluster=kubernetes --user=kfree $ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://192.168.133.128:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kfree name: kfree@kubernetes - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kfree user: client-certificate: /etc/kubernetes/pki/kfree.crt client-key: /etc/kubernetes/pki/kfree.key - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED
$ kubectl config use-context kfree@kubernetes # 因为我们只处理了认证,没有授予权限,所以没有权限的; $ kubectl get pods Error from server (Forbidden): pods is forbidden: User "kfree" cannot list resource "pods" in API group "" in the namespace "default"