K8S | 容器和Pod组件
对比软件安装和运行;
一、场景
作为研发人员,通常自己电脑的系统环境都是非常复杂,在个人的习惯上,是按照下图的模块管理电脑的系统环境;

对于「基础设施」、「主机操作系统」、「系统软件」来说,通常只做配置修改;
对于自行安装的软件环境来说,个人通常这样分类:「应用软件」、「研发软件」、「持续集成」、「虚拟机环境」;
- 应用软件:主要指常用的办公软件,比如文档编写,画图设计,通信产品等;
- 研发软件:比如基础开发环境,各种中间件环境,数据存储查询等;
- 持续集成:主流的就是Jenkins、Docker、Kubernetes等组件,整体比较复杂,不好管理;
- 虚拟机环境:研发必备的Linux操作系统,用来部署一些标准的组件集群;
不论是这些软件环境还是虚拟机系统的搭建,基本都是通过下载软件安装包,然后在本地部署和定期更新以及运行,基于这个场景再去理解容器和Pod组件,会轻松许多;
二、容器
1、容器镜像
参考上面系统环境的管理,软件包和安装部署的原理;
Docker容器镜像是一个轻量级的、独立的、可执行的软件包,它包含了运行应用程序所需的一切:代码、运行时、系统工具、系统库和设置,带有创建Docker容器的说明;
可以通过Dockerfile脚本自定义镜像,也可以使用云端仓库中其他人公开发布的,生产环境通常采用私有仓库管理镜像;

容器镜像所承载的是封装了应用程序及其所有软件依赖的二进制数据,容器镜像是可执行的软件包,可以单独运行;通常会创建应用的容器镜像并将其推送到某仓库,然后在Pod中引用它;
2、容器
容器将应用程序从底层的主机设施中解耦,这使得在不同的云或OS环境中部署更加容易;
容器的本质就是一个视图隔离、可限制资源、独立文件系统的进程集合;
以常见的Linux研发环境来分析,可以限制容器的资源分配,比如内存大小、CPU使用,隔离进程之间的通信,设置独立的文件系统等;
Kubernetes集群中的每个节点都会运行容器,这些容器构成分配给该节点的Pod,单个Pod中的容器会在共同调度下,于同一位置运行在相同的节点上;
从整体上可以把K8S理解为「操作系统」,镜像理解为「软件安装包」,容器理解为「应用进程」;
3、实践案例
制作镜像,首先将代码工程auto-client和auto-serve打包,然后构建镜像文件,放在本地环境中;
- 制作【auto-client】镜像
构建命令
docker build -t auto-client:latest .
Dockerfile脚本
# 基础镜像
FROM openjdk:8
# 维护者
MAINTAINER cicadasmile
# 持久化目录
VOLUME /data/docker/logs
# 添加应用服务JAR包
ADD auto-client.jar application.jar
# 配置参数
ENTRYPOINT ["java","-Dspring.profiles.active=dev","-Djava.security.egd=file:/dev/./urandom","-jar","/application.jar"]
- 制作【auto-serve】镜像
构建命令
docker build -t auto-serve:latest .
Dockerfile脚本
# 基础镜像
FROM openjdk:8
# 维护者
MAINTAINER cicadasmile
# 持久化目录
VOLUME /data/docker/logs
# 添加应用服务JAR包
ADD auto-serve.jar application.jar
# 配置参数
ENTRYPOINT ["java","-Dspring.profiles.active=dev","-Djava.security.egd=file:/dev/./urandom","-jar","/application.jar"]

三、Pod组件
1、基本概念
Pod是可以在K8S中创建和管理的、最小的可部署的计算单元;
Pod是一组(一个或多个)容器,这些容器共享存储、网络、以及怎样运行这些容器的声明,Pod中的内容总是并置的并且一同调度,在共享的上下文中运行;
2、Pod管理
【Pod创建】
通常不会直接创建Pod,而是使用诸如Deployment或Job这类工作负载资源来创建Pod;是相对临时性的、用后即抛的一次性实体;
【单容器Pod】
每个Pod都意在运行给定应用程序的单个实例,可以使用多个Pod对应用程序横向扩展,即一个实例一个Pod对应,Pod看作单个容器的包装器由K8S直接管理,是常见的部署方式;
【多容器Pod】
分布式系统中可能存在由多个紧密耦合且需要共享资源的共处容器组成的应用程序,比较典型的是「生产消费」场景,Pod将这些容器和存储资源打包为一个可管理的实体;

