Kubernetes:让容器编排管理变得容易高效

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 在专栏《面向WEB开发人员的Docker》介绍了容器在开发过程中的使用,虽然整个专栏还未完成,想必现有的内容可以大概了解清楚容器的概念,能够做什么。

在专栏《面向WEB开发人员的Docker》介绍了容器在开发过程中的使用,虽然整个专栏还未完成,想必现有的内容可以大概了解清楚容器的概念,能够做什么。

本文是一篇读书笔记,个人觉得内容可以进一步加深了解容器技术应用。

Kubernetes是什么?

Kubernetes(简称k8s) 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用。

pod介绍

pod是一组并置的容器,是Kubernetes的基本构建模型。一个pod的所有容器(docker)都运行在同一个工作节点上,绝不会跨越多个工作节点。

pod是Kubernetes中最为重要的核心概念,本文主要围绕 pod 的概念、管理及使用展开。

image.png

为什么需要pod而不直接使用容器

多个容器比单个容器中包含多个进程要好,如果一个容器运行多个进程,在需要查看每个进程的运行日志将非常困难,不利于排查问题。

了解pod

pod是逻辑主机,其行为与非容器世界中的物理主机或者虚拟机非常相似。

由于不能将多个进程聚集在一个单独的容器中,因此就需要pod将容器作为一个单元进行管理。在包含容器的pod下,既可以同时运行密切相关的进程,又能保持一定的隔离。

同一个Pod中容器之间的部分隔离

同一个pod中的所有容器都在相同的network和UTS命名空间下运行,因此它们都共享相同的主机名和网络接口。当涉及文件系统时,每个容器的文件系统和其他容器是完全隔离的。

容器如何共享相同的ip和端口空间

由于一个pod中的容器运行于相同的Network命名空间中,因此他们共享相同的IP地址和端口空间,可以通过localhost与同一个pod中的其他容器通信。

对于端口,同一pod中的容器运行的多个进程绑定到相同的端口号会导致冲突,对于不同pod中的容器则永远不会出现端口冲突。

平坦pod间网络

Kubernetes集群中所有pod都在同一个共享网络地址空间中,可以通过IP地址来实现相互访问。

image.png

通过pod合理管理容器

由于pod比较轻量,可以在几乎不导致任何额外开销的前提下拥有尽可能多的pod,将应用组织到多个pod中,而每个pod只包含紧密相关的组件或进程。

  • 将多层应用分散到多个pod中:如果有一个双节点的Kubernetes集群,如果只用一个pod,始终只会用一个工作节点,而不会充分利用第二个节点上的计算资源。合理做法是前端后端分别部署在不同节点上。
  • 基于扩缩容考虑而分割到多个Pod中:pod也是扩缩容的基本单位,如果全部部署在一个pod中,扩缩容会导致所有的应用层都将受影响。如前端和后端,就无法只对后端进行扩缩容。不利于资源利用。
  • 何时在Pod中使用多个容器:应用由一个主进程和一个或多个辅助进程组成
  • 决定何时在Pod中使用多个容器:容器不应该包含多个进程,Pod也不应该包含多个并不需要运行在同一个主机上的容器

image.png

以YAML或者JSON描述文件创建Pod

使用YAML描述文件创建,可以存储在版本控制系统中,方便维护

image.png

主要部分:

* `metadata`:包括名称、命名空间、标签和关于该容器的其他信息
* `spec`:包含pod内容的实际说明,如容器、卷和其他数据
* `status`:包含运行中的pod的当前信息,如条件、描述、状态、IP等

为pod创建一个简单的YAML描述文件

apiVersion: v1
kind: Pod
metadata:
  name: kubia-manual  //pod名称
spec:
  containers:
  - image: luksa/kubia
    name: kubia
    ports:
    - containerPort: 8080  //应用监听的端口
      protocol: TCP

使用kubectl create 创建pod

