Kubernetes中Pod详解

文章目录

  • 一、kubectl命令
  • 二、基础命令
    • 基础命令
    • 部署命令
    • 集群管理命令
    • 故障和调试命令
    • 其它命令
  • 三、YAML文件
  • 四、Pod介绍
    • 4.1 pod存在的意义
    • 4.2 Pod实现机制
      • 共享网络
        • 同一pod内容器共享网络
        • pod1与pod2不在同一主机
        • 同一主机中的pod通讯解决方案
      • 共享存储
    • 4.3 Pod中镜像拉取策略
    • 4.4 Pod资源限制
    • 4.5 Pod重启策略
    • 4.6 Pod健康检查
    • 4.7 Pod创建流程
    • 4.8 创建Pod的调度策略
      • 污点容忍
    • 4.9 Pod标签

一、kubectl命令

kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装和部署

命令格式如下

kubectl [command] [type] [name] [flags]

参数

  • command:指定要对资源执行的操作,例如create、get、describe、delete
  • type:指定资源类型,资源类型是大小写敏感的,开发者能够以单数 、复数 和 缩略的形式

例如:

kubectl get pod pod1
kubectl get pods pod1
kubectl get po pod1

Kubernetes中Pod详解_第1张图片

  • name:指定资源的名称,名称也是大小写敏感的,如果省略名称,则会显示所有的资源
  • flags:指定可选的参数,例如,可用 -s 或者 -server参数指定Kubernetes API server的地址和端口

二、基础命令

基础命令

命令 介绍
create 通过文件名或标准输入创建资源
expose 将一个资源公开为一个新的Service
run 在集群中运行一个特定的镜像
set 在对象上设置特定的功能
get 显示一个或多个资源
explain 文档参考资料
edit 使用默认的编辑器编辑一个资源
delete 通过文件名,标准输入,资源名称或标签来删除资源

部署命令

命令 介绍
rollout 管理资源的发布
rolling-update 对给定的复制控制器滚动更新
scale 扩容或缩容Pod数量,Deployment、ReplicaSet、RC或Job
autoscale 创建一个自动选择扩容或缩容并设置Pod数量

集群管理命令

命令 介绍
certificate 修改证书资源
cluster-info 显示集群信息
top 显示资源(CPU/M)
cordon 标记节点不可调度
uncordon 标记节点可被调度
drain 驱逐节点上的应用,准备下线维护
taint 修改节点taint标记

故障和调试命令

命令 介绍
describe 显示特定资源或资源组的详细信息
logs 在一个Pod中打印一个容器日志,如果Pod只有一个容器,容器名称是可选的
attach 附加到一个运行的容器
exec 执行命令到容器
port-forward 转发一个或多个
proxy 运行一个proxy到Kubernetes API Server
cp 拷贝文件或目录到容器中
auth 检查授权

其它命令

命令 介绍
apply 通过文件名或标准输入对资源应用配置
patch 使用补丁修改、更新资源的字段
replace 通过文件名或标准输入替换一个资源
convert 不同的API版本之间转换配置文件
label 更新资源上的标签
annotate 更新资源上的注释
completion 用于实现kubectl工具自动补全
api-versions 打印受支持的API版本
config 修改kubeconfig文件(用于访问API,比如配置认证信息)
help 所有命令帮助
plugin 运行一个命令行插件
version 打印客户端和服务版本信息

三、YAML文件

k8s 集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML)文件来解决,也就是可以把需要对资源对象操作编辑到YAML 格式文件中,我们把这种文件叫做资源清单文件,通过kubectl 命令直接使用资源清单文件就可以实现对大量的资源对象进行编排部署了。一般在我们开发的时候,都是通过配置YAML文件来部署集群的。

  • YAML :仍是一种标记语言。为了强调这种语言以数据做为中心,而不是以标记语言为重点。
  • YAML文件:就是资源清单文件,用于资源编排
  • YAML 是一个可读性高,用来表达数据序列的格式在这里插入代码片

基本语法:

  • 使用空格做为缩进
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • 低版本缩进时不允许使用Tab 键,只允许使用空格
  • 使用#标识注释,从这个字符一直到行尾,都会被解释器忽略
  • 使用---表示新的yaml文件开始

yaml支持的数据结构:

  • 对象:键值对的集合,又称为映射(mapping) / 哈希(hashes) / 字典(dictionary)
# 对象类型:对象的一组键值对,使用冒号结构表示
name: Tom
age: 18

# yaml 也允许另一种写法,将所有键值对写成一个行内对象
hash: {name: Tom, age: 18}
  • 数组
# 数组类型:一组连词线开头的行,构成一个数组
People
- Tom
- Jack

# 数组也可以采用行内表示法
People: [Tom, Jack]