Pod中的容器被自动安排到集群中的同一物理机或虚拟机上,并可以一起进行调度,容器之间可以共享网络和存储资源和依赖、彼此通信、协调何时以及何种方式终止自身;
容器之间原本是被隔离开的,而Pod在设计上可以突破这种隔离,进而实现资源共享;
- 存储共享
在Pod层面设置共享的Volume,该Pod中所有容器都可以访问该共享Volume,这也是Pod组件的存储方式,Volume还允许Pod中持久数据保留下来,即使其中的容器需要重新启动;
- 网络共享
同一个Pod内,所有容器共享一个IP地址和端口空间,并且可以通过localhost发现对方;
3、实践案例
3.1 Pod脚本
在此前的案例中,都是单容器Pod,这里演示多容器Pod,将【auto-client】和【auto-serve】放在同一个「auto-pod」中运行;
并且这里为两个容器分配CPU和内存资源,requests是要为容器指定资源需求,limits是要为容器指定资源限制;
apiVersion: v1
kind: Pod
metadata:
name: auto-pod
spec:
containers:
- name: auto-client
image: auto-client
imagePullPolicy: Never
ports:
- containerPort: 8079
resources:
requests:
cpu: "250m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "128Mi"
- name: auto-serve
image: auto-serve
imagePullPolicy: Never
ports:
- containerPort: 8082
resources:
requests:
cpu: "250m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "128Mi"
3.2 Pod命令
- 创建Pod
kubectl create -f pod.yaml
- 查看指定Pod
kubectl get pod/auto-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
auto-pod 2/2 Running 0 9m2s 10.1.0.123 docker-desktop <none> <none>
- 查看指定Pod描述
kubectl describe pod/auto-pod
# 此处只展示部分信息
Name: auto-pod
Namespace: default
Node: docker-desktop/192.168.65.11
Status: Running
IP: 10.1.0.123
Containers:
auto-client:
Container ID: docker://Container-ID
Image: auto-client
Image ID: docker://sha256:Image-ID
Port: 8079/TCP
Limits:
cpu: 500m
memory: 128Mi
Requests:
cpu: 250m
memory: 64Mi
auto-serve:
Container ID: docker://Container-ID
Image: auto-serve
Image ID: docker://sha256:Image-ID
Port: 8082/TCP
Limits:
cpu: 500m
memory: 128Mi
Requests:
cpu: 250m
memory: 64Mi
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 38s default-scheduler Successfully assigned default/auto-pod to docker-desktop
Normal Pulled 37s kubelet Container image "auto-client" already present on machine
Normal Created 37s kubelet Created container auto-client
Normal Started 37s kubelet Started container auto-client
Normal Pulled 37s kubelet Container image "auto-serve" already present on machine
Normal Created 37s kubelet Created container auto-serve
Normal Started 37s kubelet Started container auto-serve
- 删除Pod
kubectl delete -f pod.yaml
3.3 服务日志
在「auto-client」服务中,提供一个简单的定时任务,每10秒访问一次「auto-serve」的接口,打印请求的响应结果;
@Component
public class HttpJob {
private static final Logger LOG = LoggerFactory.getLogger(HttpJob.class.getName()) ;
private static final String SERVER_URL = "http://localhost:8082/serve";
/**
* 每10秒执行一次
*/
@Scheduled(fixedDelay = 10000)
public void systemDate (){
try{
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(3000);
factory.setConnectTimeout(6000);
RestTemplate restTemplate = new RestTemplate(factory);
Map<String,String> paramMap = new HashMap<>() ;
String result = restTemplate.getForObject(SERVER_URL,String.class,paramMap);
LOG.info("server-resp::::"+result);
} catch (Exception e){
e.printStackTrace();
}
}
}
在「auto-serve」服务中,提供一个简单的Get请求接口;
@RestController
public class ServeWeb {
private static final Logger logger = LoggerFactory.getLogger(ServeWeb.class) ;
@Value("${server.port:}")
private Integer servePort ;
@GetMapping("/serve")
public String serve (){
logger.info("serve:{}",servePort);
return "serve:"+servePort ;
}
}
查看两个容器的运行日志,发现「auto-client」和「auto-serve」可以正常通信,以此来验证同一个Pod内网络共享;

