☰
k8s 1.13.3 部署电商微服务实战:集群搭建与避坑指南
2026/10/1 19:12:32 网站建设 项目流程

简介:这份资源面向具备一定 Linux 与容器基础的运维、云计算及后端开发人员,聚焦 Kubernetes 1.13.3 环境下电商微服务的落地部署,帮助读者打通从集群搭建到业务上线的完整链路,解决微服务在 k8s 中编排、暴露与治理的实战问题。压缩包共 6 个文件,约 950.8MB,包含 gz 与 tar 形式的安装包(如 JDK、Maven、微服务镜像归档)、用于 Ingress 入口配置的 yaml 清单,以及一份 docx 详细文档笔记,覆盖环境准备、镜像导入、服务编排与访问验证等环节。目前已有 223 人学习下载,说明该案例具备一定的参考价值。读者可借助文档笔记与配套安装包,快速复现电商微服务的部署流程,理解 Deployment、Service、Ingress 等核心对象的配置要点,并对照 yaml 与镜像归档排查常见启动与网络问题,适合作为 k8s 微服务实战的练手素材与排错参考。

1. k8s 1.13.3 部署电商微服务:一套能跑起来的老版本集群实战路径

2019 年前后落地的电商项目里,k8s 1.13.3 是出现频率极高的一个版本。它卡在 1.13 这个 LTS 分支上,kubelet 的 device plugin、CSI 的 beta 接口、CoreDNS 作为默认 DNS 都已经稳定,但 API 又没到 1.16 那波大规模弃用。很多做电商中台的团队当年就是拿它跑商品、订单、库存、支付这几条微服务链路。现在回头看,这套组合依然有复现价值:一是老机房、老镜像仓库、老 CI 流水线还在用,二是拿它练手能避开新版本里被隐藏掉的很多细节,比如 kube-proxy 的 iptables 模式、flannel 的 host-gw、以及 Deployment 的 extensions/v1beta1 写法。这篇笔记不讲概念史,只讲一条能落地的路径:三台机器起集群,把电商微服务拆成可部署的 workload,再补上安装包和文档该怎么整理。适合手上有旧版本约束、或者想彻底搞懂 k8s 部署链路的工程师。

2. 集群落地:k8s 1.13.3 三节点安装与网络选型

2.1 为什么这个版本还要用 kubeadm 而不是二进制

k8s 1.13.3 的安装方式主要有三种:kubeadm、二进制手工部署、以及当时流行的 ansible 脚本。电商项目里我一般推荐 kubeadm,原因很实际——1.13 的 kubeadm 已经支持--config配置文件,能把kubeletExtraArgs、networking.podSubnet、imageRepository一次性写清楚,后面换镜像仓库、改网段不用重装。二进制部署虽然可控,但证书轮换、etcd 集群、kube-proxy 的 iptables 规则都要自己维护,电商这种要频繁扩缩容的场景,维护成本太高。

安装前先确认三台机器的角色划分。常见做法是一台 master 加两台 node,master 不跑业务 pod,用 taint 隔离。系统层面要关 swap、关 SELinux、配好 hosts 和内核参数。下面这段是每台机器都要执行的预处理,注意br_netfilter和ip_forward这两项,flannel 和 kube-proxy 都依赖它们。

# 关闭 swap,k8s 1.13 的 kubelet 默认不允许 swap 开启 swapoff -a sed -i '/swap/s/^/#/' /etc/fstab # 关闭 SELinux,避免 kubelet 挂载 volume 时被拒绝 setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config # 加载内核模块并开启转发 modprobe br_netfilter cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sysctl --system

逻辑说明:br_netfilter让网桥流量经过 iptables,这是 flannel 的 host-gw 和 kube-proxy 的 service 转发能生效的前提。ip_forward不开启的话,跨节点 pod 通信会直接丢包,现象是 pod 能起但 service 访问超时。参数上,net.bridge.bridge-nf-call-iptables必须为 1,很多教程漏掉 ip6tables 那行,在双栈环境里会出玄学问题。

2.2 用 kubeadm 初始化 master 的完整命令

