💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] 参考:[https://blog.csdn.net/u011142688/article/details/80372552](https://blog.csdn.net/u011142688/article/details/80372552) Kubernetes中有各种各样的组件,对于容器来说Kubernetes最小的单元是由Pod进行组成的,但是我们在使用过程中经常会使用到Deployment来部署我们的应用,其中究竟区别在哪里,我们今天就来一同探索 ## 什么是pod pod是kubernetes里的一个基本概念,可能我们从一开始接触kubernetes的时候就开始接触pod,并被灌输pod是kubernetes里最小的不可分割的工作单元,这里再从多容器的角度对其进行一些基本阐释. 简言之,pod是kubernetes可以部署和管理的最小单元,换言之也就是说如果你想要运行一个容器,你先要为这个容器创建一个pod.同时,一个pod也可以包含多个容器,之所以多个容器包含在一个pod里,前面讲到过的初始容器为普通应用容器准备环境是一种使用场景,往往由于业务上的紧密耦合,一组容器也需要放在同一个pod里. ## kubernetes为什么使用pod作为最小单元,而不是container 直接部署一个容器看起来更简单,但是这里也有更好的原因为什么在容器基础上抽象一层.容器是一个存在的实体,并指向一个具体的事物.这个具体的事物可能是一个docker容器,但也可能是一个rtk容器,或者一个Virtlet管理的虚拟机.它们有不同的要求. 更深层的原因是为了管理容器,kubernetes需要更多的信息,比如重启策略,它定义了容器终止后要采取的策略;或者是一个可用性探针,从应用程序的角度去探测是否一个进程还存活着. 基于这些原因,kubernetes架构师决定使用一个新的实体,也就是pod,而不是重载容器的信息添加更多属性,用来在逻辑上包装一个或者多个容器的管理所需要的信息 ## kubernetes为什么允许一个pod里有多个容器 pod里的容器运行在一个逻辑上的"主机"上,它们使用相同的网络名称空间(也就是说,同一pod里的容器使用相同的ip和相同的端口段区间)和相同的IPC名称空间.它们也可以共享存储卷.这些特性使它们可以更有效的通信.并且pod可以使你把紧密耦合的应用容器作为一个单元来管理. 因此一个应用如果需要多个运行在同一主机上的容器时,为什么为把它们放在同一个容器里呢?首先,这样何故违反了一个容器只负责一个应用的原则.这点非常重要,如果我们把多个应用放在同一个容器里,这将使解决问题变得非常麻烦因为它们的日志记录混合在了一起,并且它们的生命周期也很难管理.因此一个应用使用多个容器将更简单,更透明,并且使应用依赖解偶.并且粒度更小的容器更便于不同的开发团队共享和复用. ## Pod最小的单元 Pod封装了一个或多个应用程序的容器(比如nginx等),存储资源,唯一的网络IP以及管理容器的一些选项 Pod标示的是一个部署单元,可以理解为Kubernetes中的应用程序的单个实例,它可能由单个容器组成,也可能由少量紧密耦合并共享资源的容器组成。 >如果多个容器在同一Pod下他们公用一个IP所以不能出现重复的端口号,比如在一个Pod下运行两个nginx就会有一个容器异常,一个Pod下的多个容器可以使用localhost来访问对方端口 因为Pod是最小的单元如果在Pod中容器出现异常终止了是不会重启,在实际使用场景下基本不会直接使用Pod而是使用Deployment部署自己的应用 示例: 编写文件 app-pod.yaml: ``` vim app-pod.yaml ``` ``` apiVersion: v1 kind: Pod metadata: name: app-pod.yaml labels: app: myapp spec: containers: - name: myapp-container image: ubuntu.18.04 command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600'] ``` 启动容器:· ``` > kubectl create -f app-pod.yaml.yaml > kubectl get pod NAME READY STATUS RESTARTS AGE app-pod.yaml 1/1 Running 0 8s ``` 可以在web页面中查看到具体的pod(UI上称为容器组),查看日志可以看到 ![](http://pic.w-blog.cn/kubernetes/43.png) ### 可以在一个Pod下运行多个容器(注意不要端口冲突) ``` > vim nginx-mysql-pod.yaml apiVersion: v1 # api版本 kind: Pod # 组件类型 metadata: name: nginx-mysql-pod labels: # 标签 app: nginx-mysql spec: containers: - name: nginx # 名称 image: nginx # image地址 - name: mysql image: mysql env: # 环境变量 - name: MYSQL_ROOT_PASSWORD value: mysql > kubectl create -f nginx-mysql-pod.yaml > kubectl get pod NAME READY STATUS RESTARTS AGE nginx-mysql-pod 2/2 Running 0 1m ``` 在ui中就可以看到一个Pod下运行着两个容器 ![](http://pic.w-blog.cn/kubernetes/44.png) 通过运行命令可以进入到那个容器的终端,这里选择mysql容器, 这里系统没有curl这里安装好了curl访问本地80端口,能访问到nginx容器的内容(这里证明了在一个Pod下的网络是共享的) ## Deployment部署 在早期版本使用Replication Controller对Pod副本数量进行管理,在**新的版本中官方推荐使用Deployment来代替RC,Deployment**相对RC有这些好处 * **Deployment拥有更加灵活强大的升级、回滚功能,并且支持滚动更新** * **使用Deployment升级Pod只需要定义Pod的最终状态**,k8s会为你执行必要的操作(RC要自己定义如何操作) 不管是RC还是Deployment解决的主要问题是,每个Pod都运行给定应用程序的单个实例。如果您想水平扩展应用程序(例如,运行多个同样的实例),则应该使用多个Pod。这里带来的Pod管理成本 ``` > vim nginx-deployment.yaml apiVersion: extensions/v1beta1 # K8S对应的API版本 kind: Deployment # 对应的类型 metadata: name: nginx-deployment labels: name: nginx-deployment spec: replicas: 1 # 镜像副本数量 template: metadata: labels: # 容器的标签 可和service关联 app: nginx spec: containers: - name: nginx # 容器名和镜像 image: nginx imagePullPolicy: Always > kubectl create -f nginx-deployment.yaml > kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-68fcbc9696-tr5fm 1/1 Running 0 6s nginx-mysql-pod 2/2 Running 0 15m > kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 1 1 1 1 2m ``` 扩容 ``` > kubectl scale deployment nginx-deployment --replicas=3 > kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-68fcbc9696-9r4p8 1/1 Running 0 22s nginx-deployment-68fcbc9696-lkff2 1/1 Running 0 22s nginx-deployment-68fcbc9696-tr5fm 1/1 Running 0 5m nginx-mysql-pod 2/2 Running 0 21m ``` 恢复一个 ``` > kubectl scale deployment nginx-deployment --replicas=1 > kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-68fcbc9696-tr5fm 1/1 Running 0 6m nginx-mysql-pod 2/2 Running 0 21m ``` 最关键的功能就是可以弹性扩容根据CPU的占用率(需要结合资源限制一同使用),后面会进行实际演示 ``` > kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=80 ``` Deployment回保障你的容器的运行状态,如果删除Pod,Deployment会立即重启一个 ``` > kubectl delete pod nginx-deployment-68fcbc9696-tr5fm pod "nginx-deployment-68fcbc9696-tr5fm" deleted > kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-68fcbc9696-ndfzj 1/1 Running 0 12s nginx-mysql-pod 2/2 Running 0 32m ```