8.k8s中发布策略-集群认证-kubeconfig优先级
基于X509证书的Kubernetes认证全流程
1. 客户端证书准备阶段
1.1 创建私钥
openssl genrsa -out jiege.key 2048
- 作用:生成RSA私钥(2048位),用于证书签名
- 结果:
jiege.key文件,必须保密
1.2 创建证书签名请求(CSR)
openssl req -new -key jiege.key -out jiege.csr -subj "/CN=jiege/O=oldboyedu"
- 作用:创建证书签名请求
- 关键参数:
CN=jiege:用户名(User)O=oldboyedu:用户组(Group)
- 结果:
jiege.csr文件
1.3 Base64编码CSR
cat jiege.csr | base64 | tr -d '\n';echo
从这里可以获取到CSR
- 作用:将CSR编码为base64,便于在K8s资源中存储
2. 服务端证书签发阶段
2.1 创建CSR资源清单
cat > csr-jiege.yaml << EOF
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: jiege-csr
spec:
request: [base64编码的CSR]
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400
usages:
- client auth
EOF
kubectl apply -f csr-jiege.yaml
- 关键配置:
signerName:指定证书签发者类型expirationSeconds:证书有效期(24小时)usages:证书用途(客户端认证)
2.2 批准CSR请求,手动签发
kubectl certificate approve jiege-csr
- 作用:手动批准证书签发请求
- 状态变化:Pending → Approved,Issued
2.3 获取签发后的证书
kubectl get csr jiege-csr -o jsonpath='{.status.certificate}' | base64 -d > jiege.crt
- 作用:从CSR资源中提取已签发的证书
将证书拷贝到客户端节点,便于后续使用
[root@master231 ~]# scp /opt/jiege.crt 10.0.0.233:~
客户端测试验证233
查看本地证书文件
[root@worker233 ~]# ll jiege*
-rw-r--r-- 1 root root 1115 Sep 27 15:46 jiege.crt
-rw-r--r-- 1 root root 911 Sep 27 15:28 jiege.csr
-rw------- 1 root root 1704 Apr 14 10:43 jiege.key
3. kubeconfig配置阶段
3.1 添加用户凭证
kubectl config set-credentials jiege \
--client-certificate=jiege.crt \
--client-key=jiege.key \
--embed-certs=true \
--kubeconfig=./yinzhengjie-k8s-certs.conf
- 作用:创建用户认证配置
--embed-certs=true:将证书内容嵌入kubeconfig文件
./yinzhengjie-k8s-certs.conf创建用户的时候会第一次进行创建,随着集群和上下文创建会不断的填充。可以随时进行cat
3.2 配置集群信息
kubectl config set-cluster myk8s \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--server="https://10.0.0.231:6443" \
--kubeconfig=./yinzhengjie-k8s-certs.conf
- 作用:定义K8s集群连接信息
- 关键参数:
- CA证书:验证API Server身份
- Server地址:API Server端点
3.3 创建上下文
kubectl config set-context jiege@myk8s \
--user=jiege \
--cluster=myk8s \
--kubeconfig=./yinzhengjie-k8s-certs.conf
- 作用:绑定用户和集群,创建访问上下文
3.4 设置默认上下文
kubectl config use-context jiege@myk8s --kubeconfig=./yinzhengjie-k8s-certs.conf
- 作用:设置默认使用的上下文
4. 测试验证阶段
4.1 设置环境变量
export KUBECONFIG=/root/yinzhengjie-k8s-certs.conf
- 作用:指定kubeconfig文件路径
4.2 测试访问权限
kubectl get pods
# 返回:Error from server (Forbidden)
- 结果分析:认证成功但授权失败
- 说明:用户
jiege已通过证书认证,但缺少RBAC权限
5. 关键知识点总结
认证流程
- 客户端:生成密钥对和CSR
- 服务端:审批CSR并签发证书 crt
- 配置:将证书集成到kubeconfig
- 认证:使用证书向API Server证明身份
当执行kubectl get pods --kubeconfig=./yinzhengjie-k8s-certs.conf时,api-server知道你是jiege了但是没授权
文件作用
.key:私钥,身份证明.crt:公钥证书,CA签发.csr:证书签名请求.conf:kubeconfig配置文件
当前状态
用户jiege已成功通过X509证书认证,但需要配置RBAC授权才能访问集群资源。下一步应该创建相应的Role和RoleBinding来授权。
基于token证书的Kubernetes认证全流程
静态令牌认证完整流程总结
1. 生成令牌 Token
两种生成方式:
# 方式1:使用openssl
echo "$(openssl rand -hex 3).$(openssl rand -hex 8)"
# 示例:01b202.d5c4210389cbff08
# 方式2:使用kubeadm
kubeadm token generate
# 示例:jvt496.ls43vufojf45q73i
2. 创建令牌认证文件
cd /etc/kubernetes/pki/
cat > token.csv <<EOF
b4gp4h.tqnqlkov8zzbzuot,yinzhengjie,10001,k8s
53llgt.n4xci771guevocbk,jasonyin,10002,k8s
m7k336.omp1yul0w1i3t0pp,linux97,10003,k3s
EOF
格式: token,用户名,用户ID,用户组
3. 配置 API Server
修改 /etc/kubernetes/manifests/kube-apiserver.yaml:
spec:
containers:
- command:
- kube-apiserver
- --token-auth-file=/etc/kubernetes/pki/token.csv # 添加这行
...
volumeMounts:
- mountPath: /etc/kubernetes/pki/token.csv
name: static-token-file
readOnly: true
volumes:
- hostPath:
path: /etc/kubernetes/pki/token.csv
type: File
name: static-token-file
4. 重启 API Server
# 通过移动文件触发重启
mv /etc/kubernetes/manifests/kube-apiserver.yaml /opt/
mv /opt/kube-apiserver.yaml /etc/kubernetes/manifests/
5. 创建 Kubeconfig 文件
5.1 创建集群配置
kubectl config set-cluster myk8s \
--embed-certs=true \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--server="https://10.0.0.231:6443" \
--kubeconfig=./yinzhengjie-k8s-token.conf
5.2 创建用户凭证
kubectl config set-credentials yinzhengjie \
--token="b4gp4h.tqnqlkov8zzbzuot" \
--kubeconfig=./yinzhengjie-k8s-token.conf
5.3 创建上下文
kubectl config set-context yinzhengjie@myk8s \
--user=yinzhengjie \
--cluster=myk8s \
--kubeconfig=./yinzhengjie-k8s-token.conf
5.4 设置当前上下文
kubectl config use-context yinzhengjie@myk8s \
--kubeconfig=./yinzhengjie-k8s-token.conf
以上都是232节点操作
6. 测试认证
拷贝kubeconfig文件:从这开始231操作
[root@worker232 ~]# scp yinzhengjie-k8s-token.conf 10.0.0.231:~
# 使用kubeconfig文件测试
kubectl get pods --kubeconfig=./yinzhengjie-k8s-token.conf
# 使用curl直接测试
curl -k -H "Authorization: Bearer b4gp4h.tqnqlkov8zzbzuot" \
https://10.0.0.231:6443/api/v1/pods
Kubeconfig 加载优先级
-
--kubeconfig参数 (最高优先级)kubectl get nodes --kubeconfig=/root/yinzhengjie-k8s-token.conf -
KUBECONFIG环境变量export KUBECONFIG=/path/to/kubeconfig kubectl get nodes -
~/.kube/config文件 (默认位置)(管理员文件,默认配置文件)kubectl get nodes # 自动使用 ~/.kube/config -
内建配置 (最低优先级)
- 连接
localhost:8080
- 连接
🔐 认证 vs 授权
当前状态:
- ✅ 认证成功:用户能够通过token成功认证
- ❌ 授权失败:用户没有相应的RBAC权限
认证成功但授权失败的典型错误
Error from server (Forbidden): nodes is forbidden: User "yinzhengjie" cannot list resource "nodes" in API group "" at the cluster scope
这个流程清晰地展示了从令牌生成到kubeconfig创建的完整过程,是非常好的静态令牌认证实践案例!
Master节点配置文件
# Master 节点默认使用这个配置文件
/etc/kubernetes/admin.conf
# 直接使用(默认已经配置好)
kubectl get nodes
kubectl加载kubeconfig文件的优先级总结
-
- 使用
--kubeconfig的优先级最大,直接无视后面的两个配置文件;
- 使用
-
- 使用
KUBECONFIG变量的优先级次之;
- 使用
-
- 如果没有定义上面两个配置,则默认使用的
~/.kube/config文件;一般worker节点没有
- 如果没有定义上面两个配置,则默认使用的
-
- 如果前面3个环境都没有,则默认链接
localhost:8080;
- 如果前面3个环境都没有,则默认链接
K8S实现灰度发布案例
2.1 设计思路
- A. 旧版本使用deploy部署副本数量3;
- B. 新版本也是deploy部署副本数量0;
- C. svc同时指向新旧的Pod;
- D. 将旧版本的副本数量逐渐调小到3 --> 0;
- E. 将新版本的副本数量逐渐调大到0 --> 3;
K8S实现蓝绿部署案例
3.1 设计思路
- A. 旧版本使用deploy部署副本数量3;
- B. 新版本也是deploy部署副本数量3;
- C. svc将标签选择器指向旧的Pod;
- D. 切换流量是将标签选择器指向新版本的Pod;
api-server认证体系
API Server内置了插件化的访问控制机制(每种访问控制机制均有一组专用的插件栈):
认证(Authentication):
核验请求者身份的合法性,进行身份识别,验证客户端身份。
身份核验过程遵循"或"逻辑,且任何一个插件核验成功后都将不再进行后续的插件验证。
均不成功,则失败,或以"匿名者"身份访问,建议禁用"匿名者"。
授权(Authorization):
核验请求的操作是否获得许可,验证客户端是否有权限操作资源对象。
鉴权过程遵循"或"逻辑,且任何一个插件对操作的许可授权后都将不再进行后续的插件验证。
均未许可,则拒绝请求的操作
准入控制(Admission Control):
检查操作内容是否合规,仅同"写"请求相关,负责实现"检验"字段类型是否合法及和补全默认字段。
内容合规性检查过程遵循"与"逻辑,且无论成败,每次的操作请求都要经由所有插件的检验。
将数据写入etcd前,负责检查内容的有效性,因此仅对"写"操作有效。
分两类:validating(校验)和 mutating(补全或订正)。
认证、授权、准入控制的关系:
- 认证:你是谁
- 授权:你有没有访问资源的权限
- 准入控制:验证字段是否合法,修订补全(补充一些字段比如nodeName)
kubeconfig的组成部分
1. kubeconfig概述
kubeconfig是YAML格式的文件,用于存储身份认证信息,以便于客户端加载并认证到API Server。
kubeconfig保存有认证到一至多个Kubernetes集群的相关配置信息,并允许管理员按需在各配置间灵活切换:
clusters:
Kubernetes集群访问端点(API Server)列表。
说白了,就是可以定义多个K8S集群列表。
users:
认证到API Server的身份凭据列表。
说白了,可以定义多个用户列表,这个用户可以是token,或者x509证书凭据。
contexts:
将每一个user同可认证到的cluster建立关联的上下文列表。用户,集群进行绑定。
说白了,就是将多个用户和对应的集群进行关联,将来使用哪个用户,就会去关联的集群进行访问认证。也可以定义多个上下文的关系。
current-context:
当前默认使用的context。
Kubernetes系统的用户大体可分Service Account,User Account和Anonymous Account
Service Account:
Kubernetes内置的资源类型,用于Pod内的进程访问API Server时使用的身份信息。
引用格式: "system:serviceaccount:NAMESPACE:SA_NAME"
User Account:
用户账户,指非Pod类的客户端访问API Server时使用的身份标识,一般是现实中的"人"。
API Server没有为这类账户提供保存其信息的资源类型,相关的信息通常保存于外部的文件(特指"kubeconfig"文件)或认证系统中。
身份核验操作可由API Server进行,也可能是由外部身份认证服务完成。
可以手动定义证书,其中O字段表示组,CN字段表示用户名。
Anonymous Account:
不能被识别为Service Account,也不能被识别为User Account的用户。
这类账户K8S系统称之为"system:anonymous",即"匿名用户"。
API Server内置的访问控制机制
API Server的访问方式:
-
集群外部:
https://IP:Port
比如:https://10.0.0.231:6443 -
集群内部:
https://kubernetes.default.svc.oldboyedu.com
比如: 直接基于名为"kubernetes"的svc访问即可
hostNetwork指定dnsPolicy解析策略
当Pod使用hostNetwork: true时,表示Pod使用宿主机网络命名空间,此时DNS策略dnsPolicy有以下几种选择:
-
ClusterFirstWithHostNet(推荐):
- 使用Kubernetes集群DNS(CoreDNS)解析
- 将集群域名的解析请求转发给CoreDNS
- 非集群域名解析请求转发给宿主机DNS服务器
-
Default:
- 继承宿主机/etc/resolv.conf配置
- 直接使用宿主机DNS服务器
-
ClusterFirst:
- 对hostNetwork Pod无效,K8s不允许这种组合
- 如果设置会报错或忽略
-
None:
- 不设置任何DNS配置
- 需要手动配置dnsConfig
coreDNS组件验证是否正常工作
验证CoreDNS是否正常工作的完整流程:
1. 检查CoreDNS Pod状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 期望:Running状态,READY为2/2
2. 检查CoreDNS Service
kubectl get svc -n kube-system kube-dns
# 期望:ClusterIP为10.96.0.10(默认)
3. 检查CoreDNS配置文件
kubectl get configmap -n kube-system coredns -o yaml
# 查看Corefile配置
4. 测试DNS解析
方法1:使用busybox测试
# 创建busybox测试Pod
kubectl run busybox --image=busybox:1.28 --restart=Never -- sleep 3600
# 测试集群内部服务解析
kubectl exec busybox -- nslookup kubernetes.default
# 测试外部域名解析
kubectl exec busybox -- nslookup www.baidu.com
# 清理
kubectl delete pod busybox
方法2:使用dig命令测试
# 在节点上安装dig
yum install bind-utils -y
# 测试集群DNS
dig @10.96.0.10 kubernetes.default.svc.cluster.local
# 测试外部域名
dig @10.96.0.10 www.baidu.com
方法3:创建DNS测试Pod
apiVersion: v1
kind: Pod
metadata:
name: dns-test
namespace: default
spec:
containers:
- name: dns-test
image: busybox:1.28
command:
- sleep
- "3600"
dnsPolicy: ClusterFirst
# 执行测试
kubectl exec -it dns-test -- sh
# 在容器内执行
nslookup kubernetes.default
nslookup www.baidu.com
cat /etc/resolv.conf
5. 检查DNS查询日志
# 开启CoreDNS日志(如果未开启)
kubectl edit configmap coredns -n kube-system
# 在Corefile的.:53配置块中添加:log
# 查看CoreDNS日志
kubectl logs -n kube-system -l k8s-app=kube-dns -c coredns
6. 检查DNS服务器连通性
# 从节点测试DNS服务
nc -zv 10.96.0.10 53
telnet 10.96.0.10 53
7. 常见问题排查
问题1:DNS解析超时
# 检查网络策略
kubectl get networkpolicy -A
# 检查Calico/Flannel网络插件状态
kubectl get pods -n kube-system | grep -E 'calico|flannel'
问题2:无法解析外部域名
# 检查CoreDNS配置中的forward设置
kubectl get configmap coredns -n kube-system -o yaml | grep forward
# 检查节点DNS配置
cat /etc/resolv.conf
问题3:间歇性解析失败
# 检查CoreDNS副本数
kubectl get deployment -n kube-system coredns
# 检查节点资源使用情况
kubectl top nodes
8. 快速诊断命令汇总
# 检查CoreDNS整体状态
kubectl get all -n kube-system -l k8s-app=kube-dns
# 检查端点
kubectl get endpoints -n kube-system kube-dns
# 检查事件
kubectl describe svc -n kube-system kube-dns
kubectl describe pods -n kube-system -l k8s-app=kube-dns
# 测试连通性(从Pod内)
kubectl run test --rm -i --tty --image=busybox:1.28 --restart=Never -- nslookup kubernetes.default
# 查看CoreDNS配置
kubectl exec -n kube-system -c coredns $(kubectl get pods -n kube-system -l k8s-app=kube-dns -o jsonpath='{.items[0].metadata.name}') -- cat /etc/coredns/Corefile
通过以上步骤,可以全面验证CoreDNS组件是否正常工作,并及时发现和解决DNS相关问题。
问题:跨资源空间两个容器如何进行通信
更多推荐
所有评论(0)