装 docker 和 kubeadm/kubelet/kubectl 三件套时,1.13.3 对应的 docker 版本建议用 18.06.3,太新的 docker 会和 kubelet 的 CRI 对接出兼容问题。安装源用阿里云的 kubernetes 仓库,把版本锁死。

# 安装 docker 18.06.3 yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce-18.06.3.ce-3.el7 systemctl enable docker && systemctl start docker # 安装 k8s 1.13.3 组件 cat > /etc/yum.repos.d/kubernetes.repo <<EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=0 EOF yum install -y kubelet-1.13.3 kubeadm-1.13.3 kubectl-1.13.3 systemctl enable kubelet

初始化配置文件kubeadm-config.yaml是这套部署的核心,把镜像仓库、pod 网段、service 网段、API 地址都写进去。电商项目里 pod 网段我一般用10.244.0.0/16,service 网段用10.96.0.0/12,这两个网段不能和机房现有网段重叠,否则会出现路由黑洞。

apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.1.10 bindPort: 6443 nodeRegistration: kubeletExtraArgs: cgroup-driver: cgroupfs --- apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration kubernetesVersion: v1.13.3 imageRepository: registry.aliyuncs.com/google_containers networking: podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12

执行kubeadm init --config kubeadm-config.yaml后,会输出 join 命令。这里有个血泪经验:1.13.3 的 kubeadm 默认拉取k8s.gcr.io镜像,国内环境必须靠imageRepository换成阿里云,否则卡在[preflight] running pre-flight checks之后的拉镜像阶段,日志里只报 timeout,看不出是网络问题。

2.3 flannel 网络插件的部署与验证

网络插件选 flannel,1.13 时代最稳的是 v0.10.0 或 v0.11.0。host-gw 模式性能好,但要求所有节点在同一二层网络;如果跨网段,就得用 vxlan。电商项目里如果三台机器在同一交换机下,直接上 host-gw。

# 下载 flannel 并修改网段 wget https://raw.githubusercontent.com/coreos/flannel/v0.11.0/Documentation/kube-flannel.yml # 编辑 kube-flannel.yml,把 Network 改成 10.244.0.0/16 kubectl apply -f kube-flannel.yml # 验证节点和 pod 状态 kubectl get nodes kubectl get pods -n kube-system -o wide

逻辑说明:flannel 的 ConfigMap 里Network字段必须和 kubeadm 的podSubnet完全一致,差一位都会导致 pod 拿到 IP 但跨节点不通。验证时看kube-flannel-ds是否在每个节点都 Running,再看kubectl get pods -o wide里 pod 的 IP 是否落在 10.244 段。如果 node 状态是 NotReady,八成是 flannel 没起来或者内核参数没生效。

3. 电商微服务拆分:从单体到可部署的 workload

3.1 电商链路拆成哪几个微服务

电商系统拆微服务,不是越细越好。1.13.3 这套集群资源有限,我一般按业务边界拆成六个:商品服务、订单服务、库存服务、用户服务、支付服务、网关服务。每个服务独立 Deployment,独立 Service,数据库按服务分库。这样拆的好处是订单和库存可以独立扩缩容,大促时只扩订单和库存,商品和用户保持基础副本数。

微服务架构图在文档里要画清楚调用关系:网关对外暴露,内部服务之间用 Service 名做 DNS 解析。1.13.3 的 CoreDNS 已经默认启用,服务间调用直接写http://order-svc:8080这种形式,不用配 IP。这里要注意,Service 的clusterIP是虚拟 IP,跨节点访问靠 kube-proxy 的 iptables 规则转发,所以 kube-proxy 必须正常运行。

3.2 用 Deployment 和 Service 描述一个订单服务

下面这个 YAML 是订单服务的最小可部署单元,包含 Deployment 和 Service。1.13.3 还支持extensions/v1beta1的 Deployment,但建议直接用apps/v1,因为 1.16 之后extensions/v1beta1会被移除,提前用新 API 后面迁移省事。

