Due to the problem of containerization, it has caused some problems for important applications running in containers
1. Container restart kubelet will restart the container in a clean state, and the history in the container will be lost
2. When deleting the container, there is no stop in k8s, and the data in the container will also be deleted together
3. There is a need to share files or directories in multiple containers
Scratch volume:
The life cycle of the type is the same as that of the pod. When the pod does not exist, k8s will also destroy the temporary volume
Persistent volume:
When the pod execution ends or is deleted, k8s will not destroy the persistent volume
scratch volume
emptyDir volume
The essence of emptyDir is a simple empty directory that lives and dies with the pod
for temporary space
configMap volume
secret volume
emptyDir volume
1. Define the volume object
2. The container references emptyDir
1.定义卷对象
---
apiVersion: v1
kindL Pod
metadata:
name: web
spec:
volumes:
- name: cache-volume
emptyDir: {}
containers:
2.容器引用
volumes:
- name: cache-volume
emptyDir: {}
containers:
configMap volume
Allows configuration files to be separated from images, making containerized applications portable
Used to temporarily set environment variables
View: kubectl get configmaps
1. Create configmap syntax
2. Reference the configmap object to set the variable
# 使用命令创建 configMap
[root@master ~]# kubectl create configmap mycm1 --from-literal=username=admin --from-literal=password=123456
configmap/mycm1 created
# 使用资源文件创建 configMap
[root@master ~]# vim timezone.yaml
---
kind: ConfigMap
apiVersion: v1
metadata:
name: timezone
data:
TZ: "Asia/Shanghai"
[root@master ~]# kubectl apply -f timezone.yaml
configmap/timezone created
# 查看 configMap
[root@master ~]# kubectl get configmaps
NAME DATA AGE
kube-root-ca.crt 1 2d5h
mycm1 1 33s
timezone 1 54s
Modify the system time zone
[root@master ~]# vim myv2.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: web2
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
containers:
- name: nginx
image: myos:nginx
ports:
- protocol: TCP
containerPort: 80
envFrom: # 引用变量配置
- configMapRef: # configmap 资源对象
name: timezone # configmap 名称
[root@master ~]# kubectl delete -f myv2.yaml
pod "web2" deleted
[root@master ~]# kubectl apply -f myv2.yaml
pod/web2 created
[root@master ~]# kubectl exec -it web2 -- /bin/bash
[root@web2 html]# echo ${TZ}
Asia/Shanghai
[root@web2 html]# date +%T
# 与我们时间一致
Create a ConfigMap
# 拷贝 5/public/info.php 到 master 主机,创建测试页面
[root@master ~]# mkdir webphp
[root@master ~]# echo "Hello Nginx ." >webphp/info.html
[root@master ~]# cp info.php webphp/
# 把目录做 configMap
[root@master ~]# kubectl create configmap website --from-file=webphp
configmap/website created
# 修改 nginx 配置文件,并做成 ConfigMap
[root@master ~]# kubectl cp web2:/usr/local/nginx/conf/nginx.conf ./nginx.conf
[root@master ~]# vim nginx.conf
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
[root@master ~]# kubectl create configmap webconf --from-file=nginx.conf
configmap/webconf created
[root@master ~]# kubectl get configmaps
NAME DATA AGE
timezone 1 73m
webconf 1 5s
website 2 4m18s
nginx parses php
[root@master ~]# vim myv2.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: web2
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
volumes: # 卷配置
- name: myphp # 卷名称
configMap: # configmap 资源对象
name: website # configmap 名称
- name: webconf # 卷名称
configMap: # configmap 资源对象
name: webconf # configmap 名称
containers:
- name: nginx
image: myos:nginx
volumeMounts: # mount 卷
- name: myphp # 卷名称
mountPath: /usr/local/nginx/html/myphp # 路径
- name: webconf # 卷名称
subPath: nginx.conf # 如果是单一文件,需要指定键名称
mountPath: /usr/local/nginx/conf/nginx.conf # 路径
ports:
- protocol: TCP
containerPort: 80
envFrom:
- configMapRef:
name: timezone
- name: php
image: myos:phpfpm
volumeMounts:
- name: myphp
mountPath: /usr/local/nginx/html/myphp
[root@master ~]# kubectl delete -f myv2.yaml
pod "web2" deleted
[root@master ~]# kubectl apply -f myv2.yaml
pod/web2 created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
web2 2/2 Running 0 7s 10.244.3.13 node-0003
[root@master ~]# curl http://10.244.3.13/myphp/info.php
<pre>
Array
(
[REMOTE_ADDR] => 10.244.0.0
[REQUEST_METHOD] => GET
[HTTP_USER_AGENT] => curl/7.29.0
[REQUEST_URI] => /info.php
)
php_host: web2
1229
secret volume
[root@master ~]# kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
secret/mysecret created
[root@master ~]# kubectl get secrets
NAME TYPE DATA AGE
default-token-qw9b9 kubernetes.io/service-account-token 3 5d1h
mysecret Opaque 2 54s
# configMap 数据明文存放
[root@master ~]# kubectl get configmaps mycm1 -o yaml
apiVersion: v1
data:
password: "123456"
username: admin
kind: ConfigMap
metadata:
creationTimestamp: "2023-02-01T02:35:54Z"
name: mycm1
namespace: default
resourceVersion: "280963"
uid: 7ea3cfc4-7930-4d33-b26c-97502710692d
# secret 数据加密存放
[root@master ~]# kubectl get secrets mysecret -o yaml
apiVersion: v1
data:
password: MTIzNDU2
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2023-02-01T09:56:08Z"
name: mysecret
namespace: default
resourceVersion: "318028"
uid: 83e3a77d-e8b9-4935-83e7-a3d9bb44f2ce
type: Opaque
Create authentication file
# 生成加密 base64 数据
[root@master ~]# kubectl exec -it web2 -c nginx -- /bin/bash
[root@web2 html]# yum install -y httpd-tools
[root@web2 html]# htpasswd -nbm admin 123456 |base64
YWRtaW46JGFwcjEkdGJqOXJISUckdk9DRFpDaFZJUHl0ZHdGSXl1Qm91MAoK
[root@web2 html]# exit
# 使用 secret 设置密码
[root@master ~]# vim myv2.yaml
---
kind: Secret
apiVersion: v1
metadata:
name: myauth
type: Opaque
data:
webauth: YWRtaW46JGFwcjEkdGJqOXJISUckdk9DRFpDaFZJUHl0ZHdGSXl1Qm91MAoK
---
apiVersion: v1
kind: Pod
metadata:
name: web2
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
volumes:
- name: myphp
configMap:
name: website
- name: webconf
configMap:
name: webconf
- name: webauth # 卷名称
secret: # secret 资源对象
secretName: myauth # secret 名称
items: # 枚举多个键值
- key: webauth # 键值名称
path: webauth # 文件名称
mode: 0644 # 权限
containers:
- name: nginx
image: myos:nginx
volumeMounts:
- name: myphp
mountPath: /usr/local/nginx/html/myphp
- name: webconf
subPath: nginx.conf
mountPath: /usr/local/nginx/conf/nginx.conf
- name: webauth # 卷名称
subPath: webauth # 键名称
mountPath: /usr/local/nginx/conf/webauth # 路径
ports:
- protocol: TCP
containerPort: 80
envFrom:
- configMapRef:
name: timezone
- name: php
image: myos:phpfpm
volumeMounts:
- name: myphp
mountPath: /usr/local/nginx/html/myphp
[root@master ~]# kubectl delete pod web2
pod "web2" deleted
[root@master ~]# kubectl apply -f myv2.yaml
configmap/timezone created
secret/myauth created
pod/web2 created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
web2 2/2 Running 0 4s 10.244.3.22 node-0003
[root@master ~]# curl -u admin:123456 http://10.244.3.22/myphp/info.php
<pre>
Array
(
[REMOTE_ADDR] => 10.244.0.0
[REQUEST_METHOD] => GET
[HTTP_USER_AGENT] => curl/7.29.0
[REQUEST_URI] => /myphp/info.php
)
php_host: web2
1229
The temporary volume is the above three
persistent volume
hostPath persistent volume
The essence of hostPath is to use local devices, such as disks, partitions, directories, socker, chardevice, blockdevice
Depending on the availability of underlying nodes,
pod deleted data still
[root@master ~]# vim myv3.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: web3
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
volumes: # 卷配置
- name: logdata # 卷名称
hostPath: # hostPath 资源类型
path: /var/weblog # 宿主机路径
type: DirectoryOrCreate # 目录不存在就创建
containers:
- name: nginx
image: myos:nginx
ports:
- protocol: TCP
containerPort: 80
volumeMounts: # mount 卷
- name: logdata # 卷名称
mountPath: /usr/local/nginx/logs # 路径
[root@master ~]# kubectl apply -f myv3.yaml
pod/web3 created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
web3 1/1 Running 0 4s 10.244.2.28 node-0002
[root@master ~]# curl http://10.244.2.28/
Nginx is running !
# 删除 Pod ,日志数据也不会丢失
[root@master ~]# kubectl delete -f myv3.yaml
pod "web3" deleted
[root@node-0002 ~]# cat /var/weblog/access.log
10.244.0.0 - - [27/Jun/2022:02:00:12 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"
NFS volume
Build an NFS server
# 搭建 NFS 服务
[root@registry ~]# yum install -y nfs-utils
[root@registry ~]# mkdir -m 0777 /var/webroot
[root@registry ~]# echo "This is NFS server" >/var/webroot/index.html
[root@registry ~]# echo -e "/var/webroot\t*(rw)" >/etc/exports
[root@registry ~]# systemctl enable --now nfs
# 在 master 上验证服务
[root@master ~]# yum install -y nfs-utils
[root@master ~]# showmount -e registry
Export list for registry:
/var/webroot *
# 在所有节点安装 NFS 模块
[root@node-0001 ~]# yum install -y nfs-utils
[root@node-0002 ~]# yum install -y nfs-utils
[root@node-0003 ~]# yum install -y nfs-utils
Pod calls NFS volume
[root@master ~]# vim myv3.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: web3
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
volumes:
- name: logdata
hostPath:
path: /var/weblog
type: DirectoryOrCreate
- name: website # 卷名称
nfs: # NFS 资源类型
server: registry # NFS 服务器地址
path: /var/webroot # NFS 共享目录
containers:
- name: nginx
image: myos:nginx
ports:
- protocol: TCP
containerPort: 80
volumeMounts:
- name: logdata
mountPath: /usr/local/nginx/logs
- name: website # 卷名称
mountPath: /usr/local/nginx/html # 路径
[root@master ~]# kubectl apply -f myv3.yaml
pod/web3 created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
web3 1/1 Running 0 3s 10.244.1.18 node-0001
[root@master ~]# curl http://10.244.1.18/
This is NFS server
# 清理实验 Pod
[root@master ~]# kubectl delete -f myv3.yaml
pod "web3" deleted
PV/PVC
The full name of PV is Persistent Volume, which is a persistent volume resource provider
The full name of PVC is Persistent VolumeClaim, which is a persistent volume claim. The resource user will automatically find the PV to complete the binding according to the user's needs.
storage------PV--------PVC--------volume---------containers
Persistent Volume (PV)
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv-local
spec:
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
capacity:
storage: 30Gi
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /var/weblog
type: DirectoryOrCreate
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv-nfs
spec:
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
- ReadOnlyMany
- ReadWriteMany
capacity:
storage: 20Gi
persistentVolumeReclaimPolicy: Retain
nfs:
server: registry
path: /var/webroot
Persistent Volume Claims (PVCs)
[root@master ~]# vim pvc.yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc1
spec:
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 18Gi
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc2
spec:
volumeMode: Filesystem
accessModes:
- ReadWriteMany
resources:
requests:
storage: 15Gi
[root@master ~]# kubectl apply -f pvc.yaml
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
[root@master ~]# kubectl get persistentvolumeclaims
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc1 Bound pv-local 30Gi RWO 8s
pvc2 Bound pv-nfs 20Gi RWO,ROX,RWX
Pod invokes PVC
[root@master ~]# cat myv3.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: web3
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
volumes: # 卷配置
- name: logdata # 卷名称
persistentVolumeClaim: # 通过PVC引用存储资源
claimName: pvc1 # PVC名称
- name: website # 卷名称
persistentVolumeClaim: # 通过PVC引用存储资源
claimName: pvc2 # PVC名称
containers:
- name: nginx
image: myos:nginx
ports:
- protocol: TCP
containerPort: 80
volumeMounts:
- name: logdata
mountPath: /usr/local/nginx/logs
- name: website
mountPath: /usr/local/nginx/html
[root@master ~]# kubectl apply -f myv3.yaml
pod/web3 created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
web3 1/1 Running 0 19s 10.244.1.20 node-0001
[root@master ~]# curl http://10.244.1.20/
This is NFS server
[root@master ~]# kubectl delete -f myv3.yaml
pod "web3" deleted
[root@node-0001 ~]# cat /var/weblog/access.log
10.244.0.0 - - [27/Jun/2022:02:00:12 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"
10.244.0.0 - - [27/Jun/2022:02:00:14 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"
- Create a Pod using the myos:nginx image, which provides https services
reference answer
Problem solving analysis:
1. https requires a certificate, created by the openssl command
2. You can modify the configuration file through configMap
3. The certificate can be loaded into the Pod through the secret
# 创建证书和 key 文件
[root@localhost ~]# openssl genrsa -out my.key 2048
[root@localhost ~]# openssl req -new -x509 -key my.key -out my.crt -subj "/C=CN/ST=BJ/L=BJ/O=Tedu/OU=NSD/CN=localhost/[email protected]"
# 把证书做成 secrets
[root@localhost ~]# kubectl create secret tls webcert --cert=my.crt --key=my.key
secret/webcert created
# 获取 nginx 配置文件
[root@localhost ~]# kubectl run myweb --image=myos:nginx
pod/myweb created
[root@localhost ~]# kubectl cp myweb:/usr/local/nginx/conf/nginx.conf ./nginx.conf
tar: Removing leading `/' from member names
[root@localhost ~]# kubectl delete pod myweb
pod "myweb" deleted
# 修改配置文件,添加证书配置项
[root@localhost ~]# vim nginx.conf
... ...
server {
listen 443 ssl;
ssl_certificate ssl/tls.crt;
ssl_certificate_key ssl/tls.key;
... ...
# 把配置文件做成 configMap
[root@localhost ~]# kubectl create configmap nginx-conf --from-file=nginx.conf
configmap/nginx-conf created
# 编写 Pod 资源文件
[root@localhost ~]# vim myweb.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: myweb
spec:
terminationGracePeriodSeconds: 0
restartPolicy: Always
volumes:
- name: mycert
secret:
defaultMode: 0400
secretName: webcert
- name: nginx-conf
configMap:
name: nginx-conf
containers:
- name: nginx
image: myos:nginx
volumeMounts:
- name: mycert
mountPath: /usr/local/nginx/conf/ssl
- name: nginx-conf
subPath: nginx.conf
mountPath: /usr/local/nginx/conf/nginx.conf
ports:
- protocol: TCP
containerPort: 443
# 测试验证
[root@localhost ~]# kubectl apply -f myweb.yaml
pod/myweb created
[root@localhost ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
myweb 1/1 Running 0 8s 10.244.1.15 node-0001
[root@localhost ~]# curl -k https://10.244.1.15
Nginx is running !