Label k8s中的资源都可以添加属性标签,识别当前资源。
Selector k8s中标签选择器,可以使用Select根据label查找资源
Service k8s中访问pod一种策略
Ingress k8s中使用域名访问pod的策略
ConfigMap
Secret
Volume
https://kubernetes.io/zh-cn/docs/concepts/configuration/configmap/
ConfigMap :
ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时, Pod 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。
一般用 ConfigMap 去管理一些配置文件、或者一些大量的环境变量信息。用来将非机密性的数据保存到键值对中。 ConhaMap将配置和Pod分开。 更易于配置文件的更改和管理。
如果把nginx和配置文件都放到容器中,不方便修改,把 ngins和nginx.conf分开,把nginx.config-> configmap.nginx 中,nginx运行时加载配置。
Secret :
和configMap作用一样,不过它更倾向于存储和共享敏感、加密的配置信息。
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-pod-configmap/
mkdir k8s-configmap 在主目录下创建 后面复制官网
cd k8s-configmap/
mkdir -p configure-pod-container/configmap/
ls configure-pod-container/configmap/
wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties--no-check-certificate
wget 下载器 -O 保存到哪个位置
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties--no-check-certificate
ls configure-pod-container/configmap/
cat configure-pod-container/configmap/game.properties
cat configure-pod-container/configmap/ui.properties
--no-check-certificate 解决证书过期错误
如果下载不了,重复操作
创建 ConfigMap
kubectl create configmap game-config --from-file=configure-pod-container/configmap/
以上命令将 configure-pod-container/configmap 目录下的所有文件,也就是 game.properties 和 ui.properties 打包到 game-config ConfigMap 中。
kubectl describe configmaps game-config 查看详情
查看:
kubectl get configmap
查看详情:
kubectl get configmaps game-config -o yaml
企业使用最多的
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties
查看:
kubectl get configmap
查看详情:
kubectl get configmap game-config-2 -o yaml
kubectl describe configmaps game-config-2
创建(也可以修改名字):
kubectl create configmap game-config-3 --from-file=game3=configure-pod-container/configmap/game.properties
kubectl get configmap game-config-3 -o yaml
kubectl describe configmaps game-config-3
使用 --from-env-file
选项基于 env 文件创建 ConfigMap
vim configure-pod-container/configmap/game-env-file.properties
复制官网内容:
enemies=aliens
lives=3
allowed="true"
创建:
kubectl create configmap game-config-env-file \
--from-env-file=configure-pod-container/configmap/game-env-file.properties
查看:
kubectl get configmap
查看详情:
kubectl get configmap game-config-env-file -o yaml
和基于文件创建,少了一个名称
不常用
创建:
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm --from-literal=special.aaa=111
literal 字面 --from-literal 可以添加多个字面值
查看:
kubectl get configmap
查看详情:
kubectl get configmaps special-config -o yam
kubectl get configmap
kubectl delete configmap special-config
kubectl get configmap
上面已经创建过(不用再执行):
kubectl create configmap special-config --from-literal=special.how=very
创建pod:
vim pod-single-configmap-env-variable.yaml
apiVersion: v1 # 这一行指定了 Kubernetes API 的版本,确保 YAML 文件与 Kubernetes 集群的版本兼容。
kind: Pod # 这一行声明了这是一个 Pod 类型的资源。
metadata: # 这一部分包含了 Pod 的元数据。
name: cm-test-pod # 这一行指定了 Pod 的名称,是唯一的标识符。
spec: # 这一部分是 Pod 的规格说明,定义了 Pod 的具体配置。
containers: # 这一部分定义了 Pod 中要运行的容器列表。
- name: test-container # 这一行指定了容器的名称。
image: busybox:1.28 # 这一行指定了容器使用的镜像及其版本。
command: [ "/bin/sh", "-c", "env" ] # 这一行定义了容器启动时执行的命令,这里是列出所有环境变量。
env: # 这一部分定义了要注入容器的环境变量列表。
- name: SPECIAL_LEVEL_KEY # 这一行指定了环境变量的名称。
valueFrom: # 这一行表示环境变量的值将从其他地方动态获取。
configMapKeyRef: # 这一行指定了值来源于 ConfigMap 中的某个键。
name: special-config # 这一行指定了 ConfigMap 的名称。
key: special.how # 这一行指定了 ConfigMap 中与取值相关的键名,即环境变量 SPECIAL_LEVEL_KEY 的值将从 special-config ConfigMap 的 special.how 键中获取。
restartPolicy: Never # 这一行指定了 Pod 的重启策略。Never 表示 Pod 一旦终止,就不会被自动重启。
创建:
kubectl create -f pod-single-configmap-env-variable.yaml
查看(已经执行完毕):
kubectl get pod
查看日志:
kubectl logs cm-test-pod
kubectl logs -f cm-test-pod
发现打印了外面的configmap中定义的变量
删除原来一个值的ConfigMap
kubectl delete configmap special-config
创建多个值:
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.aaa=111 --from-literal=special.bbb=222 --from-literal=special.ccc=333
编辑:
vim pod-configmap-multikeys.yaml
apiVersion: v1 # 指定 Kubernetes API 的版本
kind: Pod # 定义资源的类型为 Pod
metadata:
name: multi-key-test-pod # Pod 的名称
spec:
containers: # 定义 Pod 中要运行的容器列表
- name: test-container # 容器的名称
image: busybox:1.28 # 容器使用的镜像及其版本
command: [ "/bin/sh", "-c", "env" ] # 容器启动后执行的命令,这里是列出所有环境变量
envFrom: # 从 ConfigMap 或 Secret 中添加环境变量
- configMapRef: # 指定从 ConfigMap 中获取环境变量
name: special-config # ConfigMap 的名称,其键值对将被转换为环境变量
restartPolicy: Never # Pod 的重启策略,Never 表示 Pod 终止后不会自动重启
kubectl create -f pod-configmap-multikeys.yaml
kubectl logs pod-configmap-multikeys.yaml
查看所有CM:
kubectl get cm
查看详情:
kubectl describe cm special-config
查看详情:
kubectl describe cm game-config-2
编辑:
vim pod-configmap-volume.yaml
apiVersion: v1 # 指定 Kubernetes API 的版本
kind: Pod # 定义资源的类型为 Pod
metadata:
name: volume-test-pod # Pod 的名称
spec:
containers: # 定义 Pod 中要运行的容器列表
- name: test-container # 容器的名称
image: busybox:1.28 # 容器使用的镜像及其版本
command: [ "/bin/sh", "-c", "sleep 3600" ] # 容器启动后执行的命令,这里是让容器休眠3600秒
volumeMounts: # 定义容器内部挂载点列表
- name: config-volume # 引用下面定义的 volumes 中的 config-volume
mountPath: /mnt/dir1 # 容器内挂载点的路径
- name: config-volume-a # 引用下面定义的 volumes 中的 config-volume-a
mountPath: /mnt/dir2 # 容器内另一个挂载点的路径
volumes: # 定义 Pod 中的卷列表
- name: config-volume # 卷的名称
configMap: # 指定这是一个 ConfigMap 卷
name: special-config # ConfigMap 的名称,其内容将被挂载到 /mnt/dir1
- name: config-volume-a # 另一个卷的名称
configMap: # 指定这也是一个 ConfigMap 卷
name: game-config-2 # ConfigMap 的名称,其内容将被挂载到 /mnt/dir2
restartPolicy: Never # Pod 的重启策略,Never 表示 Pod 终止后不会自动重启
创建:
kubectl create -f pod-configmap-volume.yaml
查看:
kubectl get pod
登录容器
kubectl exec -it pod-cm-volume-test -- sh
https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-kubectl/
企业常用
创建目录把例子放一起:
mkdir k8s-secret
cd k8s-secret/
将凭据保存到文件:
echo -n 'admin' > username.txt
echo -n 'tiger' > password.txt
使用命令中传递文件路径创建:
kubectl create secret generic db-user-pass \
--from-file=./username.txt \
--from-file=./password.txt
查看:
kubectl get secret
删除:
kubectl delete secret db-user-pass
你也可以通过 --from-file=[key=]source 设置键名,例如:
kubectl create secret generic db-user-pass \
--from-file=username=./username.txt \
--from-file=password=./password.txt
通常三种创建方式:
kubectl create secret generic:创建通用的 Secret 对象。
kubectl create secret docker-registry:创建用于 Docker 镜像仓库认证的 Secret 对象。
kubectl create secret tls:创建用于存储 TLS 证书和私钥的 Secret 对象。
查看:
kubectl get secrets
查看详情:
kubectl describe secret db-user-pass
查看你所创建的 Secret 内容
kubectl get secret db-user-pass -o jsonpath='{.data}'
经过base64 编码的字符串的字符串
-o=output 输出
jsonpath 是一个输出格式选项,它指定了 kubectl 应该如何从 JSON 格式的响应中提取并输出特定的数据。
.data 字段会以 JSON 数组的形式返回所有的键值对,但是每个值都是 base64 编码的。如果你想要查看解码后的值,你需要对每个值进行 base64 解码。
解码 username和password 数据
echo 'dGlnZXI=' |base64 --decode
echo 'YWRtaW4=' |base64 --decode
编辑 Secret
kubectl edit secret db-user-pass
能编辑的内容就可以直接编辑
删除:
kubectl delete secret db-user-pass
echo -n 'root' | base64
echo -n '123456' | base64
编写文件:
vim secret-data.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret-1
type: Opaque #不透明的,隐蔽的
data:
username: cm9vdA==
password: MTIzNDU2
创建:
kubectl create -f secret-data.yaml
查看:
kubectl get secret
查看详情:
kubectl get secret mysecret-1 -o yaml
解码看原始值:
echo 'MTIzNDU2'|base64 --decode
参考官网
vim string-data-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret-1
type: Opaque
stringData:
config.yaml: |
apiUrl: "https://my.api.com/api/v1"
username: root
password: tiger
创建:
kubectl create -f string-data-secret.yaml
查看:
kubectl get secret
查看详情:
kubectl get secret mysecret-2 -o yaml
解码查看:
echo 'YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHJvb3QKcGFzc3dvcmQ6IHRpZ2VyCg==' |base64 --decode
参考官网
base64编码生成用户名:
echo -n 'admin'|base64
vim data-string-and-data-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
stringData:
username: administrator
kubectl create -f data-string-and-data-secret.yaml
查看:
kubectl get secret
查看详情:
kubectl get secret mysecret-3 -o yaml
解码:
echo 'YWRtaW5pc3RyYXRvcg==' |base64 --decode
如果你在 data 和 stringData 中设置了同一个字段username,则使用来自 stringData 中的值。
参考官网
https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-kustomize/
cd /root/k8s-secret/
mkdir ktn
vim ktn/kustomization.yaml
secretGenerator:
- name: database-creds
literals:
- username=admin
- password=tiger
创建:
kubectl apply -k /root/k8s-secret/ktn/
查看详情:
kubectl get -k /root/k8s-secret/ktn/ -o jsonpath='{.data}'
解码:
echo 'dGlnZXI='|base64 --decode
echo 'YWRtaW4='|base64 --decode
修改:
vim ktn/kustomization.yaml
把用户名或者密码修改
kubectl apply -k /root/k8s-secret/ktn/
kubectl get -k /root/k8s-secret/ktn/ -o jsonpath='{.data}'
删除:
kubectl get secret
查看和创建时名称一致的secret: database-creds
根据名称删除
kubectl delete secret database-creds-cd6d9492c7
https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/distribute-credentials-secure/
创建secret:
kubectl create secret generic test-secret --from-literal='username=admin' --from-literal='password=tiger'
查看:
kubectl get secret
创建pod使用secret:
vim secret-pod.yaml
复制格式错乱:使用:set paste
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx:1.18.0
volumeMounts:
# name 必须与下面的卷名匹配
- name: secret-volume
mountPath: /etc/secret-volume
readOnly: true
# Secret 数据通过一个卷暴露给该 Pod 中的容器
volumes:
- name: secret-volume
secret:
secretName: test-secret
创建:
kubectl apply -f secret-pod.yaml
查看:
kubectl get pod
登录:
kubectl exec -i -t secret-test-pod -- /bin/bash
查看挂载点:
ls /etc/secret-volum
查看内容:
echo "$( cat /etc/secret-volume/username )"
echo "$( cat /etc/secret-volume/password )"
映射 Secret 键到特定文件路径:
创建secret:
kubectl create secret generic mysecret --from-literal='username=admin' --from-literal='password=tiger' --from-literal='aaa=111'
查看:
kubectl get secret
查看详情:
kubectl describe secret mysecret
编辑pod:
vim secret-pod-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis:5.0.5
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
注意:redis的image修改secretName: mysecret- key: username
创建pod:
kubectl apply -f secret-pod-1.yaml
查看pod:
kubectl get pod
redis:5.0.5 第一拉去
登录:
kubectl exec -i -t mypod -- /bin/bash
查看挂载点:
cat /etc/foo/my-group/my-username
注意:来自 mysecret 的键 username 可以在路径 /etc/foo/my-group/my-username 下供容器使用,而不是路径 /etc/foo/username
ConfigMap和Secret挂载时,会覆盖目录中其他文件,如果覆盖就会引起容器出问题。使用SubPath解决这个问题。
查看deploy
kubectl get deploy
如果存在删除(查询后如果存在deploy,根据实际查询结果删除):
kubectl delete deploy nginx-deloy
再次创建
mkdir k8s-cm-st-subpath
cd k8s-cm-st-subpath/
cp ../k8s-deploy/deploy-2.yaml .
kubectl create -f deploy-2.yaml
查看pod:
kubectl get pod
查看nginx配置文件:
根据上面查询pod的结果,执行下面命令
kubectl exec -it 查看到的pod名称 -- cat /etc/nginx/nginx.conf
kubectl exec -it nginx-744d557cd6-7ktzn -- cat /etc/nginx/nginx.conf
导出nginx配置文件
kubectl exec -it 查看到的pod名称 -- cat /etc/nginx/nginx.conf>nginx.conf
kubectl exec -it nginx-744d557cd6-7ktzn -- cat /etc/nginx/nginx.conf>nginx.conf
查看容器nginx目录下的文件:
kubectl exec -it 查看到的pod名称 -- ls /etc/nginx
kubectl exec -it nginx-744d557cd6-7ktzn -- ls /etc/nginx
通过文件创建CM(常用):
kubectl create configmap cm-nginx --from-file=nginx.conf
或者
kubectl create cm cm-nginx --from-file=nginx.conf
查看使用已知的配置创建出的ConfigMap:
kubectl get cm
编辑pod,挂载cm:
kubectl edit deploy nginx-deploy
40 command: ["sh","-c","sleep 3600"]
44 volumeMounts:
- mountPath: /etc/nginx
name: config-volume
52 volumes:
- configMap:
name: cm-nginx
name: config-volume
再次查看pod(发现pod名字都不一样了)
kubectl get pod
根据现在pod的名称再次查看所有配置:
kubectl exec -it 查看到的pod名称 -- ls /etc/nginx
发现配置文件不存在了
再次修改配置:
kubectl edit deploy nginx
terminationMessagePath: "/dev/termination-log" # 容器终止时消息的写入路径
terminationMessagePolicy: "File" # 终止消息的策略,通常是"File"或"FallbackToLogsOnError"
volumeMounts: # 挂载的卷列表
- mountPath: "/etc/nginx/nginx.conf" # 挂载的路径
subPath: "etc/nginx/nginx.conf" # 从ConfigMap中选取的特定文件路径
name: nginx-config # 挂载的卷的名称,和volumes中的name对应
dnsPolicy: "ClusterFirst" # DNS策略
restartPolicy: "Always" # 重启策略
schedulerName: "default-scheduler" # 调度器名称
securityContext: {} # 安全上下文,此处为空
terminationGracePeriodSeconds: 30 # 终止前的宽限时间(秒)
volumes: # 定义的卷列表
- configMap: # 类型为ConfigMap的卷
name: cm-config # ConfigMap的名称
defaultMode: 420 # 文件的默认权限
items: # 从ConfigMap中选取的文件列表
- key: nginx.conf # ConfigMap中的键
path: etc/nginx/nginx.conf # 挂载到容器中的路径(注意,这里的路径需要是相对于mountPath的)
name: nginx-config # 挂载的卷的名称
kubectl get pod
kubectl exec -it 查看到的pod名称 -- ls /etc/nginx
kubectl exec -it nginx-77db94fd56-2rfmv -- ls /etc/nginx
发现配置文件都存在
3.1.5 ConfigMap或者Secret动态更新配置
kubectl edit deploy nginx
cm或者secret一旦发生变化,引用cm或者secret的容器的配置也会跟着变化。
修改deploy 添加volume,让nginx.conf再挂载一份
多次执行,可以看到pod在新建
kubectl get pod -owide
等pod重新运行后
修改ConfigMap:
kubectl edit cm cm-nginx
先查看pod
kubectl get pod
查看pod配置时,pod名字是动态的(大家自己根据自己的pod运行下面命令)
kubectl exec -it nginx-deploy-7c747c84b5-2p42v -- cat /etc/nginx/nginx.conf
发现没有修改
kubectl exec -it nginx-deploy-7c747c84b5-2p42v -- cat /mnt/nginx.conf
发现修改了
ConfigMap和 Secret 如果是以 subPath 的形式挂的,那么 Pod 是不会感知到 ConfigMap.和 Secret 的更新的。
如果 Pod 的变量来自于 ConfigMap和 Secret中固定的内容,那么 ConfigMap和 Secret 更新后,也不会更新 Pod 中的变量。
volumes
Container(容器)中的磁盘文件是短暂的,当容器崩溃时,kubelet会重新启动容器,但最初的文件将丢失,Container会以最干净的状态启动。另外,当一个Pod运行多个Container时,各个容器可能需要共享一些文件。Kubernetes Volume可以解决这两个问题。
一些需要持久化数据的程序才会用到Volumes,或者一些需要共享数据的容器需要volumes。Redis-Cluster:redis.conf
日志收集的需求:需要在应用程序的容器里面加一个sidecar,这个容器是一个收集日志的容器,比如filebeat,它通过volumes共享应用程序的日志文件目录。
Volumes:官方文档https://kubernetes.io/docs/concepts/storage/volumes/
Docker也有卷的概念,但是在Docker中卷只是磁盘上或另一个Container中的目录,其生命周期不受管理。虽然目前Docker已经提供了卷驱动程序,但是功能非常有限,例如从Docker 1.7版本开始,每个Container只允许一个卷驱动程序,并且无法将参数传递给卷。
另一方面,Kubernetes卷具有明确的生命周期,与使用它的Pod相同。因此,在Kubernetes中的卷可以比Pod中运行的任何Container都长,并且可以在Container重启或者销毁之后保留数据。Kubernetes支持多种类型的卷,Pod可以同时使用任意数量的卷。
从本质上讲,卷只是一个目录,可能包含一些数据,Pod中的容器可以访问它。要使用卷Pod需要通过spec.volumes字段指定为Pod提供的卷,以及使用spec.containers.volumeMounts 字段指定卷挂载的目录。从容器中的进程可以看到由Docker镜像和卷组成的文件系统视图,卷无法挂载其他卷或具有到其他卷的硬链接,Pod中的每个Container必须独立指定每个卷的挂载位置。
和上述volume不同的是,如果删除Pod,emptyDir卷中的数据也将被删除,一般emptyDir卷用于Pod中的不同Container共享数据。它可以被挂载到相同或不同的路径上。
默认情况下,emptyDir卷支持节点上的任何介质,可能是SSD(固态硬盘)、磁盘或网络存储,具体取决于自身的环境。可以将emptyDir.medium字段设置为Memory,让Kubernetes使用tmpfs(内存支持的文件系统),虽然tmpfs非常快,但是tmpfs在节点重启时,数据同样会被清除,并且设置的大小会被计入到Container的内存限制当中。
使用emptyDir卷的示例,直接指定emptyDir为{}即可:
mkdir k8s-volumes
cd k8s-volumes/
vim empty-dir.yaml
:set paste
# 定义Deployment的API版本和类型
apiVersion: apps/v1
kind: Deployment
# Deployment的元数据
metadata:
annotations:
deployment.kubernetes.io/revision: "1" # Deployment的修订版本
creationTimestamp: "2024-01-04T15:27:07Z" # 创建时间戳
generation: 1 # 生成的版本
labels:
app: nginx-1 # Deployment的标签
name: nginx-1 # Deployment的名称
# Deployment的规格说明
spec:
progressDeadlineSeconds: 600 # 进度死线秒数,用于等待Deployment的进度
replicas: 2 # Pod的副本数量
revisionHistoryLimit: 10 # 保留的历史版本数量
# 选择器,用于匹配Pod的标签
selector:
matchLabels:
app: nginx # 注意:这里应该与Pod模板中的标签一致,但示例中可能是一个错误
# 更新策略
strategy:
rollingUpdate:
maxSurge: 25% # 滚动更新时最大额外副本数
maxUnavailable: 25% # 滚动更新时最大不可用副本数
type: RollingUpdate # 更新类型,这里是滚动更新
# Pod模板
template:
metadata:
creationTimestamp: null # Pod的创建时间戳,这里为null,因为Pod还未创建
labels:
app: nginx # Pod的标签
spec:
containers:
# 第一个容器
- image: nginx:1.18.0 # 容器镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略
name: nginx1 # 容器名称
resources: {} # 资源限制和请求,此处为空
terminationMessagePath: /dev/termination-log # 终止消息的路径
terminationMessagePolicy: File # 终止消息的策略
volumeMounts: # 挂载的卷
- mountPath: /opt # 容器内的挂载路径
name: share-volume # 卷的名称
# 第二个容器
- image: nginx:1.18.0 # 容器镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略
name: nginx2 # 容器名称
command: # 容器启动命令
- sh
- -c
- sleep 3600 # 执行sleep命令,持续3600秒
resources: {} # 资源限制和请求,此处为空
terminationMessagePath: /dev/termination-log # 终止消息的路径
terminationMessagePolicy: File # 终止消息的策略
volumeMounts: # 挂载的卷
- mountPath: /mnt # 容器内的挂载路径
name: share-volume # 卷的名称
dnsPolicy: ClusterFirst # DNS策略
restartPolicy: Always # 重启策略
schedulerName: default-scheduler # 调度器名称
securityContext: {} # 安全上下文
terminationGracePeriodSeconds: 30 # 优雅终止的宽限期秒数
volumes:
- name: share-volume # 卷的名称
emptyDir: {} # 使用emptyDir卷
创建:
kubectl create -f empty-dir.yaml
查看deploy:
kubectl get deploy
查看pod:
kubectl get pod
登录不同容器(根据查看的结果):
kubectl exec -it nginx-3-7c4886fc69-72n4b -c nginx1 -- bash
在/opt下进行操作:
touch /opt/a.log
touch /opt/b.log
exit
kubectl exec -it nginx-3-7c4886fc69-72n4b -c nginx2 -- bash
查看/mnt目录:
ls /mnt
touch /mnt/c.log
exit
kubectl exec -it nginx-1-7c4886fc69-v9wjx -c nginx1 -- bash
ls /opt/
opt和mnt互通
emptyDir没有持久化,pod退出,数据就没了!
不推荐使用
hostPath卷可将节点上的文件或目录挂载到Pod上,用于Pod自定义日志输出或访问Docker内部的容器等。
使用hostPath卷的示例。将主机的/etc/hostname文件挂载到Pod的/etc/hostname文件:
vim hostpath-1.yaml
:set paste
# 定义Deployment的API版本和类型
apiVersion: apps/v1
kind: Deployment
# Deployment的元数据
metadata:
# Deployment的注解,记录了Deployment的修订版本
annotations:
deployment.kubernetes.io/revision: "1"
# Deployment的创建时间戳
creationTimestamp: "2024-01-04T15:27:07Z"
# 元数据的生成版本
generation: 1
# Deployment的标签
labels:
app: nginx-host-path # 通常建议与Deployment名称一致,但这里使用了nginx-host-path
# Deployment的名称
name: nginx-host-path
# Deployment的规格说明
spec:
# 进度死线秒数,用于等待Deployment的进度
progressDeadlineSeconds: 600
# Pod的副本数量
replicas: 2
# 保留的历史版本数量
revisionHistoryLimit: 10
# 选择器,用于匹配Pod的标签
selector:
matchLabels:
app: nginx # 这里应该与Pod模板中的标签一致,但示例中不一致,可能是个错误
# 更新策略
strategy:
rollingUpdate:
# 滚动更新时最大额外副本数
maxSurge: 25%
# 滚动更新时最大不可用副本数
maxUnavailable: 25%
# 更新类型,这里是滚动更新
type: RollingUpdate
# Pod模板
template:
metadata:
# Pod的创建时间戳,这里为null,因为Pod还未创建
creationTimestamp: null
# Pod的标签
labels:
app: nginx # Pod的标签,应该与selector中的matchLabels一致
spec:
# Pod中的容器列表
containers:
- # 第一个容器
image: nginx:1.18.0 # 容器镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略
name: nginx # 容器名称
resources: {} # 资源限制和请求,此处为空
terminationMessagePath: /dev/termination-log # 终止消息的路径
terminationMessagePolicy: File # 终止消息的策略
# 容器内的卷挂载点
volumeMounts:
- mountPath: /etc/hostname # 容器内的挂载路径
name: hostname # 挂载的卷名称
# DNS策略
dnsPolicy: ClusterFirst
# 重启策略
restartPolicy: Always
# 调度器名称
schedulerName: default-scheduler
# 安全上下文
securityContext: {}
# 优雅终止的宽限期秒数
terminationGracePeriodSeconds: 30
# Pod中定义的卷列表
volumes:
- # 第一个卷
name: hostname # 卷的名称
# 使用hostPath卷,将宿主机的文件或目录挂载到Pod中
hostPath:
path: /etc/hostname # 宿主机的文件或目录路径
type: File # hostPath的类型,这里是文件
创建:
kubectl create -f hostpath-1.yaml
查看deploy:
kubectl get deploy
查看pod:
kubectl get pod -owide
登录容器,查看共享文件:
kubectl exec -it nginx-host-path-7c496b484d-jmlr2 -- bash
cat /etc/hostname
这个名字和pod运行所在的节点的主机名称一致
把当前pod所在主机上的的/tmp/aaa目录和Pod中container的/tmp目录共享,任何一个目录下的变动,都会共享。注意一定要在pod所在的主机上创建共享目录。
vim hostpath-2.yaml
# 定义Deployment的API版本和类型
apiVersion: apps/v1
kind: Deployment
# Deployment的元数据
metadata:
# Deployment的注解,记录了Deployment的修订版本
annotations:
deployment.kubernetes.io/revision: "1"
# Deployment的创建时间戳
creationTimestamp: "2024-01-04T15:27:07Z"
# 元数据的生成版本
generation: 1
# Deployment的标签
labels:
app: nginx-host-path-dir # 自定义的标签,用于标识这个Deployment
# Deployment的名称
name: nginx-host-path-dir
# Deployment的规格说明
spec:
# 进度死线秒数,用于等待Deployment的进度
progressDeadlineSeconds: 600
# Pod的副本数量
replicas: 2
# 保留的历史版本数量
revisionHistoryLimit: 10
# 选择器,用于匹配Pod的标签
selector:
matchLabels:
app: nginx # Pod的标签,应该与这里的matchLabels一致
# 更新策略
strategy:
rollingUpdate:
# 滚动更新时最大额外副本数
maxSurge: 25%
# 滚动更新时最大不可用副本数
maxUnavailable: 25%
# 更新类型,这里是滚动更新
type: RollingUpdate
# Pod模板
template:
metadata:
# Pod的创建时间戳,这里为null,因为Pod还未创建
creationTimestamp: null
# Pod的标签
labels:
app: nginx # Pod的标签,与selector中的matchLabels一致
spec:
# Pod中的容器列表
containers:
- # 第一个容器
image: nginx:1.18.0 # 容器镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略
name: nginx # 容器名称
resources: {} # 资源限制和请求,此处为空
terminationMessagePath: /dev/termination-log # 终止消息的路径
terminationMessagePolicy: File # 终止消息的策略
# 容器内的卷挂载点
volumeMounts:
- mountPath: /tmp/ # 容器内的挂载路径
name: hostname1 # 挂载的卷名称
# DNS策略
dnsPolicy: ClusterFirst
# 重启策略
restartPolicy: Always
# 调度器名称
schedulerName: default-scheduler
# 安全上下文
securityContext: {}
# 优雅终止的宽限期秒数
terminationGracePeriodSeconds: 30
# Pod中定义的卷列表
volumes:
- # 第一个卷
name: hostname1 # 卷的名称
# 使用hostPath卷,将宿主机的目录挂载到Pod中
hostPath:
path: /tmp/aaa/ # 宿主机的目录路径
type: Directory # hostPath的类型,这里是目录
根据配置在node01和02上创建目录(如果不创建,pod创建会一直报错,使用命令kubectl describe pod pod名称 显示/tmp/aaa不存在):
mkdir /tmp/aaa
创建deploy:
kubectl create -f hostpath-2.yaml
查看deploy:
kubectl get deploy
查看pod:
kubectl get pod -owide
在pod的运行节点的/tmp/aaa下操作:
touch /tmp/aaa/a.log
登录容器:
kubectl exec -it nginx-host-path-dir-9bb879b87-n7zcl -- bash
查看/tmp:
ls /tmp/
在pod中创建文件:
touch /tmp/b.log
touch /tmp/c.log
exit
去pod所在节点的/tmp/aaa下查看:
ls /tmp/aaa
hostPath 卷常用的type(类型)如下:
type为空字符串:默认选项,意味着挂载hostPath卷之前不会执行任何检查。
DirectoryOrCreate:如果给定的path不存在任何东西,那么将根据需要创建一个权限为755的空目录,和Kubelet具有相同的组和权限。
Directory:目录必须存在于给定的路径下。
FileOrCreate:如果给定的路径不存储任何内容,则会根据需要创建一个空文件,权限设置为0644,和Kubelet具有相同的组和所有权。
File:文件,必须存在于给定路径中。
Socket:UNIX套接字,必须存在于给定路径中。
CharDevice:字符设备,必须存在于给定路径中。
BlockDevice:块设备,必须存在于给定路径中。
运行并查看,在运行起来后,可以进入创建的容器,并在容器中/tmp/挂载目录下创建一个文件,这时候可以看到Node物理机的/tmp/aaa目录下也会出现该文件。
试着删除该pod,宿主机上的文件并不会被删除,重启启动pod后,可以继续使用该文件,但是不同的宿主机都在各自的目录下,有一份自己的文件,并没有做到唯一性。
NFS是Network File System的简写,即网络文件系统,NFS是FreeBSD支持的文件系统中的一种。NFS基于RPC(Remote Procedure Call)远程过程调用实现,其允许一个系统在网络上与它人共享目录和文件。通过使用NFS,用户和程序就可以像访问本地文件一样访问远端系统上的文件。
NFS是一个非常稳定的,可移植的网络文件系统。具备可扩展和高性能等特性,达到了企业级应用质量标准。由于网络速度的增加和延迟的降低,NFS系统一直是通过网络提供文件系统服务的有竞争力的选择 。
NFS 使用RPC(Remote Procedure Call)的机制进行实现,RPC使得客户端可以调用服务端的函数。同时,由于有 VFS 的存在,客户端可以像使用其它普通文件系统一样使用 NFS 文件系统。
都在node01上操作
安装nfs(所有节点都装,也可以在master01和所有要使用nfs的worker node节点):
yum -y install nfs-utils
启动(只启动node01 或者你安装的节点上):
systemctl status nfs-server
systemctl start nfs-server
systemctl status nfs-server
如果常用,建议设置开机启动(这里不设置,以后使用到了,记得启动):
systemctl enable nfs-server
创建共享目录(只在node01或者你安装的节点上):
mkdir /usr/nfs
修改权限:
chmod a+w /usr/nfs/
Exporter配置
echo "/usr/nfs/ *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
*代表任何网络都可以访问
(rw,sync,no_subtree_check,no_root_squash):这是一组选项,用于定义访问权限和其他行为。
rw:表示允许读写访问。
sync:表示所有对NFS服务器的写操作都会被同步到磁盘上,确保数据的一致性。
no_subtree_check:禁用子树检查,这可以提高性能,但可能会在某些情况下导致不一致的状态。
no_root_squash:通常,NFS会将远程root用户的访问映射为一个非特权用户(通常是nobody)。这个选项允许远程root用户以root权限访问导出的文件系统,这可能会带来安全风险。
让配置生效:
exportfs -r
重启服务:
systemctl reload nfs-server
在master01上挂载(要求必须安装nfs-uitls):
mount -t nfs 192.168.3.114:/usr/nfs /mnt
查看挂载:
df -Th|grep nfs
主机上卸载(如果演示卸载,就再次挂载):
umount /mnt
mount -t nfs 192.168.170.154:/usr/nfs /mnt
复制文件:
vim nfs.yaml
:set paste
# 定义API版本和Kubernetes资源类型
apiVersion: apps/v1
kind: Deployment
# Deployment的元数据
metadata:
# Deployment的注解,记录Deployment的修订版本
annotations:
deployment.kubernetes.io/revision: "1"
# Deployment的创建时间戳
creationTimestamp: "2024-01-04T15:27:07Z"
# 元数据的生成版本
generation: 1
# Deployment的标签
labels:
app: nginx-3 # 自定义标签,用于标识这个Deployment
# Deployment的名称
name: nginx-3
# Deployment的规格说明
spec:
# 进度死线秒数,用于等待Deployment的进度
progressDeadlineSeconds: 600
# Pod的副本数量
replicas: 2
# 保留的历史版本数量
revisionHistoryLimit: 10
# 选择器,用于匹配Pod的标签
selector:
matchLabels:
app: nginx # 这里可能是一个错误,通常应该与Pod模板中的labels一致,即app: nginx-3
# 更新策略
strategy:
rollingUpdate:
# 滚动更新时最大额外副本数
maxSurge: 25%
# 滚动更新时最大不可用副本数
maxUnavailable: 25%
# 更新类型,这里是滚动更新
type: RollingUpdate
# Pod模板
template:
metadata:
# Pod的创建时间戳,这里为null,因为Pod还未创建
creationTimestamp: null
# Pod的标签
labels:
app: nginx # Pod的标签,建议与Deployment的selector匹配,但这里可能是为了特定的选择而设置
spec:
# Pod中的容器列表
containers:
- # 第一个容器
image: nginx:1.18.0 # 容器镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略
name: nginx1 # 容器名称
resources: {} # 资源限制和请求,此处为空
terminationMessagePath: /dev/termination-log # 终止消息的路径
terminationMessagePolicy: File # 终止消息的策略
# 容器内的卷挂载点
volumeMounts:
#- mountPath: /opt # 容器内的挂载路径
# name: share-volume # 挂载的卷名称(但注意,share-volume未在volumes中定义)
- mountPath: /opt # 另一个挂载路径
name: nfs-volume # 挂载的NFS卷名称
- # 第二个容器
image: nginx:1.18.0 # 与第一个容器相同的镜像
imagePullPolicy: IfNotPresent
name: nginx2 # 容器名称
# 覆盖容器的默认命令
command:
- sh
- -c
- sleep 3600 # 容器启动后执行sleep 3600命令
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
# 容器内的卷挂载点
volumeMounts:
- mountPath: /mnt # 与第一个容器共享的挂载路径
name: nfs-volume # 挂载的NFS卷名称
# DNS策略
dnsPolicy: ClusterFirst
# 重启策略
restartPolicy: Always
# 调度器名称
schedulerName: default-scheduler
# 安全上下文
securityContext: {}
# 优雅终止的宽限期秒数
terminationGracePeriodSeconds: 30
# Pod中定义的卷列表
volumes:
- name: nfs-volume # NFS卷的名称
nfs: # 使用NFS卷
server: 192.168.170.114 # NFS服务器的IP地址
path: /usr/nfs/aaa # NFS服务器上共享的路径
在node01创建目录:
mkdir /usr/nfs/aaa
创建deploy:
kubectl create -f nfs.yaml
查看deploy:
kubectl get deploy
登录容器:
kubectl exec -it nginx-3-5ddd488979-9r7fm -c nginx1 -- bash
看挂载:
df -TH
创建目录:
touch /mnt/a.txt
发现node01下存在:
ls /usr/nfs/aaa/
kubectl exec -it nginx-3-5ddd488979-9r7fm -c nginx1 -- bash
ls /opt
touch /opt/c.log
在node01查看nfs的目录:
ls /usr/nfs/aaa
kubectl exec -it nginx-3-5ddd488979-9r7fm -c nginx2 -- bash
ls /mnt