10-28-Kubernetes健康检查认证授权与Dashboard

Kubernetes 健康检查、认证授权与 Dashboard 小白教程

日期:2026-10-28

面向:零基础小白,每条命令可直接复制执行(命令后 ------ 是注释,别复制进去)


第一部分:Kubernetes Health Check(健康检查)

1. 这是干啥的

应用会突然"病倒":连接断开、配置错误、程序 bug。kubelet 用**探针(probe)**周期性检查容器里的应用是否健康,不行就重启它,保证服务不掉线。

2. 不配健康检查的后果(先看反面教材)

kubectl create ns health

kubectl config set-context --current --namespace health

kubectl run web --image=hub.laoma.cloud/library/httpd --image-pull-policy=IfNotPresent

kubectl describe pod web | grep '^IP:'

curl 10.224.73.16

kubectl exec web -- rm -f htdocs/index.html

kubectl get pod

删掉主页文件后,pod 状态依然是 Running------应用已经废了,K8s 还当你活着。这就是必须上探针的原因。

清理:kubectl delete pod web --force

3. 三种探针(记住三句话)

探针 问什么 不通过会怎样
LivenessProbe 存活 你还活着吗? 重启 pod
ReadinessProbe 就绪 能接客了吗? 从 Service 的 endpoints 踢出去,不转发流量(但不重启)
StartupProbe 启动 启动完成了吗? 启动期间不跑前两个探针,给慢启动应用保命

4. 四种检查方式

  • httpGet:发 HTTP GET,返回码 200-399 算健康(适合 Web 应用)
  • exec:进容器执行命令,退出码 0 算健康
  • tcpSocket:端口能连上算健康
  • grpc:调 gRPC 健康检查接口(今天不深入)

5. 探针 5 个参数(必背)

  • initialDelaySeconds:容器启动后多久开始查(必填)
  • timeoutSeconds:一次检查超时多久算失败(默认 1s)
  • periodSeconds:隔多久查一次(默认 10s)
  • successThreshold:连续成功几次才算健康(默认 1)
  • failureThreshold:连续失败几次才算病倒(默认 3)

6. 实验一:livenessProbe + httpGet(活着就重启)

cat > deploy-httpGet-liveness.yaml <<'EOF'

apiVersion: apps/v1

kind: Deployment

metadata:

labels:

app: web

name: web

spec:

replicas: 1

selector:

matchLabels:

app: web

template:

metadata:

labels:

app: web

spec:

containers:

  • image: hub.laoma.cloud/library/httpd

imagePullPolicy: IfNotPresent

name: httpd

livenessProbe:

failureThreshold: 3

initialDelaySeconds: 5

periodSeconds: 5

successThreshold: 1

timeoutSeconds: 10

httpGet:

path: /index.html

port: 80

scheme: HTTP

EOF

kubectl apply -f deploy-httpGet-liveness.yaml

kubectl get pod

kubectl exec web-85c6ff748f-qwszz -- bash -c 'rm htdocs/index.html'

kubectl get pod

看 RESTARTS 从 0 变 1------探针发现 index.html 没了,自动把容器重启,主页恢复:

curl 10.98.146.216

清理:kubectl delete deployments.apps web

7. 实验二:readinessProbe(就绪才接客,3 副本演示)

cat > deploy-httpGet-readiness.yaml <<'EOF'

apiVersion: apps/v1

kind: Deployment

metadata:

labels:

app: web

name: web

spec:

replicas: 3

selector:

matchLabels:

app: web

template:

metadata:

labels:

app: web

spec:

containers:

  • image: hub.laoma.cloud/library/httpd

imagePullPolicy: IfNotPresent

name: httpd

readinessProbe:

failureThreshold: 3

initialDelaySeconds: 5

periodSeconds: 5

successThreshold: 1

timeoutSeconds: 10

httpGet:

path: /index.html

port: 80

scheme: HTTP

EOF

kubectl apply -f deploy-httpGet-readiness.yaml

kubectl expose deployment web --port=80 --target-port=80

给每个 pod 写上不同的主页,便于观察流量走向:

for pod in (kubectl get pods -o name \| awk -F / '{print 2}'); do kubectl exec pod -- bash -c "echo pod > htdocs/index.html"; done

kubectl get endpoints web

for i in {1...90}; do curl -s 10.96.180.30; done | sort | uniq -c

三个 pod 轮流接客(web-...-6bpg7 / -d2gbn / -hqh8q 都有流量)。

现在删掉一个 pod 的主页文件:

kubectl exec -it web-9479dc55c-6bpg7 -- rm -f htdocs/index.html

kubectl get endpoints web

endpoints 里少了一个 IP!再看 pod 状态:

kubectl get pod

