4.k8s-存储卷-初始化容器-静态pod
·
Kubernetes存储卷与进阶功能详解
Pod容器数据持久化方案之emptyDir
概念
- emptyDir是一个空目录,用于将容器的数据做临时的存储。
- 应用场景多用于一个Pod内多个容器共享数据的场景。
- 特点就是随着Pod删除,其数据丢失。
资源清单模板:一个pod容器做数据存储
[root@master231 volumes]# cat 01-pods-emptyDir.yaml
apiVersion: v1
kind: Pod
metadata:
name: volumes-emptydir
spec:
nodeName: worker232
# 定义存储卷
volumes:
# 定义存储卷的名称
- name: data
# 指定存储卷类型为emptyDir,本质上是在Pod的数据目录中创建一个临时目录。
# 该目录随着Pod删除(是pod,不是docker进程),目录的数据也会一并删除!
emptyDir: {}
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
# 容器引用Pod定义的存储卷
volumeMounts:
# 引用存储卷的名称
- name: data
# 指定挂载点,如果挂载点之前存在数据则会清空该目录数据。
mountPath: /usr/share/nginx/html
资源清单模板:两个pod做数据共享
- 编写资源清单:挂载到同一个存储卷叫data,假如c1往它挂载的目录下的文件写数据,c2可以看到。
[root@master231 volumes]# cat 02-pods-emptyDir-multiple.yaml
apiVersion: v1
kind: Pod
metadata:
name: volumes-multiple-emptydir
spec:
nodeName: worker232
volumes:
- name: data
emptyDir: {}
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
volumeMounts:
- name: data
mountPath: /oldboyedu
- name: c2
image: harbor250.oldboyedu.com/oldboyedu-elasticstack/filebeat:7.17.25
volumeMounts:
- name: data
mountPath: /linux99/xixi
测试
测试1:删除docker业务容器c1,发现重新启动后数据也在。删除pod后,数据丢失。
# 验证:查看数据存储的实际路径
ll /var/lib/kubelet/pods/dd8856e4-fee3-463f-a6da-56320d7f7f0b/volumes/kubernetes.io~empty-dir/
# 本质上数据存储在该目录下。
测试2:在c1写入数据,c2对应的挂载目录可以看到。
[root@master231 volumes]# kubectl exec -it volumes-multiple-emptydir -c c1 -- sh
for i in `seq 1000`;do sleep 0.5;echo $i >> /oldboyedu/haha.log;done &
测试3:c2采集c1的数据。
filebeat@volumes-multiple-emptydir:~$ cat > /tmp/test.conf <<EOF
filebeat.inputs:
- type: filestream
paths:
- /linux99/xixi/haha.log
output.console:
pretty: true
EOF
Pod容器数据持久化方案之hostPath
概念
hostPath主要作用就是让Pod的容器访问worker节点宿主机的某个特定路径。删除pod后数据目录依旧存在。
资源清单
# 在worker节点上创建目录和文件
[root@worker233 ~]# mkdir /data
[root@worker233 ~]# echo www.oldboyedu.com > /data/index.html
[root@worker233 ~]# ls -l /data/
# 资源清单:此时 /usr/share/nginx/html 和 /data/ 里的数据一致
[root@master231 volumes]# cat 05-pods-hostPath.yaml
apiVersion: v1
kind: Pod
metadata:
name: volumes-hostpath
spec:
nodeName: worker233
volumes:
- name: data
# 指定存储卷的类型是hostPath,并指定worker宿主机的路径
hostPath:
path: /data
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
测试
修改容器的数据:
[root@master231 volumes]# kubectl exec -it volumes-hostpath -- sh
/ # echo linux99 > /usr/share/nginx/html/index.html
/ #
[root@master231 volumes]# curl 10.100.2.86
linux99
验证worker宿主机的数据是否变化:发生了变化,因为指向同一个数据。
[root@worker233 ~]# cat /data/index.html
linux99
存储卷之DownwardAPI实战
概念
DownwardAPI只是一种将Pod的metadata、spec或status中的字段值注入到其内部Container里的方式。
资源清单模板
功能:注入两个环境变量进容器,在启动业务容器之前就可以进行注入。
[root@master231 volumes]# cat 03-pods-downwardAPI-env.yaml # 这个案例记住
apiVersion: v1
kind: Pod
metadata:
name: volumes-downwardapi-env
spec:
nodeName: worker232
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
env:
- name: oldboyedu-PODNAME
# 值表示从一个地方引用
valueFrom:
# 基于字段引用
fieldRef:
# 指的字段的路径
fieldPath: metadata.name
- name: oldboyedu-IP
valueFrom:
fieldRef:
fieldPath: status.podIP
测试
进入容器查看环境变量是否存在:
[root@master231 volumes]# kubectl exec -it volumes-downwardapi-env -- env | grep oldboyedu
oldboyedu-PODNAME=volumes-downwardapi-env
oldboyedu-IP=10.100.1.29
初始化容器实战
概念
- 什么是初始化容器:先有基础架构容器,然后跑初始化容器,最后有业务容器。
- 所谓的初始化容器就是为Pod提供初始化的相关操作,在基础架构容器启动后先执行所有的初始化容器。
- 当所有的初始化容器执行完成后,才能执行业务容器。因此,初始化容器可以定义多个。
资源清单主要是格式
[root@master231 pods]# cat 12-pods-initContainers.yaml
apiVersion: v1
kind: Pod
metadata:
name: initcontainers-casedemo
spec:
# 初始化容器定义
initContainers:
- name: i1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
command:
- sleep
- "10"
- name: i2
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
command:
- sleep
- "30"
# 业务容器定义
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
测试:查看节点的启动顺序
# 2.3 查看worker节点的容器创建顺序
[root@worker233 ~]# docker ps -a | grep initcontainers-casedemo
95c2d9178ebe d65adc8a2f32 "sleep 30" 14 seconds ago Up 13 seconds k8s_i2_initcontainers-casedemo_default_82e809a0-d078-4f6b-9e7d-cb0b13e2d067_0
22085e7c4d7a d65adc8a2f32 "sleep 10" 25 seconds ago Exited (0) 14 seconds ago k8s_i1_initcontainers-casedemo_default_82e809a0-d078-4f6b-9e7d-cb0b13e2d067_0
63dbd311539a registry.aliyuncs.com/google_containers/pause:3.6 "/pause" 25 seconds ago Up 24 seconds k8s_POD_initcontainers-casedemo_default_82e809a0-d078-4f6b-9e7d-cb0b13e2d067_0
[root@worker233 ~]# docker ps -a | grep initcontainers-casedemo
6c5d74ba481b d65adc8a2f32 "/docker-entrypoint.…" 8 seconds ago Up 7 seconds (业务容器) k8s_c1_initcontainers-casedemo_default_82e809a0-d078-4f6b-9e7d-cb0b13e2d067_0
95c2d9178ebe d65adc8a2f32 "sleep 30" 38 seconds ago Exited (0) 7 seconds ago k8s_i2_initcontainers-casedemo_default_82e809a0-d078-4f6b-9e7d-cb0b13e2d067_0
22085e7c4d7a d65adc8a2f32 "sleep 10" 49 seconds ago Exited (0) 38 seconds ago (初始化容器) k8s_i1_initcontainers-casedemo_default_82e809a0-d078-4f6b-9e7d-cb0b13e2d067_0
63dbd311539a registry.aliyuncs.com/google_containers/pause:3.6 "/pause" 49 seconds ago Up 48 seconds (基础架构容器) k8s_POD_initcontainers-casedemo_default_82e809a0-d078-4f6b-9e7d-cb0b13e2d067_0
综合案例:rc, downwardApi, emptyDir, svc
需求
初始化nginx的站点首页,要求如下:
-
- 使用rc控制器创建3个副本的Pod;
-
- 首页文件(“index.html”)返回获取各个Pod的IP地址,Pod的名称;
-
- 使用Service暴露服务,并基于Service访问测试;
编写资源清单
[root@master231 case-demo]# cat 01-rc-svc-downwardAPI-volume-initContainers.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: rc-xiuxian
spec:
replicas: 3
selector:
version: v1
# 定义副本的模板
template:
metadata:
labels:
app: xiuxian
version: v1
# 定义存储卷,连接了data的目录都可以实现数据的共享
spec:
volumes:
- name: data
emptyDir: {}
# 初始化容器的时候注入一些环境变量,并将它挂载到对应的/data目录
initContainers:
- name: i1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
volumeMounts:
- name: data
mountPath: /data
# 环境变量
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
# 命令执行,在启动业务容器之前就把两个环境变量注入到文件data目录下的文件中
command:
- /bin/sh
- -c
- echo "${POD_NAME}, ${POD_IP}" > /data/index.html
# 启动业务容器,共享目录连接存储卷/data,该文件可以查看到环境变量
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
---
# 进行service,实现服务发现,负载,和外部进行访问的作用。即使pod重启clusterIP进行变化,依旧可以访问service的IP查看
apiVersion: v1
kind: Service
metadata:
name: svc-xiuxian-nodeport
spec:
type: NodePort
selector:
app: xiuxian
ports:
- port: 80
targetPort: web
nodePort: 30081
测试
[root@master231 case-demo]# kubectl get rc,svc,po -o wide
[root@master231 case-demo]# for i in `seq 10`; do curl 10.0.0.233:30081;done
rc-xiuxian-mj9hf, 10.100.1.40
rc-xiuxian-2qwm8, 10.100.2.78
rc-xiuxian-mj9hf, 10.100.1.40
rc-xiuxian-hmftr, 10.100.2.77
rc-xiuxian-2qwm8, 10.100.2.78
rc-xiuxian-hmftr, 10.100.2.77
rc-xiuxian-2qwm8, 10.100.2.78
rc-xiuxian-hmftr, 10.100.2.77
rc-xiuxian-mj9hf, 10.100.1.40
rc-xiuxian-2qwm8, 10.100.2.78
名称空间
概念
说白了,就是用来隔离K8S集群资源的。但并不是所有的资源都支持名称空间进行隔离,不支持名称空间的资源我们称之为全局资源,支持名称空间的资源称之为局部资源。
命令行操作
# 查看现有的名称空间
kubectl get ns
# 或者
kubectl get ns -o wide
# 创建名称空间
kubectl create ns xixi
# 查看名称空间的标签
kubectl get ns --show-labels
# 删除名称空间
kubectl delete ns xixi
# 查看指定名称空间的资源
kubectl get po -o wide --namespace kube-system
# 或者直接
kubectl get po -o wide -n kube-system
在指定的名称空间下创建pod
[root@master231 namespace]# cat 01-pods-ns.yaml
apiVersion: v1
kind: Pod
metadata:
name: xixi
# 指定资源的名称空间,若不指定,则默认为default
namespace: kube-public
spec:
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v2
# 查看指定名称空间的pod
kubectl get pods -n kube-public -o wide
删除名称空间
kubectl delete ns oldboyedu # 删除名称空间,它下面的pod都被删除
全局资源在任意名称空间查看的结果都相同
kubectl get nodes = kubectl get nodes -n kube-system
查看所有名称空间的资源
kubectl get po -A
kubectl get svc -A
kuboard管理k8s集群实战(见笔记)
2. 下载镜像
[root@harbor250 ~]# wget http://192.168.16.253/Resources/Kubernetes/Project/kuboard/kuboard-on-docker/oldboyedu-kuboard-v3.tar.gz
[root@harbor250 ~]# docker load -i oldboyedu-kuboard-v3.tar.gz
3. 安装kuboard
[root@harbor250 ~]# docker run -d \
--restart=unless-stopped \
--privileged \
--name=kuboard \
-p 90:80/tcp \
-p 10081:10081/tcp \
-e KUBOARD_ENDPOINT="http://10.0.0.250:90" \
-e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
-v /root/kuboard-data:/data \
swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard:v3
4. 访问Kuboard
http://10.0.0.250:90/
5. 登录
- 用户名:admin
- 密 码:Kuboard123
6. 添加K8S集群并且创建工作负载




