1. Kubernetes 集群架构设计与核心概念解析
当我们需要在生产环境部署容器化应用时,单机Docker已经无法满足需求。Kubernetes作为容器编排的事实标准,其核心价值在于提供高可用、弹性伸缩的集群管理能力。我将在本手册中分享经过多个生产环境验证的部署方案——1个Master节点搭配多个Worker节点的经典架构。
1.1 为什么选择1主多从架构
这种架构设计在中小规模集群(节点数<50)中表现出最佳性价比。Master节点作为控制平面运行关键组件:
- API Server:集群操作的唯一入口
- Scheduler:负责Pod调度决策
- Controller Manager:维护集群状态
- etcd:分布式键值存储
而Worker节点则专注于运行业务容器,通过kubelet与Master保持通信。实际测试表明,单个Master节点可稳定管理20-30个Worker节点,当集群规模超过此范围时才需要考虑多Master高可用方案。
关键提示:生产环境务必为Master节点配置至少4核CPU和8GB内存,etcd对磁盘IOPS要求极高,建议使用SSD存储。
1.2 YAML声明式配置的优势
与传统脚本式部署相比,YAML文件提供了声明式的资源配置方式。这意味着我们只需要定义"期望状态",而不必关心具体的操作步骤。例如一个Deployment的YAML片段:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80这种方式的三大核心优势:
- 版本可控:YAML文件可纳入Git版本管理
- 幂等操作:重复apply不会导致异常
- 状态可观测:kubectl diff可预览变更
2. 集群部署实战:从零搭建K8s环境
2.1 基础设施准备
以CentOS 7为例,所有节点需要执行以下预处理:
# 关闭防火墙 systemctl stop firewalld systemctl disable firewalld # 禁用SELinux setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config # 配置内核参数 cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sysctl --system # 安装Docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum install -y docker-ce-19.03.15 docker-ce-cli-19.03.15 containerd.io systemctl enable --now docker2.2 使用kubeadm初始化Master节点
在Master节点执行:
# 添加Kubernetes源 cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF # 安装kubeadm yum install -y kubelet-1.20.15 kubeadm-1.20.15 kubectl-1.20.15 --disableexcludes=kubernetes systemctl enable --now kubelet # 初始化集群 kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=<MASTER_IP> --kubernetes-version=1.20.15初始化完成后会输出Worker节点加入集群的命令,形如:
kubeadm join <MASTER_IP>:6443 --token <TOKEN> --discovery-token-ca-cert-hash sha256:<HASH>2.3 部署CNI网络插件
Kubernetes需要网络插件实现Pod间通信,这里选择Flannel:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml验证网络插件状态:
kubectl get pods -n kube-system -l app=flannel3. 应用部署:纯YAML实践
3.1 Deployment与Service配置解析
完整的应用部署通常需要组合多种资源类型。以下是一个包含Deployment、Service和Ingress的示例:
# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: web-app spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: web image: nginx:alpine ports: - containerPort: 80 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "200m" memory: "256Mi" livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 30 periodSeconds: 10 # service.yaml apiVersion: v1 kind: Service metadata: name: web-service spec: selector: app: web ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP部署命令:
kubectl apply -f deployment.yaml -f service.yaml3.2 高级调度策略实践
通过节点亲和性和反亲和性实现精细化调度:
apiVersion: apps/v1 kind: Deployment metadata: name: cache-service spec: replicas: 3 selector: matchLabels: app: cache template: metadata: labels: app: cache spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - cache topologyKey: "kubernetes.io/hostname" containers: - name: redis image: redis:6这个配置确保相同应用的Pod不会调度到同一节点,提高服务可用性。
4. 访问原理深度解析
4.1 服务发现机制
Kubernetes提供了两种基本的服务发现方式:
- 环境变量方式:Pod启动时,Kubernetes会将所有Service信息以环境变量形式注入
- DNS方式(推荐):CoreDNS为每个Service创建DNS记录,格式为
<service-name>.<namespace>.svc.cluster.local
4.2 流量走向分析
当外部请求到达集群时,典型的流量路径:
- 客户端访问NodePort或LoadBalancer
- kube-proxy根据iptables/ipvs规则将请求转发到具体Pod
- 如果配置了Ingress,请求会先经过Ingress Controller处理
- 最终到达业务Pod
可以通过以下命令观察iptables规则:
iptables-save | grep <service-name>4.3 Ingress实战配置
以Nginx Ingress为例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: demo.example.com http: paths: - path: /web pathType: Prefix backend: service: name: web-service port: number: 80需要先部署Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml5. 生产环境经验与排错指南
5.1 常见问题速查表
| 问题现象 | 可能原因 | 排查命令 |
|---|---|---|
| Pod一直Pending | 资源不足/调度失败 | kubectl describe pod <name> |
| Pod启动后立即Crash | 应用配置错误 | kubectl logs <pod-name> --previous |
| Service无法访问 | 标签选择器不匹配 | kubectl get endpoints <service-name> |
| DNS解析失败 | CoreDNS异常 | kubectl logs -n kube-system -l k8s-app=kube-dns |
5.2 性能优化建议
- 设置合理的资源请求和限制:
resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "512Mi" - 使用HorizontalPodAutoscaler实现自动扩缩容:
kubectl autoscale deployment web-app --cpu-percent=50 --min=2 --max=10 - 定期清理无用资源:
kubectl delete pods --field-selector=status.phase==Succeeded
5.3 监控与日志方案
推荐部署Prometheus + Grafana监控套件:
# 安装kube-prometheus-stack helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack日志收集建议采用EFK(Elasticsearch+Fluentd+Kibana)或直接使用云厂商提供的日志服务。