kubectl create -f kubia-manual.yaml

获得运行中Pod的完整定义

  • 返回yaml格式:kubectl get po kubia-manual -o yaml
  • 返回json格式:kubectl get po kubia-manual -o json

在pod列表中查看新创建的pod

kubectl get pods

查看应用日志

使用 docker logs

容器化的应用程序会将日志记录到标准输出和标准错误流,不会写入文件,允许用户可以通过简单、标准的方式查看。

容器运行是将这些流重定向到文件,可以通过以下命令获取容器日志:

docker logs <container id>

可以通过ssh命名登录到pod正在运行的节点,并使用docker logs命令查看其日志。

使用kubectl logs

查看pod的日志,只需要在本地机器上运行以下命令:kubectl logs kubia-manual

获取多容器pod的日志

获取多容器pod的日志时需指定容器名称,使用-c <容器名称>来显式指定容器名称

kubectl logs kubia-manual -c kubia

向pod发送请求

将本地网络端口转发到pod中的端口

Kubernetes允许配置端口转发到该pod,如将本地端口8888转发到kubia-manual pod的端口8080。这样就可以通过本地端口连接到pod。

kubectl port-forward kubia-manual 8888:8080

通过端口转发连接到pod

在另外的终端上,可以通过运行localhost:8888上的代理,向pod发送一个Http请求:

curl localhost:8888

image.png

使用标签组织pod

在实际运营中,随着Pod数量的增加,使用标签可以有效的组织。

举例:微服务架构

部署的微服务数量可以很轻松就超过20个,在实际运营过程中面临版本发布、快速扩容等,很容易导致混乱。如图:

image.png

很明显需要一种方式,可以通过一次操作对所有或者某些pod进行操作,而不必要为每个pod执行操作。

因此就需要使用标签来组织pod,标签是Kubernetes的一种简单却强大的特征,可以组织pod,也可以组织其他资源。

还是上面的示例,为pod添加两个标签:

  • app:指定pod属于那些应用、组件或者微服务
  • rel:指定pod中运行的应用所属的版本,如stable、beta

image.png

创建pod时指定标签

kubia-manual-with-labels.yaml

apiVersion: v1
kind: Pod
metadata:
  name: kubia-manual-v2
  labels:  //附加标签到pod上
    creation_method: manual
    env: prod
spec:
  containers:
  - image: luksa/kubia
    name: kubia
    ports:
    - containerPort: 8080
      protocol: TCP

执行命令创建:kubectl create -f kubia-manual-with-labels.yaml

默认不会列出任何标签,需要执行下面命令来查看:

执行命令:kubectl get po --show labels

如果需要筛选某些标签,可以使用-L选项来指定,如:

kubectl get po -L creation_method,env

修改现有pod的标签

标签可以在现有的pod上进行添加和修改,下面通过命令为kubia-manual添加标签:

kubectl label po kubia-manual creation_method=manual

将名为kubia-manual-v2的pod的标签env=prod更改为env=debug,更改现有标签需要使用--overwrite选项。

kubectl label po kubia-manual-v2 env=debug --overwrite

通过标签选择器列出pod子集

前面我们了解了标签的使用,现在我们来介绍标签选择器,实际使用过程中标签要与标签选择器结合使用才能发挥其作用。

使用标签选择器列出pod

  • 列出包含creation_method标签并且标签值为manual的pod:kubectl get po -l creation_method=manual
  • 列出包含env标签的pod:kubectl get po -l env
  • 列出没有env标签的pod:kubectl get po -l '!env'
  • 其他选择条件:
  • creation_method!=manual:选择带有creation_method标签并且值不等于manual的pod
  • env in (prod,devel):选择带有env标签且值为prod或者devel的pod
  • env notin (prod,devel):选择带有env标签,但其值不是pord或者devel的pod

在标签选择器中使用多个条件

标签选择器中同时使用多个条件,每个条件使用逗号分隔,选择的pod或者资源需要全部匹配才算。

