可以使用kubectl、客户端库方式对REST API的访问,Kubernetes的普通账户和Service帐户都可以实现授权访问API。API的请求会经过多个阶段的访问控制才会被接受处理,
其中包含认证、授权以及准入控制(Admission Control)等。如下图所示:
需要注意:认证授权过程只存在HTTPS形式的API中。也就是说,如果客户端使用HTTP连接到kube-apiserver,是不会进行认证授权的。所以说,可以这么设置,在集群内部组件间通信使用HTTP
集群外部就使用HTTPS,这样既增加了安全性,也不至于太复杂。
认证
开启TLS时,所有的请求首先需要认证。Kubernetes支持多种认证机制,并支持同时开启多个认证插件(只要有一个认证通过即可)。如果认证成功,则用户的username会传入授权模块做进一步授权验证;对于认证失败的请求则返回HTTP 401。
当TLS建立时,HTTP请求会进行身份认证步骤,如图中步骤1,集群管理器将apiserver配置为运行一个或多个认证器模块。
认证模块包含客户端证书,密码、Plain Tokens、Bootstrap Tokens、JWT Tokens(used for service accounts)。
我们可以指定多个认证模块,每个认证模块都会按顺序进行,直到其中一个成功。
(在GCE上,客户端证书、密码、Plain Tokens和JWT Tokens都会启用。)
更多认证模块的使用方法可以参考 官方文档认证
所有Kubernetes集群有两类用户:由Kubernetes管理的Service Accounts (服务账户)和(Users Accounts) 普通账户。
普通账户是假定被外部或独立服务管理的,由管理员分配keys,用户像使用Keystone或google账号一样,被存储在包含usernames和passwords的list的文件里。
需要注意:在Kubernetes中不能通过API调用将普通用户添加到集群中。
相比之下,Service Accounts是由Kubernetes API管理的帐户。它们被绑定到特定的命名空间,并由APIserver自动创建或通过API调用手动创建。Service Accounts与存储为Secrets的一组证书相关联,这些凭据被挂载到pod中,以便集群进程与Kubernetes API通信。
Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同
- User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
- User account是跨namespace的,而service account则是仅局限它所在的namespace;
- 每个namespace都会自动创建一个default service account
- Token controller检测service account的创建,并为它们创建secret
- 开启ServiceAccount Admission Controller后
- 每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccout)
- 验证Pod引用的service account已经存在,否则拒绝创建
- 如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
- 每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/
验证策略
Kubernetes用户可以使用client certificates、bearer tokens、authenticating proxy、HTTP basic auth等认证插件来验证API请求。比如HTTP请求到达API Server,插件会尝试将以下属性与请求关联:
- UserName:普通用户的字符串。比如“kube-admin”或“xxxx@kubernetes.org.cn”。
- UID:普通用户的字符串,比UserName更具有唯一性。
- Groups:一组字符串,将常用的user分组的组合字符串。
- Extra fields:将一些有用的字符串信息映射成的列表。
所有values值对于认证系统都是不透明的,只有当授权解释后才有意义。
可以同时启用多个认证方法。最少使用两种:
- 为Service Accounts使用service account tokens方法。
- 使用另外一种用户认证方法。
system:authenticated组被包括在所有已认证用户的组列表中。
详细的认证参考认证
开启本机的代理来访问API ,来获取相应的资源
[root]@k8s-master ~]# kubectl proxy --port=8080
Starting to serve on 127.0.0.1:8080
API group
下面命令可以看到API 有哪些组
[root@k8s-master k8s]# kubectl api-versions
curl http://localhost:8080/api/v1/namespaces/
[root@k8s-master ~]# kubectl get deploy -n kube-system
curl http://localhost:8080/apis/apps/v1/namespaces/kube-system/deployments/
curl http://localhost:8080/apis/apps/v1/namespaces/kube-system/deployments/coredns
pod通过内部网络访问APIserver
[root@k8s-master ~]# kubectl get svc
[root@k8s-master ~]# kubectl describe svc kubernetes
Name: kubernetes
Namespace: default
Labels: component=apiserver
IP: 10.96.0.1
Port: https 443/TCP
[root@k8s-master ~]# kubectl explain pods.spec.serviceAccountName
kubectl describe pod myapp-deploy-675558bfc5-4f8hz
volumes:
default-token-zzm2j:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-zzm2j
[root@k8s-master k8s]# kubectl get secret
NAME TYPE DATA AGE
default-token-zzm2j kubernetes.io/service-account-token 3 53d
mysql-root-password Opaque 1 10d
tomcat-ingress-secre t kubernetes.io/tls 2 11d
kubectl create serviceaccount -h
[root@k8s-master k8s]# kubectl create serviceaccount mysa -o yaml --dry-run(没生成,用来做测试,或者打印yaml)
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: null
name: mysa
kubectl get pods myapp-deploy-675558bfc5-4f8hz -o yaml --export 导出相应的配置清单
[root@k8s-master k8s]# kubectl get sa(serviceaccount)
NAME SECRETS AGE
default 1 53d
自己创建sa
[root@k8s-master k8s]# kubectl create sa admin
serviceaccount/admin created
[root@k8s-master k8s]# kubectl get sa
NAME SECRETS AGE
admin 1 6s
default 1 53d
[root@k8s-master k8s]# kubectl describe sa admin
Mountable secrets: admin-token-77fqm
Tokens: admin-token-77fqm
[root@k8s-master k8s]# kubectl get secret
NAME TYPE DATA AGE
admin-token-77fqm kubernetes.io/service-account-token 32 6s
default-token-zzm2j kubernetes.io/service-account-token 3 53d
POD 中引入自己新建的sa,默认用的是default
vim pod-sa.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-sa
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
serviceAccountName: admin
kubectl describe pods pod-sa
admin-token-77fqm:
Type: Secret (a volume populated by a Secret)
SecretName: admin-token-77fqm
kubectl describe sa admin
Image pull secrets: <none>
如果用使用私有仓库,两种方式:
1.sa 定义这个Image pull secrets
2.定义POD 指定 Image pull secrets
apiVersion: v1
kind: ServiceAccount metadata: creationTimestamp: 2015-08-07T22:02:39Z name: default namespace: default selfLink: /api/v1/namespaces/default/serviceaccounts/default uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 secrets: - name: default-token-uudge imagePullSecrets: - name: myregistrykey
在K8S集群当中,每一个用户对资源的访问都是需要通过apiserver进行通信认证才能进行访问的,那么在此机制当中,对资源的访问可以是token
也可以是通过配置文件的方式进行保存和使用认证信息,可以通过kubectl config进行查看配置,如下:
kubeconfig 认证格式的客户端配置文件
[root@k8s-master k8s]# kubectl config view
apiVersion: v1
clusters: #集群列表
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.211.55.11: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
kubectl config -h
各种证书生成到这个下面:
/etc/kubernetes/pki
创建自定义的签名证书
(umask077;openssl genrsa -out doudou.key 2048)
openssl req -new -key doudou.key -out doudou.csr -subj "/CN=doudou"
openssl x509 -req -in doudou.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out doudou.crt -days 365
openssl x509 -in doudou.crt -text -noout
往配置文件里面增加用户认证信息:
kubectl config set-credentials doudou --client-certificate=./doudou.crt --client-key=./doudou.key --embed-certs
kubectl config view 可以看到新加的信息
切换用户
kubectl config use-context doudou@kubernetes
[root@k8s-master pki]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "doudou" cannot list resource "pods" in API group "" in the namespace "default"
上面报错是因为没有授权,只是通过认证了
切换之前的管理账号
kubectl config use-context kubernetes-admin@kubernetes
可以修改之前默认的配置文件,和其他相关的消息
[root@k8s-master ~]# kubectl config set-cluster -h
默认配置文件的认证消息在
3. Otherwise, ${HOME}/.kube/config is used
[root@k8s-master ~]# cat .kube/config
kubectl config set-cluster mycluster --kubeconfig=/tmp/test.conf \
--server="https://10.211.55.11:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true
kubectl config view --kubeconfig=/tmp/test.config
所有评论(0)