YAML文件组成部分,一个是控制器的定义 和 被控制的对象

属性名称 介绍
apiVersion API版本
kind 资源类型
metadata 资源元数据
spec 资源规格
replicas 副本数量
selector 标签选择器
template Pod模板
metadata Pod元数据
spec Pod规格
containers 容器配置

一般来说,我们很少自己手写YAML文件,因为这里面涉及到了很多内容,我们一般都会借助工具来创建
使用kubectl create命令
这种方式一般用于资源没有部署的时候,我们可以直接创建一个YAML配置文件

# 尝试运行,并不会真正的创建镜像
kubectl create deployment web --image=nginx -o yaml --dry-run > nginx.yaml

[root@k8s-master ~]# cat nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}


对一个已经运行的pod创建
kubectl get deploy nginx -o=yaml --export > nginx.yaml

四、Pod介绍

Pod是在K8S集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。同时Pod对多容器的支持是K8S中最基础的设计理念。在生产环境中,通常是由不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。

其它的资源对象都是用来支撑或者扩展Pod对象功能的,比如控制器对象是用来管控Pod对象的,Service或者Ingress资源对象是用来暴露Pod引用对象的,PersistentVolume资源对象是用来为Pod提供存储等等,K8S不会直接处理容器,而是Pod,Pod是由一个或多个container组成。

Pod是Kubernetes的最重要概念,每一个Pod都有一个特殊的被称为 “根容器”的Pause容器。Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器。

Kubernetes中Pod详解_第2张图片
总结:

最小部署的单元
Pod里面是由一个或多个容器组成【一组容器的集合】
一个pod中的容器是共享网络命名空间
Pod是短暂的
每个Pod包含一个或多个紧密相关的用户业务容器

4.1 pod存在的意义

创建容器使用docker,一个docker对应一个容器,一个容器运行一个应用进程
Pod是多进程设计,运用多个应用程序,也就是一个Pod里面有多个容器,而一个容器里面运行一个应用程序

Pod的存在主要是为了亲密性应用更方便的交互

  • 两个或多个应用之间进行交互
  • 网络之间的调用【通过127.0.0.1 或 socket】
  • 两个应用之间需要频繁调用

Pod是K8S集群中所有业务类型的基础,可以把Pod看作运行在K8S集群上的小机器人,不同类型的业务就需要不同类型的小机器人去执行。目前K8S的业务主要可以分为以下几种

  • 长期伺服型:long-running
  • 批处理型:batch
  • 节点后台支撑型:node-daemon
  • 有状态应用型:stateful application

上述的几种类型,分别对应的小机器人控制器为:Deployment、Job、DaemonSet 和 StatefulSet (后面将介绍控制器)

4.2 Pod实现机制

共享网络

同一pod内容器共享网络

通过 Pause 容器,把其它业务容器加入到Pause容器里,让所有业务容器在同一个名称空间中,可以实现网络共享

pod1与pod2不在同一主机

Flannel网络模型解决方案:

同一主机中的pod通讯解决方案

由docker0网桥直接转发请求至pod2 ,不需要经过Flannal

共享存储

一个Pod里的多个容器可以共享存储卷,这个存储卷会被定义为Pod的一部分,并且可以挂载到该Pod里的所有容器的文件系统上。
Kubernetes中Pod详解_第3张图片

4.3 Pod中镜像拉取策略

拉取策略主要分为了以下几种

  • IfNotPresent:默认值,镜像在宿主机上不存在才拉取
  • Always:每次创建Pod都会重新拉取一次镜像
  • Never:Pod永远不会主动拉取这个镜像
    Kubernetes中Pod详解_第4张图片

4.4 Pod资源限制

我们在对Pod进行调度的时候,可以对调度的资源进行限制,例如我们限制 Pod调度是使用的资源是 2C4G,那么在调度对应的node节点时,只会占用对应的资源,对于不满足资源的节点,将不会进行调度。

示例:
Kubernetes中Pod详解_第5张图片

  • request:表示调度所需的资源
  • limits:表示最大所占用的资源

4.5 Pod重启策略

restartPolicy

Pod中包含了很多个容器,假设某个容器出现问题了,那么就会触发Pod重启机制
Kubernetes中Pod详解_第6张图片
重启策略主要分为以下三种

  • Always:当容器终止退出后,总是重启容器,默认策略 【nginx等,需要不断提供服务】
  • OnFailure:当容器异常退出(退出状态码非0)时,才重启容器,正常退出时,不会重启。
  • Never:当容器终止退出,从不重启容器 【批量任务】

注:当控制器是job或者是cronjob时,重启策略只能是OnFailure和Never。

4.6 Pod健康检查

通过容器检查,原来我们使用下面的命令来检查

kubectl get pod