4、状态与重启
4.1 重启策略
可以在Pod中通过restartPolicy属性设置重启策略,常用的取值是Always以降低应用的中断时间,适用于Pod中的所有容器;
- Always:默认值,容器失效时,kubelet自动重启该容器。
- OnFailure:容器停止运行且退出码不为0时,kubelet自动重启该容器。
- Never:不论容器是什么状态,kubelet都不重启该容器。
4.2 生命周期
- Pending:Pod被Kubernetes系统接受,但有一个或者多个容器未创建,此阶段包括等待Pod被调度的时间和通过网络下载镜像的时间。
- Running:Pod已经绑定到了某个节点,Pod中所有的容器都已被创建,至少有一个容器在运行,或者正处于启动或重启状态。
- Succeeded:Pod中的所有容器都已成功终止,并且不会再重启。
- Failed:Pod中的所有容器都已终止,并且至少有一个容器是因为失败被终止。
- Unknown:因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败。
Pod遵循预定义的生命周期,起始于Pending阶段,如果至少其中有一个主要容器正常启动,则进入Running阶段,之后取决于Pod中是否有容器以失败状态结束而进入Succeeded或者Failed阶段。
四、参考源码
文档仓库:
https://gitee.com/cicadasmile/butte-java-note
脚本仓库:
https://gitee.com/cicadasmile/butte-auto-parent
K8S | 容器和Pod组件的更多相关文章
- 从零开始入门 K8s| 详解 Pod 及容器设计模式
作者|张磊 阿里云容器平台高级技术专家,CNCF 官方大使 一.为什么需要 Pod 容器的基本概念 我们知道 Pod 是 Kubernetes 项目里面一个非常重要的概念,也是非常重要的一个原子调度单 ...
- K8s容器编排
K8s容器编排 Kubernetes(k8s)具有完备的集群管理能力: 包括多层次的安全防护和准入机制 多租户应用支撑能力 透明的服务注册和服务发现机制 内建智能负载均衡器 强大的故障发现和自我修复能 ...
- 使用k8s容器钩子触发事件
原文: http://yunke.science/2018/04/15/k8s-hook/ 容器生命周期的钩子 Kubernetes为容器提供了生命周期钩子.钩子能使容器感知其生命周期内的事件,并且当 ...
- K8s容器资源限制
在K8s中定义Pod中运行容器有两个维度的限制: 1. 资源需求:即运行Pod的节点必须满足运行Pod的最基本需求才能运行Pod. 如: Pod运行至少需要2G内存,1核CPU 2. 资源限额: ...
- K8s容器存储接口(CSI)介绍
Container Storage Interface是由来自Kubernetes.Mesos.Docker等社区member联合制定的一个行业标准接口规范,旨在将任意存储系统暴露给容器化应用程序. ...
- 一文讲明白K8S各核心架构组件
目录 一.写在前面 二.K8S为我们提供了怎样的能力 三.架构 3.1.MasterNode 3.2.WorkerNode 四.核心组件 4.1.ApiServer 4.1.1.概述 4.1.2.是集 ...
- k8s 中的 Pod 细节了解
k8s中Pod的理解 基本概念 k8s 为什么使用 Pod 作为最小的管理单元 如何使用 Pod 1.自主式 Pod 2.控制器管理的 Pod 静态 Pod Pod的生命周期 Pod 如何直接暴露服务 ...
- k8s容器的资源限制
1.k8s支持内存和cpu的限制 requests:容器运行需求,最低保障limits:限制,硬限制(资源上限) CPU: 1颗逻辑CPU(1核CPU=4个逻辑CPU) 1物理核=1000个微核(mi ...
- k8s学习 - 概念 - Pod
k8s学习 - 概念 - Pod 这篇继续看概念,主要是 Pod 这个概念,这个概念非常重要,是 k8s 集群的最小单位. 怎么才算是理解好 pod 了呢,基本上把 pod 的所有 describe ...
- 如何为k8s中的pod配置QoS等级?
1.概述 本文介绍如何为pod分配特定的QoS等级. 我们知道,在k8s的环境中,通过使用QoS等级来做决定,在资源紧张的时候,将哪些的pod进行驱逐,或者说如何对pod进行调度. OK,话不多说,让 ...
随机推荐
- java基础--lambda表达式
lambda表达式,一种常见用法,就是简化匿名内部类.使用前提条件:如果一个方法A(),只涉及一个抽象方法待实现,那么使用A()时,涉及到匿名内部类,就可以简化为 lambda 表达式 lambda表 ...
- Semantic Kernel 入门系列:🥑Memory内存
了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了. Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样 ...
- 【Vue】Vuex
Vuex简介 概念: 专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中管理(读.写),也是一种适用于任意组件间的通信方式. 什么时候用Vuex ①多个 ...
- 宝塔ftp无法连接的解决方案
宝塔面板现在使用率非常的高.今天把自己的踩坑处理方法记录一下. 在配置号宝塔面板ftp后,使用vscode的sftp插件,发现一直链接不上.一度以为自己配置文件,配置的参数有问题.各种度娘后,花了好长 ...
- Vue3 element-plus 下拉分页 select分页
由于用 input 实现下拉分页不太理想,转换了一个角度,用 select 实现,以下是具体实现(script-setup TS) script-setup <script lang=" ...
- Locust 运行方式
命令参数方式运行 # -*- coding: utf-8 -*- from locust import TaskSet, task, User ''' 命令行参数运行示例代码 ''' class ...
- SQLlabs less1-10通关笔记
SQLlabs 通关笔记 mysql数据结构 在练习靶场前我们需要了解以下mysql数据库结构,mysql数据库5.0以上版本有一个自带的数据库叫做information_schema,该数据库下面有 ...
- 2022-09-22:以下go语言代码输出什么?A:5、B:不能编译;C:运行时死锁。 package main import ( “fmt“ “time“ ) func main
2022-09-22:以下go语言代码输出什么?A:5.B:不能编译:C:运行时死锁. package main import ( "fmt" "time" ) ...
- 2022-08-07:以下go语言代码输出什么?A:1 1;B:3 1;C:0 3;D:不能编译。 package main import ( “fmt“ “math“ ) func main
2022-08-07:以下go语言代码输出什么?A:1 1:B:3 1:C:0 3:D:不能编译. package main import ( "fmt" "math&q ...
- Django4全栈进阶之路12 render 函数和 redirect 函数
在 Django 中,你可以使用 render 函数来渲染模板并将其返回给客户端,也可以使用 redirect 函数来重定向到其他 URL. 在 Django 中,render 函数和 redirec ...