web-9479dc55c-6bpg7 是 0/1(不 Ready)但 RESTARTS 是 0 ------readiness 只踢人不重启。再 curl,流量只剩两个 pod 的。这就是"就绪探针把病号从名单里踢出去"。

清理:kubectl delete deployments.apps web

8. 实验三:exec(命令退出码判健康)

cat > deploy-exec-liveness.yaml <<'EOF'

apiVersion: apps/v1

kind: Deployment

metadata:

labels:

app: web

name: web

spec:

replicas: 1

selector:

matchLabels:

app: web

template:

metadata:

labels:

app: web

spec:

containers:

  • image: hub.laoma.cloud/library/httpd

imagePullPolicy: IfNotPresent

name: httpd

livenessProbe:

failureThreshold: 3

initialDelaySeconds: 5

periodSeconds: 5

successThreshold: 1

timeoutSeconds: 10

exec:

command:

  • cat

  • /usr/local/apache2/htdocs/index.html

EOF

kubectl apply -f deploy-exec-liveness.yaml

kubectl exec web-8c9ff9b76-nm6s2 -- bash -c 'rm htdocs/index.html'

kubectl get pods

cat 命令失败 → 探针失败 → RESTARTS 变 1。

busybox 加强版(自定义健康文件,10 秒后消失):

kubectl run busybox --image=busybox --image-pull-policy=IfNotPresent -o yaml --dry-run=client > busybox.yml

yaml 里关键加两段:

复制代码
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 100
livenessProbe:
  ...
  exec:
    command:
    - ls
    - /tmp/healthy

启动 10 秒内健康文件在 → 探针通过;10 秒后被删 → 探针失败 → 重启。

9. 实验四:tcpSocket(端口通不通)

cat > deploy-tcpSocket-liveness.yaml <<'EOF'

apiVersion: apps/v1

kind: Deployment

metadata:

labels:

app: web

name: web

spec:

replicas: 1

selector:

matchLabels:

app: web

template:

metadata:

labels:

app: web

spec:

containers:

  • image: hub.laoma.cloud/library/httpd

imagePullPolicy: IfNotPresent

name: httpd

livenessProbe:

failureThreshold: 3

initialDelaySeconds: 5

periodSeconds: 5

successThreshold: 1

timeoutSeconds: 10

tcpSocket:

port: 80

EOF

kubectl apply -f deploy-tcpSocket-liveness.yaml

端口连不上就重启。

10. 健康检查的两大实战场景(面试必考)

场景 1:Scale Up 扩容

应用启动要时间(加载缓存、连数据库),新副本没准备好就放进 Service 会把请求打崩。readiness 探针检查通过才让它接客。

场景 2:滚动更新

  • 没配健康检查:新副本还没就绪就被当"好的"替换旧副本,全换完 → 整个服务瘫痪
  • 配了健康检查:新副本通过探测才替换;不通过 → 旧副本继续服务,业务不断

11. 环境清理

kubectl delete ns health


第二部分:Kubernetes 认证和授权

1. 访问控制四道关(按顺序过)

一个请求进来,依次过:传输安全(TLS)→ ①身份认证 → ②鉴权 → ③准入控制 ,最后写入存储;全程有审计记录。

  • ① 身份认证(Authentication):你是谁?失败返回 401
  • ② 鉴权(Authorization):你配做这事吗?失败返回 403
  • ③ 准入控制(Admission):请求内容能不能放行(可改可拒),只拦写操作不拦读
  • 审计(Audit):按时间记录所有安全相关操作

2. 两类用户

  • 普通用户(人):K8s 不管这个,由外部认证插件提供(如 X509 证书),证书 CN 字段就是用户名
  • 服务账号 ServiceAccount(程序):K8s 自己管,绑 namespace,给 pod 里的程序用

3. 认证插件速览

  • X509 客户证书:默认开启,你的 kubeconfig 就是它
  • 静态令牌文件:--token-auth-file,默认不开
  • 引导令牌 Bootstrap Token:kubeadm 建集群时用
  • 服务账号令牌:自动启用
  • Webhook / 认证代理:企业集成用
  • basic-auth:1.19 以后弃用
  • 匿名请求:没被拦下的就是 system:anonymous 匿名用户

4. 实验:用 X509 证书创建一个用户 laoma(重点,一步步来)

① 客户端准备材料

openssl genrsa -out laoma.key 2048

openssl req -new -key laoma.key -out laoma.csr -subj '/CN=laoma/O=kubernets'

CN(Common Name)就是用户名,O(Organization)是组。把 CSR 发给管理员:

scp laoma.csr root@master30:

② 管理员用集群 CA 签名发证

openssl x509 -req -in laoma.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out laoma.crt -days 1095

kubectl config view > config.tpl

scp config.tpl laoma.crt /etc/kubernetes/pki/ca.crt root@client:~

③ 客户端拼 kubeconfig(方法一:命令生成)

