Kubernetes学习(二)Pod
创始人
2024-05-28 14:07:03
0

创建Pod

kubectl创建nginx pod

编写 nginx pod的yaml文件

apiVersion: v1
kind: Pod
metadata:name: my-nginxlabels:name: my-nginx
spec:containers:- image: nginxname: my-nginxresources:limits:memory: "128Mi"cpu: "500m"ports:- name: nginx-portcontainerPort: 80protocol: TCP

创建

kubectl create -f nginx.yaml

Pod实现原理

什么是Pod

Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。Pod的共享上下文包括一组Linux命名空间、控制组(cgroup)和可能的一些其他隔离,即用来隔离docker容器的技术。在Pod上下文中,每个独立的应用可能会进一步实施隔离。就Docker概念的术语而言,Pod类似于共享命名空间和文件系统卷的一组Docker容器。

使用Pod

通常不需要直接创建Pod、甚至单实例Pod。相反,会使用诸如Deployment或job这类工作负载资源来创建Pod。如果pod需要跟踪状态,可以考虑StatefulSet资源。

Kubernetes集群中Pod主要有2种用法:

1、运行单个容器的Pod。”每个Pod一个容器“模型是最常见的Kubernetes用例,在这种情况下,可以将Pod看做单个容器的包装器,并且Kubernetes直接管理Pod,而不是容器;

2、运行多个协同工作的容器的Pod。Pod可能封装有多个精密耦合切需要共享资源的共处容器组成的应用程序。这些位于同一位置的容器可能形成单个内聚的服务单元:一个容器将文件从共享卷提供给公众,而另一个单独的边车(sidecar)容器则刷新或更新这些文件。Pod将这些容器和存储资源打包为一个可管理的实体。

Pod网络

每个Pod都在每个地址族中获得一个唯一的Ip地址。Pod中的每个容器共享网络命名空间,包括IP地址和网络端口。Pod内的容器可以使用localhost互相通信。当Pod中的容器与Pod外的实体通信是,他们必须协调如果使用共享的网络资源(例如端口)

Pod生命周期

和一个个独立的应用容器一样,Pod也别认为是相对临时性(而不是长期存在)的实体。Pod会被创建、赋予一个唯一ID,并被调度到节点,并在终止或删除之前一直运行在该节点。如果一个节点挂掉了,调度到该节点的Pod也被计划在预定超时时限结束后删除

容器阶段 Phase

1、Pending(挂起) Pod已被Kubernetes系统接受,但有一个或多个容器尚未创建或运行。此阶段包括等待pod被调度的时间和通过网络下载镜像的时间

2、Running(运行中)Pod已被绑定到某个节点,Pod中所有的容器都已被创建,至少有一个容器仍在运行或正处于启动或重启状态

3、Succeeded(正常终止)Pod中所有的容器都成功终止,并且不会再重启

4、Failed(异常停止)Pod中所有容器都已终止,并且最少有一个容器是因为失败终止,也就是说,容器以非0状态退出或者被系统终止

5、Unknown(未知状态)因为某些原因无法取得Pod状态。这种情况通常是因为与Pod所在主机通信故障导致

容器状态

调度器将Pod分派给某个节点,kubelet就通过容器运行时开始为Pod创建容器。容器的状态有3中:Wating、Running、Terminated

容器生命周期事件处理函数

postStart和preStop处理函数

示例:lifecycle.yaml

apiVersion: v1
kind: Pod
metadata:name: lifecyclelabels:name: lifecycle
spec:containers:- name: lifecycle-demo-containerimage: nginxresources:limits:memory: "128Mi"cpu: "500m"ports:- containerPort: 81lifecycle:postStart:exec:command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]preStop:exec:command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]

验证:

[root@master k8s]# kubectl exec -it lifecycle sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# cat /usr/share/message
Hello from the postStart handler
# 

包含Init容器的Pod

Init容器

每个Pod中可以包含多个容器,应用运行在这些容器里面,同时Pod也可以有一个或多个先于用用启动的Init容器。

Init容器与普通的容器非常像,除了以下2点:

1、它们总是运行到完成

2、每个都必须在下一个启动之前成功完成

如果Pod的Init容器失败,Kubernetes会不断重启该Pod,知道Init容器成功启动为止。然而,如果Pod对应的restartPolicy值为Never,Kubernetes不会重新启动Pod

与普通容器的不同之处

Init容器支持应用容器的全部属性和特性,包括资源限制、数据卷和安全设置。

Init容器不支持lifecycle、livenessProbe、readinessProbe和startupProbe,因为它们必须在Pod就绪之前运行完成

示例:initPod.yaml

