Kubernetes学习目录
1、证书信息
1.1、简介
我们知道,通过kubeadm在创建集群的时候,其中有一步就是:生成kubernetes控制组件的kubeconfig文
件及相关的启动配置文件,通过各种conf文件,让不同的组件具备操作相关资源的权限。
1.2、位置
master1 ~]# ll /etc/kubernetes/pki/
-rw-r--r-- 1 root root 1310 Mar 16 20:42 apiserver.crt
-rw-r--r-- 1 root root 1155 Mar 16 20:42 apiserver-etcd-client.crt
-rw------- 1 root root 1679 Mar 16 20:42 apiserver-etcd-client.key
-rw------- 1 root root 1675 Mar 16 20:42 apiserver.key
-rw-r--r-- 1 root root 1164 Mar 16 20:42 apiserver-kubelet-client.crt
-rw------- 1 root root 1675 Mar 16 20:42 apiserver-kubelet-client.key
-rw-r--r-- 1 root root 1099 Mar 16 20:06 ca.crt
-rw------- 1 root root 1675 Mar 16 20:06 ca.key
drwxr-xr-x 2 root root 162 Mar 16 20:06 etcd
-rw-r--r-- 1 root root 1115 Mar 16 20:06 front-proxy-ca.crt
-rw------- 1 root root 1679 Mar 16 20:06 front-proxy-ca.key
-rw-r--r-- 1 root root 1119 Mar 16 20:42 front-proxy-client.crt
-rw------- 1 root root 1679 Mar 16 20:42 front-proxy-client.key
-rw------- 1 root root 1675 Mar 16 20:06 sa.key
-rw------- 1 root root 451 Mar 16 20:06 sa.pub
master1 ~]# ll /etc/kubernetes/manifests/
-rw------- 1 root root 2402 Mar 16 20:06 etcd.yaml
-rw------- 1 root root 3372 Mar 16 20:42 kube-apiserver.yaml
-rw------- 1 root root 2878 Mar 16 20:42 kube-controller-manager.yaml
-rw------- 1 root root 1464 Mar 16 20:42 kube-scheduler.yaml
1.3、配置信息
1.3.1、kubectl config命令解析
master1 ~]# kubectl config -h
Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"
# 配置的加载顺序
1. --kubeconfig flag
2. $KUBECONFIG environment variable
3. ${HOME}/.kube/config
Available Commands:
current-context # 显示 current_context
delete-cluster # 删除 kubeconfig 文件中指定的集群
delete-context # 删除 kubeconfig 文件中指定的 context
get-clusters # 显示 kubeconfig 文件中定义的集群
get-contexts # 描述一个或多个 contexts
rename-context # 重命名上下文
set # 设置 kubeconfig 文件中的一个单个值
set-cluster # 设置 kubeconfig 文件中的一个集群条目
set-context # 设置 kubeconfig 文件中的一个 context 条目
set-credentials # 设置 kubeconfig 文件中的一个用户条目
unset # 取消设置 kubeconfig 文件中的一个单个值
use-context # 设置 kubeconfig 文件中的当前上下文
view # 显示合并的 kubeconfig 配置或一个指定的 kubeconfig 文件
Usage:
kubectl config SUBCOMMAND [options]
结果显示:
对于一个用户账号来说,至少包含了三部分:
1、用户条目-credentials 设定具体的user account名称
2、集群-cluster 设定该user account所工作的区域
3、上下文环境-context 设定用户和集群的关系
1.3.2、kubectl config view-查看当前的配置内容
master1 ~]# kubectl config view
apiVersion: v1
clusters:
- cluster: # 集群列表
certificate-authority-data: DATA+OMITTED # 证书的认证方式
server: https://vip.k8test.com:6443 # api_server 的地址
name: kubernetes # 当前集群的名称
contexts: # 上下文列表,一般指的是多集群间用户的切换所需的环境属性
- context:
cluster: kubernetes # 集群名称kubernetes
user: kubernetes-admin # 使用kubernetes-admin用户来访问集群kubernetes
name: kubernetes-admin@kubernetes # 该context的名称标准写法
current-context: kubernetes-admin@kubernetes # 当前上下文的名称
kind: Config
preferences: {}
users: # 用户列表
- name: kubernetes-admin # 用户名称
user:
client-certificate-data: REDACTED # 客户端证书
client-key-data: REDACTED # 客户端密钥
总结:
一个config主要包含了三部分内容:users、clusters、contexts,每个部分都有两部分组成:
name和user|cluster|context
对于cluster,对外的地址-server 和 基本的认证方式-certificate-authority-data
对于context,连接到的集群-cluster 和 连接集群的用户-user
对于user,连接集群的认证方式-client-certificate-data 和 私钥信息-client-key-data
current-context表明我们是处于哪一个环境中。
1.4、kubectl加载配置的3种方法
1.4.1、--kubeconfig
node1 ~]# kubectl --kubeconfig /opt/admin.conf get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 13d v1.25.7
master2 Ready control-plane 13d v1.25.7
master3 Ready control-plane 13d v1.25.7
node1 Ready <none> 13d v1.25.7
node2 Ready <none> 13d v1.25.7
1.4.2、KUBECONFIG
export KUBECONFIG=/opt/admin.conf
node1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 13d v1.25.7
master2 Ready control-plane 13d v1.25.7
master3 Ready control-plane 13d v1.25.7
node1 Ready <none> 13d v1.25.7
node2 Ready <none> 13d v1.25.7
1.4.3、.kube
mkdir ~/.kube -p
cp /opt/admin.conf ~/.kube/config
node1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 13d v1.25.7
master2 Ready control-plane 13d v1.25.7
master3 Ready control-plane 13d v1.25.7
node1 Ready <none> 13d v1.25.7
node2 Ready <none> 13d v1.25.7
1.5、kubectl流程图