apiVersion: apps/v1 kind: Deployment metadata: name: order-svc namespace: ecommerce spec: replicas: 2 selector: matchLabels: app: order-svc template: metadata: labels: app: order-svc spec: containers: - name: order image: registry.local/ecommerce/order-svc:1.0.0 ports: - containerPort: 8080 env: - name: DB_HOST value: "mysql-order.ecommerce.svc.cluster.local" resources: requests: cpu: "500m" memory: "512Mi" limits: cpu: "1" memory: "1Gi" readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 20 periodSeconds: 10 --- apiVersion: v1 kind: Service metadata: name: order-svc namespace: ecommerce spec: selector: app: order-svc ports: - port: 8080 targetPort: 8080 type: ClusterIP

逻辑说明:replicas: 2保证订单服务至少两个副本,滚动更新时不会中断。resources的 requests 和 limits 必须写,1.13.3 的调度器靠 requests 做打分,不写的话 pod 会被随机调度到负载高的节点。readinessProbe是关键,电商服务启动要连数据库、加载缓存,没有就绪探针的话,pod 一 Running 就接流量,会出现大量 502。参数上initialDelaySeconds根据服务启动时间调,订单服务一般 20 秒够,商品服务如果加载大量 SKU 缓存,可能要 40 秒。

3.3 配置 ConfigMap 和 Secret 管理环境差异

电商微服务的数据库地址、Redis 地址、支付密钥这些不能写死在镜像里。1.13.3 用 ConfigMap 存普通配置,Secret 存敏感信息。下面是把数据库配置抽出来的做法。

# 创建 ConfigMap kubectl create configmap order-config \ --from-literal=DB_HOST=mysql-order.ecommerce.svc.cluster.local \ --from-literal=REDIS_HOST=redis.ecommerce.svc.cluster.local \ -n ecommerce # 创建 Secret,注意 base64 编码 kubectl create secret generic order-secret \ --from-literal=DB_PASSWORD=yourpassword \ -n ecommerce

然后在 Deployment 里用envFrom引用。逻辑说明:ConfigMap 更新后,挂载为环境变量的 pod 不会自动重启,需要kubectl rollout restart deployment/order-svc。这是 1.13.3 的一个坑,很多人改了 ConfigMap 发现服务没变化,以为是缓存问题,其实是 pod 没重建。Secret 的 base64 只是编码不是加密,生产环境要配合 RBAC 限制读取权限。

4. 避坑与排查:1.13.3 部署电商微服务最容易翻车的五个点

4.1 节点 NotReady 但 kubelet 日志无报错

现象:kubectl get nodes显示 NotReady,journalctl -u kubelet里没有明显 error。原因:多半是 docker 的 cgroup driver 和 kubelet 不一致。1.13.3 的 kubelet 默认cgroup-driver是cgroupfs,而 docker 18.06 默认也是cgroupfs,但如果系统是 CentOS 7.6 以上,systemd 可能把 docker 的 cgroup 改成了 systemd。解决:在 kubeadm 配置里显式写cgroup-driver: cgroupfs,并确认/etc/docker/daemon.json里没有冲突配置,重启 docker 和 kubelet。

4.2 Service 能 ping 通但端口访问超时

现象:pod 之间ping service-name通,但curl service-name:8080超时。原因:kube-proxy 的 iptables 规则没生效,或者 service 的targetPort和容器实际端口不一致。1.13.3 的 kube-proxy 默认用 iptables 模式,如果节点上 iptables 规则被其他软件清过,service 转发就断了。解决:iptables -t nat -L KUBE-SERVICES -n看规则是否存在,不存在就重启 kube-proxy;再检查kubectl get endpoints order-svc是否有 pod IP,没有就说明 readinessProbe 没过。

4.3 镜像拉取失败但镜像仓库能 ping 通

现象:pod 一直 ImagePullBackOff,但ping registry.local正常。原因:docker 没有配置私有仓库的 insecure-registries,或者镜像 tag 写错。1.13.3 的 kubelet 调 docker 拉镜像,docker 对 http 仓库默认拒绝。解决:在/etc/docker/daemon.json里加insecure-registries,重启 docker;再用docker pull手动验证一次,确认镜像名和 tag 完全一致。

4.4 pod 调度失败提示 Insufficient cpu

现象:新扩的 pod 一直 Pending,kubectl describe pod显示Insufficient cpu。原因:节点的 allocatable CPU 被 requests 占满,1.13.3 的调度器只看 requests 不看实际使用率。解决:kubectl describe node看 Allocated resources,把不重要的服务 requests 调小,或者加节点。电商大促前要提前算好 requests 总和,别等扩容时才发现调度不上去。

