ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

k8s 1.13.3 部署电商微服务实战:集群搭建与避坑指南

k8s 1.13.3 部署电商微服务实战:集群搭建与避坑指南 简介这份资源面向具备一定 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 加两台 nodemaster 不跑业务 pod用 taint 隔离。系统层面要关 swap、关 SELinux、配好 hosts 和内核参数。下面这段是每台机器都要执行的预处理注意br_netfilter和ip_forward这两项flannel 和 kube-proxy 都依赖它们。# 关闭 swapk8s 1.13 的 kubelet 默认不允许 swap 开启 swapoff -a sed -i /swap/s/^/#/ /etc/fstab # 关闭 SELinux避免 kubelet 挂载 volume 时被拒绝 setenforce 0 sed -i s/SELINUXenforcing/SELINUXpermissive/ /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] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled1 gpgcheck0 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/16service 网段用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 网络插件的部署与验证网络插件选 flannel1.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. 电商微服务拆分从单体到可部署的 workload3.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-literalDB_HOSTmysql-order.ecommerce.svc.cluster.local \ --from-literalREDIS_HOSTredis.ecommerce.svc.cluster.local \ -n ecommerce # 创建 Secret注意 base64 编码 kubectl create secret generic order-secret \ --from-literalDB_PASSWORDyourpassword \ -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显示 NotReadyjournalctl -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 一直 Pendingkubectl 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 的 rpmimages/放所有离线镜像的 tar 包包括 k8s 组件镜像、flannel 镜像、电商各服务的业务镜像yaml/放 kubeadm 配置、flannel 配置、各微服务的 Deployment 和 Servicedocs/放安装步骤和排错记录。镜像 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跨网段用 vxlanCoreDNS 副本数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 --imagebusybox:1.28 --restartNever -- nslookup order-svc.ecommerce.svc.cluster.local逻辑说明节点状态看是否全 Ready系统 pod 看 flannel、kube-proxy、CoreDNS 是否 Running业务 pod 看副本数是否达标Endpoints 看 service 是否关联到 podDNS 测试验证服务发现是否正常。这个脚本我一般放在安装包的bin/目录下交付时让对方先跑脚本再验收。参数上busybox:1.28这个版本带 nslookup新版本 busybox 去掉了用之前确认镜像里有这个命令。这套 k8s 1.13.3 部署电商微服务的路径我前后在三个项目里用过每次都会遇到新问题但骨架不变先把集群网络和 cgroup 对齐再把微服务按业务边界拆开最后用文档和脚本把经验固化下来。老版本有老版本的坑但把这些坑填平之后它对理解 k8s 的调度、网络、服务发现反而更直观。希望帮到你。本文还有配套的精品资源点击获取
返回列表