1.6、K8S-证书体系
1.6.1、证书体系图

1.6.2、证书对应表
参考官网:https://kubernetes.io/zh-cn/docs/setup/best-practices/certificates/
| 默认 CN | 父级 CA | O(位于 Subject 中) | kind | 主机 (SAN) |
| kube-etcd |
etcd-ca |
|
server, client |
<hostname>, <Host_IP>, localhost, 127.0.0.1 |
| kube-etcd-peer |
etcd-ca |
|
server, client |
<hostname>, <Host_IP>, localhost, 127.0.0.1 |
| kube-etcd-healthcheck-client |
etcd-ca |
|
client |
|
| kube-apiserver-etcd-client |
etcd-ca |
system:masters |
client |
|
| kube-apiserver |
kubernetes-ca |
|
server |
<hostname>, <Host_IP>, <advertise_IP>, [1] |
| kube-apiserver-kubelet-client |
kubernetes-ca |
system:masters |
client |
|
| front-proxy-client |
kubernetes-front-proxy-ca |
|
client
|
1.7、权限关系
1.7.1、用户组
我们知道所有的资源操作,其实都是node结点上的kubelet和master结点上的apiserver中间的通信,而
在kubernetes的认证目录中尤其专用的通信认证证书 apiserver-kubelet-client.crt,我们可以通
过该文件来检查一下这两者之间是一个怎样的关系。
]# cd /etc/kubernetes/pki/
]# openssl x509 -in ./apiserver-kubelet-client.crt -text -noout
Certificate:
Validity
Not Before: Mar 16 12:06:54 2023 GMT
Not After : Mar 15 12:42:10 2024 GMT
Subject: O=system:masters, CN=kube-apiserver-kubelet-client
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
...
结果显示:
对于kubelet来说,他的用户名是kube-apiserver-kubelet-client,而且属于system:master
的组,这两者的关系是我们在基于openssl或者csffl工具创建用户时候基于CN和O来设定的信息。
1.7.2、绑定关系
在我们的集群环境中有一个资源叫clusterrolebindings,该资源会基于用户的名称或者组信息将其绑定到
一个权限列表中(即clusterrole),在这个绑定关系中有一个cluster-admin,在这里面定义了group和clusterrole之间的关系。
master1 ~]# kubectl describe clusterrolebindings cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
Role:
Kind: ClusterRole
Name: cluster-admin
Subjects:
Kind Name Namespace
---- ---- ---------
Group system:masters
master1 ~]# kubectl get clusterrolebindings cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-03-16T12:07:00Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "131"
uid: 7e9e1f2f-0958-42c3-93c2-1057b3efa54f
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:masters
总结:
只要是"system:masters"组中的成员,都具有cluster-admin的所有权限
1.7.3、角色权限
master1 ~]# kubectl describe clusterrole cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
# 对于cluster-admin来说,它拥有所有资源在所有空间的所有权限。
2、创建用户关联集群认证-实践【重点】
2.1、基本流程
1、创建私钥文件
2、基于私钥文件创建证书签名请求
3、基于私钥和签名请求生成证书文件
4、基于tls文件在k8s上创建用户
5、创建工作区域-cluster
6、将cluster和user关联起来-context
7、验证效果
2.2、技术关键点
这七步各有操作关键点,我们在操作之前必须提前认识清楚,否则的话,在执行过程中,会遇到各种意外。
1、创建私钥文件
对于用户名和用户组需要提前规划好,如果用户多权限集中的情况下,一定要规划好用户组信息
2、基于私钥文件创建证书签名请求
要基于我们自建的私钥来创建签证请求文件
3、基于私钥和签名请求生成证书文件
因为我们的生成的证书要应用在kubernetes环境中,所以必须由kubernetes的全局证书来认证
4、基于tls文件在k8s上创建用户
我们说过kubernetes平台上的普通用户需要基于秘钥认证通信
5、创建工作区域-cluster
所谓的工作区域是用户的工作场景,必须定制好,一个cluster可以被多个用户使用
6、将cluster和user关联起来-context
关联的作用就是,将用户和区域整合在一起,我们使用资源的时候便于调用
7、验证效果
因为我们主要做的是认证,而用户的操作涉及到资源权限,这部分是需要结合授权机制来进行的
默认情况下,基于创建好的文件来获取资源是被forbidden的
2.3、开始实操
2.3.1、创建私钥文件
给用户 cyc 创建一个私钥,命名成:cyc.key(无加密)
cd /etc/kubernetes/pki/
(umask 077; openssl genrsa -out cyc.key 2048)
命令解析:
genrsa 该子命令用于生成RSA私钥,不会生成公钥,因为公钥提取自私钥
-out filename 生成的私钥保存至filename文件,若未指定输出文件,则为标准输出
-numbits 指定私钥的长度,默认1024,该项必须为命令行的最后一项参数
注意:
为了避免对当前环境产生不必要的影响,我们这里使用子shell的方式创建私钥
由于我们后面需要k8s的私钥对用户进行认证,所以我们在k8s的认证文件目录中创建
# 检查创建好的文件
master1 pki]# ll cyc.key
-rw------- 1 root root 1675 Mar 30 15:00 cyc.key
2.3.2、签名请求
用刚创建的私钥创建一个证书签名请求文件:cyc.csr
openssl req -new -key cyc.key -out cyc.csr -subj '/CN=cyc/O=cyc'
参数说明:
-new 生成证书请求文件
-key 指定已有的秘钥文件生成签名请求,必须与-new配合使用
-out 输出证书文件名称
-subj 输入证书拥有者信息,这里指定 CN 以及 O 的值,/表示内容分隔
CN以及O的值对于kubernetes很重要,因为kubernetes会从证书这两个值对应获取相关信息:
"CN":Common Name,用于从证书中提取该字段作为请求的用户名 (User Name);
浏览器使用该字段验证网站是否合法;
"O":Organization,用于分组认证
注意:
证书名称必须设计好,在我们这里,用户是cyc、组是cyc。
master1 pki]# ll cyc*
-rw-r--r-- 1 root root 903 Mar 30 15:03 cyc.csr # 签名请求文件
-rw------- 1 root root 1675 Mar 30 15:00 cyc.key # 私钥
2.3.3、生成证书
刚才的私钥和认证并没有被我们的Kubernetes集群纳入到管理体系,我们需要基于kubeadm集群的CA相关证
书来进行认证,CA相关文件位于/etc/kubernetes/pki/目录下面,我们会利用该目录下面的ca.crt和ca.key两个文件来批准上面的证书请求
master1 pki]# openssl x509 -req -in cyc.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out cyc.crt -days 1000
Signature ok
subject=/CN=cyc/O=cyc
Getting CA Private Key
参数说明:
-req 产生证书签发申请命令
-in 指定需要签名的请求文件
-CA 指定CA证书文件
-CAkey 指定CA证书的秘钥文件
-CAcreateserial 生成唯一的证书序列号
-x509 表示输出一个X509格式的证书
-days 指定证书过期时间为365天
-out 输出证书文件
master1 pki]# ls -l cyc.*
-rw-r--r-- 1 root root 989 Mar 30 16:01 cyc.crt # *.crt就是我们最终生成的签证证书
-rw-r--r-- 1 root root 903 Mar 30 15:03 cyc.csr
-rw------- 1 root root 1675 Mar 30 15:00 cyc.key
master1 pki]# openssl x509 -in cyc.crt -text -noout
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
aa:fb:cb:30:af:d9:c7:e2
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes # 表示是哪个CA机构帮我们认证的
Validity
Not Before: Mar 30 08:01:55 2023 GMT
Not After : Dec 24 08:01:55 2025 GMT
Subject: CN=cyc, O=cyc # 重点在于Subject内容中的请求用户所属的组信息
Subject Public Key Info:
2.3.4、创建k8s用户
# 创建用户 cyc 信息
master1 pki]# kubectl config set-credentials cyc --client-certificate=./cyc.crt --client-key=./cyc.key --embed-certs=true --kubeconfig=/tmp/cyc.conf
User "cyc" set.
参数详解:
set-credentials 子命令的作用就是给kubeconfig认证文件创建一个用户条目
--client-certificate=path/to/certfile 指定用户的签证证书文件
--client-key=path/to/keyfile 指定用户的私钥文件
--embed-certs=true,在kubeconfig中为用户条目嵌入客户端证书/密钥,默认值是false,
--kubeconfig=/path/to/other_config.file 表示将属性信息单独输出到一个文件,不指定的话,表示存到默认的 ~/.kube/config文件中
# 在指定配置文件的users部分增加了一个cyc的普通用户
master1 pki]# kubectl config view --kubeconfig=/tmp/cyc.conf
apiVersion: v1
clusters: null
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: cyc
user:
client-certificate-data: REDACTED # cyc.crt
client-key-data: REDACTED # cyc.key
2.3.5、创建集群
# 创建一个新的集群-mycluster
master1 pki]# kubectl config set-cluster mycluster --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=/tmp/cyc.conf --server="https://vip.k8test.com:6443"
Cluster "mycluster" set.
参数详解:
--server=cluster_api_server
--certificate-authority=path/to/certificate/authority
注意:
这里使用到的证书,必须是kubernetes的ca证书。
# 查看clusters集群:用户cyc是否多了一个mycluster集群
master1 ~]# kubectl config view --kubeconfig=/tmp/cyc.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://vip.k8test.com:6443
name: mycluster
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: cyc
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
属性解析
如果不用--embed-certs=true
需要手动指定ca.crt的位置:certificate-authority: /etc/kubernetes/pki/ca.crt
2.3.6、关联用户和集群
master1 ~]# kubectl config set-context cyc@mycluster --cluster=mycluster --user=cyc --kubeconfig=/tmp/cyc.conf
Context "cyc@mycluster" created.
属性详解
--cluster=cluster_nickname 关联的集群名称
--user=user_nickname 关联的用户名称
--namespace=namespace 可以设置该生效的命名空间
# 查看contexts是否关联集群与用户
master1 ~]# kubectl config view --kubeconfig=/tmp/cyc.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://vip.k8test.com:6443
name: mycluster
contexts:
- context:
cluster: mycluster
user: cyc
name: cyc@mycluster
current-context: ""
kind: Config
preferences: {}
users:
- name: cyc
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
2.3.7、验证效果
根据刚才的信息显示,current-context的信息是空,那么我们切换一下用户更改用户
master1 ~]# kubectl config use-context cyc@mycluster --kubeconfig=/tmp/cyc.conf
Switched to context "cyc@mycluster".
master1 ~]# kubectl config view --kubeconfig=/tmp/cyc.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://vip.k8test.com:6443
name: mycluster
contexts:
- context:
cluster: mycluster
user: cyc
name: cyc@mycluster
current-context: cyc@mycluster
kind: Config
preferences: {}
users:
- name: cyc
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
master1 ~]# kubectl get pod --kubeconfig=/tmp/cyc.conf
Error from server (Forbidden): pods is forbidden: User "cyc" cannot list resource "pods" in API group "" in the namespace "default"
# 简便方法
master1 ~]# kubectl get pod --context=cyc@mycluster --kubeconfig=/tmp/cyc.conf
Error from server (Forbidden): pods is forbidden: User "cyc" cannot list resource "pods" in API group "" in the namespace "default"
# 虽然认证信息我们配置好了,但是由于权限相关的内容没有设置,所以我们看不了任何资源信息。
3、kubectl加载配置&上下文切换-进阶-实践
3.1、默认的kubectl config-加载配置文件
master1 ~]# kubectl get sa
NAME SECRETS AGE
admin 0 3h58m
default 0 13d
这里使用的配置文件是 ~/.kube/config 文件
master1 ~]# ll ~/.kube/config
-rw------- 1 root root 5638 Mar 16 20:10 /root/.kube/config
3.2、--kubeconfig 参数-加载配置文件
master1 ~]# kubectl get sa --kubeconfig=/etc/kubernetes/admin.conf
NAME SECRETS AGE
admin 0 4h
default 0 13d
--kubeconfig 参数的优先级要高于 默认的 .kube/config 配置文件
3.3、环境变量-加载配置文件
master1 ~]# export KUBECONFIG='/etc/kubernetes/admin.conf'
[root@master1 ~]# kubectl get sa
NAME SECRETS AGE
admin 0 4h1m
default 0 13d
# 还没有分配资源,所以查询不了
master1 ~]# export KUBECONFIG="/tmp/cyc.conf"
master1 ~]# kubectl get sa
Error from server (Forbidden): serviceaccounts is forbidden: User "cyc" cannot list resource "serviceaccounts" in API group "" in the namespace "default"
# --kubeconfig 的优先级要高于 环境变量KUBECONFIG
master1 ~]# kubectl get sa --kubeconfig=/etc/kubernetes/admin.conf
NAME SECRETS AGE
admin 0 4h2m
default 0 13d
3.4、环境变量-加载配置文件-多配置文件合并查询
3.4.1、环境变量方式-多配置文件合并查询
# 多个文件可以通过冒号隔开
master1 ~]# export KUBECONFIG='/etc/kubernetes/admin.conf:/tmp/cyc.conf'
master1 ~]# kubectl get sa
NAME SECRETS AGE
admin 0 4h4m
default 0 13d
# 查看多个配置文件的合并统一查询效果
master1 ~]# kubectl get sa
NAME SECRETS AGE
admin 0 4h4m
default 0 13d
[root@master1 ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://vip.k8test.com:6443
name: kubernetes
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://vip.k8test.com:6443
name: mycluster
contexts:
- context:
cluster: mycluster
user: cyc
name: cyc@mycluster
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: cyc
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
3.4.2、采用 merge 参数合并当前的配置文件
master1 ~]# kubectl config view --merge --flatten > /tmp/cyc_kube-admin.conf
属性解析:
--flatten 用于显示加密后的内容
# 可以在一个config文件中,配置多个用户和集群及配套的上下文环境。
master1 ~]# kubectl get sa --kubeconfig=/tmp/cyc_kube-admin.conf
NAME SECRETS AGE
admin 0 4h10m
default 0 13d
3.4.3、查看kubectl当前的上下文
master1 ~]# kubectl config view --kubeconfig=/tmp/cyc_kube-admin.conf | grep current
current-context: kubernetes-admin@kubernetes
3.4.4、切换上下文
master1 ~]# kubectl config use-context cyc@mycluster --kubeconfig=/tmp/cyc_kube-admin.conf
Switched to context "cyc@mycluster".
master1 ~]# kubectl config view --kubeconfig=/tmp/cyc_kube-admin.conf | grep current
current-context: cyc@mycluster
master1 ~]# kubectl get sa --kubeconfig=/tmp/cyc_kube-admin.conf
Error from server (Forbidden): serviceaccounts is forbidden: User "cyc" cannot list resource "serviceaccounts" in API group "" in the namespace "default"