本文目录结构
虚拟机与容器的区别
虚拟机(Virtual Machine, VM)和容器(Container)是两种不同的虚拟化技术,它们在资源隔离、部署和扩展、操作系统支持等方面有着各自的特点和优劣。
- 资源隔离: 虚拟机通过在物理硬件上创建完整的虚拟操作系统环境,使得每个虚拟机拥有独立的操作系统和应用程序,彼此之间资源隔离。而容器技术通过将应用程序及其运行环境打包成容器,容器之间共享同一个操作系统内核,使得容器之间资源相互隔离。
- 部署和扩展: 虚拟机需要安装和配置相应的操作系统,部署和扩展相对繁琐。容器只需将应用程序及其运行环境打包成一个容器镜像,然后通过容器引擎在集群中部署和扩展。这使得容器在部署和扩展方面更加轻量级和灵活。
- 操作系统支持: 虚拟机通过虚拟化技术提供完整的操作系统环境,可以运行任何支持的操作系统。容器技术通常支持一个或多个应用程序及其运行环境,只能运行在特定的操作系统上。
- 资源占用: 虚拟机需要为每个虚拟机分配独立的操作系统资源,因此资源占用较高。容器共享同一个操作系统内核,资源占用相对较低。
- 安全性: 虚拟机之间通过虚拟化层隔离,安全性较高;容器之间通过操作系统内核隔离,安全性相对较低。
- 应用场景: 虚拟机适用于需要运行不同操作系统或对资源隔离要求较高的场景,如数据库、Web服务器等。容器适用于微服务架构下的应用程序开发、部署和扩展,以及轻量级、需要快速启动的场景,如Web应用程序、API服务等。

容器技术
容器技术是指将应用程序及其依赖项打包在一起,形成一个独立的单元,可以在任何支持容器运行时环境的操作系统上运行。容器技术的主要优点包括易于移植、可扩展、易于管理、易于组合和隔离。常见的容器技术包括Docker、rkt、containerd等。以Docker为例本质由命名空间、cgroup和镜像三块组成。

Kubernetes
什么是Kubernetes
Kubernetes,简称K8s,是用8代替名字中间的8个字符“ubernete”而成的缩写,它是一种容器集群管理技术,由Google开发并开源。k8s由Master和Node组成,工作流和各组件如下:

Master组件 | Node组件 |
---|---|
kube-apiserver ETCD kube-controller-manager cloud-controller-manager kube-scheduler 插件 addons DNS 用户界面 容器资源监测 Cluster-level Logging |
kubelet kube-proxy docker RKT supervisord fluentd |
Kubernetes 重要概念
pod
- pod是k8s中的基本的部署单元,在worker nodes之间进行调度。
- 可以把pod看作一个独立的机器,一个pod中可以运行一个或者多个容器,这些容器之间共享相同的ip和port空间。
- 一个pod的所有容器都运行在同一个woker node中,一个pod不会跨越两个worker node。
- 由于大多数容器的文件系统来自于容器镜像,所以每个容器的文件系统与其他容器是完全隔离的,但是可以试用Volume在容器间共享文件目录。
- pod是短暂的, 他们随时的会启动或者关闭。也就是这如果某个pod被销毁之后,重新创建的pod的IP可能会变化。
如何创建一个pod。将以下保存到pod.yaml中然后执行kubectl apply -f pod.yaml。
1 | apiVersion: v1 |
配置文件相关解释:
apiVersion记录K8S的API Server版本,现在看到的都是v1,用户不用管。
kind记录该yaml的对象,比如这是一份Pod的yaml配置文件,那么值内容就是Pod。
metadata记录了Pod自身的元数据,比如这个Pod的名字、这个Pod属于哪个namespace(命名空间的概念,后文会详述,暂时理解为“同一个命名空间内的对象互相可见”)。
spec记录了Pod内部所有的资源的详细信息,看懂这个很重要:
- containers记录了Pod内的容器信息,containers包括了:name容器名,image容器的镜像地址,resources容器需要的CPU、内存、GPU等资源,command容器的入口命令,args容器的入口参数,volumeMounts容器要挂载的Pod数据卷等。可以看到,上述这些信息都是启动容器的必要和必需的信息。
- volumes记录了Pod内的数据卷信息,后文会详细介绍Pod的数据卷。
注:如果使用服务的vim编辑工具推荐以下vim配置,编辑vim ~.vimrc,并保存一下内容:
1 | set paste |
执行 source ~.vimrc 实时生效文件的中的配置。
k8s控制器
在kubernetes中,有很多类型的pod控制器,每个都有自己的适合的场景,常见的有下面这些:
- ReplicaSet:保证指定数量的pod运行,并支持pod数量变更,镜像版本变更
- Deployment:通过空值ReplicaSet来空值pod,并支持滚动升级,版本回退。管控它们运行在用户期望的状态。
- Horizontal Pod Autoscaler:可以根据集群负载自动调整pod的数量,实现消峰填谷
- DaemonSet:在集群中的指定Node上都运行一个副本,一般用于守护进行类的任务
- Job:它创建出来的pod只要完成任务就立即退出,用于执行一次性任务
- Cronjob:它创建的pod会周期性的执行,用于执行周期性任务
- StatefulSet:管理有状态应用,如数据库
1 | apiVersion: apps/v1 #版本号 |
Service和Ingress
Service
在Kubernetes中,Pod是应用程序的载体,我们可以通过Pod的IP来访问应用程序,但是Pod的IP地址不是固定的,这也就意味着不方便直接采用Pod的IP对服务进行访问。
为了解决这个问题,Kubernetes提供了Service资源,Service会对提供同一个服务的多个Pod进行聚合,并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的Pod服务
Service在很多情况下只是一个概念,真正起作用的其实是kube-proxy服务进程,每个Node节点上都运行着一个kube-proxy服务进程。当创建Service的时候会通过api-server向etcd写入创建的Service的信息,而kube-proxy会基于监听的机制发现这种Service的变动,然后它会将最新的Service信息转换成对应的访问规则。
services案例
1 | kind: Service # 资源类型 |
- ClusterIP:默认值,它是Kubernetes系统自动分配的虚拟IP,只能在集群内部访问
- NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务
- LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境支持
- ExternalName: 把集群外部的服务引入集群内部,直接使用
Ingress
Service对集群之外暴露服务的主要方式有两种:NotePort和LoadBalancer,但是这两种方式,都有一定的缺点:
- NodePort方式的缺点是会占用很多集群机器的端口,那么当集群服务变多的时候,这个缺点就愈发明显
- LB方式的缺点是每个service需要一个LB,并且需要Kubernetes之外设备的支持
本文参考
https://blog.csdn.net/qq_40378034/article/details/123297408