kubernetes的有状态服务定义程序运行要记住历史数据、身份标识比如 MySQL、Redis 集群必须固定身份、独立存储不能随意互换 Pod就得用有状态部署。三大组成StatefulSet 管控 Pod命名固定app-0、app-1严格顺序启动、删除。Headless 无头 Service 不分配统一集群 IP通过 DNS 域名精准访问单个 Pod。独立 PVC 每个 Pod 绑定专属持久化存储删除 Pod 数据保留。特点Pod 按照固定顺序启停Pod 名称与域名永久固定每个实例拥有独立磁盘实现数据隔离。与Deployment 区别Deployment所有 Pod 完全一致可随意替换、共享存储用于无状态服务。 StatefulSet每个 Pod 独立身份、独立存储用来部署数据库类有状态集群。基于 StatefulSet 部署 Redis 实现数据持久化无头服务 yamlredis-svc.yaml# api版本固定v1 apiVersion: v1 # 资源类型为服务 kind: Service metadata: # Service名称 name: redis-service spec: # 匹配标签为app:redis的Pod selector: app: redis # clusterIP: None 无头服务不分配统一集群IP靠DNS解析单个Pod域名 clusterIP: None ports: # 对外开放端口6379Redis默认端口 - port: 6379StatefulSet 主体 yamlredis-sts.yaml# StatefulSet所属api版本 apiVersion: apps/v1 # 资源类型有状态控制器 kind: StatefulSet metadata: # StatefulSet名称 name: redis-sts spec: # 绑定上方无头Service名称建立关联 serviceName: redis-service # 副本数量这里单实例测试写1 replicas: 1 # 标签选择器匹配Pod标签 selector: matchLabels: app: redis # Pod模板定义容器配置 template: metadata: labels: app: redis spec: containers: - name: redis # 使用redis6官方镜像 image: redis:6 ports: # 容器内部端口 - containerPort: 6379 # 将持久化存储挂载到Redis的数据目录 volumeMounts: - name: redis-data mountPath: /data # PVC模板StatefulSet自动为每一个Pod单独创建一块持久化磁盘 volumeClaimTemplates: - metadata: name: redis-data spec: # 读写权限单节点读写 accessModes: [ ReadWriteOnce ] # 申请1G存储空间 resources: requests: storage: 1Gi部署# 部署无头服务 kubectl apply -f redis-svc.yaml # 部署有状态控制器 kubectl apply -f redis-sts.yaml # 查看生成的Pod可以看到名称固定为 redis-sts-0 kubectl get pods # 进入redis写入测试数据 kubectl exec redis-sts-0 -- redis-cli SET name test123 # 手动删除Pod模拟容器宕机 kubectl delete pod redis-sts-0 # Pod重建完毕后查询数据验证持久化生效 kubectl exec redis-sts-0 -- redis-cli GET name注意StatefulSet 的serviceName必须和无头 Service 名称一致且 Service 必须配置clusterIP: None。三处标签Service 选择器、STS 标签选择器、Pod 标签必须完全匹配。删除 StatefulSet 不会自动删除 PVC清理环境需手动删除 PVC 释放存储。Pod 按序号从小到大创建、从大到小销毁切勿强制删除序号靠前的 Pod。无头服务仅用于集群内部 DNS 寻址不能暴露 NodePort 对外访问。数据库类业务严禁改用 Deployment 部署会造成集群身份混乱。kubernetes的helmHelm3 无 Tiller仅客户端依靠本机 kubeconfig 操作集群。定义Helm 是 Kubernetes 的应用包管理工具等同于 Linux 的 yum、apt用来打包、分发、部署 K8s 整套应用 yaml不用手写一堆配置。三大核心Chart应用安装包内含部署模板、默认配置。Repo仓库存放 Chart 的线上仓库。ReleaseChart 部署到集群后的运行实例一个 Chart 可多次安装生成多个 Release。二进制部署Helm下载 Helm 二进制包wget https://get.helm.sh/helm-v3.16.2-linux-amd64.tar.gz解压tar -zxvf helm-v3.16.2-linux-amd64.tar.gz将 helm 程序移入系统全局目录任意终端可执行sudo mv linux-amd64/helm /usr/local/bin/验证是否安装成功helm version配置国内镜像仓库# 添加 Bitnami 仓库常用中间件全都有 helm repo add bitnami https://charts.bitnami.com/bitnami # 更新仓库索引 helm repo update查看# 查看已安装应用 helm list -n middleware # 卸载应用 helm uninstall redis -n middleware常用命令总结# 添加仓库 helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update # 搜索软件 helm search repo redis # 安装应用 helm install redis bitnami/redis -n middleware --create-namespace # 查看已部署应用 helm list -n middleware # 导出配置进行修改 helm show values bitnami/redis redis.yaml # 使用自定义配置安装 helm install redis bitnami/redis -f redis.yaml -n middleware # 升级、回滚、卸载 helm upgrade redis bitnami/redis -f redis.yaml -n middleware helm rollback redis 1 -n middleware helm uninstall redis -n middleware用helm安装常用软件Helm --set 方式一键部署 MySQL 一主一从添加仓库并更新helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update一键部署 MySQL 一主一从helm install mysql # 发布名称为 mysql --version 10.3.0 # 固定chart版本防止版本变动引发异常 --set auth.rootPasswordPssw0rd # 设置root管理员密码 --set global.storageClasssc-nfs # 全局使用sc-nfs存储类动态创建存储卷 --set auth.databasewordpress # 自动创建业务库 wordpress --set auth.usernamewordpress # 创建业务普通账号 --set auth.passwordPssw0rd # 业务账号密码 --set architecturereplication # 开启主从复制架构standalone为单机模式 --set secondary.replicaCount1 # 从节点数量1个实现一主一从 --set auth.replicationPasswordPssw0rd # 主从同步账号密码 bitnami/mysql # 调用bitnami仓库中的mysql安装包 -n wordpress --create-namespace # 部署到wordpress命名空间不存在自动创建查看运行状态# 查看pod正常会生成 mysql-primary-0(主)、mysql-replica-0(从) kubectl get pods -n wordpress # 查看helm已部署应用 helm list -n wordpress # 查看创建的PVC数据持久化存储 kubectl get pvc -n wordpress验证主从同步登录主库写入测试数据kubectl exec -it mysql-primary-0 -n wordpress -- mysql -uroot -pPssw0rd执行 SQLuse wordpress; create table test(id int); insert into test values(666); exit;登录从库校验是否同步kubectl exec -it mysql-replica-0 -n wordpress -- mysql -uroot -pPssw0rd执行 SQLuse wordpress; select * from test;查询出666即代表主从同步成功从节点默认只读禁止写入。扩容从节点helm upgrade mysql \ --set secondary.replicaCount2 \ bitnami/mysql -n wordpress查看发布历史helm history mysql -n wordpress回滚版本helm rollback mysql 1 -n wordpress卸载 MySQLPVC 保留数据不会删除helm uninstall mysql -n wordpress测试环境彻底清理删除存储释放资源kubectl delete pvc -n wordpress -l app.kubernetes.io/namemysql注意architecturereplication 是开启主从的核心配置集群内必须提前存在 sc-nfs 这个 StorageClass否则 PVC 无法绑定。kubernetes的安全机制身份认证 → RBAC 授权 → 准入控制→Pod 容器安全身份认证 Authentication作用校验发起请求的客户端是否合法陌生人直接拒绝连接 APIServer。TLS 证书认证 master 组件、kubelet、运维管理员全部使用 CA 签发的证书接入集群安全性最高。 ServiceAccount Token 集群内部 Pod 想要调用 K8s APIServer默认自动挂载 SA 令牌完成认证。 LDAP/OIDC 企业场景对接公司统一账号体系员工工号即可登录集群。 明文密码、静态 Token 仅本地测试使用生产环境禁用极易泄露。RBAC 授权 AuthorizationRole-Based Access Control基于角色的访问控制前提身份认证通过之后再管控操作权限严格遵循最小权限原则。Role 权限规则作用范围仅限某一个命名空间无法跨命名空间操作。 ClusterRole 集群级别权限作用整个集群所有命名空间。 RoleBinding / ClusterRoleBinding 绑定动作把 Role/ClusterRole 的权限赋予用户、用户组、Pod 的 ServiceAccount。 强制规范 普通开发人员、业务 Pod 账号禁止绑定 cluster-admin 集群超级管理员权限。准入控制器 Admission Control时机认证 授权全都放行资源存入 etcd 数据库之前最后一次校验拦截。ResourceQuota 限制单个命名空间整体 CPU、内存、PVC 存储上限防止某个项目耗尽集群全部资源。 LimitRanger 约束单个 Pod 的最大、最小资源避免单个容器霸占节点资源导致节点宕机。 PodSecurity 安全准入 拦截高危 Pod 配置禁止特权容器、禁止容器以 root 账号运行。 Webhook 自定义准入 扩展能力可自定义规则例如只允许部署私有仓库镜像、拦截带 latest 标签的镜像。Pod 容器安全SecurityContext 安全上下文 配置关闭 privileged 特权模式、runAsNonRoot:true 非 root 运行容器、移除多余 Linux 权限降低容器逃逸风险。 镜像安全管控 仅使用私有镜像仓库、镜像固定版本号禁止 latest、上线前进行漏洞扫描。 配置 requests limits requests 为容器申请资源limits 限制资源上限避免容器无节制抢占节点资源。案例K8s 如何使用同一个运维账号管理两套集群环境集群 1192.168.9.100、集群 2192.168.9.101两套集群互相独立各自用自身 CA 签发同名运维证书分别做 RBAC 授权本地电脑合并两份集群 kubeconfig切换上下文即可用同一个账号轮流管理两个集群。集群 1192.168.9.100生成运维证书并授权进入证书目录cd /etc/kubernetes/pki创建证书配置 ops-csr.json{ CN: ops-admin, key: { algo: rsa, size: 2048 }, names: [ { C: CN, O: system:masters, OU: ops } ] }签发证书cfssl gencert -caca.crt -ca-keyca.key -profilekubernetes ops-csr.json | cfssljson -bare ops-adminRBAC 赋予集群管理员权限apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: ops-bind-cluster1 subjects: - kind: User name: ops-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminkubectl apply -f rbac.yaml导出集群连接配置 cluster1.kubeconfigkubectl config set-cluster cluster-1 \ --serverhttps://192.168.9.100:6443 \ --certificate-authorityca.crt \ --embed-certstrue \ --kubeconfigcluster1.kubeconfig kubectl config set-credentials ops-admin \ --client-certificateops-admin.pem \ --client-keyops-admin-key.pem \ --embed-certstrue \ --kubeconfigcluster1.kubeconfig kubectl config set-context ctx-cluster1 \ --clustercluster-1 \ --userops-admin \ --kubeconfigcluster1.kubeconfig集群 2192.168.9.101执行同理进入 /etc/kubernetes/pki使用相同 ops-csr.json 签发同名 ops-admin 证书。 应用上面 rbac.yaml绑定 cluster-admin 权限。生成集群配置文件 cluster2.kubeconfigkubectl config set-cluster cluster-2 \ --serverhttps://192.168.9.101:6443 \ --certificate-authorityca.crt \ --embed-certstrue \ --kubeconfigcluster2.kubeconfig kubectl config set-credentials ops-admin \ --client-certificateops-admin.pem \ --client-keyops-admin-key.pem \ --embed-certstrue \ --kubeconfigcluster2.kubeconfig kubectl config set-context ctx-cluster2 \ --clustercluster-2 \ --userops-admin \ --kubeconfigcluster2.kubeconfig本地合并两份集群配置# 写入第一个集群配置 KUBECONFIGcluster1.kubeconfig kubectl config view --flatten ~/.kube/config # 合并第二个集群配置 KUBECONFIG~/.kube/config:cluster2.kubeconfig kubectl config view --flatten tmp mv tmp ~/.kube/config切换集群管理# 管控 192.168.9.100 kubectl config use-context ctx-cluster1 kubectl get nodes # 管控 192.168.9.101 kubectl config use-context ctx-cluster2 kubectl get nodesRBAC生产别直接绑定 cluster-admin遵循最小权限。两个集群绑定不同名称的 ClusterRoleBinding方便维护。kubeconfig合并加 --flatten上下文名称不能重复。config 文件权限设 600合并前备份。