apiVersion: v1
kind: Pod
metadata:name: myapplabels:name: myapp
spec:containers:- name: myappimage: busybox:1.28command: ['sh','-c','date && sleep 3600']resources:limits:memory: "128Mi"cpu: "500m"ports:- containerPort: 81initContainers:- name: initimage :  busybox:1.28command: ['sh','-c','date && sleep 10']

定义一个具有2个Init容器的简单Pod。第一个等待myservice启动,第二个等待mydb启动,一旦这个2个Init容器都启动完成,Pod将启动应用容器

[root@master k8s]# kubectl get pods -w
NAME       READY   STATUS     RESTARTS   AGE
my-nginx   1/1     Running    0          19h
myapp      0/1     Init:0/1   0          14s
myapp      0/1     PodInitializing   0          17s
myapp      1/1     Running           0          18s
kubect^C[root@master k8s]# 
[root@master k8s]# kubectl logs myapp
Thu Mar  2 02:24:57 UTC 2023
[root@master k8s]# kubectl logs myapp -c init
Thu Mar  2 02:24:46 UTC 2023
[root@master k8s]# 

Init容器将会等待10秒,Init容器执行完毕,随后my-app的Pod进入running状态

用探针检查Pod的健康

探针的作用

探针是由kubelet 对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的handler,有三种类型的handler:

ExecAction:在容器内执行指定命令,如果命令退出时返回状态码为0,则认为诊断成功

TCPSockerAction:对容器的Ip地址上的指定端口执行TCP检查,如果端口打开,则认为诊断成功

HTTPGetAction:对容器ip地址上指定的端口和路径执行HTTP GET请求,如果响应的状态码>=200且

每次探针都将获得以下三种结果之一:

Success:容器诊断成功

Failure:容器未通过诊断

Unknown:诊断失败,不会采取任何动作

使用场景

容器需要较长时间才能启动就绪的Pod而言,启动探针是有用的。不需要配置一个较长的存活态探测时间间隔,只需要设置另一个独立的配置选定,对启动期间的容器执行探测,从而允许使用远远超出存活态时间间隔所允许的时长。

如果容器启动时间通常超出initialDelaySeconds+failureThreshold*periodSeconds总值,你就应该设置一个启动探针,对存活态探针所使用的同一端点执行检查。periodSeconds的默认值是30秒,failureThreshold设置的应其足够高,以便容器有充足的时间完成启动,并且避免更改存活态探针所使用的默认值,这一设置有助于减少死锁状况的发生。

示例:liveness.yaml

apiVersion: v1
kind: Pod
metadata:name: liveness-httplabels:test: liveness
spec:containers:- name: livenessimage: mirrorgooglecontainers/livenessargs:- /serverresources:limits:memory: "128Mi"cpu: "500m"livenessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 3periodSeconds: 3

liveness /healthz 在容器存活的最开始10秒内,会返回200状态码,之后返回500状态码

kubelet在容器启动之后3秒开始执行健康检查,所以前几次健康检查都是成功的,但是10秒之后,健康检查会失败,同时kubelet会杀死容器再重新启动容器

启动命令和参数

创建Pod时设置命令和参数

创建Pod时,可以为容器设置启动时要执行的命令和参数。可以在配置文件的command字段下设置命令,在args字段下设置命令参数。一旦Pod创建完成,改命令和参数就无法进行更改了。

如果在配置文件中设置了容器启动时要执行的命令和参数,那么容器镜像中自带的命令和参数将会被覆盖而不在执行。如果配置文件中只是设置了参数,却没有设置对应的命令,那么容器镜像中自带的命令会使用改新参数

示例:args.yaml

apiVersion: v1
kind: Pod
metadata:name: argslabels:name: args
spec:containers:- name: argsimage: debiancommand: ["printenv"]args: ["HOSTNAME", "KUBERNATES_PORT"]restartPolicy: OnFailure
[root@master k8s]# kubectl create -f args.yaml 
pod/args created
[root@master k8s]# kubectl get pod -w
NAME   READY   STATUS              RESTARTS   AGE
args   0/1     ContainerCreating   0          2s
args   0/1     Completed           0          4s
^C[root@master k8s]kubectl logs args
args
[root@master k8s]#

使用环境变量设置参数

apiVersion: v1
kind: Pod
metadata:name: argslabels:name: args
spec:containers:- name: argsimage: debianresources:limits:memory: "128Mi"cpu: "500m"env:- name: MESSAGEvalue: "hello world"command: ["/bin/echo"]args: ["$(MESSAGE)"]restartPolicy: OnFailure
[root@master k8s]# kubectl create -f args.yaml 
pod/args created
[root@master k8s]# kubectl get pod -w
NAME   READY   STATUS              RESTARTS   AGE
args   0/1     ContainerCreating   0          3s
args   0/1     Completed           0          4s
^C[root@master k8s]kubectl logs args
hello world
[root@master k8s]#

相互依赖的环境变量