mv config.tpl config

kubectl config set-cluster kubernetes --kubeconfig=config --certificate-authority=ca.crt --embed-certs --server=https://10.1.8.30:6443

kubectl config set-credentials laoma --kubeconfig=config --client-key=laoma.key --client-certificate=laoma.crt --embed-certs

kubectl config set-context laoma --kubeconfig=config --namespace=default --cluster=kubernetes --user=laoma

参数速记:

  • --embed-certs:把证书内容直接嵌进 config 文件(不用每次找路径)
  • --namespace / --cluster / --user:context 三件套

④ 管理员授权后客户端就能干活了

kubectl create clusterrolebinding laoma-admin --clusterrole=cluster-admin --user=laoma

kubectl get nodes --kubeconfig=config

能列出节点,说明认证 + 授权全通。

⑤ 删除账户:删绑定即可(认证是证书干的,与 K8s 无关,彻底删要吊销证书)

kubectl delete clusterrolebindings.rbac.authorization.k8s.io laoma-admin

删完客户端再执行 kubectl get nodes,报 Forbidden------权限没了。

5. 授权模式有哪些

  • Node:专给 kubelet 用的
  • ABAC:属性策略,老古董
  • RBAC:角色访问控制,主流,K8s 默认
  • Webhook:外接企业系统
  • AlwaysAllow:全放行(别在生产用)
  • AlwaysDeny:全拒绝(admin 除外)

看当前用哪种:

cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep mode

输出 --authorization-mode=Node,RBAC

6. role vs clusterrole(区别就一句话)

范围 怎么绑
Role 只管一个命名空间 rolebinding
ClusterRole 管整个集群所有命名空间 clusterrolebinding

预定义 clusterrole 四兄弟:view(只读)< edit < admin(大部分权限)< cluster-admin(万能)

verbs 动作:get(查单个)、list(列清单)、watch(监听变化)、create、delete、update、patch、exec

7. 创建 role 三连

kubectl create role pod-role --verb=get,list,watch --resource=pods -n default

kubectl create rolebinding default-pod-laoma -n default --role=pod-role --user=laoma

kubectl get pod -n default

绑定后,laoma 在 default 里就能看 pod 了。回收:

kubectl delete rolebindings default-pod-laoma -n default

8. apiGroups 这个坑(必踩必背)

role 的 rules 里 apiGroups 写错,权限直接失效:

资源 apiGroups
pod、service、PV、PVC ""(空)
Deployment、DaemonSet、StatefulSet apps
Job、CronJob batch
Role/RoleBinding/ClusterRole/ClusterRoleBinding rbac.authorization.k8s.io
NetworkPolicy networking.k8s.io

查法:kubectl explain deployment | grep VERSION

9. clusterrole 绑定两种模式(重点区别)

kubectl create clusterrole pod-role --verb=get,list,watch --resource=pods

  • clusterrolebinding:绑定后全集群所有命名空间生效
  • rolebinding 绑 clusterrole:只在当前命名空间生效

kubectl create clusterrolebinding laoma-pod-role --clusterrole=pod-role --user=laoma

绑完 laoma 在 kube-system、default 都能看 pod。

坑:给 clusterrole 指定"限定在 auth 命名空间"没意义,cluster 角色就是全局的。

10. 服务账户 ServiceAccount

每个命名空间默认有一个叫 default 的 SA,pod 不指定就用它跑。

kubectl get sa

kubectl run web --image=hub.laoma.cloud/library/httpd --image-pull-policy=IfNotPresent

kubectl get pod web -o yaml | grep serviceAccount

token 怎么进容器:1.24+ 版本不再自动建永久 Secret,改用短期 token(TokenRequest)。kubelet 把 token、ca.crt、namespace 三个文件自动挂到容器里:

kubectl exec -it web -- bash

ls /var/run/secrets/kubernetes.io/serviceaccount

里面有 ca.crt、namespace、token 三个文件。

pod 内程序访问 apiserver 的完整流程:

  1. 读 token 文件
  2. 请求头带 Authorization: Bearer
  3. 发给 apiserver
  4. apiserver 验 token,解析出是哪个 SA(ns + 名字)
  5. 找这个 SA 绑定的 RoleBinding / ClusterRoleBinding
  6. 按 RBAC 规则判断允不允许
  7. 返回结果

实验:建一个带权限的 SA

kubectl create sa sa1

kubectl create clusterrolebinding auth-sa1-cluster-admin --clusterrole=cluster-admin --serviceaccount=auth:sa1

格式:--serviceaccount=命名空间:SA名

cat > web.yaml <<'EOF'

apiVersion: v1

kind: Pod

metadata:

labels:

run: web

name: web

spec:

containers:

  • image: httpd
    imagePullPolicy: IfNotPresent
    name: web
    restartPolicy: Always
    serviceAccount: sa1
    serviceAccountName: sa1
    EOF