kubectl get po -l app=pc,rel=beta

使用标签和选择器来约束pod的调度

由于Kubernetes将集群中的所有节点抽象为一个整体的大型部署平台,对于pod实际调度到哪个节点无关紧要。对于每个pod,获得所请求的确切数量的计算资源(CPU、内存等)及其他pod的可访问性,不受该pod所调度到的节点的影响。

在实际情况中,我们有将那些pod调度到哪里的需求,不需要特别说明pod应该调度到哪个节点上,这会使应用程序与基础架构强耦合,违背了Kubernetes对运行在其上的应用程序隐藏实际的基础架构的构想。因此这时可以对节点使用标签和标签选择器,使Kubernetes选择符合一定条件的节点。

使用标签分类工作节点

加入集群中有一个用于通用GPU计算的GPU,希望向节点添加标签来标记这个功能特征,通过将标签gpu=true来实现。

kubectl label node gke-kubia-85f6-node-orrx gpu=true

现在就可以使用标签选择器来列出节点:

kubectl get nodes -l gpu=true

将pod调度到特定节点

现在创建一个需要执行GPU的新pod,为了让调度器只在提供适当GPU的节点进行选择,在YAML文件中添加一个节点选择器

apiVersion: v1
kind: Pod
metadata:
  name: kubia-gpu
spec:
  nodeSelector:
    gpu: "true"   //只将pod部署到包含标签gpu=true的节点上
  containers:
  - image: luksa/kubia
    name: kubia

调度到一个特定的节点

同样,可以将pod调度到某个确定的节点,使用键值:kubernetes.io/hostname,即节点实际主机名。不建议pod调度到按个节点上,而应该通过标签选择器来选择特定的逻辑节点组。

注解pod

除标签外,pod和其他对象还可以包含注解,也是键值对,本质和标签相似。不同的是注解不能像标签一样用于分组。

注解可以容纳更多的信息,大量使用注解可以为每个pod或者其他API对象添加说明,方便使用者协作。

使用命名空间对资源进行分组

如果将对象分割成完全独立且不重叠的组时,可以考虑命名空间。Kubernetes命名空间简单的为对象名称提供了一个作用域。

命名空间的需求

使用多个命名空间的前提下,可以将包含大量组件的复杂系统拆分为更小的不同组,这些不同组也可以用于在多租户环境中分配资源,如生产、开发、测试环境等。资源名称只需在命名空间内保持唯一即可。

发现其他命名空间及其pod

列出集群中所有命名空间:kubectl get ns

使用kubectl get命令列出资源时,默认只列出default命名空间下的对象。

列出命名空间kube-system的pod:kubectl get po --namespace kube-system

命名空间可以将不属于一组的资源分到不重叠的组中,并为资源名称提供了一个作用域。

创建一个命名空间

命名空间是一种和其他资源一样的Kubernetes资源,因此也可以通过YAML文件来创建。

从YAML文件创建命名空间:

custom-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: custom-namespace

执行命令:kubectl create -f custom-namespace.yaml

使用kubectl create namespace命令创建命名空间

命名空间名称规则:比附符合域名中规定的命名规范,但不允许包含点号,即只能包含字母、数字、横杆(-)

创建:kubectl create namespace custom-namespace

管理其他命名空间中的对象

在指定命名空间中创建资源:

kubectl create -f kubia-manual.yaml -n custom-namespace

命名空间提供的隔离

命名空间将对象分隔到不同的组,只允许对属于特定命名空间的对象进行操作,但实际上并不提供正在运行的对象的任何隔离。命名空间之间是否提供网络隔离取决于Kubernetes所使用的网络解决方案。

停止和移除pod

按名称删除pod

删除pod的过程,是先终止pod所有容器

删除单个:kubectl delete po kubia-gpu

删除多个:kubectl delete po pod1 pod2

使用标签选择器删除pod

