对比软件安装和运行;

一、场景

作为研发人员,通常自己电脑的系统环境都是非常复杂,在个人的习惯上,是按照下图的模块管理电脑的系统环境;

对于「基础设施」、「主机操作系统」、「系统软件」来说,通常只做配置修改;

对于自行安装的软件环境来说,个人通常这样分类:「应用软件」、「研发软件」、「持续集成」、「虚拟机环境」;

  • 应用软件:主要指常用的办公软件,比如文档编写,画图设计,通信产品等;
  • 研发软件:比如基础开发环境,各种中间件环境,数据存储查询等;
  • 持续集成:主流的就是Jenkins、Docker、Kubernetes等组件,整体比较复杂,不好管理;
  • 虚拟机环境:研发必备的Linux操作系统,用来部署一些标准的组件集群;

不论是这些软件环境还是虚拟机系统的搭建,基本都是通过下载软件安装包,然后在本地部署和定期更新以及运行,基于这个场景再去理解容器和Pod组件,会轻松许多;

二、容器

1、容器镜像

参考上面系统环境的管理,软件包和安装部署的原理;

Docker容器镜像是一个轻量级的、独立的、可执行的软件包,它包含了运行应用程序所需的一切:代码、运行时、系统工具、系统库和设置,带有创建Docker容器的说明;

可以通过Dockerfile脚本自定义镜像,也可以使用云端仓库中其他人公开发布的,生产环境通常采用私有仓库管理镜像;

容器镜像所承载的是封装了应用程序及其所有软件依赖的二进制数据,容器镜像是可执行的软件包,可以单独运行;通常会创建应用的容器镜像并将其推送到某仓库,然后在Pod中引用它;

2、容器

容器将应用程序从底层的主机设施中解耦,这使得在不同的云或OS环境中部署更加容易;

容器的本质就是一个视图隔离、可限制资源、独立文件系统的进程集合;

以常见的Linux研发环境来分析,可以限制容器的资源分配,比如内存大小、CPU使用,隔离进程之间的通信,设置独立的文件系统等;

Kubernetes集群中的每个节点都会运行容器,这些容器构成分配给该节点的Pod,单个Pod中的容器会在共同调度下,于同一位置运行在相同的节点上;

从整体上可以把K8S理解为「操作系统」,镜像理解为「软件安装包」,容器理解为「应用进程」;

3、实践案例