kubectl apply -f web.yaml

提醒:pod 有了 cluster-admin 权限,不代表它会乱动------程序用什么权限是它自己代码说了算。

手动创建 token(两种):

  • 临时令牌:kubectl create token sa1(带生命周期,pod 删了自动失效)
  • 永久令牌:创建带注解 kubernetes.io/service-account.name: sa1 的 Secret(新版不推荐)

回收:kubectl delete clusterrolebindings auth-sa1-cluster-admin


第三部分:Kubernetes Dashboard

1. kuboard(第三方界面,老师课堂用)

Kuboard 是开源中文 K8s 管理界面,功能比官方 Dashboard 全(多集群、内置监控、终端工具、审计)。

在线体验:https://demo.kuboard.cn(用户 demo / 密码 demo123)

独立容器方式安装(不占集群资源,课堂推荐):

mkdir /kuboard-data

nerdctl run -d --name=kuboard

-p 80:80/tcp

-p 10081:10081/tcp

-e KUBOARD_ENDPOINT="http://10.1.8.30:80"

-e KUBOARD_AGENT_SERVER_TCP_PORT="10081"

-v /kuboard-data:/data

eipwork/kuboard:v3

浏览器访问 http://10.1.8.30,登录 admin / Kuboard123,导入集群时用 .kubeconfig 文件。

卸载:nerdctl container rm kuboard --force,再 rm -fr /kuboard-data

2. Kubernetes Dashboard(官方)

部署:

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.1/aio/deploy/recommended.yaml

grep image: recommended.yaml

wget -O recommended.yaml http://192.168.50.200/class/course-materials/software/stage03/kubernetes-dashboard-recommended-v2.6.1.yaml

grep image: recommended.yaml

kubectl apply -f recommended.yaml

镜像换成内网源(hub.laoma.cloud),执行部署。

验证:

kubens kubernetes-dashboard

kubectl get deployments.apps

kubectl get service

  • dashboard 以 serviceAccount: kubernetes-dashboard 身份运行
  • 它绑的 ClusterRole 默认只有读 metrics 的权限(nodes.metrics.k8s.io、pods.metrics.k8s.io)
  • 所以刚装完的 dashboard 只能看监控数据,管理不了一点

改成 NodePort 方便访问:

kubectl edit svc kubernetes-dashboard

把 spec.type 改成 NodePort。再查看:

kubectl get svc kubernetes-dashboard

kubectl -n kubernetes-dashboard create token kubernetes-dashboard

浏览器访问 https://10.1.8.30:30518,选 Token 方式,粘贴上面生成的长 token 登录。

提示:新版本只支持 Bearer Token 登录;token 有效期 24 小时,过期重新生成。想要管理权限,把 cluster-admin 绑给 dashboard 的 SA 即可:

kubectl create clusterrolebinding kubernetes-dashboard-cluster-admin --clusterrole=cluster-admin --serviceaccount kubernetes-dashboard:kubernetes-dashboard


今日小结(一句话版)

  1. 健康检查:liveness 管死活(不健康就重启),readiness 管接客(不健康就踢出负载均衡),滚动更新和扩容都靠它保命
  2. 认证授权:认证问"你是谁"(X509 证书),授权问"你能干啥"(RBAC 角色),服务账号是给程序用的身份
  3. Dashboard:官方默认最小权限(只读监控),想管集群要自己绑 cluster-admin
相关推荐
做运维的阿瑞7 小时前
EKS 可销毁环境:集群创建、应用部署到账单归零
云原生·云计算·terraform
每天一道题7 小时前
微服务为什么会变慢?从 QPS、P99 到 Trace 与性能瓶颈
微服务·云原生·架构
牛马工作号7 小时前
Copyparty 轻量文件共享:Docker Compose 部署、权限与多协议使用全指南
运维·docker·容器
oioihoii8 小时前
Windows部署MySpeed自建测速服务:Docker运行后直接测速,再配置固定公网地址远程查看
运维·docker·容器
时间售卖铺9 小时前
MySQL事务ACID与隔离级别深度解析
运维·数据库·mysql·云原生
SatanII9 小时前
Kubernetes 认证与授权详解:守护集群API访问安全
安全·贪心算法·kubernetes
每天一道题9 小时前
微服务为什么会发生级联故障?从 Timeout、Retry 到熔断、限流与 Backpressure
微服务·云原生·架构
无心水10 小时前
15、云原生架构设计理论与实践 核心考点与学习笔记
笔记·学习·云原生·架构师·软考·系统架构设计师·软考系统架构设计师
闲云野鹤在人间10 小时前
头秃修炼手册:StorageClass+StatefulSet+ETCD 全套渡劫笔记
linux·数据库·笔记·云原生·kubernetes·etcd