kubectl delete po -l create_method=manual

通过删除整个命名空间来删除pod

kubectl delete ns custom-namespace

删除命名空间中的所有pod,但保留命名空间

对于使用kubectl run命名创建的pod,如果需要全部删除掉,需要删除ReplicationCcontroller

删除命名空间中的(几乎)所有资源

kubectl delete all --all

使用该命令可以删除当前命名空间中的所有资源,也可以删除ReplicationCcontroller。当然还是会有些资源会被保留下来,如Secret。


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
针对本地存储和 PVC 这两种容器存储使用方式,我们对 ACK 的容器存储监控功能进行了全新升级。此次更新完善了对集群中不同存储类型的监控能力,不仅对之前已有的监控大盘进行了优化,还针对不同的云存储类型,上线了全新的监控大盘,确保用户能够更好地理解和管理容器业务应用的存储资源。
348 178
|
4天前
|
弹性计算 人工智能 资源调度
DeepSeek大解读系列公开课上新!阿里云专家主讲云上智能算力、Kubernetes容器服务、DeepSeek私有化部署
智猩猩「DeepSeek大解读」系列公开课第三期即将开讲,聚焦阿里云弹性计算助力大模型训练与部署。三位专家将分别讲解智能算力支撑、Kubernetes容器服务在AI场景的应用实践、以及DeepSeek一键部署和多渠道应用集成,分享云计算如何赋能大模型发展。欲观看直播,可关注【智猩猩GenAI视频号】预约。 (239字符)
|
1月前
|
存储 运维 Kubernetes
正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
飞轮科技推出了 Doris 的 Kubernetes Operator 开源项目(简称:Doris Operator),并捐赠给 Apache 基金会。该工具集成了原生 Kubernetes 资源的复杂管理能力,并融合了 Doris 组件间的分布式协同、用户集群形态的按需定制等经验,为用户提供了一个更简洁、高效、易用的容器化部署方案。
正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
|
1月前
|
存储 监控 对象存储
ACK容器监控存储全面更新:让您的应用运行更稳定、更透明
介绍升级之后的ACK容器监控体系,包括各大盘界面展示和概要介绍。
|
2月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
189 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
1月前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
245 11
|
2月前
|
存储 Kubernetes Docker
Kubernetes(k8s)和Docker Compose本质区别
理解它们的区别和各自的优势,有助于选择合适的工具来满足特定的项目需求。
254 19
|
2月前
|
Prometheus Kubernetes 监控
OpenAI故障复盘 - 阿里云容器服务与可观测产品如何保障大规模K8s集群稳定性
聚焦近日OpenAI的大规模K8s集群故障,介绍阿里云容器服务与可观测团队在大规模K8s场景下我们的建设与沉淀。以及分享对类似故障问题的应对方案:包括在K8s和Prometheus的高可用架构设计方面、事前事后的稳定性保障体系方面。
|
1月前
|
人工智能 运维 监控
容器服务Kubernetes场景下可观测体系生产级最佳实践
阿里云容器服务团队在2024年继续蝉联Gartner亚洲唯一全球领导者象限,其可观测体系是运维的核心能力之一。该体系涵盖重保运维、大规模集群稳定性、业务异常诊断等场景,特别是在AI和GPU场景下提供了全面的观测解决方案。通过Tracing、Metric和Log等技术,阿里云增强了对容器网络、存储及多集群架构的监控能力,帮助客户实现高效运维和成本优化。未来,结合AI助手,将进一步提升问题定位和解决效率,缩短MTTR,助力构建智能运维体系。
|
1月前
|
缓存 容灾 网络协议
ACK One多集群网关:实现高效容灾方案
ACK One多集群网关可以帮助您快速构建同城跨AZ多活容灾系统、混合云同城跨AZ多活容灾系统,以及异地容灾系统。

热门文章

最新文章

相关产品

  • 容器服务Kubernetes版