02kubernetes-POD控制器
POD相关命令
## 1.查看所有的node,所有节点
[root@db01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
db01 Ready master 58m v1.19.3
db02 Ready <none> 54m v1.19.3
db03 Ready <none> 54m v1.19.3
## 2.给node打标签
# 加标签
kubectl label nodes <node名> node-role.kubenetes.io/node=
# 减标签
kubectl label nodes <node名> node-role.kubenetes.io/node-
## 3.查看所有pod,默认是default名称空间
[root@db01 ~]# kubectl get pods
## 4.指定名称空间查看pod
[root@db01 ~]# kubectl -n get pods kube-system
## 5.输出所有详细信息
# 输出所有pod的详细信息
[root@db01 ~]# kubectl -n kube-system get pods -o wide
# 输出所有节点的详细信息
[root@db01 ~]# kubectl -n kube-system get nodes -o wide
# 6.进入容器
[root@db01 ~]# kubectl exec -it pod名 -c 容器名 -- cmd
# 7.查看日志
[root@db01 ~]# kubectl logs -f pod pod名
# 8.查看pod创建过程
[root@db01 ~]# kubectl describe pod pod名
POD沉浸式体验
创建pod两种方式
1.清单,yaml文件
2.命令行
清单
# yml文件
nginx_pod.yaml
apiVersion: v1 ## 版本
kind: Pod ## controller
metadata: ## 元数据
name: nginx-lw ## POD名
labels: ## 标签
app: nginx-v1 ## app: nginx-v1 标签名
spec: ## 容器详细信息
containers: ## 第一个容器
- image: nginx:alpine ## 容器的镜像
imagePullPolicy: IfNotPresent ## 镜像拉取规则,always(默认)
name: nginx ## 容器名字
## 创建容器
kubectl create -f
## 查看帮助
kubectl explain pods
kubectl explain pods.spec
kubectl explain pods.spec.containers
K8S官方:https://kubernetes.io/docs/reference/config-api/apiserver-audit.v1/
黑科技:https://k8s.mybatis.io/v1.19/
命令行
## 2.命令行
[root@db01 ~]# kubectl create deployment nginx-v1 --image=nginx:alpine
# 查看pod创建流程详细信息
[root@db01 ~]# kubectl describe pods nginx-v1-xxx
# 进入pod
[root@db01 ~]# kubectl exec -it nginx-v1-5b6b969d55-wlfg4 /bin/sh
### 未来版本使用
[root@db01 ~]# kubectl exec -it nginx-v1-5b6b969d55-wlfg4 -- /bin/sh
## 容器名字的组成
k8s_nginx_nginx-lw_default_f55bc7be-69e9-4efe-bafc-3d997b075cc3_0
k8s前缀_容器名_POD名_名称空间_随机值_0后缀
标签的设置与使用
# 1.查看node标签
[root@db01 ~]# kubectl get nodes --show-labels
# 2.给node打标签
## 语法:
kubectl label <操作对象nodes|pods> <对应对象名> 标签名=标签值
[root@db01 ~]# kubectl label nodes db02 CPU=Xeon
[root@db01 ~]# kubectl label nodes db03 Disk=Flash
# 3.根据指定标签查找node
参数: -l
[root@db01 ~]# kubectl get nodes --show-labels -l CPU=Xeon
# 4.删除标签
## 语法
kubectl label <操作对象nodes|pods> <对应对象名> 标签名-
[root@db01 ~]# kubectl label nodes db02 CPU-
## 清单中指定node标签
cat > nginx_pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx-v5
labels:
app: nginx-v4
spec:
containers:
- image: nginx:alpine
imagePullPolicy: IfNotPresent
name: nginx-v4
nodeSelector: # node节点
Disk: Flash # 指定Flash标签
EOF
# 1.查看pod标签
[root@db01 ~]# kubectl get pods --show-labels
# 2.给pod打标签
[root@db01 ~]# kubectl label pods nginx-lw test=label
pod/nginx-lw labeled
[root@db01 ~]# kubectl get pods --show-labels
# 3.删除pod标签
[root@db01 ~]# kubectl label pods nginx-lw test-
# 4.查找指定标签的pods
[root@db01 ~]# kubectl get pods --show-labels -l app=nginx-v3
## 在清单中打标签
apiVersion: v1
kind: Pod
metadata:
name: nginx-v5
labels:
app: nginx-v4 # 标签
name: lw # 标签
[root@db01 ~]# kubectl create -f nginx_pod.yaml
pod/nginx-v6 created
# 查看pods标签
[root@db01 ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-v1-5b6b969d55-wlfg4 1/1 Running 0 82m app=nginx-v1,pod-template-hash=5b6b969d55
nginx-v2 1/1 Running 0 9m35s app=nginx-v2
nginx-v3 1/1 Running 0 8m25s app=nginx-v3
nginx-v4 1/1 Running 0 5m50s app=nginx-v4
nginx-v5 1/1 Running 0 5m32s app=nginx-v4
nginx-v6 1/1 Running 0 7s app=nginx-v4,name=lw
nginx-lw 1/1 Running 0 70m app=nginx-v1
# 查看指定标签为app=nginx-v4的pods
[root@db01 ~]# kubectl get pods --show-labels -l app=nginx-v4
NAME READY STATUS RESTARTS AGE LABELS
nginx-v4 1/1 Running 0 6m6s app=nginx-v4
nginx-v5 1/1 Running 0 5m48s app=nginx-v4
nginx-v6 1/1 Running 0 23s app=nginx-v4,name=lw
## 删除pod
[root@db01 ~]# kubectl delete pods nginx-v2
## 根据标签删除
[root@db01 ~]# kubectl delete pods -l app=nginx-v4
## 一个pod启动多个容器
apiVersion: v1
kind: Pod
metadata:
name: nginx-redis01
labels:
app: nginx-redis
spec:
containers:
- image: nginx:alpine
imagePullPolicy: IfNotPresent
name: nginx-web01
- image: redis
imagePullPolicy: IfNotPresent
name: redis-db01
# vim 8-14行复制移动到15行
:8,14t15
重新认识pod
共享网络
POD内的容器使用Container模式共享根容器的网络
容器看到的网络设备信息和根容器完全相同
POD内的多个容器可以使用localhost进行网络通讯
POD内的多个容器不能绑定相同的端口
POD的生命周期和根容器一样,如果根容器退出了,POD就退出了
# 测试一个pod中运行两个容器
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: nginx
spec:
containers:
- image: nginx:alpine
imagePullPolicy: IfNotPresent
name: nginx-web01
ports:
- containerPort: 80
- image: nginx:alpine
imagePullPolicy: IfNotPresent
name: nginx-web02
ports:
- containerPort: 8080 # 只是对外暴露8080端口
# 查看日志
[root@db01 ~]# kubectl logs -f web nginx-web02
## 查看日志
kubectl logs -f nginx nginx2
## 指定node节点
nodeName: node1
## 验证所有机器是否连接根容器
docker inspect
## 进入pod
kubectl exec -it pod名 /bin/bash
kubectl exec -it pod名 -c 容器名 /bin/bash
共享文件
默认情况下一个POD内的容器文件系统是互相隔离的
如果想让一个POD容器共享文件那么只需要定义一个Volume,然后两个容器分别挂载到这个Volume中
即:共享存储
cat > nginx_pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: node2
volumes:
- name: nginxlog
hostPath:
path: /var/log/nginx #容器内部需要挂载的路径
containers:
- name: nginx-1
image: nginx
volumeMounts:
- name: nginxlog
mountPath: /var/log/nginx
- name: tail-log
image: busybox
args: [/bin/sh, -c, 'tail -f /var/log/nginx/access.log']
volumeMounts:
- name: nginxlog
mountPath: /var/log/nginx
EOF
POD的生命周期
POD创建流程
生命周期
init container
初始化容器是指,在主容器启动之前,我们可以让他做一些准备工作。
比如:
1.两个容器做了共享存储,那么我们可以让它先启动一个容器,来对目录进行更改用户和授权
2.容器需要连接数据库,那么可以让初始化容器检测数据库是否可以正常连接,如果可以再启动主容器
hook
PostStart:在容器启动创建后,立即执行,但时间不能太长,否则容器不会是running状态
PreStop:在容器停止前,执行一些命令,主要用于优雅关闭程序
liveness probe
存活探针,用于定义容器内,应用是否满足探针指定状态
readiness probe
就绪探针,指定何时允许容器进入流量
POD对容器的封装和应用
那么我们在工作中,一个pod究竟要放几个容器?
在实际工作中我们除了完成任务以外还需要考虑以后扩容的问题,就拿wordpress举例,有以下两种方案:
第一种:全部放一个pod里
第二种: WordPress和MySQL分开
那么如何扩容呢?如果第一种方案大家会发现没有办法很好的扩容,因为数据库和wordpress已经绑定成一个整体了,扩容wordpress就得扩容mysql。而第二种方案就要灵活的多。
初始化容器
apiVersion: v1
kind: Pod
metadata:
name: nginx-init
spec:
nodeName: node2
volumes:
- name: nginx-index
emptyDir: {} # 临时创建目录挂载
initContainers:
- name: init
image: busybox
imagePullPolicy: IfNotPresent
args: [/bin/sh, -c, 'echo k8s >> /usr/share/nginx/html/index.html']
args:
- /bin/sh
- -c
- 'echo k8s >> /usr/share/nginx/html/index.html'
volumeMounts:
- name: nginx-index
mountPath: "/usr/share/nginx/html"
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- name: nginx-index
mountPath: "/usr/share/nginx/html"
hook
postStart
apiVersion: v1
kind: Pod
metadata:
name: nginx-hook
spec:
nodeName: node2
containers:
- name: nginx
image: nginx:alpine
lifecycle:
postStart:
exec:
command: [/bin/sh, -c, 'echo k8s > /usr/share/nginx/html/index.html']
ports:
- containerPort: 80
preStop
apiVersion: v1
kind: Pod
metadata:
name: nginx-hook
spec:
volumes:
- name: nginxlog
hostPath:
path: /var/log/nginx/
containers:
- name: nginx
image: nginx:alpine
lifecycle:
postStart:
exec:
command: [/bin/sh, -c, 'echo postStart and preStop > /usr/share/nginx/html/index.html']
preStop:
exec:
command: [/bin/sh, -c, 'echo bye > /var/log/nginx/stop.log']
ports:
- containerPort: 80
volumeMounts:
- name: nginxlog
mountPath: /var/log/nginx/
POD健康检查
存活探针
存活探针简单来说就是用来检测容器的应用程序是否还正常工作,如果应用程序不正常,即使容器还活着也没有意义了,所以这时候就可以使用存活探针来探测,如果应用程序不正常,就重启POD。
## 使用exec方法
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
nodeName: node2
volumes:
- name: nginx-html
hostPath:
path: /usr/share/nginx/html/
containers:
- name: liveness
image: nginx
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: [/bin/sh, -c, 'echo k8s > /usr/share/nginx/html/index.html']
livenessProbe:
exec:
command:
- cat
- /usr/share/nginx/html/index.html
initialDelaySeconds: 3
periodSeconds: 1
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html/
## 使用getHttp方法
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
nodeName: node2
volumes:
- name: nginx-html
hostPath:
path: /usr/share/nginx/html/
containers:
- name: liveness
image: nginx
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: [/bin/sh, -c, 'echo k8s > /usr/share/nginx/html/index.html']
livenessProbe:
#exec:
# command:
# - cat
# - /usr/share/nginx/html/index.html
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 3
periodSeconds: 3
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html/
配置解释
livenessProbe:
httpGet: #基于http请求探测
path: /index.html #请求地址,如果这个地址返回的状态码在200-400之间正常
port: 80 #请求的端口
initialDelaySeconds: 3 #第一次启动探测在容器启动后3秒开始
periodSeconds: 3 #容器启动后每隔3秒检查一次
就绪探针
有时候我们Pod本身已经起来了,但是pod的容器还没有完全准备好对外提供服务,那么这时候流量进来就会造成请求失败的情况出现,针对这种情况k8s有一种探针叫就绪探针,他的作用就是让k8s知道你的Pod内应用是否准备好为请求提供服务。只有就绪探针ok了才会把流量转发到pod上。
有时候,应用程序会暂时性的不能提供通信服务。 例如,应用程序在启动时可能需要加载很大的数据或配置文件,或是启动后要依赖等待外部服务。 在这种情况下,既不想杀死应用程序,也不想给它发送请求。 Kubernetes 提供了就绪探测器来发现并缓解这些情况。 容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量。
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
containers:
- name: liveness-pod
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo ok > /usr/share/nginx/html/health.html"]
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 3
periodSeconds: 3
successThreshold: 3
failureThreshold: 3
livenessProbe:
httpGet:
path: /health.html
port: 80
initialDelaySeconds: 3
periodSeconds: 3
配置解释
initialDelaySeconds : 第一次执行探针需要在容器启动后等待的时候时间periodSeconds : 容器启动后每隔多少秒执行一次存活探针
timeoutSeconds: 探针超时时间,黑t认1秒,最小1秒
successThreshold: 探针失败后最少连续探测成功多少次才被认定成功,默认1次,如果是liveness必须为1
failureThreshold: 探针成功后被视为失败的探测的最小连续失败次数。默认3次。最小值为1
POD资源限制
在学习Docker的时候我们知道容器可以使用Linux系统的CGroup技术限制内存和CPU的使用率,那么POD里应该如何限制容器的CPU和内存资源呢?
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: resource-demo
image: nginx
ports:
- containerPort: 80
resources:
requests:
memory: 50Mi
cpu: 1500m
limits:
memory: 100Mi
cpu: 2000m
参数解释:
requests :节点所需的最小计算资源量,k8s调度的时候的依据值
limits :限制允许的最大计算资源量,真正的资源限制参数
数值的转换:
1 CPU = 1000m
0.5 CPU = 500m
1 Mib = 1024 Kib
1 MB = 1000 KB
查看验证:
docker inspect 容器ID|grep CgroupParent
cd /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podxxxx.slice
cat cpu.cfs_quota_us
Comments | NOTHING