k8s 是一个为 容器化 应用提供集群部署和管理的开源工具,由 Google 开发。
主要特性
- 高可用,不宕机,自动灾难恢复
- 灰度更新,不影响业务正常运转
- 一键回滚到历史版本
- 方便的伸缩扩展(应用伸缩,机器加减)、提供负载均衡
- 有一个完善的生态
什么时候需要 Kubernetes
- 当你的应用只是跑在一台机器,直接一个 docker + docker-compose 就够了,方便轻松;
- 当你的应用需要跑在 3,4 台机器上,你依旧可以每台机器单独配置运行环境 + 负载均衡器;
- 当你应用访问数不断增加,机器逐渐增加到十几台、上百台、上千台时,每次加机器、软件更新、版本回滚,都会变得非常麻烦、痛不欲生,再也不能好好的摸鱼了,人生浪费在那些没技术含量的重复性工作上。
Kubernetes 可以让你轻松管理百万千万台机器的集群。
Kubernetes 可以为你提供集中式的管理集群机器和应用,加机器、版本升级、版本回滚,那都是一个命令就搞定的事,不停机的灰度更新,确保高可用、高性能、高扩展。
k8s 用于大规模部署你的分布式应用的平台;它管理一系列主机或服务器,这些主机或服务器被称作Node节点;每个节点运行了N个互相独立的Pod,
k8s中部署的最小执行单元是Pod,一个节点有多个Pod,一个 Pod 可以包含一个或多个容器,每个 Pod 有自己的虚拟IP。
master
主节点,控制平台,不需要很高性能,不跑任务,通常一个就行了,也可以开多个主节点来提高集群可用度。
worker
工作节点,可以是虚拟机或物理计算机,任务都在这里跑,机器性能需要好点;通常都有很多个,可以不断加机器扩大集群;每个工作节点由主节点管理
一个工作节点可以有多个 pod,主节点会考量负载自动调度 pod 到哪个节点运行。
N个节点的N个Pod需要相互协调才能做到均衡负债或者故障转移,这就需要一台中心计算机(管理节点和里面的Pod的 Control Plane/控制平面),控制平面通过专有的API与各个节点进行通讯,控制面板会实时检测节点的网络状态来平衡服务器的负载、或者临时下发指令来应对突发的状态,比如k8s发现某个容器或者Pod挂掉了,它会立刻启用在后台预先准备好的、随时待命的备用容器来替换它,这些容器被称作 ReplicaSet/副本集合,正是有它,才让我们的应用能够长时间、不间断地可靠运行;
N个节点(节点中N个Pod,每个Pod的N个容器)<==+API+==> 控制平面(master节点) = Cluster/集群
集群代表了Kubernetes所管理的全部主机节点;
要配置一个以学习为目的的Kubernetes集群,可以使用 minikube 在本地模拟一个 Kubernetes集群
如何在k8s部署一个应用?
首先我们需要创建一个yaml文件:deployment.yaml ,里面定义了我们应用的基本信息,比如:由哪些Pod组成,Pod里面运行了哪些容器,网络配置等等;
deployment.yaml 和 dockerfile 很类似,你可以把deployment.yaml看做是一个自动化脚本,里面描述了应用部署的整个过程;
在vscode中,安装 kubernetes扩展,打开一个目录,新建一个 deployment.yaml 文件,输入 deployment 后让vscode自动帮我们填:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp222 # 名字
spec:
replicas: 3 # 指定了连同备用pod在内的所有pod数量
selector:
matchLabels:
app: myapp222
template: # 最重要的是template下面的内容,定义了与Pod相关的所有信息
metadata:
labels:
app: myapp222
spec:
containers: # 指定了 Pod 中运行的所有容器
- name: myapp222
image: nginx:latest
resources:
limits: # 为每个Pod设置合理的CPU和内存配额
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 5000 # 指定了容器需要对外暴露的端口
默认情况下,我们的Pod只能与同一个集群内的其它Pod进行通信,虽然每一个Pod都拥有一个独立的IP,但这个IP地址对于外网是不可见的,如果要从外网访问我们的应用,我们还需要用到Kubernetes中另一个重要的组件 ———— 服务(Services)
这里讲一个最基本的 NodePort服务:它是一种最原始的将应用端口暴露给外网的方式,即在每个节点上都挂在一个NodePort,每个节点都暴露在外网上了
除了 NodePort服务 外,Kubernetes 还提供LoadBalancer 或者更加复杂的Ingress来实现负载的均衡;
改造上面的 yaml 文件,即在文本最后面加入 三个横杠,输入Server让vscode自动帮我们生成,改成如下:
apiVersion: apps/v1
kind: Deployment
...省略...
ports:
- containerPort: 5000 # 指定了容器需要对外暴露的端口
---
apiVersion: v1
kind: Service
metadata:
name: myapp222-np-service
spec:
selector:
app: myapp222 # 应该将请求来的数据转发到 myapp222 这个Pod上
type: NodePort # 服务的类型为 NodePort
ports:
- port: 5000
targetPort: 5000
nodePort: 30080 # 指定暴露给外网的端口,省略这后k8s会自动分配
写好的yaml文件如何部署?
用到一个命令行工具 kubectl,来与 Kubernetes 集群进行交互,这是一个所有平台通用的工具,就好比我们之前用到的docker命令一样,它可以操纵任何的集群,包括使用本地模拟的minikube;
执行部署:kubectl apply -f deployment.yaml 运行后,Kubernetes会在后台开始应用的部署
查看所有pod运行状态:kubectl get pods
查看所有创建的服务:kubectl get services
如果yaml文件更新了(更新应用),如何重新部署?(比如:切换容器镜像版本,重新分配cpu和内存资源等)
修改 yaml 文件后,重新执行 kubectl apply -f deployment.yaml 即可,Kubernetes会在后台无缝地更新我们的应用,确保新版本运行起来以后再去销毁旧的版本,因此用户不会遇到服务停机的问题
删除部署?
kubectl delete -f deployment.yaml 从集群上完全移除它