深入理解Pod对象:基本管理
Pod基本概念
Pod是Kubernetes创建和管理的最小单元,一个Pod由一个容器或多个容器组成,这些容器共享存储、网络。
Pod特点
- .一个Pod可以理解为是一个应用实例,提供服务.
- Pod中容器始终部署在一个Node上
- Pod中容器共享网络、存储资源
- Kubernetes直接管理Pod,而不是容器
Pod存在意义
Pod主要用法:
- ·运行单个容器:最常见的用法,在这种情况下,可以将Pod看做是单个容器的抽象封装
- 运行多个容器:封装多个紧密耦合且需要共享资源的应用程序
如果有这些需求,你可以运行多个容器:
- 两个应用之间发生文件交互
- 两个应用需要通过127.0.0.1或者socket通信
- 两个应用需要发生频繁的调用
Pod资源共享实现机制
Pod管理命令
//创建Pod:
kubectl apply -f pod.yaml
或者使用命令kubectl run nginx --image=nginx
//查看Pod:
kubectl get pods
kubectl describe pod <Pod名称>
//查看日志:
kubectl logs <Pod名称>[-c CONTAINER]
kubectl logs <Pod名称>[-c CONTAINER] -f
//进入容器终端:
kubectl exec <Pod名称> [-c CONTAINER] -- bash
//删除pod
kubectl delete <Pod名称>
//定义Pod
apiVersion: v1
kind: Pod
metadata:
name: my-podspec:
containers:
- name: container1
image: nginx
- name: container2
image: centos
重启策略
- Always:当容器终止退出后,总是重启容器,默认策略
(总是重启)
- OnFailure:当容器异常退出(退出状态码非0)时,才重启容器
(非正常退出,比如stop、kill)
- Never:当容器终止退出,从不重启容器
(永不重启)
[root@master ~]# kubectl explain pod.spec.restartPolicy
KIND: Pod
VERSION: v1
FIELD: restartPolicy <string>
DESCRIPTION:
Restart policy for all containers within the pod. One of Always, OnFailure,
Never. Default to Always. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
//修改为Never
[root@master ~]# cat test.yml
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
- name: test
image: busybox
imagePullPolicy: IfNotPresent
command: ["bin/sh","-c","sleep 45"]
restartPolicy: Never #默认的话不用修改,改为never后停止容器不会重启
[root@master ~]# kubectl apply -f test.yml
pod/web created
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web 2/2 Running 0 12s
[root@master ~]# kubectl get pod -o wide -w #-w实时监控,在node2上面用docker命令关上其中一个,发现不会重启
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web 2/2 Running 0 23s 10.244.1.78 node1 <none> <none>
web 1/2 NotReady 0 46s 10.244.1.78 node1 <none> <none>
//修改为Always
[root@master ~]# cat test.yml
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
- name: test
image: busybox
imagePullPolicy: IfNotPresent
command: ["bin/sh","-c","sleep 45"]
restartPolicy: Always
//删除原来的test.yml ,重启启动一个新的pod
[root@master ~]# kubectl delete -f test.yml
pod "web" deleted
[root@master ~]# kubectl apply -f test.yml
pod/web created
//启动好后,在node1上停止test
[root@master ~]# kubectl get pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web 2/2 Running 0 6s 10.244.1.79 node1 <none> <none>
web 1/2 NotReady 0 46s 10.244.1.79 node1 <none> <none>
web 2/2 Running 1 47s 10.244.1.79 node1 <none> <none>
web 1/2 NotReady 1 92s 10.244.1.79 node1 <none> <none>
web 1/2 CrashLoopBackOff 1 102s 10.244.1.79 node1 <none> <none>
web 2/2 Running 2 103s 10.244.1.79 node1 <none> <none>
等待一定的时间后重启,而后自动起一台新的
//OnFailure
[root@master ~]# cat test.yml
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
- name: test
image: busybox
imagePullPolicy: IfNotPresent
command: ["bin/sh","-c","sleep 45"]
restartPolicy: OnFailure
//删除原来的test.yml ,重启启动一个新的pod
[root@master ~]# kubectl delete -f test.yml
pod "web" deleted
[root@master ~]# kubectl apply -f test.yml
pod/web created
//启动好后,在node1上停止test
[root@node1 ~]# docker ps | grep test
6ed4e11715d8 ffe9d497c324 "bin/sh -c 'sleep 45'" 3 seconds ago Up 3 seconds k8s_test_web_default_cc265ebd-4dae-49e7-8235-d1ba1102b4af_0
[root@node1 ~]# docker kill 6ed4e11715d8
6ed4e11715d8
//又起来了
[root@node1 ~]# docker ps | grep test
bf042b813e7c ffe9d497c324 "bin/sh -c 'sleep 45'" 14 seconds ago Up 13 seconds k8s_test_web_default_cc265ebd-4dae-49e7-8235-d1ba1102b4af_1
[root@master ~]# kubectl get pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web 2/2 Running 0 1s 10.244.1.80 node1 <none> <none>
web 1/2 Error 0 34s 10.244.1.80 node1 <none> <none>
//异常退出(手动杀掉)
web 2/2 Running 1 35s 10.244.1.80 node1 <none> <none>
//正常退出(60秒)
web 1/2 NotReady 1 80s 10.244.1.80 node1 <none> <none>
web 1/2 NotReady 1 2m26s 10.244.1.80 node1 <none> <none>
健康检查
- livenessProbe(存活检查)︰如果检查失败,将杀死容器,根据Pod的restartPolicy来操作
- readinessProbe(就绪检查)︰如果检查失败,Kubernetes会把Pod从service endpoints中剔除
支持的检查方式:
- httpGet:发送HTTP请求,返回200-400范围状态码为成功
- exec: 执行hell命令返回状态码是0为成功
- tcpSocket:发起TCP Socket建立成功
与重启策略相结合使用
重启策略+健康检查(应用自修复)
//端口探测
[root@master ~]# cat test.yml
---
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
hostPort: 80
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 20 #启动容器后多少秒健康检查
periodSeconds: 10 #以后间隔多少秒检查一次
readinessProbe:
httpGet:
port: 80
initialDelaySeconds: 20
periodSeconds: 10
[root@master ~]# kubectl apply -f test.yml
pod/web created
//查看pod,发现在进行初始化
[root@master ~]# kubectl get pod
NAME READY(就绪状态) STATUS(存活状态) RESTARTS AGE
web 0/1 Running 0 18s
//等待一定时间后会进入运行
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 34s
如果失败init容器默认会在State中显示CrashLoopBackOff (重启/异常)
在Reason会显示Error
State 代表状态
Reason 原因
Terminated 终止
Completed 完成
环境变量
变量值几种定义方式:
- 自定义变量值
- 变量值从Pod属性获取
- 变量值从Secrt,ConfigMap
[root@master ~]# kubectl explain pod.spec.containers.env.valueFrom
KIND: Pod
VERSION: v1
RESOURCE: valueFrom <Object>
DESCRIPTION:
Source for the environment variable's value. Cannot be used if value is not
empty.
EnvVarSource represents a source for the value of an EnvVar.
FIELDS:
configMapKeyRef <Object>
Selects a key of a ConfigMap.
fieldRef <Object>
Selects a field of the pod: supports metadata.name, metadata.namespace,
`metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`, spec.nodeName,
spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
resourceFieldRef <Object>
Selects a resource of the container: only resources limits and requests
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu,
requests.memory and requests.ephemeral-storage) are currently supported.
secretKeyRef <Object>
Selects a key of a secret in the pod's namespace
第一种
---
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: bi
image: busybox
imagePullPolicy: IfNotPresent
command: ["bin/sh","-c","sleep 45"]
env:
- name: HN
value: tom
[root@master ~]# kubectl apply -f test.yml
pod/test created
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 21s
[root@master ~]# kubectl exec -it test -- /bin/sh
/ # echo $HN
tom
第二种
[root@master ~]# cat test.yml
---
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: bi
image: busybox
imagePullPolicy: IfNotPresent
command: ["bin/sh","-c","sleep 45"]
env:
- name: HN
valueFrom:
fieldRef:
fieldPath: metadata.name
[root@master ~]# kubectl delete -f test.yml
pod "test" deleted
[root@master ~]# kubectl apply -f test.yml
pod/test created
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 21s
[root@master ~]# kubectl exec -it test -- /bin/sh
/ # echo $HN
test
第三种
[root@master ~]# cat test.yml
---
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: bi
image: busybox
imagePullPolicy: IfNotPresent
command: ["bin/sh","-c","sleep 45"]
env:
- name: HN
valueFrom:
fieldRef:
fieldPath: spec.nodeName
[root@master ~]# kubectl delete -f test.yml
pod "test" deleted
[root@master ~]# kubectl apply -f test.yml
pod/test created
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 17s
[root@master ~]# kubectl exec -it test -- /bin/sh
/ # echo $HN
node1
第四种
[root@master ~]# cat test.yml
---
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: bi
image: busybox
imagePullPolicy: IfNotPresent
command: ["bin/sh","-c","sleep 45"]
env:
- name: HN
valueFrom:
fieldRef:
fieldPath: status.podIP
[root@master ~]# kubectl delete -f test.yml
pod "test" deleted
[root@master ~]# kubectl apply -f test.yml
pod/test created
[root@master ~]# kubectl exec -it test -- /bin/sh
/ # echo $HN
10.244.1.84
/ # exit
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test 1/1 Running 1 50s 10.244.1.84 node1 <none> <none>
init Container(初始化容器)
初始化容器
- Init Container:用于初始化工作,执行完就结束(一次性任务)
- 支持大部分应用容器配置,但不支持健康检查
- 优先应用容器执行
应用场景:
- 环境检查:例如确保应用容器依赖的服务启动后再启动应用容器
- 初始化配置:例如给应用容器准备配置文件
示例
这里部署一个web网站,网站程序没有打到镜像中,而是希望从代码仓库中动态拉取放到应用容器中
在这里插入代码片[root@master ~]# cat test.yml
---
apiVersion: v1
kind: Pod
metadata:
name: web
namespace: default
spec:
initContainers:
- name: download
image: busybox
imagePullPolicy: IfNotPresent
volumeMounts:
- name: data
mountPath: /tmp
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
hostPort: 80
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
hostPath:
path: /var/www/html
//不管在哪个节点我都创建
[root@node1 ~]# mkdir /var/www/html/ -p
[root@node1 ~]# cd /var/www/html/
[root@node1 html]# echo "1314444" > index.html
[root@node1 html]# cat index.html
1314444
[root@node2 ~]# mkdir /var/www/html/ -p
[root@node2 ~]# cd /var/www/html/
[root@node2 html]# echo "hello world" > index.html
[root@node2 html]# cat index.html
hello world
[root@master ~]# kubectl apply -f test.yml
pod/web created
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 8s
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web 1/1 Running 0 45s 10.244.1.85 node1 <none> <none>
[root@master ~]# curl 10.244.1.85
1314444
//详细信息
[root@master ~]# kubectl describe pod web
Name: web
Namespace: default
Priority: 0
Node: node1/192.168.129.135
Start Time: Wed, 22 Dec 2021 22:27:06 +0800
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.244.1.86
IPs:
IP: 10.244.1.86
Init Containers:
download:
Container ID: docker://ec747a2654371d818661cc8e1da08d465d15e8d8d13c3a8d6a47f1ca21106d94
Image: busybox
Image ID: docker-pullable://busybox@sha256:b5cfd4befc119a590ca1a81d6bb0fa1fb19f1fbebd0397f25fae164abe1e8a6a
Port: <none>
Host Port: <none>
State: Terminated
Reason: Completed
Exit Code: 0
Started: Wed, 22 Dec 2021 22:27:07 +0800
Finished: Wed, 22 Dec 2021 22:27:07 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/tmp from data (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ck7n4 (ro)
Containers:
nginx:
Container ID: docker://6dd618f9591a8d27623d1394d07def8498e25741af293ff5ef101db3516206e1
Image: nginx
Image ID: docker-pullable://nginx@sha256:9522864dd661dcadfd9958f9e0de192a1fdda2c162a35668ab6ac42b465f0603
Port: 80/TCP
Host Port: 80/TCP
State: Running
Started: Wed, 22 Dec 2021 22:27:08 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/usr/share/nginx/html from data (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ck7n4 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
data:
Type: HostPath (bare host directory volume)
Path: /var/www/html
HostPathType:
default-token-ck7n4:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ck7n4
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 6m35s default-scheduler Successfully assigned default/web to node1
Normal Pulled 6m34s kubelet Container image "busybox" already present on machine
Normal Created 6m34s kubelet Created container download
Normal Started 6m34s kubelet Started container download
Normal Pulled 6m33s kubelet Container image "nginx" already present on machine
Normal Created 6m33s kubelet Created container nginx
Normal Started 6m33s kubelet Started container nginx
总结:Pod中会有这几种类型的容器
- Infrastructure Container:基础容器
维护整个Pod网络空间 - lnitContainers:初始化容器
先于业务容器开始执行 - Containers:业务容器
并行启动
先简单的做出两个运行httpd程序的pod
[root@master httpd]# vim Dockerfile
FROM busybox
RUN mkdir /data && \
echo "test page on jjyy" > /data/index.html
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
[root@master ~]# docker build -t 1314444/httpd:v0.1 httpd
[root@master ~]# vim httpd/Dockerfile
FROM busybox
RUN mkdir /data && \
echo "test page on 666" > /data/index.html
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
[root@master ~]# docker build -t 1314444/httpd:v0.2 httpd
web
[root@master ~]# cat manifest/web.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web1
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: web1
template:
metadata:
labels:
app: web1
spec:
containers:
- name: web1
image: 1314444/httpd:v0.1
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: web1
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: web1
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web2
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: web2
template:
metadata:
labels:
app: web2
spec:
containers:
- name: web2
image: 1314444/httpd:v0.2
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: web2
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: web2
type: NodePort
[root@master ~]# kubectl apply -f manifest/web1.yml
deployment.apps/web1 created
service/web1 created
[root@master ~]# kubectl apply -f manifest/web2.yml
deployment.apps/web2 created
service/web2 created
[root@master ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/web1-855b788957-8fzpg 1/1 Running 0 17m
pod/web2-5f7456967b-t5vqs 1/1 Running 0 17m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d8h
service/web1 NodePort 10.101.207.28 <none> 80:31807/TCP 17m
service/web2 NodePort 10.100.246.130 <none> 80:31413/TCP 17m
haproxy
[root@master ~]# cat manifest/haproxy.yml
---
apiVersion: v1
kind: Pod
metadata:
name: haproxy
namespace: default
labels:
app: haproxy
spec:
restartPolicy: OnFailure
initContainers:
- name: data
volumeMounts:
- name: data
mountPath: /tmp
containers:
- image: 1314444/haproxy:v0.3
imagePullPolicy: IfNotPresent
name: haproxy
env:
- name: RSIP
value: "web1 web2"
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 20
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: haproxy
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: haproxy
type: NodePort
[root@master ~]# kubectl apply -f manifest/haproxy.yml
deployment.apps/haproxy created
[root@master ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/haproxy-54c76db7b8-bl44g 1/1 Running 0 111s
pod/web1-855b788957-8fzpg 1/1 Running 0 17m
pod/web2-5f7456967b-t5vqs 1/1 Running 0 17m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/haproxy NodePort 10.101.200.144 <none> 80:30311/TCP 13m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d9h
service/web1 NodePort 10.101.207.28 <none> 80:31807/TCP 17m
service/web2 NodePort 10.100.246.130 <none> 80:31413/TCP 17m
测试
[root@master ~]# curl 10.101.207.28
test page on jjyy
[root@master ~]# curl 10.100.246.130
test page on 666
[root@master ~]# curl 10.101.200.144
test page on jjyy
[root@master ~]# curl 10.101.200.144
test page on 666
[root@master ~]# curl 10.101.200.144
test page on jjyy
[root@master ~]# curl 10.101.200.144
test page on 666