ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Kubernetes 1.13.3 部署电商微服务实战:安装包与详细文档笔记

Kubernetes 1.13.3 部署电商微服务实战:安装包与详细文档笔记 简介这份资源面向具备一定容器与 Linux 基础的云计算运维人员及微服务开发者围绕 k8s 1.13.3 版本提供一套电商微服务在 Kubernetes 上落地的实战案例资料帮助读者理解从环境搭建到服务编排的完整流程。压缩包共 6 个文件约 950.8MB包含 gz 与 tar 格式的安装包如 JDK、Maven、微服务镜像及 ingress-controller 组件、一份 yaml 编排清单以及一份 docx 详细文档笔记覆盖依赖准备、镜像导入与资源配置等环节。目前已有 223 人学习下载。资料中的文档笔记对部署步骤、组件作用与常见问题做了整理yaml 文件可直接参考或改造用于自己的集群配合安装包能较快复现一套可运行的电商微服务环境适合作为 k8s 入门到进阶的练手项目也便于在面试或实际运维中对照排查部署问题。1. k8s 1.13.3 部署电商微服务一套能跑起来的实战路径2019 年前后大量中小团队手里跑的还是 k8s 1.13.3 这个版本电商业务又刚好在往微服务拆。这个组合放到今天看有点旧但它的价值恰恰在于“旧”——组件依赖少、镜像体积小、单机也能把整套链路跑通非常适合拿来吃透 Kubernetes 部署微服务的完整流程。标题里的“安装包和详细文档笔记整理”本质是把一套可复现的部署方案固化下来从集群初始化、镜像准备、微服务拆分到 Service、Ingress、配置与存储的落地。它适合两类人一是刚学 k8s、想找一个真实业务场景练手的工程师二是手上真有老集群、需要把电商微服务迁上去的运维和开发。下面按“集群怎么搭 → 微服务怎么拆 → 怎么部署 → 坑在哪 → 怎么验证”的顺序讲透。2. 集群与镜像准备把 k8s 1.13.3 的地基打稳2.1 为什么这个版本要锁死组件版本k8s 1.13.3 属于 1.13 分支的补丁版本API 还是apps/v1为主extensions/v1beta1的 Deployment 已经废弃但部分资源仍在用。这个版本对容器运行时只认 Dockerkubelet和kubeadm的版本必须严格对齐否则kubeadm init阶段就会因为版本偏差直接报错退出。我一般会把三个节点的系统统一成 CentOS 7.6 或 Ubuntu 18.04内核 4.x关闭 swap因为 1.13 的 kubelet 对 swap 的容忍度很低开着 swap 会出现 Pod 反复重启的玄学问题。组件版本建议这样锁组件版本说明kubeadm / kubelet / kubectl1.13.3三者必须一致Docker18.06.1-ce1.13 官方验证过的运行时flannelv0.10.0网络插件配置简单etcd3.2.24kubeadm 内置无需单独装2.2 用 kubeadm 初始化单 master 集群单节点或一主两从是练手最稳的形态。先在所有节点装好 Docker 和 kubelet然后在 master 上执行初始化。下面这段是初始化配置文件比纯命令行更好维护# kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.1.10 # master 内网 IP bindPort: 6443 --- apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration kubernetesVersion: v1.13.3 imageRepository: registry.aliyuncs.com/google_containers # 国内拉镜像更稳 networking: podSubnet: 10.244.0.0/16 # 必须和 flannel 网段一致执行初始化kubeadm init --config kubeadm-config.yaml --ignore-preflight-errorsSwap mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.ymladvertiseAddress填 master 的真实内网 IP填错会导致 node 注册不上。podSubnet一旦定了就不要改flannel 的 ConfigMap 里网段必须和它一致否则跨节点 Pod 通信直接断。--ignore-preflight-errorsSwap是临时绕过 swap 检查生产环境还是老老实实关掉 swap。初始化完成后用kubectl get nodes确认状态是 Ready如果一直是 NotReady八成是 flannel 没起来用kubectl get pods -n kube-system看具体哪个 Pod 在 CrashLoopBackOff。2.3 镜像准备与私有仓库电商微服务的镜像通常有十几个直接走公网拉取在集群里会非常慢。常见做法是在本地或一台跳板机上起一个 registry把镜像统一推上去再让 kubelet 从内网拉。给 Docker 配置私有仓库信任# /etc/docker/daemon.json { insecure-registries: [192.168.1.20:5000], exec-opts: [native.cgroupdriversystemd] }native.cgroupdriversystemd这一项在 1.13 上很关键Docker 默认用 cgroupfs和 kubelet 的 systemd 驱动不一致时节点资源统计会出错严重时 Pod 起不来。改完systemctl daemon-reload systemctl restart docker。镜像命名统一成192.168.1.20:5000/ecommerce/order-service:1.0.0这种格式后面写 Deployment 时直接引用省得每个 yaml 里再改地址。3. 电商微服务拆分与部署清单设计3.1 按业务边界拆成哪几个服务电商系统拆微服务最忌讳一上来就按技术分层拆。我一般按业务能力切用户服务、商品服务、订单服务、库存服务、支付服务、网关。每个服务独立镜像、独立 Deployment、独立 Service。服务之间用 ClusterIP 的 Service 名做 DNS 调用比如订单服务调库存直接写http://inventory-service:8080kube-dns 会解析到对应 Pod。这样拆的好处是每个服务能单独扩缩容订单高峰时只扩订单和库存不用整个系统一起加机器。拆分时要注意数据库边界。订单库和库存库最好物理分开至少逻辑上分库否则一个服务的慢查询会把另一个拖死。配置方面每个服务的数据库连接、Redis 地址、MQ 地址都通过 ConfigMap 注入敏感信息走 Secret不要硬编码在镜像里。3.2 一个可复用的 Deployment 模板下面以订单服务为例给出 Deployment 加 Service 的完整 yaml。这个模板改改镜像名和端口就能套到其他服务上apiVersion: apps/v1 kind: Deployment metadata: name: order-service namespace: ecommerce spec: replicas: 2 selector: matchLabels: app: order-service template: metadata: labels: app: order-service spec: containers: - name: order-service image: 192.168.1.20:5000/ecommerce/order-service:1.0.0 ports: - containerPort: 8080 envFrom: - configMapRef: name: order-config - secretRef: name: order-secret resources: requests: cpu: 250m memory: 512Mi limits: cpu: 500m memory: 1Gi readinessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 --- apiVersion: v1 kind: Service metadata: name: order-service namespace: ecommerce spec: selector: app: order-service ports: - port: 8080 targetPort: 8080 type: ClusterIPreplicas: 2是起步值单副本在滚动更新时会有短暂不可用。resources的 requests 和 limits 必须写1.13 的调度器靠 requests 算资源不写的话所有 Pod 都往一个节点挤。readinessProbe指向 Spring Boot 的 health 端点没就绪的 Pod 不会被挂到 Service 后面这是滚动更新不丢请求的关键。envFrom把 ConfigMap 和 Secret 里的键值对整体注入成环境变量改配置不用重新打镜像。3.3 用 Ingress 暴露网关集群内部走 ClusterIP对外只暴露一个网关服务。1.13 时代 Ingress 还是extensions/v1beta1写法如下apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ecommerce-gateway namespace: ecommerce annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: shop.example.com http: paths: - path: / backend: serviceName: gateway-service servicePort: 8080host换成你自己的域名或 hosts 里配的假域名。rewrite-target在路径转发时很有用网关内部路由和外部路径不一致时靠它对齐。Ingress controller 需要单独部署1.13 上常用 nginx-ingress 的 0.22 左右版本装好后kubectl get pods -n ingress-nginx确认 Running再用kubectl get ingress -n ecommerce看 ADDRESS 有没有分配出来。4. 配置、存储与滚动更新让微服务真正可用4.1 ConfigMap 和 Secret 的正确用法配置外置是微服务的基本功。ConfigMap 存非敏感配置Secret 存密码和密钥。创建方式有两种命令行和 yaml。我倾向用 yaml 管理方便进版本库kubectl create configmap order-config \ --from-literalDB_HOSTmysql-service \ --from-literalREDIS_HOSTredis-service \ -n ecommerce kubectl create secret generic order-secret \ --from-literalDB_PASSWORDyourpassword \ -n ecommerce--from-literal适合少量键值配置多的时候用--from-file挂整个配置文件。Secret 默认是 base64 编码不是加密集群里谁能读 Secret 谁就能拿到明文所以 RBAC 要收紧。改完 ConfigMap 后已经运行的 Pod 不会自动加载新值要么重启 Pod要么用 sidecar 做热加载这一点在 1.13 上没有原生支持别指望改完就生效。4.2 有状态服务用 PV 和 PVCMySQL、Redis 这类有状态服务不能像无状态服务那样随便漂。1.13 上动态存储供给还不普及常见做法是手动建 PV 再让 PVC 绑定apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv spec: capacity: storage: 20Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: path: /data/mysql --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc namespace: ecommerce spec: accessModes: - ReadWriteOnce resources: requests: storage: 20GihostPath只适合单节点练手多节点必须换成 NFS 或云盘。persistentVolumeReclaimPolicy: Retain是后悔药删 PVC 时数据不会被一起清掉。MySQL 的 Deployment 里把mysql-pvc挂到/var/lib/mysqlPod 重建后数据还在。注意 hostPath 的目录权限MySQL 容器里是 mysql 用户宿主机目录属主不对会启动失败报错通常是Permission denied。4.3 滚动更新参数怎么调电商服务更新不能停服靠的是 Deployment 的滚动更新策略。默认maxUnavailable是 25%副本少的时候这个值会导致更新期间可用 Pod 不够。我一般显式设置spec: strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 1maxUnavailable: 0保证更新过程中可用副本数不低于期望值maxSurge: 1允许临时多起一个 Pod。这样更新时先起新 Pod就绪后再杀旧 Pod全程服务不断。配合 readinessProbe 的initialDelaySeconds给应用留足启动时间否则新 Pod 还没起来就被判定失败更新会卡住。用kubectl rollout status deployment/order-service -n ecommerce观察更新进度kubectl rollout undo可以回滚到上一版。5. 部署电商微服务时最容易翻车的几个点5.1 Pod 一直 Pending事件里写 Insufficient cpu现象是kubectl get pods显示 Pendingkubectl describe pod的 Events 里报0/3 nodes are available: Insufficient cpu。原因是 Deployment 里 requests 设得太大或者节点上已有 Pod 占满了可分配资源。解决方法是先看kubectl describe node里的 Allocated resources把不合理的 requests 调小或者给集群加节点。1.13 的调度器不会自动压缩requests 写多少就占多少。5.2 Service 能 ping 通但访问超时现象是集群内curl service-name:port卡住Pod 本身是 Running。原因多半是 targetPort 和容器实际监听端口不一致或者 readinessProbe 没通过导致 Endpoints 为空。用kubectl get endpoints order-service -n ecommerce看有没有后端地址空的就说明探针没过。检查容器里应用是不是真的监听在containerPort上Spring Boot 默认 8080改过端口的话 yaml 里要同步改。5.3 镜像拉取报 ImagePullBackOff现象是 Pod 起不来describe 里写Failed to pull image。原因是私有仓库没配信任或者镜像 tag 写错。先在节点上手动docker pull一次能拉下来再排查 kubelet。1.13 的 kubelet 读的是/etc/docker/daemon.json里的 insecure-registries改完要重启 docker 和 kubelet。另外镜像名里的仓库地址必须和 daemon.json 里配的一致少个端口号都会失败。5.4 跨节点 Pod 通信不通现象是同节点 Pod 能通跨节点就不行。原因是 flannel 没起来或者网段冲突。kubectl get pods -n kube-system看 flannel 的 Pod 是否 Runningkubectl logs看有没有报错。还要确认podSubnet和 flannel ConfigMap 里的Network一致以及节点之间 8285/8472 端口没被防火墙拦。云服务器上安全组也要放行这些端口血泪经验是安全组问题最容易被忽略。5.5 滚动更新卡住不结束现象是kubectl rollout status一直不返回新 Pod 起不来旧 Pod 也不杀。原因是 readinessProbe 一直失败新 Pod 永远不就绪。先kubectl describe pod看探针的失败信息再进容器curl localhost:8080/actuator/health确认应用状态。initialDelaySeconds设太短也会导致这个问题Java 应用启动慢给到 30 到 60 秒比较稳。6. 验证部署是否真的可用从命令到压测部署完不算完得验证。第一步看整体状态kubectl get pods,svc,ingress -n ecommerce kubectl get endpoints -n ecommerce所有 Pod 是 RunningEndpoints 里每个 Service 都有对应 IPIngress 有 ADDRESS这是基本盘。第二步从集群内发请求起一个临时 Pod 做 curlkubectl run curl-test --imageradial/busyboxplus:curl -it --rm -- sh # 进入后执行 curl http://order-service:8080/actuator/health curl http://gateway-service:8080/api/products能返回 JSON 说明服务间调用链路通了。第三步从集群外验证 Ingress在 hosts 里把shop.example.com指到任意节点 IP浏览器或 curl 访问能看到网关返回的内容就说明对外暴露成功。进阶一点用kubectl scale deployment order-service --replicas4 -n ecommerce手动扩容观察新 Pod 是否自动挂到 Service 后面kubectl get endpoints的地址数量应该跟着变。再模拟一次滚动更新改镜像 tag 后kubectl apply同时用while true; do curl -s -o /dev/null -w %{http_code}\n http://shop.example.com/api/orders; sleep 0.5; done持续打请求观察有没有 5xx。全程没有错误码说明滚动更新策略和探针配置是有效的。我自己的习惯是每次部署完必做这三步验证尤其是 Endpoints 那一步很多“服务起不来”的问题其实卡在探针上看一眼 Endpoints 就能定位。k8s 1.13.3 虽然老但把这一套跑通后面换任何版本都是换汤不换药。希望帮到你。本文还有配套的精品资源点击获取
返回列表