但是有的时候,程序可能出现了 Java 堆内存溢出,程序还在运行,但是不能对外提供服务了,这个时候就不能通过 容器检查来判断服务是否可用了,这个时候就可以使用应用层面的检查。
Kubernetes中Pod详解_第7张图片

  • livenessProbe
    存活检查,如果检查失败,将杀死容器,根据Pod的restartPolicy【重启策略】来操作livenessProbe

  • readinessProbe
    就绪检查,如果检查失败,Kubernetes会把Pod从Service endpoints中剔除

    检测的是容器是否正常对外提供服务。如果检测失败则从负载均衡器上删除
    就绪性探测的检测方式分为以下三种:
             EXEC 	 : 执行命令探测,如果探测不成功一直在探测直至探测成功
    		TCP 	:ping端口探测,如果探测失败则一分钟重启探测一次
    		HTTP	:访问链接探测
    	
        
    ### 存活性检查和就绪性检查共有的五个参数
    	initialDelaySeconds:30s   设置开始延时时间 (默认情况下延迟0秒)
    	failureThreshold: 3        探测失败的次数(失效的阀值)(默认的情况下为3次)
    	timeoutSeconds:1           探测的超时时间(默认的情况下为1秒)
    	periodSeconds: 5s          每次探测的时间间隔(默认的情况下间隔10秒)
    	successThreshold:2         探测成功的次数 (默认情况下为1次)	
    

Probe支持以下三种检查方式

  • http Get:发送HTTP请求,返回200 - 400 范围状态码为成功
  • exec:执行Shell命令返回$?是0为成功
  • tcpSocket:发起TCP Socket建立成功

Pod的整个生命周期都伴随着存活性探测和就绪性探测
三种示例如下:

# exec
spec:
  containers:      # 定义容器
    - name: nginx     # 容器名称
      image: alvinos/django:v1  # 定义镜像名称
      imagePullPolicy: IfNotPresent   # 拉取策略(可写可不写)
      livenessProbe:                  #存活性检查的配置项
        exec:           # 选项
          command:            # 指定的命令
            - "/bin/sh"
            - "-c"
            - "cat /usr/share/nginx/html/index.html"  # 如果返回的状态不为0,则探测失败


# TCP
spec:
  containers:
    - name: nginx
      image: alvinos/django:v1
      imagePullPolicy: IfNotPresent   # 镜像拉取策略(可写可不写)
      livenessProbe:                  #存活性检查的配置项
        tcpSocket:                 # 验证tcp探测的方式
          port: 80             # 探测的是80端口


# http
 spec:
   containers:
     - name: nginx
       image: alvinos/django:v1
       imagePullPolicy: IfNotPresent   # 镜像拉取策略(可写可不写)
       livenessProbe:                  #存活性检查的配置项
         httpGet:                 #http的探测方式
           port: 80            #指定端口
           path: /index       # 有index这个链接,返回的状态码为200
              

Kubernetes中Pod详解_第8张图片

4.7 Pod创建流程

Kubernetes中Pod详解_第9张图片
Master节点上:

  1. 当create pod时,首先会将 pod信息通过apiserver保存在etcd中
  2. scheduler会时刻监视着apiserver,当有新的pod创建时,会通过apiserver从etcd中读取pod信息,根据调度算法把pod分配到某一节点中,并且存储在etcd中。

node节点:

  1. 通过kubelet访问apiserver,读取etcd信息,拿到分配给当前节点的pod,通过docker创建容器,然后将结果状态返回给apiserver, 通过apiserver写入etcd中。

4.8 创建Pod的调度策略

影响pod调度的属性

  1. pod资源限制(resources.requests)
  2. 节点选择器标签影响Pod调度
    Kubernetes中Pod详解_第10张图片

例如可以根据生产环境和开发环境调度,先让pod调度到开发环境
可以通过以下命令,给我们的节点新增标签,然后节点选择器就能根据指定的标签进行调度。

[root@k8s-master ~]# kubectl label node k8s-node1 env_role=dev
node/k8s-node1 labeled

# 查看节点标签
root@k8s-master ~]# kubectl get nodes k8s-node1 --show-labels
NAME        STATUS   ROLES    AGE   VERSION   LABELS
k8s-node1   Ready    <none>   18h   v1.20.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,env_role=dev,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux

  1. 节点亲和性 nodeAffinity
    节点亲和性 和之前nodeSelector 基本一样的,根据节点上标签约束来决定Pod调度到哪些节点上
    • 硬亲和性:约束条件必须满足
    • 软亲和性:尝试满足,不保证

Kubernetes中Pod详解_第11张图片
支持常用操作符:in、NotIn、Exists、Gt、Lt、DoesNotExists