4.5 CoreDNS 解析间歇性失败

现象:服务间调用偶尔报no such host,重启 pod 又好。原因:1.13.3 的 CoreDNS 默认副本数是 1,节点多了之后 DNS 查询压力大,或者 conntrack 表满了导致 UDP 丢包。解决:把 CoreDNS 扩到 2 到 3 副本,并在 kubelet 配置里加--resolv-conf指向正确的 resolv.conf;如果 conntrack 满,调大nf_conntrack_max。

5. 安装包与文档整理:让这套方案能被别人复现

5.1 安装包该收哪些文件

一套能交付的 k8s 1.13.3 电商微服务安装包,不是把 rpm 堆一起就行。我一般按目录分四层:bin/放 kubeadm、kubelet、kubectl 的 rpm 和 docker 的 rpm;images/放所有离线镜像的 tar 包,包括 k8s 组件镜像、flannel 镜像、电商各服务的业务镜像;yaml/放 kubeadm 配置、flannel 配置、各微服务的 Deployment 和 Service;docs/放安装步骤和排错记录。镜像 tar 包用docker save导出,导入时docker load,这样内网环境不用连外网。

文档部分要写清楚三件事:机器规划表、安装命令顺序、验证清单。机器规划表列出每台机器的 IP、角色、CPU、内存、磁盘。安装命令顺序按预处理、装 docker、装 k8s、init master、join node、装 flannel、部署业务这个顺序写,每步后面附验证命令。验证清单包括kubectl get nodes全 Ready、kubectl get pods -n kube-system全 Running、业务 pod 能互相 curl 通、service 能对外访问。

5.2 文档里必须记录的参数表

下面这张表是我整理文档时必放的,读者照着填就能避开大部分配置错误。

参数项示例值说明
podSubnet10.244.0.0/16必须和 flannel 的 Network 一致
serviceSubnet10.96.0.0/12不能和机房网段重叠
cgroup-drivercgroupfs要和 docker 保持一致
imageRepositoryregistry.aliyuncs.com/google_containers国内环境必改
flannel 模式host-gw 或 vxlan同网段用 host-gw,跨网段用 vxlan
CoreDNS 副本数2节点多时建议 3

文档里还要附一份「常见故障速查」,把第 4 章那五个坑的现象、原因、解决写成表格,别人遇到问题时能直接查。这套整理方式的好处是,半年后自己回头看也能快速重建环境,不用重新踩一遍坑。

5.3 一个验证集群是否健康的脚本

最后给一个我常用的健康检查脚本,部署完跑一遍,输出全绿才算交付。

#!/bin/bash # k8s 1.13.3 集群健康检查 echo "=== 节点状态 ===" kubectl get nodes -o wide echo "=== 系统 pod 状态 ===" kubectl get pods -n kube-system -o wide echo "=== 业务 pod 状态 ===" kubectl get pods -n ecommerce -o wide echo "=== Service Endpoints ===" for svc in order-svc product-svc inventory-svc; do echo "--- $svc ---" kubectl get endpoints $svc -n ecommerce done echo "=== CoreDNS 解析测试 ===" kubectl run dns-test --rm -it --image=busybox:1.28 --restart=Never -- nslookup order-svc.ecommerce.svc.cluster.local

逻辑说明:节点状态看是否全 Ready;系统 pod 看 flannel、kube-proxy、CoreDNS 是否 Running;业务 pod 看副本数是否达标;Endpoints 看 service 是否关联到 pod;DNS 测试验证服务发现是否正常。这个脚本我一般放在安装包的bin/目录下,交付时让对方先跑脚本再验收。参数上,busybox:1.28这个版本带 nslookup,新版本 busybox 去掉了,用之前确认镜像里有这个命令。

这套 k8s 1.13.3 部署电商微服务的路径,我前后在三个项目里用过,每次都会遇到新问题,但骨架不变:先把集群网络和 cgroup 对齐,再把微服务按业务边界拆开,最后用文档和脚本把经验固化下来。老版本有老版本的坑,但把这些坑填平之后,它对理解 k8s 的调度、网络、服务发现反而更直观。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询