设置了相互依赖的环境变量,就可以再配置清单文件中的env的value使用 $(VAR_NAME)

示例:dependency-var.yaml

apiVersion: v1
kind: Pod
metadata:name: myapplabels:name: myapp
spec:containers:- name: myappimage: busyboxresources:limits:memory: "128Mi"cpu: "500m"command:- "sh"- "-c"args:- printf UNCHANGED_REFERENCE=$UNCHANGED_REFERENCE'\n'; printf SERVICE=$SERVICE'\n'; printf ESCAPED_SERVICE=$ESCAPED_SERVICE; sleep 120env:- name: SERVICE_IPvalue: "192.168.99.102"- name: SERVICE_PORTvalue: "31111"- name: UNCHANGED_REFERENCEvalue: $(PROTOCAL)://$(SERVICE_IP):$(SERVICE_PORT)- name: PROTOCALvalue: "https"- name: SERVICEvalue: $(PROTOCAL)://$(SERVICE_IP):$(SERVICE_PORT)- name: ESCAPED_SERVICEvalue: $$(PROTOCAL)://$(SERVICE_IP):$(SERVICE_PORT)
[root@master k8s]# kubectl logs myapp
UNCHANGED_REFERENCE=$(PROTOCAL)://192.168.99.102:31111
SERVICE=https://192.168.99.102:31111
[root@master k8s]# 

配额管理

创建一个命名空间,以便资源隔离

kubectl create namespace cpu-example

指定CPU请求和CPU限制

要为容器执行CPU请求,请在容器资源清单中包含 resources:requests字段。要指定CPU限制,请包含resources:limits

示例:cpu-limit.yaml

apiVersion: v1
kind: Pod
metadata:name: myapplabels:name: myapp
spec:containers:- name: myappimage: registry.cn-beijing.aliyuncs.com/qingfeng666/stressresources:limits:memory: "128Mi"cpu: "1"ports:- containerPort: 80args:- -cups- "2"
[root@master k8s]# kubectl describe pod myapp
Name:         myapp
Namespace:    default
Priority:     0
Node:         node2/179.220.56.232
Start Time:   Thu, 02 Mar 2023 14:57:46 +0800
Labels:       name=myapp
Annotations:  
Status:       Running
IP:           10.244.2.20
IPs:IP:  10.244.2.20
Containers:myapp:Container ID:  docker://f41321840ba2dfdf841a869593f106acf86484d7f4b4f1dbaa9f3044efc9bc12Image:         registry.cn-beijing.aliyuncs.com/qingfeng666/stressImage ID:      docker-pullable://registry.cn-beijing.aliyuncs.com/qingfeng666/stress@sha256:155d7266cb7ed6fecd34b2e4f8a25c2b21eb77723658fb4ab2db630d41118c7dPort:          80/TCPHost Port:     0/TCPArgs:-cpus2State:          RunningStarted:      Thu, 02 Mar 2023 14:57:49 +0800Ready:          TrueRestart Count:  0Limits:cpu:     1memory:  128MiRequests:cpu:        1memory:     128MiEnvironment:  Mounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-dh67f (ro)

利用亲和性分配Pod

preferredDuringSchedulingIgnoredDuringExecution:软策略 requiredDuringSchedulingIgnoredDuringExecution: 硬策略

软策略:意思就是尽量不要将 pod 调度到匹配到的节点,但是如果没有不匹配的节点的话,也可以调度到匹配到的节点

硬策略:意思就是必须调度到满足条件的节点上,否则就等着 Pending

键值运算关系

  • In:label 的值在某个列表中
  • NotIn:label 的值不在某个列表中
  • Gt:label 的值大于某个值
  • Lt:label 的值小于某个值
  • Exists:某个 label 存在
  • DoesNotExist:某个 label 不存在

添加自定义lable

kubectl label nodes node1 disktype=ssd

节点亲和性配置

示例:affinity.yaml

apiVersion: v1
kind: Pod
metadata:name: myapplabels:name: myapp
spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: disktypeoperator: Invalues:- hardcontainers:- name: myappimage: nginxresources:limits:memory: "128Mi"cpu: "500m"ports:- containerPort: 80
[root@master k8s]# kubectl get pod -w
NAME    READY   STATUS    RESTARTS   AGE
myapp   1/1     Running   0          6s
^C[root@master k8s]# kubectl describe pod myapp
Name:         myapp
Namespace:    default
Priority:     0
Node:         node2/179.220.56.232
Start Time:   Thu, 02 Mar 2023 15:26:04 +0800
Labels:       name=myapp
Annotations:  
Status:       Running
IP:           10.244.2.21

ConfigMap数据注入容器

创建自定义的ConfigMap

示例:configmap-multi.yaml

apiVersion: v1
kind: ConfigMap
metadata:name: my-db-confignamespace: default
data:db-url: localhostusername: rootpassword: root
kubectl create -f configmap-multi.yaml