反亲和性:就是和亲和性刚刚相反,如 NotIn、DoesNotExists等

  1. 污点(Taint)和污点容忍
    nodeSelector 和 NodeAffinity,都是Prod调度到某些节点上,属于Pod的属性,是在调度的时候实现的。
    Taint 污点:节点不做普通分配调度,是节点属性

场景

  • 专用节点【限制ip】
  • 配置特定硬件的节点【固态硬盘】
  • 基于Taint驱逐【在node1不放,在node2放】

查看节点污点情况

kubectl describe node k8smaster | grep Taint
[root@k8s-master ~]# kubectl describe node k8s-master | grep Taint
Taints:             node-role.kubernetes.io/master:NoSchedule

[root@k8s-master ~]# kubectl describe node k8s-node1 | grep Taint
Taints:             

污点值有三个

  • NoSchedule:一定不被调度
  • PreferNoSchedule:尽量不被调度【也有被调度的几率】
  • NoExecute:不会调度,并且还会驱逐Node已有Pod

给指定节点添加污点:

kubectl taint node [nodename] key=value:污点的三个值

例:

kubectl taint node k8s-node1 env_role=yes:NoSchedule

删除污点

kubectl taint node k8s-node1 env_role:NoSchedule-

示例: 先创建 多个Pod,查看分配到node的情况

[root@k8s-master ~]# kubectl create deployment  web --image=nginx
deployment.apps/web created

[root@k8s-master ~]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE        NOMINATED NODE   READINESS GATES
nginx-6799fc88d8-zzdqb   1/1     Running   1          20h   10.244.1.3   k8s-node2   <none>           <none>
web-96d5df5c8-x2thn      1/1     Running   0          59s   10.244.3.6   k8s-node1   <none>           <none>

可以看到 web 创建到了node1上了,我们在复制5份

[root@k8s-master ~]# kubectl scale deployment web --replicas=5
deployment.apps/web scaled

[root@k8s-master ~]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP           NODE        NOMINATED NODE   READINESS GATES
nginx-6799fc88d8-zzdqb   1/1     Running   1          20h     10.244.1.3   k8s-node2   <none>           <none>
web-96d5df5c8-d857s      1/1     Running   0          113s    10.244.1.4   k8s-node2   <none>           <none>
web-96d5df5c8-k8mgg      1/1     Running   0          113s    10.244.3.7   k8s-node1   <none>           <none>
web-96d5df5c8-n54tf      1/1     Running   0          113s    10.244.1.5   k8s-node2   <none>           <none>
web-96d5df5c8-txbwz      1/1     Running   0          113s    10.244.3.8   k8s-node1   <none>           <none>
web-96d5df5c8-x2thn      1/1     Running   0          5m18s   10.244.3.6   k8s-node1   <none>           <none>

可以看到 node1 、node2节点都有分配。

删除刚创建的所有pod

kubectl delete deployment web

现在给了更好的演示污点的用法,我们现在给 node1节点打上污点
kubectl taint node k8s-node1 env_role=yes:NoSchedule

[root@k8s-master ~]# kubectl taint node k8s-node1 env_role=yes:NoSchedule
node/k8s-node1 tainted

[root@k8s-master ~]# kubectl describe node k8s-node1 | grep Taint
Taints:             env_role=yes:NoSchedule

然后我们重新创建一个 pod

# 创建nginx pod
kubectl create deployment web --image=nginx
# 复制五次
kubectl scale deployment web --replicas=5

再次查看,可以看到所有Pod都创建到了node2

[root@k8s-master ~]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
nginx-6799fc88d8-zzdqb   1/1     Running   1          21h     10.244.1.3    k8s-node2   <none>           <none>
web-96d5df5c8-4nqsz      1/1     Running   0          2m29s   10.244.1.8    k8s-node2   <none>           <none>
web-96d5df5c8-57vfn      1/1     Running   0          2m29s   10.244.1.7    k8s-node2   <none>           <none>
web-96d5df5c8-g8nvl      1/1     Running   0          2m51s   10.244.1.6    k8s-node2   <none>           <none>
web-96d5df5c8-jhwlh      1/1     Running   0          2m29s   10.244.1.10   k8s-node2   <none>           <none>
web-96d5df5c8-zq6g9      1/1     Running   0          2m29s   10.244.1.9    k8s-node2   <none>           <none>

删除污点,删除web

kubectl delete deployment web
kubectl taint node k8s-node1 env_role:NoSchedule-

污点容忍

污点容忍就是某个节点可能被调度,也可能不被调度
Kubernetes中Pod详解_第12张图片

4.9 Pod标签

相当于别名
1、添加标签
		
	① 创建之时文件中添加(
			
	② 使用命令方式给pod添加标签
		kubectl label pods pod名称 school=beij
		
2、删除标签
	kubectl label pods test beij-

你可能感兴趣的:(kubernetes,容器,云原生)