尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Kubernetes的pod管理与优化及微服务

Kubernetes的pod管理与优化及微服务 摘要梳理K8s核心知识点涵盖资源管理三种方式、kubectl全套命令、Pod概念与控制器管理、YAML资源清单全参数、QoS等级、Init初始化容器、三大探针、Service四种类型、IPVS模式、MetalLB、Ingress-nginx七层代理与高级功能、Canary金丝雀灰度发布。1.K8s资源基础与kubectl核心命令1.1 资源管理概述在Kubernetes中所有内容都抽象为资源用户通过操作资源管理集群。K8s最小管理单元是Pod容器运行在Pod内部K8s一般不直接管理Pod而是通过Pod控制器管理Pod服务访问靠Service数据持久化靠Volume/PVC/ConfigMap/Secret。1.2 三种资源管理方式1.命令式对象管理 kubectl run/delete/get 简单却只能操作活动对象无法审计跟踪2.命令式对象配置 kubectl create/patch -f xxx.yaml 可以审计跟踪但是配置文件多操作繁琐3.声明式对象配置 kubectl apply -f xxx.yaml 支持目录批量操作但在异常情况难调试1.3 kubectl核心命令基础语法kubectl [command] [type] [name] [flags]1.# 集群信息kubectl versionkubectl cluster-infokubectl api-resources # 查看所有资源类型2.# 资源操作kubectl create deployment web --image nginx --replicas 2 kubectl get deployments.apps kubectl explain deployment.spec kubectl edit deployments.apps web kubectl patch deployments.apps web -p {spec:{replicas:4}} kubectl delete deployments.apps web3.# 运行调试kubectl run testpod --image nginx kubectl expose pod testpod --port 80 --target-port 80 kubectl describe pods testpod # 排查报错首选 kubectl logs pods/testpod kubectl exec -it pods/nginx -- /bin/bash kubectl cp 本地文件 nginx:/ # 上传文件到pod kubectl cp nginx:/路径 本地路径 # 下载pod文件4.# 标签管理kubectl get pods --show-labels kubectl label pods nginx applee kubectl label pods nginx appweb --overwrite kubectl label pods nginx app-5.# 生成yaml模板--dry-runclient只输出不创建kubectl create deployment --image nginx web --dry-runclient -o yaml web.yml kubectl run pod1 --image myapp:v1 --dry-runclient -o yaml pod.yml1.4 实战从零部署一个Nginx应用下面通过一个完整示例演示如何用声明式配置kubectl apply从零部署一个Nginx应用并对外提供服务。整个过程包含资源清单编写、部署、验证和清理四个步骤。步骤一编写Deployment资源清单创建文件nginx-deploy.yaml内容如下apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx-demo spec: replicas: 2 selector: matchLabels: app: nginx-demo template: metadata: labels: app: nginx-demo spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 200m memory: 256Mi关键步骤注释apiVersion/kind声明资源类型为Deployment使用apps/v1版本。replicas: 2期望运行2个Pod副本控制器保证始终有2个可用。selector.matchLabels控制器通过该标签选择并管理Pod。template.metadata.labelsPod模板标签必须与selector匹配。resourcesrequests是调度依据limits是资源上限二者相等时QoS等级为Guaranteed。步骤二编写Service资源清单创建文件nginx-svc.yaml内容如下apiVersion: v1 kind: Service metadata: name: nginx-demo-svc spec: type: ClusterIP selector: app: nginx-demo ports: - port: 80 targetPort: 80 protocol: TCP关键步骤注释type: ClusterIP默认类型分配集群内部虚拟IP仅集群内可访问。selector.app: nginx-demoService通过该标签自动发现后端Pod并维护Endpoints列表。port/targetPortport是Service对外端口targetPort是Pod容器端口这里均为80。步骤三部署并验证执行以下命令完成部署和验证# 1. 应用资源清单 kubectl apply -f nginx-deploy.yaml kubectl apply -f nginx-svc.yaml 2. 查看Deployment和Pod状态 kubectl get deployment nginx-demo kubectl get pods -l appnginx-demo 3. 查看Service和Endpoints kubectl get svc nginx-demo-svc kubectl get endpoints nginx-demo-svc 4. 集群内访问测试 kubectl run test-pod --imagebusybox --rm -it -- sh -c wget -qO- http://nginx-demo-svc 5. 查看Pod日志 kubectl logs -l appnginx-demo预期输出说明kubectl get deployment显示READY 2/2表示2个副本全部就绪。kubectl get pods2个Pod状态均为RunningREADY列为1/1。kubectl get svcService获得一个ClusterIP如10.97.xx.xxCLUSTER-IP不为None。kubectl get endpointsEndpoints列出2个Pod的IP和端口格式如10.244.1.5:80,10.244.2.7:80。wget测试返回Nginx默认欢迎页HTML包含Welcome to nginx!字样。kubectl logs输出Nginx访问日志包含刚才wget请求的GET /记录。步骤四清理资源验证完成后执行以下命令清理资源kubectl delete -f nginx-deploy.yaml kubectl delete -f nginx-svc.yaml预期输出说明两条命令均返回deleted随后kubectl get all -l appnginx-demo不再显示任何相关资源。2 Pod核心概念与控制器管理2.1 Pod核心概念Pod是K8s最小可部署计算单元代表集群中运行的一个进程每个Pod有唯一IP。一个Pod类似豌豆荚包含一个或多个容器多容器间共享IPC、Network和UTC namespace共用网络栈可直接用localhost互访。注意同一Pod多容器不能占用相同端口否则端口冲突启动报错。2.2 自主式Pod VS 控制器管理Pod1.自主式Pod生产不推荐直接kubectl run创建。优点是灵活、方便学习调试缺点是无自愈、不支持扩缩容和滚动更新、Pod删除不会重建、维护成本高。2.控制器管理Pod生产强烈推荐Deployment自动故障恢复Pod宕机/删除自动重建维持副本数健康检查自愈支持存活/就绪探针扩缩容与HPA手动或基于指标自动伸缩滚动更新与回滚逐步替换旧版本出问题一键回滚声明式配置YAML版本控制CI/CD友好服务发现负载均衡Service自动发现后端Pod。kubectl create deployment timinglee --image nginx kubectl scale deployment timinglee --replicas 6 # 扩容 kubectl scale deployment timinglee --replicas 2 # 缩容2.3 应用版本更新与回滚kubectl create deployment timinglee --image myapp:v1 --replicas 2 kubectl expose deployment timinglee --port 80 --target-port 80 kubectl rollout history deployment timinglee # 查看历史版本 kubectl set image deployments/timinglee myappmyapp:v2 # 升级v2 kubectl rollout undo deployment timinglee --to-revision 1 # 回滚v13 Pod资源清单YAML与QoS等级3.1 YAML四大必写字段apiVersionAPI版本kubectl api-versions查询kind资源类型Pod/Deployment/Servicemetadata元数据name/labels/namespacespec期望状态定义。3.2 关键spec参数spec.containers[] 容器列表name/imageimagePullPolicy 镜像拉取策略Always/IfNotPresent/Nevercommand/args 容器启动命令与参数ports containerPort/hostPort/protocolenv[] 环境变量resources.limits 资源使用上限cpu/memoryresources.requests 调度请求资源调度器选节点依据spec.restartPolicy 重启策略Always/OnFailure/NeverDeployment只能AlwaysnodeSelector 节点标签选择指定Pod调度节点hostNetwork 是否使用宿主机网络3.3 常用YAML示例单容器PodapiVersion: v1 kind: Pod metadata: labels: {run: timing} name: timinglee spec: containers: - image: myapp:v1 name: timinglee多容器Pod业务sidecar注意端口不冲突apiVersion: v1 kind: Pod metadata: name: test spec: containers: - image: myapp:v1 name: myapp1 - image: busyboxplus:latest name: busybox command: [/bin/sh,-c,sleep 1000000]资源限制节点选择宿主机网络apiVersion: v1 kind: Pod metadata: {name: test} spec: nodeSelector: kubernetes.io/hostname: k8s-node1 hostNetwork: true restartPolicy: Always containers: - image: myapp:v1 name: myapp resources: limits: {cpu: 500m, memory: 100M} requests: {cpu: 500m, memory: 100M}3.4 QoS服务质量等级资源限制影响Pod的QoS优先级节点资源紧张时低优先级Pod优先被驱逐资源设定 QoS等级未设定资源限制 BestEffort最低设定且limits≠requests Burstable中等设定且limitsrequests Guaranteed最高4.Pod生命周期Init容器与三大探针4.1 Init初始化容器Pod可配置一个或多个Init容器串行执行全部成功后才启动业务主容器。特点Init容器必须运行到完成下一个才执行不支持readiness探针Init失败kubelet反复重启PodrestartPolicyNever则不重启。用途前置环境初始化、等待外部依赖就绪、下载配置、安全执行初始化工具、访问业务容器不能访问的Secret权限。apiVersion: v1 kind: Pod metadata: {name: initpod} spec: containers: - image: myapp:v1 name: myapp initContainers: - name: init-myservice image: busybox command: [sh,-c,until test -e /testfile;do echo waiting; sleep 2;done]注意Init容器等待/testfile存在才完成手动touch /testfile后主容器启动。4.2 三大探针探针由kubelet定期执行诊断支持三种方式ExecAction容器内执行命令返回码0成功、TCPSocketActionTCP端口探测、HTTPGetActionHTTP Get状态码200-399成功。1.livenessProbe存活探针: 判断容器是否活着 杀死容器按重启策略重启2.readinessProbe就绪探针 : 判断容器是否可接收流量 不杀容器从Service端点列表移除探测成功重新加入3.startupProbe启动探针:判断应用是否启动完成 失败杀容器重启成功前禁用另外两个探针适合慢启动应用注意三探针同时存在时先执行startupProbe成功后liveness/readiness才生效startup只探测一次另外两个持续探测直到容器消亡。livenessProbe存活探针示例TCP探测8080服务实际监听80会反复CrashLoopBackOffapiVersion: v1 kind: Pod metadata: {name: liveness} spec: containers: - image: myapp:v1 name: myapp livenessProbe: tcpSocket: {port: 8080} initialDelaySeconds: 3 # 启动后等待秒数 periodSeconds: 1 # 探测间隔 timeoutSeconds: 1 # 超时时间readinessProbe就绪探针示例HTTP探测/test.html不存在则Pod不加入Service后端apiVersion: v1 kind: Pod metadata: {name: readiness} spec: containers: - image: myapp:v1 name: myapp readinessProbe: httpGet: path: /test.html port: 80 initialDelaySeconds: 1 periodSeconds: 35 Service微服务与IPVS模式5.1 Service概念Service是一组提供相同服务的Pod对外开放的接口实现**服务发现和四层负载均衡。Service默认只支持四层TCP/UDP七层HTTP需通过Ingress实现。Service通过spec.selector标签匹配后端Pod维护Endpoints端点列表。5.2 DeploymentService联合部署apiVersion: apps/v1 kind: Deployment metadata: labels: {app: timinglee} name: timinglee spec: replicas: 2 selector: {matchLabels: {app: timinglee}} template: metadata: {labels: {app: timinglee}} spec: containers: - image: myapp:v1 name: myapp --- apiVersion: v1 kind: Service metadata: labels: {app: timinglee} name: timinglee spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: {app: timinglee}5.3 IPVS模式Service由kube-proxyiptables实现。大量Pod时iptables规则海量CPU开销大。**IPVS模式**基于内核负载均衡模块性能更高支持更大规模Pod。配置三步骤# 1.所有节点安装ipvsadm yum install ipvsadm -y # 2.修改kube-proxy configmapmode改为ipvs kubectl -n kube-system edit cm kube-proxy # mode: ipvs # 3.重启kube-proxy pod使配置生效 kubectl -n kube-system get pods | awk /kube-proxy/{system(kubectl -n kube-system delete pods $1)} ipvsadm -Ln # 验证ipvs规则注意切换ipvs后生成虚拟网卡kube-ipvs0所有Service ClusterIP绑定到此网卡。6 Service四大类型与MetalLB6.1 ClusterIP默认分配集群虚拟IP仅集群内部访问。DNS域名格式svc名称.namespace.svc.cluster.local。dig timinglee.default.svc.cluster.local 10.96.0.10 # 解析到ClusterIP 10.97.59.256.2 Headless无头服务clusterIP: None不分配ClusterIPkube-proxy不处理DNS直接解析到后端Pod真实IP常用于StatefulSet有状态应用。spec:type: ClusterIPclusterIP: None注意dig解析返回所有Pod的IP地址。6.3 NodePort在每个集群节点打开物理端口外部访问任意节点IP:NodePort。默认端口范围30000-32767超出报错。自定义端口范围修改apiserver启动参数--service-node-port-range30000-40000api-server自动重启。spec: type: NodePort ports: - port: 80 targetPort: 80 # nodePort: 31771 # 可指定不指定则自动分配6.4 LoadBalancer云厂商环境自动分配公网VIP裸金属环境需要MetalLB提供外部IP。未安装MetalLB时EXTERNAL-IP显示pending。6.5 ExternalName不分配集群IP通过DNS CNAME转发到外部域名适合外部业务迁移到集群的过渡阶段IP变化但域名固定。spec: type: ExternalName externalName: www.timinglee.org6.6 MetalLB裸金属实现LoadBalancerMetalLB为LoadBalancer类型Service分配VIP。部署步骤1.kube-proxy开启ipvs并设置strictARP: true重启kube-proxy2.下载metallb-native.yaml修改镜像地址与harbor一致并上传镜像3.部署MetalLBcontrollerspeaker组件4.配置IPAddressPool地址池和L2Advertisement二层宣告apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - 172.25.254.50-172.25.254.99 --- apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: example namespace: metallb-system spec: ipAddressPools: - first-pool注意部署后LoadBalancer Service自动从地址池分配EXTERNAL-IP集群外可直接访问。7 Ingress-nginx七层反向代理7.1 Ingress概念Service是四层Ingress提供七层HTTP/HTTPS反向代理。由两部分组成Ingress Controller实际运行Nginx程序执行代理Ingress资源对象定义路由规则。业界Nginx、HAProxy、Envoy、Traefik均有对应Ingress Controller。7.2 部署Ingress-nginx1.下载baremetal版deploy.yaml2.修改镜像地址上传harbor3.kubectl apply -f deploy.yaml部署4.将ingress-nginx-controller的Service改为LoadBalancer配合MetalLB分配对外IP。kubectl -n ingress-nginx get svc# NAME TYPE EXTERNAL-IP PORT(S)# ingress-nginx-controller LoadBalancer 172.25.254.50 80:34512/TCP,443:34727/TCP7.3 基础Ingress示例apiVersion: networking.k8s.io/v1 kind: Ingress metadata: {name: test-ingress} spec: ingressClassName: nginx rules: - http: paths: - backend: service: name: timinglee-svc port: {number: 80} path: / pathType: PrefixpathType四种Prefix前缀匹配、Exact精确匹配、ImplementationSpecific特定实现支持正则、Regular expression正则匹配。注意Ingress必须和后端Service处于同一namespace。8.Ingress高级功能8.1 基于路径转发访问/v1转发myapp-v1/v2转发myapp-v2用rewrite-target重写URLmetadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: www.timinglee.org http: paths: - {path: /v1, pathType: Prefix, backend: {service: {name: myapp-v1, port: {number: 80}}}} - {path: /v2, pathType: Prefix, backend: {service: {name: myapp-v2, port: {number: 80}}}}8.2 基于域名虚拟主机不同域名转发不同后端spec: rules: - host: myappv1.timinglee.org http: {paths: [{path: /, pathType: Prefix, backend: {service: {name: myapp-v1, port: {number: 80}}}}]} - host: myappv2.timinglee.org http: {paths: [{path: /, pathType: Prefix, backend: {service: {name: myapp-v2, port: {number: 80}}}}]}8.3 TLS HTTPS加密# 生成证书 openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -subj /CNnginxsvc/Onginxsvc -out tls.crt # 创建tls类型secret kubectl create secret tls web-tls-secret --key tls.key --cert tls.crt spec: tls: - hosts: [myapp-tls.timinglee.org] secretName: web-tls-secret8.4 BasicAuth认证dnf install httpd-tools -y htpasswd -cm auth lee # 生成密码文件 kubectl create secret generic auth-web --from-file auth metadata: annotations: nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: auth-web nginx.ingress.kubernetes.io/auth-realm: Please input username and password测试curl -k https://域名 -u lee:密码8.5 rewrite重定向nginx.ingress.kubernetes.io/app-root: /hostname.html访问根路径自动跳转指定页面正则重写解决带前缀路径问题metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/use-regex: true spec: rules: - host: myapp-tls.timinglee.org http: paths: - {path: /lee(/|$)(.*), pathType: ImplementationSpecific, backend: {service: {name: myapp-v1, port: {number: 80}}}}9.Canary金丝雀灰度发布9.1 概念金丝雀发布灰度发布是一种软件发布策略新版本先接收小部分流量验证稳定后再全量切换降低发布故障风险。采取先添加再删除方式保证Pod总量不低于期望值更新部分Pod后暂停确认正常再继续。nginx-ingress canary注解优先级header cookie weight。9.2 基于header灰度带请求头version:2的请求访问v2新版本其余访问v1apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-by-header: version nginx.ingress.kubernetes.io/canary-by-header-value: 2 name: myapp-v2-ingress spec: ingressClassName: nginx rules: - host: myapp.timinglee.org http: {paths: [{path: /, pathType: Prefix, backend: {service: {name: myapp-v2, port: {number: 80}}}}]} curl myapp.timinglee.org # 普通请求走v1 curl -H version:2 myapp.timinglee.org # 带header走v29.3 基于权重灰度10%流量进入v290%访问v1metadata: annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-weight: 10 nginx.ingress.kubernetes.io/canary-weight-total: 100测试脚本循环100次统计分布#!/bin/bash v10; v20 for (( i0; i100; i)) do responsecurl -s myapp.timinglee.org |grep -c v1 v1expr $v1 $response v2expr $v2 1 - $response done echo v1:$v1, v2:$v2 # 输出v1:90, v2:1010.总结1.K8s所有内容抽象为资源最小管理单元是Pod生产环境禁止裸Pod优先Deployment控制器管理具备自愈、扩缩容、滚动更新、回滚能力2.三种资源管理方式命令式测试、命令式配置开发、声明式apply生产首选kubectl explain和--dry-runclient -o yaml是写yaml利器3.Pod YAML掌握四大字段熟悉容器全参数QoS等级Guaranteedlimitsrequests Burstable BestEffort4.Pod生命周期Init容器串行执行、必须成功、不支持readiness、可延迟主容器启动三大探针liveness杀容器重启、readiness切流量不杀容器、startup先执行禁用其他探针适合慢启动5.Service实现四层负载均衡IPVS性能优于iptables四大类型ClusterIP默认集群内HeadlessDNS直连Pod IP有状态应用、NodePort节点端口默认30000-32767LoadBalancer云厂商VIP裸金属需MetalLB、ExternalNameCNAME转发外部域名6.MetalLB为裸金属LoadBalancer分配VIP需配置IPAddressPool地址池L2Advertisement7.Ingress-nginx实现七层HTTP/HTTPS代理由Controller资源对象组成高级功能包括路径转发rewrite-target、域名虚拟主机、TLS加密opensslsecret tls、BasicAuth认证htpasswdsecret generic、rewrite正则重定向8.Canary金丝雀发布先添加再删除保证Pod总量支持header灰度指定请求头访问新版本和权重灰度按比例分流优先级header cookie weight。完整链路控制器Deployment→ Pod → Service四层→ Ingress七层→ 金丝雀发布构成K8s应用从部署到对外发布的完整闭环。
返回列表