使用ConfigMap数据

apiVersion: v1
kind: Pod
metadata:name: myapplabels:name: myapp
spec:containers:- name: myappimage: busyboxcommand: ["sh", "-c", "env"]envFrom:- configMapRef:name: my-db-configresources:limits:memory: "128Mi"cpu: "500m"
[root@master k8s]# kubectl logs myapp
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=myapp
SHLVL=1
username=root
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
password=root
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
db-url=localhost

容器root用户和privileged特权用户

Docker允许隔离主机OS上的进程、功能和文件系统,并且出于实际原因,大多数容器默认以root用户身份运行。

Kubernetes通过Security Context提供了相同的功能。

要为Pod设置安全性配置,可在Pod规约中包含securityContext字段。securityContext字段值是一个PodSecurityContext对象,设置的安全性配置会应用到Pod中所有的Container上

示例:security.yaml

apiVersion: v1
kind: Pod
metadata:name: myapplabels:name: myapp
spec:securityContext:runAsUser: 1000runAsGroup: 3000fsGroup: 2000volumes:- name: securityemptyDir: {}containers:- name: myappimage: busyboxcommand: ["sh","-c","sleep 1h"]volumeMounts:- name: securitymountPath: /data/demosecurityContext:allowPrivilegeEscalation: falseresources:limits:memory: "128Mi"cpu: "500m"

相关内容

热门资讯

小学师德报告会的主持词 小学师德报告会的主持词各位领导,各位老师:  大家下午好!采撷着金秋十月的累累硕果,收藏着金秋十月的...
《像小强一样儿活着》的经典台... 《像小强一样儿活着》的经典台词  《像小强一样活着》改编自同名网络小说,是难得的本土电影。曾有影评家...
汇演主持词 汇演主持词  主持词要根据活动对象的不同去设置不同的主持词。在人们积极参与各种活动的今天,主持人在各...
联欢会主持词结束语 联欢会主持词结束语(通用6篇)  晚会开得就是否成功圆满与主持人的讲话有很大关系。下面小编整理的联欢...
幼儿园毕业晚会主持词 幼儿园毕业晚会主持词  主持人在台上表演的灵魂就表现在主持词中。时代不断在进步,司仪等是很多场合都需...
美剧经典台词 美剧精选经典台词  在快速变化和不断变革的今天,能够利用到台词的场合越来越多,台词是一种特殊的,也是...
朗诵会主持词 关于朗诵会主持词4篇  主持词要根据活动对象的不同去设置不同的主持词。在当下这个社会中,很多场合都需...
记者节晚会主持词 记者节晚会主持词  主持词是主持人在台上表演的灵魂之所在。随着社会一步步向前发展,主持词的实用频率越...
婚礼父亲致辞 婚礼父亲致辞(精选15篇)  在平凡的学习、工作、生活中,大家肯定对各类致辞都很熟悉吧,致辞具有“礼...
校园红歌赛的主持词 校园红歌赛的主持词  主持词是主持人在节目进行过程中用于串联节目的串联词。在现今人们越来越重视活动氛...
开业主持词开场白 开业主持词开场白  根据活动对象的不同,需要设置不同的主持词。在当今社会生活中,活动集会越来越多,主...
关于唱歌比赛主持词   主持词是指主持人在主持节目的过程中进行节目串联的串联词,一般由开场白、中间部分与结束语组成。以下...
动漫感人台词 动漫感人台词(通用175句)  台词可以刻画人物的性格,表现人物的感情,加强剧情的表现力。那些广为流...
最新年会主持词 最新年会主持词(精选11篇)  契合现场环境的主持词能给集会带来双倍的效果。在如今这个时代,主持人的...
新生文艺汇演主持词 新生文艺汇演主持词  主持词要根据活动对象的不同去设置不同的主持词。在当今社会生活中,各种集会的节目...
家长代表幼儿园毕业典礼主持词 家长代表幼儿园毕业典礼主持词  主持词是各种演出活动和集会中主持人串联节目的串联词。在人们积极参与各...
学校元旦晚会主持词开场白和结... 学校元旦晚会主持词开场白和结束语  2017年元旦晚会主持词怎么写?怎么开场比较好呢?结束语又该怎么...
毕业晚会致辞 毕业晚会致辞(精选18篇)  在学习、工作或生活中,大家都写过致辞吧,致辞要求风格的雅、俗、庄、谐要...
幼儿园六一节目串词 幼儿园六一节目串词红黄蓝幼第一文库网儿园节目串词主持人(师):亲爱的家长朋友们( ):敬爱的老师们(...
祝寿主持词 祝寿主持词  主持词要尽量增加文化内涵、寓教于乐,不断提高观众的文化知识和素养。在人们积极参与各种活...