静态pod技术
概念
所谓的静态Pod指的是kubelet组件无需经过API-server发号指令,而自发监控一个本地的宿主机路径下的资源清单。该路径下的所有Pod类型的资源清单都会自动被识别,并创建相应的Pod。创建的Pod名称后会自动加一个"-${NODENAME}“,例如:”-master231",“-worker233”。
测试
其他worker节点使用静态Pod技术:将资源清单移动到别的节点静态pod目录下,那么会直接运行该资源清单。
[root@master231 pods]# scp 01-pods-single-xiuxian.yaml 10.0.0.232:/etc/kubernetes/manifests
[root@master231 pods]# scp 01-pods-single-xiuxian.yaml 10.0.0.233:/etc/kubernetes/manifests
[root@master231 pods]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
xixi-worker232 1/1 Running 0 1s 10.100.1.44 worker232 <none> <none>
xixi-worker233 1/1 Running 0 21s 10.100.2.85 worker233 <none> <none>
只能将目录删除或者移走才能删除静态pod,无法手动删除。
为什么注入环境变量要在初始化容器的时候完成,而不在启动业务容器的时候完成?
初始化容器的价值在于"前置准备,扫清障碍",确保业务容器启动时就能"开箱即用"。
如果将环境变量注入放到业务容器启动后,会引入竞态条件和服务不可用的风险,违背K8s容器设计的最佳实践。
更多推荐


所有评论(0)