Kubernetes-Pod
1. 简介
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod 是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。
就 Docker 概念的术语而言,Pod 类似于共享名字空间和文件系统卷的一组 Docker 容器。
2. pod 怎样管理多个容器
Pod 被设计成支持形成内聚服务单元的多个协作过程(形式为容器)。 Pod 中的容器被自动安排到集群中的同一物理机或虚拟机上,并可以一起进行调度。 容器之间可以共享资源和依赖、彼此通信、协调何时以及何种方式终止自身。
例如,你可能有一个容器,为共享卷中的文件提供 Web 服务器支持,以及一个单独的 “sidecar(挂斗)”容器负责从远端更新这些文件,如下图所示:
3. 使用 Pod
很少会在 Kubernetes 中直接创建一个个的 Pod,甚至是单实例(Singleton)的 Pod。 这是因为 Pod 被设计成了相对临时性的、用后即抛的一次性实体。 当 Pod 由你或者间接地由 控制器创建时,它被调度在集群中的节点上运行。 Pod 会保持在该节点上运行,直到 Pod 结束执行、Pod 对象被删除、Pod 因资源不足而被 驱逐 或者节点失效为止。
说明: 重启 Pod 中的容器不应与重启 Pod 混淆。 Pod 不是进程,而是容器运行的环境。 在被删除之前,Pod 会一直存在。
3.1 Pod 和控制器
你可以使用工作负载资源来创建和管理多个 Pod。 资源的控制器能够处理副本的管理、上线,并在 Pod 失效时提供自愈能力。 例如,如果一个节点失败,控制器注意到该节点上的 Pod 已经停止工作, 就可以创建替换性的 Pod。调度器会将替身 Pod 调度到一个健康的节点执行。
下面是一些管理一个或者多个 Pod 的工作负载资源的示例:
3.2 quick start
3.2.1 创建pod
my-pod.yaml
资源模板内容如下:
apiVersion: v1
kind: Pod
metadata:
labels:
my-pod: helloworld
name: helloworld
namespace: test1
spec:
containers:
- image: nginx
name: helloworld
restartPolicy: Always
创建pod
$ kubectl create -f my-pod.yaml
可以使用 --dry-run 快速创建一个pod资源模板
# --dry-run=client 以客户端的方式空跑一个资源服务 该参数会导致 请求不会发送给server,也就不会创建pod,可以使用此参数生成一个想要的资源模板
# -oyaml 以yaml的方式输出资源模板内容
$ kubectl run helloworld1 --image=nginx --dry-run=client -oyaml -n test1
# 输出内容如下
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: helloworld1
name: helloworld1
namespace: test1
spec:
containers:
- image: nginx
name: helloworld1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
3.2.2 查看pod
查看pod 基本信息
$ kubectl get po -n test1
NAME READY STATUS RESTARTS AGE
helloworld 1/1 Running 0 5m29s
查看pod更多的信息
$ kubectl get po -n test1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
helloworld 1/1 Running 0 7m26s 10.100.132.162 k8s-woker-01 <none> <none>
可以看到pod容器ip地址为10.100.132.162
,尝试访问服务
$ curl 10.100.132.162
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
查看pod运行详情信息
# kubectl describe -f my-pod.yaml
$ kubectl describe po/helloworld -n test1
Name: helloworld
Namespace: test1
Priority: 0
Node: k8s-woker-01/192.168.0.202
Start Time: Sun, 12 Dec 2021 18:58:14 +0800
Labels: my-pod=helloworld
Annotations: cni.projectcalico.org/podIP: 10.100.132.162/32
cni.projectcalico.org/podIPs: 10.100.132.162/32
Status: Running
IP: 10.100.132.162
IPs:
IP: 10.100.132.162
Containers:
helloworld:
Container ID: docker://06d589c242e5aa16962ce0e52cd6d51b6b8f95205edcb860fb83f66ba580d0d3
Image: nginx
Image ID: docker-pullable://nginx@sha256:9522864dd661dcadfd9958f9e0de192a1fdda2c162a35668ab6ac42b465f0603
Port: <none>
Host Port: <none>
State: Running
Started: Sun, 12 Dec 2021 18:58:20 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-pxmm6 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-pxmm6:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-pxmm6
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10m default-scheduler Successfully assigned test1/helloworld to k8s-woker-01
Normal Pulling 10m kubelet Pulling image "nginx"
Normal Pulled 10m kubelet Successfully pulled image "nginx" in 4.762471154s
Normal Created 10m kubelet Created container helloworld
Normal Started 10m kubelet Started container helloworld
3.2.3 修改pod
-
使用命令修改
使用 kubectl edit 命令直接修改对应的pod信息即可
$ kubectl edit po/helloworld -n test1
-
使用资源模板
直接修改资源模板 my-pod.yaml,修改完执行apply操作
$ kubectl apply -f my-pod.yaml
3.2.4 删除pod
-
使用命令删除
$ kubectl delete po/helloworld -n test1
-
使用资源文件
$ kubectl delete -f my-pod.yaml
3.2.5 查看pod日志
-
-f :监听pod日志
-
--tail:输出最近的20条日志
$ kubectl logs -f po/helloworld --tail=20 -n test1
3.2.6 进入pod
$ kubectl exec -it po/helloworld -n test1 -- /bin/bash
4. 生命周期
Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度(分派)到某个节点,Pod 会一直在该节点运行,直到 Pod 停止或者 被终止。
Pod 自身不具有自愈能力。如果 Pod 被调度到某节点而该节点之后失效,Pod 会被删除;类似地,Pod 无法在因节点资源 耗尽或者节点维护而被驱逐期间继续存活。Kubernetes 使用一种高级抽象 来管理这些相对而言可随时丢弃的 Pod 实例,称作 控制器。
5. 容器重启策略
Pod 的 spec
中包含一个 restartPolicy
字段,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。
restartPolicy
适用于 Pod 中的所有容器。restartPolicy
仅针对同一节点上 kubelet
的容器重启动作。当 Pod 中的容器退出时,kubelet
会按指数回退 方式计算重启的延迟(10s、20s、40s、...),其最长延迟为 5 分钟。 一旦某容器执行了 10 分钟并且没有出现问题,kubelet
对该容器的重启回退计时器执行 重置操作。
6. pod 模板
apiVersion: v1 //版本
kind: pod //类型,pod
metadata: //元数据
name: String //元数据,pod的名字
namespace: String //元数据,pod的命名空间
labels: //元数据,标签列表
- name: String //元数据,标签的名字
annotations: //元数据,自定义注解列表
- name: String //元数据,自定义注解名字
spec: //pod中容器的详细定义
containers: //pod中的容器列表,可以有多个容器
- name: String
image: String //容器中的镜像
imagesPullPolicy: [Always|Never|IfNotPresent]//获取镜像的策略
command: [String] //容器的启动命令列表(不配置的话使用镜像内部的命令)
args: [String] //启动参数列表
workingDir: String //容器的工作目录
volumeMounts: //挂载到到容器内部的存储卷设置
- name: String
mountPath: String
readOnly: boolean
ports: //容器需要暴露的端口号列表
- name: String
containerPort: int //容器要暴露的端口
hostPort: int //容器所在主机监听的端口(容器暴露端口映射到宿主机的端口)
protocol: String
env: //容器运行前要设置的环境列表
- name: String
value: String
resources: //资源限制
limits:
cpu: Srting
memory: String
requeste:
cpu: String
memory: String
livenessProbe: //pod内容器健康检查的设置
exec:
command: [String]
httpGet: //通过httpget检查健康
path: String
port: number
host: String
scheme: Srtring
httpHeaders:
- name: Stirng
value: String
tcpSocket: //通过tcpSocket检查健康
port: number
initialDelaySeconds: 0//首次检查时间
timeoutSeconds: 0 //检查超时时间
periodSeconds: 0 //检查间隔时间
successThreshold: 0
failureThreshold: 0
securityContext: //安全配置
privileged: falae
restartPolicy: [Always|Never|OnFailure]//重启策略
nodeSelector: object //节点选择
imagePullSecrets:
- name: String
hostNetwork: false //是否使用主机网络模式,默认否
volumes: //在该pod上定义共享存储卷
- name: String
meptyDir: {}
hostPath:
path: string
secret: //类型为secret的存储卷
secretName: String
item:
- key: String
path: String
configMap: //类型为configMap的存储卷
name: String
items:
- key: String
path: String