了解集群、标签、Pod和Deployment
- 一、K8s`资源对象`
- 二、K8s`集群`
-
- [1. Master](#1. Master)
- [2. Node](#2. Node)
- 三、Namespace(命名空间)
- 四、Label(标签)
- 五、Pod
-
- [1. 共享网络命名空间](#1. 共享网络命名空间)
- [2. 共享数据](#2. 共享数据)
- 六、工作负载
-
- [1. 设置副本数](#1. 设置副本数)
- [2. 应用升级](#2. 应用升级)
- 结语
Kubernetes的知识真的特别庞大,知识点多,还特别看重实践操作。我从 Kubernetes
这个单词怎么拼写到在搭建好K8s集群并运行一个Nginx,花了一周的时间。我现在也是超级菜鸟一个,连入门都不算,只能边学边记录,我看的书籍是下面2本:
《Kubernetes权威指南》
第6版,知识点全面,对概念和原理讲的深入《Kubernetes企业级云原生运维实战》
李振良编写,更偏向实战操作,以便🐮🐴们能用上K8s为老板打工- 个人建议先看
《Kubernetes企业级云原生运维实战》
,不然《Kubernetes权威指南》
的第一章(共47页)都根本看不懂💀
一、K8s资源对象
K8s中的基础概念和术语大多围绕资源对象
来说的,资源对象可分如下几类:
- 基础资源对象:节点(Node)、容器组(Pod)、服务(Service)、存储卷(Volume)
- 基础资源对象相关的事务与控制器:标签(Label)、注解(Annotation)、命名空间(Namespace)、水平扩容、配置(ConfigMap、Secret)、持久化存储(PersistentVolume、PersistentVolumeClaim、StorageClass)、工作负载控制器(Deployment、StatefulSet、DeamonSet、Job、CronJob)
- 资源管控和权限相关:资源限制、资源配额、角色、角色绑定
- 网络相关 :Ingress、网络策略(NetworkPolicy)等
K8s中资源对象
包括几个公共属性:版本(Version)、类别(Kind)、名称(Name)、标签、注解。我们可以用YAML
或JSON
格式声明一个K8s资源对象
,每个资源对象都有自己特定的结构定义,比如Pod
和Service
的YAML文件的格式是不同的。定义好的资源对象会保存在etcd
这非关系型数据库中,以便快速读写。
二、K8s集群
K8s集群(Cluster)是由Master
和Node
组成的。
1. Master
Master
是控制节点,负责管理和控制整个集群,相当于集群的大脑,在每个K8s集群中都需要一个或一组Master
。在Master
上运行一下关键进程:
kube-apiserver
:提供RESTful API接口,是对资源进行增删改查的唯一入口,也是集群控制的入口kube-controller-manager
:所有资源对象的自动化控制中心,相当于"大总管"kube-scheduler
:负责资源调度(Pod调度)
2. Node
Node
是集群中的工作负载节点,是真正干活的打工人。Master
会把工作负载分配给Node
,当某个Node
宕机,其上的工作负载会被Master
转移到其他Node
上。在每个Node
上运行着以下关键进程:
kubelet
:负责Pod
对应容器的创建、启停等任务,听Mater
的指挥,实现集群管理的基本功能kube-proxy
:实现K8sService
通信与负载均衡机制容器运行时(如Docker)
:负责本机容器的创建和管理
bash
查看集群有多少节点
kubectl get nodes
查看某个Noded的信息
kubectl describe node <node_name>
三、Namespace(命名空间)
在K8s集群中还有一个重要概念-命名空间(Namespace),在大多情况下用于多租户的资源隔离,典型的思路是给每个租户分配一个命名空间。每个命名空间都是相互独立的,不同命名空间的资源对象是逻辑上
相互隔离。K8s安装运行后,默认会有2个Namespace:
default
:给用户用的,用户创建资源对象时,如不指定命名空间,会放到default命名空间kube-system
:存放系统相关的资源对象如网络组件、DNS组件、监控类组件
bash
若不指定namespace,查看的是default命名空间内的资源对象
kubectl get pods
通过参数查看指定命名空间"dev"的资源对象
kubectl get pods --namespace=dev
四、Label(标签)
Label
(标签)是K8s一个核心概念,它就是一个key=value
的键值对,其中key
和value
都是用户自定义。Lable
可以被附加到Node
、Pod
、Deployment
、Service
、Volume
等资源对象上,并且 一个资源对象可以有多个标签。 在实际生产环境中,Pod
应该都是有标签的,下面看个例子,就知道标签的重要性了。
- 下面是个定义
Service
的yaml文件,最后的selector
就是指关联有app=nginx
标签的Pod
yaml
apiVersion: v1 # API版本
kind: Service # 资源类型
metadata: # 资源元数据
name: nginx # 资源名称
spec: # 资源规格
ports: # 端口映射列表
- name: # 端口名称
port: 80 # 公开端口
protocol: TCP # 端口协议,支持TCP、UDP和SCTP,默认TCP
targetPort: 80 # 目标端口,即容器内应用程序监听的端口
selector: # 标签选择器
app: nginx # Pod标签
打上Label
后的资源对象,之后就可以通过Lable Selector
(标签选择器)查询和筛选,介绍下Lable Selector
的一些例子:
- yaml中配置
release : stable
标签,这个标签的值就是release=stable
release = stable
,匹配具有release=stable
标签的资源对象release != stable
,匹配不具有release=stable
标签的资源对象release in (stable, dev)
匹配具有release=stable
或release=dev
标签的资源对象release notin (stable, dev)
匹配不具有release=stable
和release=dev
标签的资源对象
五、Pod
Pod
(容器组)是K8s中最重要的概念之一,Pod
是K8s中最小的调度单元,每一个Pod
包含一个特殊的Pause容器
(由K8s创建)和一个或多个密切相关的用户业务容器
。
Pod
中多个业务容器
是密切相关的,将Pod
作为最小单位,让Pod
内多个应用一起有效地调度和伸缩。Pod
中的多个业务容器
共享Pause容器
的IP,简化了密切相关容器之间的通信。Pod
中的多个业务容器
共享Volume挂载,简化了密切相关容器之间的文件共享问题。Pod
都有一个唯一的Pod IP
地址,一个Pod
中多个容器共享Pod IP
地址。- 集群中任意两个
Pod
之间都可以支持TCP/IP直接通信。
1. 共享网络命名空间
假设一个场景:有2个业务容器
,一个是Nginx,一个是指标采集程序(负责采集Nginx性能指标)。这2个业务容器
关系是密切相关的。指标采集容器能通过http://127.0.0.1/nginx_status
直接访问Nginx容器吗?答案是不能,因为它们2个容器的网络命名空间是隔离的。但是在Pod中,这个2个容器可以共享网络命名空间,在创建一个Pod
时,K8s会先创建一个Pause容器
,然后业务容器
会接着被创建并加入到Pause容器
的网络命名空间,这样Pod
中的所有容器都在同一个网络命名空间中,可以通过127.0.0.1
访问彼此了。
假设有个collect指标采集程序的镜像,在定义Pod
的yaml文件
可以这样写。
kind
属性的值为Pod
,表明是一个定义Pod
的文件metadata.name
是Pod名称metadata.namespace
是命名空间metadata.labels
是标签,标签的key
和value
都是自定义,所以这个标签值就是"app=pod-network"
spec.containers
是用户容器列表,可以添加一个或多个容器
yaml
apiVersion: v1 # API版本
kind: Pod # 资源类型
metadata: # 资源元数据
name: pod-network # Pod名称
namespace: default # 指定命名空间
labels: # Pod标签
app: pod-network # 标签的key和value都是自定义,这个标签值就是"app=pod-network"
spec:
containers: # Pod中容器列表
# 第一个容器(主应用容器)
- image: nginx:1.23 # 容器镜像地址
name: web # 容器名称
# 第二个容器
- image: collect:1.0
name: collect
command: ["/bin/bash", "-c", "while true; do sleep 1; done"] # 容器执行的命令
2. 共享数据
还是上面那个场景:一个是Nginx,一个是指标采集程序(负责采集Nginx性能指标),指标采集程序要如何读取到Nginx的访问日志文件呢?我们所熟悉的Docker Volume
在K8s中也有对应的概念--Pod Volume
,它被定义在Pod
中,然后被Pod
中各个容器挂载到自己的文件系统中。

- 在
Pod
所在节点的文件系统创建一个空目录,然后挂载到2个业务容器的日志目录 - Nginx容器的
/var/log/nginx
写入文件后,指标采集容器的/var/log/nginx
也能使用Nginx的日志文件 - 卷定义的
volumes.name
和容器挂载的volumeMounts.name
要一致,这里都叫"log"
yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod-volume
name: pod-volume
namespace: default
spec:
containers:
# 第一个容器(应用容器)
- image: nginx:1.23
name: web
volumeMounts: # 卷挂载
- name: log # 挂载的卷名称
mountPath: /var/log/nginx # 卷挂载到容器中路径
# 第二个容器(日志采集容器)
- image: cooect:1.0
name: collect
command: ["/bin/bash", "-c", "while true; do sleep 1; done"]
volumeMounts: # 卷挂载
- name: log # 挂载的卷名称
mountPath: /var/log/nginx # 卷挂载到容器中的路径
volumes: # 定义卷
- name: log # 卷名称
emptyDir: {} # 卷类型:emptyDir是临时存储,与Pod生命周期一致
在实际生产环境中,不会直接用kind : Pod
这类型的Pod定义文件,一般都会用kind: Deployment
类型的工作负载
,所以一定要好好学习下面的工作负载
。
六、工作负载
通常情况下,每个Service
对应的Pod
副本数量都是固定的,如果一个一个手动创建Pod
副本那也太麻烦了。如果有一个Pod模板,在Pod模板里指定Pod副本数量,然后再根据Pod模板创建多个Pod。从这个Pod模板就引出了K8s中的一个抽象概念:工作负载
。
工作负载
用于更高层次地创建和管理Pod
,它可以定义Pod
的副本数量、运行规格、调度策略等- K8s可以自动处理
Pod
的创建、更新和删除等操作,简化了用户对Pod
生命周期的操作 工作负载
有4种类型,其中最常用的是Deployment
,支持副本管理、副本数扩缩、滚动更新、版本回滚等操作
1. 设置副本数
下面看下一个Deployment
的例子:
-
spec.replicas
:Pod的副本数量 -
spec.template
:用于自动创建新Pod副本的模板 -
spec.selector
:用于指定 Deployment 所管理的 Pod 的标签,这个选择器决定了哪些 Pod 是由这个 Deployment 管理的 -
spec.template.metadata.lables
:定义了 Pod 的标签,这些标签需要与上面的spec.selector
中的选择器匹配,以确保 Deployment 能够识别和管理这些 Pod。
yaml
apiVersion: apps/v1 # API版本
kind: Deployment # 资源类型
metadata: # 资源元数据
name: deploy-user-service # 资源名称
namespace: my-space # 指定命名空间
spec: # 资源规格
replicas: 3 # Pod副本数
selector: # 标签选择器
matchLabels: # 匹配标签
app: user
template: # Pod模板
metadata: # Pod元数据
labels: # Pod标签
app: user
spec: # Pod规格
containers: # Pod容器配置
- image: user-srvice:v3
name: web # 容器名称
2. 应用升级
当源代码需要升级时,需要重新构建镜像并上传到K8s集群中,以下有2中常见的升级方法:
- 修改资源文件,将
Deployment
资源中的image
字段修改为新的镜像地址,然后使用kubectl apply -f <资源文件>
命令。 - 使用
kubectl set image <资源类型>/资源名称 <容器名称>=<镜像地址>
命令更新Deployment
资源的镜像地址。
bash
kubectl set image deployment/deploy-user-service web=user-srvice:v4 -n my-space
结语
K8s的知识体系真的是太庞大了,本篇暂时写到这里,本篇涉及到的Pod
和Deployment
也只是真正相关知识的九牛一毛而已。但是学习一门新技术,不能按部就班地一个一个章节死磕每个知识点。要先对整体有个大概了解,着重看最主要最常用的功能,之后再反复的看书实践,提取知识点。