K8S | 容器和Pod组件

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 不论是软件环境还是虚拟机系统的搭建,基本都是通过下载软件安装包,然后在本地部署和定期更新以及运行,基于这个场景再去理解容器和Pod组件,会轻松许多;

对比软件安装和运行;

一、场景

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

1.png

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

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

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

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

二、容器

1、容器镜像

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

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

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

2.png

容器镜像所承载的是封装了应用程序及其所有软件依赖的二进制数据,容器镜像是可执行的软件包,可以单独运行;通常会创建应用的容器镜像并将其推送到某仓库,然后在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"]

3.png

三、Pod组件

1、基本概念

Pod是可以在K8S中创建和管理的、最小的可部署的计算单元;

Pod是一组(一个或多个)容器,这些容器共享存储、网络、以及怎样运行这些容器的声明,Pod中的内容总是并置的并且一同调度,在共享的上下文中运行;

2、Pod管理

【Pod创建】

通常不会直接创建Pod,而是使用诸如Deployment或Job这类工作负载资源来创建Pod;是相对临时性的、用后即抛的一次性实体;

【单容器Pod】

每个Pod都意在运行给定应用程序的单个实例,可以使用多个Pod对应用程序横向扩展,即一个实例一个Pod对应,Pod看作单个容器的包装器由K8S直接管理,是常见的部署方式;

【多容器Pod】

分布式系统中可能存在由多个紧密耦合且需要共享资源的共处容器组成的应用程序,比较典型的是「生产消费」场景,Pod将这些容器和存储资源打包为一个可管理的实体;

4.png

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内网络共享;

5.png

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
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
7天前
|
存储 Kubernetes Docker
【赵渝强老师】Kubernetes中Pod的基础容器
Pod 是 Kubernetes 中的基本单位,代表集群上运行的一个进程。它由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。基础容器负责维护 Pod 的网络空间,对用户透明。文中附有图片和视频讲解,详细介绍了 Pod 的组成结构及其在网络配置中的作用。
【赵渝强老师】Kubernetes中Pod的基础容器
|
7天前
|
运维 Kubernetes Shell
【赵渝强老师】K8s中Pod的临时容器
Pod 是 Kubernetes 中的基本调度单位,由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。临时容器用于故障排查和性能诊断,不适用于构建应用程序。当 Pod 中的容器异常退出或容器镜像不包含调试工具时,临时容器非常有用。文中通过示例展示了如何使用 `kubectl debug` 命令创建临时容器进行调试。
|
7天前
|
Kubernetes 调度 容器
【赵渝强老师】K8s中Pod中的业务容器
Pod 是 Kubernetes 中的基本调度单元,由一个或多个容器组成。除了业务容器,Pod 还包括基础容器、初始化容器和临时容器。本文通过示例介绍如何创建包含业务容器的 Pod,并提供了一个视频讲解。示例中创建了一个名为 &quot;busybox-container&quot; 的业务容器,并使用 `kubectl create -f firstpod.yaml` 命令部署 Pod。
|
5天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
23 2
|
15天前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
11天前
|
关系型数据库 MySQL API
|
27天前
|
存储 Docker 容器
docker中挂载数据卷到容器
【10月更文挑战第12天】
66 5
|
4天前
|
缓存 监控 开发者
掌握Docker容器化技术:提升开发效率的利器
在现代软件开发中,Docker容器化技术成为提升开发效率和应用部署灵活性的重要工具。本文介绍Docker的基本概念,并分享Dockerfile最佳实践、容器网络配置、环境变量和秘密管理、容器监控与日志管理、Docker Compose以及CI/CD集成等技巧,帮助开发者更高效地利用Docker。
|
5天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
5天前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用