2020年必须掌握的硬核技能k8s
kubernetes是云原生时代的基座,诞生之初是一个容器编排系统,它将底层基础设施抽象,简化了应用开发、部署、运维。
1. kubernetes集群架构
kubernetes集群由很多节点组成,分为两大类:
- 主节点: master,作为控制面管理和控制整个集群,基于高可用可以有多个。
- 工作节点: worker,运行工作负载的节点

1.1 控制面
控制集群并使它工作,包含多个组件(组件单节点或通过副本分别部署到多个主节点以确保高可用)
- k8s apiServer: 客户端kubectl、控制面板其他组件和worker节点都需要和它通信
- scheduler: 调度应用
- controller manager: 执行集群级别功能,如复制组件、持续跟踪工作节点、处理节点失败等
- etcd:可靠的分布式数据库存储,能持久化集群配置
1.2 工作节点
运行工作应用的机器, 运行、监控、管理应用服务的任务由下组件完成:
- docker container、rtk或其他容器类型
- kubelet与apiserver通信,并管理它所在节点容器
- kube-proxy:负责组件之间网络流量负载均衡
2. MiniKube环境& 核心概念
本处window10+Hyper-V搭建minikube本地集群

这台虚拟机既作为master,又作为worker,kubectl从集群外部发起管理和控制。
# 因国内极差的网络环境,建议使用阿里云的镜像地址:
minikube start --image-mirror-country=cn --image-repository=http://registry.aliyuncs.com/google_containers --registry-mirror=https://aq32bn7a.mirror.aliyuncs.com
以管理员权限执行CMD命令:
- kubectl: 发送Restful api 控制Kubernetes集群管理器
- Minikube是一个CLI工具,配置、管理(已针对开发流程优化)的单节点Kubernetes集群
2.1 k8s 核心概念
API对象
k8s API作为声明式配置方案的基石,API文档(yml文件)中定义了API端点、资源,kubectl命令行工具可操作API对象,对象的序列化对象存储在etcd中。
API由 group、verison、resource组成: apis/batch/v1/jobs
API对象:
- 元数据
- 规格spec:[由你]提供资源的特征描述和规格
- 状态status:[系统自行控制] 描述对象当前状态,由k8s系统组件设置和更新,K8s控制面板持续管理对象的实际状态去匹配你设定的期望状态
包括且不限于以下信息: - 哪些容器化应用正在运行
- 这些应用程序可用的资源
- 与这些应用程序有关的行为&策略:重新启动策略、升级和容错
APi对象是期望状态,创建对象之后,你就通知了K8s你希望集群这样运作。
kubectl 与 apiserver 是通过http协议 (eg: apply 命令是PATCH请求), apply yml文件实际是将yml文件转换为json。
为什么要用yml而不是json?
yml对开发者友好(对人类友好,强制缩进; 规格更简洁),json对于编程友好。
下面的kubia-rs.yaml文件:ReplicaSet对象启动3个nodejs应用, [spec]定义了此次ReplicaSet的规格:
启动容器: 在8080端口监听请求、匹配kubia标签
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: kubia-rs
spec:
replicas: 3
selector:
matchLabels: # 通常出现在Deployment、ReplicaSet、StatefulSet,用于确定这些控制器只会管理满足matchLabels的pod
app: kubia
template:
metadata:
labels:
app: kubia # 为控制器创建的pod打上标签
spec:
containers:
- name: kubia
image: luksa/kubia
ports:
- containerPort: 8080
# 对于ReplicaSet啰嗦两句: 新一代的ReplicationController; 通常不会直接创建ReplicaSet,而是在创建更高级的Deployment资源时自动创建它们。
Pod
Kubernetes Pod是创建/部署k8s对象中最小最简单的单元:
由于不能将多个进程聚集在一个单独容器,需要另外一种高级结构将容器绑定在一起,作为一个单元管理,这就是Pod背后根本原理, 一个pod中容器共享相同ip和端口空间。
Controller
k8s控制器是一个control loop(监控集群状态,在被需要时或主动请求时更新集群),每个控制器都试图将当前集群状态移动到期望状态。
在机器人和自动化,
control loop是一个非终止回路,用于调节系统状态,例如房间的空调。
控制器自身可以执行操作,但一般情况下,控制器会将引起连锁反应的消息发往api server.
k8s内置了一些控制器: ReplicaSet、Deployment、StatefulSets、DaemonSet、Job...
# k8s deployment检查容器健康状态、保证容器数量、还具备部署相关的特性, deployment是管理和缩放容器的推荐控制器
kubectl create deployment hello-kubia --iamge=luksa/kubia
这4个概念连起来就是:
K8s已经定义了API元数据,Controller调度K8s系统到指定的预期状态(这个预期状态以K8s API对象体现),在落地形式上以创建/调度Pod来承载应用。 (此4个概念还不包含NetWork相关)
3. 开启Kubernetes之旅
在minikube创建3实例nodejs应用,并使用不同的service方式访问 。
- 根据API对象文件产生Pod
> kubectl create -f kubia-rs.yaml
> kubectl get pod --show-labels=true
NAME READY STATUS RESTARTS AGE LABELS
kubia-rs-96ncq 1/1 Running 0 3m40s app=kubia
kubia-rs-h5ppz 1/1 Running 0 3m41s app=kubia
kubia-rs-x5578 1/1 Running 0 3m40s app=kubia
注意:Pod控制器中使用标签选择器来指定哪些Pod属于同一组(服务也使用同样机制)。
- 创建服务,做为pod的负载均衡器
[集群内访问]: ClusterIP
[提供集群外访问]
- nodeport: 把 service 的 port 映射到集群节点机器上的端口
- LoadBalancer:外部负载均衡器,负载均衡器会单独分配一个ip地址并监听后端服务的指定端口,请求的流量会通过指定的端口转发到后端对应的服务。
- Ingress (minikube addons先启用ingress,智能路由)
4种网络方式的yaml代码如下:请通过kubectl create -f ...ymal命令生成对应的服务(ingress不是服务)