制作镜像,首先将代码工程auto-clientauto-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组件的更多相关文章

  1. 从零开始入门 K8s| 详解 Pod 及容器设计模式

    作者|张磊 阿里云容器平台高级技术专家,CNCF 官方大使 一.为什么需要 Pod 容器的基本概念 我们知道 Pod 是 Kubernetes 项目里面一个非常重要的概念,也是非常重要的一个原子调度单 ...

  2. K8s容器编排

    K8s容器编排 Kubernetes(k8s)具有完备的集群管理能力: 包括多层次的安全防护和准入机制 多租户应用支撑能力 透明的服务注册和服务发现机制 内建智能负载均衡器 强大的故障发现和自我修复能 ...

  3. 使用k8s容器钩子触发事件

    原文: http://yunke.science/2018/04/15/k8s-hook/ 容器生命周期的钩子 Kubernetes为容器提供了生命周期钩子.钩子能使容器感知其生命周期内的事件,并且当 ...

  4. K8s容器资源限制

    在K8s中定义Pod中运行容器有两个维度的限制: 1. 资源需求:即运行Pod的节点必须满足运行Pod的最基本需求才能运行Pod. 如: Pod运行至少需要2G内存,1核CPU    2. 资源限额: ...

  5. K8s容器存储接口(CSI)介绍

    Container Storage Interface是由来自Kubernetes.Mesos.Docker等社区member联合制定的一个行业标准接口规范,旨在将任意存储系统暴露给容器化应用程序. ...

  6. 一文讲明白K8S各核心架构组件

    目录 一.写在前面 二.K8S为我们提供了怎样的能力 三.架构 3.1.MasterNode 3.2.WorkerNode 四.核心组件 4.1.ApiServer 4.1.1.概述 4.1.2.是集 ...

  7. k8s 中的 Pod 细节了解

    k8s中Pod的理解 基本概念 k8s 为什么使用 Pod 作为最小的管理单元 如何使用 Pod 1.自主式 Pod 2.控制器管理的 Pod 静态 Pod Pod的生命周期 Pod 如何直接暴露服务 ...

  8. k8s容器的资源限制

    1.k8s支持内存和cpu的限制 requests:容器运行需求,最低保障limits:限制,硬限制(资源上限) CPU: 1颗逻辑CPU(1核CPU=4个逻辑CPU) 1物理核=1000个微核(mi ...

  9. k8s学习 - 概念 - Pod

    k8s学习 - 概念 - Pod 这篇继续看概念,主要是 Pod 这个概念,这个概念非常重要,是 k8s 集群的最小单位. 怎么才算是理解好 pod 了呢,基本上把 pod 的所有 describe ...

  10. 如何为k8s中的pod配置QoS等级?

    1.概述 本文介绍如何为pod分配特定的QoS等级. 我们知道,在k8s的环境中,通过使用QoS等级来做决定,在资源紧张的时候,将哪些的pod进行驱逐,或者说如何对pod进行调度. OK,话不多说,让 ...

随机推荐

  1. pandas之合并操作

    Pandas 提供的 merge() 函数能够进行高效的合并操作,这与 SQL 关系型数据库的 MERGE 用法非常相似.从字面意思上不难理解,merge 翻译为"合并",指的是将 ...

  2. Redis(七)缓存穿透、缓存击穿、缓存雪崩以及分布式锁

    应用问题解决 1 缓存穿透 1.1 访问结构 正常情况下,服务器接收到浏览器发来的web服务请求,会先去访问redis缓存,如果缓存中存在数据则直接返回,否则会去查询数据库里面的数据,然后保存在red ...

  3. [Asp.Net Core] 网站中的XSS跨站脚本攻击和防范

    漏洞说明: 跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶意攻击者往 ...

  4. android studio 做登陆界面

    先来一个最简单的     AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> &l ...

  5. 【踩坑】.NET异步方法不标记async,Task<int> 返回值 return default问题

    ​ 在.NET中,返回类型为 Task<T> 的方法并不一定要标记为 async.这是因为 async 关键字只是用来告诉编译器该方法中包含异步操作,并且可以使用 await 和其他异步特 ...

  6. Python 遍历整个列表

    操作列表 遍历整个列表,无论列表有多长,循环让列表中的每一个元素都采取一个或一系列相同的措施,从而高效地处理任何长度的列表,包含数以千至数百万个元素的列表. 遍历整个列表 通过for循环解决遍历 从列 ...

  7. 联想win8改win7

    知识点分析:目前联想出厂预装Windows 8的台式和一体机使用都是UEFI+GPT硬盘的组合,并且开启了安全启动,但是目前除Window 8以外的其他Windows系统均不支持这种模式,因此如果需要 ...

  8. 2023-03-06:给定一个二维网格 grid ,其中: ‘.‘ 代表一个空房间 ‘#‘ 代表一堵 ‘@‘ 是起点 小写字母代表钥匙 大写字母代表锁 我们从起点开始出发,一次移动是指向四个基本方向之

    2023-03-06:给定一个二维网格 grid ,其中: '.' 代表一个空房间 '#' 代表一堵 '@' 是起点 小写字母代表钥匙 大写字母代表锁 我们从起点开始出发,一次移动是指向四个基本方向之 ...

  9. 2022-06-17:给定一个数组arr,含有n个数字,可能有正、有负、有0, 给定一个正数k。 返回所有子序列中,累加和最大的前k个子序列累加和。 假设K不大,怎么算最快? 来自Amazon。

    2022-06-17:给定一个数组arr,含有n个数字,可能有正.有负.有0, 给定一个正数k. 返回所有子序列中,累加和最大的前k个子序列累加和. 假设K不大,怎么算最快? 来自Amazon. 答案 ...

  10. Prometheus采集Java程序指标信息

    采集Java程序JVM信息 创建 Spring Boot Application 应用程序 进行 https://start.spring.io 使用版本 Spring Boot v2.7.11和JD ...