type 定义了service方式; ports.port=80 定义了集群内部访问; targetPort是pod暴露的服务端口;
LoadBalancer是服务暴露到集群外或者公网上的标准方式;
Ingress 这个服务类型跟我们前面的三种服务类型不一样,它实际上不是一种服务类型,而是类似一种集群服务入口的存在,
它可以基于你配置的不同路径或者子域名把流量路由到对应的后端服务,更像是一个“智能路由”服务。
Ingress 分为两块:
- 规则: 定义了域名+path 到服务的映射关系
- ingress controller: 实际是一个deploymentController, 实现方式有 nginx、trafik、istio等。
Ingress提供了七层负载均衡和反向代理功能,可以实现复杂的HTTP和HTTPS路由。相比Service只能提供四层负载均衡,Ingress可以基于URL路径、主机名等进行更细粒度的流量控制。

- 访问3 Pod实例的nodejs应用
- ClusterIP 只能在集群内访问,minikube ssh 进入集群,或者Hyper-V进入VM: curl 10.100.166.197访问
- nodePort、Loadbalancer 需要使用minikube获取本地集群url

- ingress 是复杂网络应用的常规做法
(1) 在hosts文件中添加kubia.xxx.com与IP地址的映射
(2) 通过ingress路由访问pod, 如果kubectl get ingress, Address 字段为空, 那么说明 ingress controller 没有准备好, addon安装。

上面输出差异体现了随机Pod(即使连接来自同一个客户端),SessionAffinity亲和力属性值(ClientIP)可让单一客户端请求都指向一个Pod。
总结
本文从K8s全局架构讲起,力求先在你头脑中构筑宏观思维导图;
提出核心概念帮助全流程理解;
通过一个常见的多实例nodejs应用来实践k8s核心功能。
本文的所有代码:https://github.com/zaozaoniao/k8s-example.git
https://blog.csdn.net/weixin_44267608/article/details/102728050
2025年更新
k8s ingress 能够提供service对外访问的能力, 这并不一个新的开天辟地的方案, 我其实认为是一个 取巧方案。
首先服务默认的类型是 clusterIP, 只能在集群内访问;
有 nodePort类型, 可在机器节点上开放端口(服务映射到节点端口), 但是这种能应对的服务数量受限, 且需要外部负载均衡;
loadBalance 主要用在云环境,按下不表;
ingress 的本质是 产生一个负载均衡服务(有对应的nginx pod), 这个nginx service可与集群内服务互访;
那么我们只需要给节点开放一个nodeport端口(给ingress用), 然后通过ingress-nginx转发到集群内多个服务, 这样流量从集群外到集群内多服务的链路就通了。
对于Ingress, 核心是 nginx deployment 和路由规则,
一般由运维产生 nginx deployment, 开发者自己去写ingress 资源文件。


本文来自博客园,作者:{有态度的马甲},转载请注明原文链接:https://www.cnblogs.com/JulianHuang/p/12791071.html
欢迎关注我的原创技术、职场公众号, 加好友谈天说地,一起进化

浙公网安备 33010602011771号