5. 数据存储

5.1 Volume

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data

5.2 PV and PVC

5.2.1 PV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kind: PersistentVolume
apiVersion: v1
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual //该名称将用于将PersistentVolumeClaim请求绑定到此
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/storage/pv1"

5.2.2 PVC

1
2
3
4
5
6
7
8
9
10
11
12
# 编写Yaml文件
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi

5.2.3 Pod mount PVC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 编写Yaml文件
kind: Pod
apiVersion: v1
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage

5.3 StorageClass

5.3.1 NFS环境准备

1
2
3
4
5
6
7
# NFS Server节点安装部署
apt-get -y install nfs-kernel-server
mkdir /storage && echo "/storage *(rw,sync,no_root_squash)" >> /etc/exports
systemctl restart nfs-kernel-server

# NFS Client节点安装部署
apt-get -y install nfs-common

5.3.2 StorageClass插件部署

下载系统插件

1
git clone https://github.com/kubernetes-incubator/external-storage.git

部署NFS-Client插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 修改yaml信息
cd /root/external-storage/nfs-client/deploy
vim deployment.yaml
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 172.31.53.155
- name: NFS_PATH
value: /storage
volumes:
- name: nfs-client-root
nfs:
server: 172.31.53.155
path: /storage

# 部署插件
kubectl apply -f rbac.yaml
kubectl apply -f deployment.yaml
kubectl apply -f class.yaml

5.3.3 测试

测试一:创建pvc后自动创建pv并bound

1
2
3
4
5
6
7
8
9
10
11
12
# 编写Yaml文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-test
spec:
accessModes:
- ReadWriteMany
storageClassName: managed-nfs-storage
resources:
requests:
storage: 1Gi

测试二:创建Pod,自动创建pvc与pv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 编写Yaml文件
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: "managed-nfs-storage"
resources:
requests:
storage: 1Gi

测试三:将nfs的storageclass设置为默认,创建Pod不指定storageclass,申请pvc的资源是否成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 设置managed-nfs-storage为默认
kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

# 测试,编写yaml文件不指定storageclass
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 2 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: html
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi

5.4 ConfigMap

5.4.1 环境变量使用

创建ConfigMap

1
2
3
4
5
6
7
8
# 编写Yaml文件
apiVersion: v1
kind: ConfigMap
metadata:
name: test-config
data:
username: damon
password: redhat

pod使用envFrom导入环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: test-configmap-env-pod
spec:
containers:
- name: test-container
image: radial/busyboxplus
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "sleep 1000000" ]
envFrom:
- configMapRef:
name: test-config

pod使用valueFrom导入环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: test-configmap-command-env-pod
spec:
containers:
- name: test-container
image: radial/busyboxplus
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "echo \$(MYSQLUSER) \$(MYSQLPASSWD); sleep 1000000" ]
env:
- name: MYSQLUSER
valueFrom:
configMapKeyRef:
name: test-config
key: username
- name: MYSQLPASSWD
valueFrom:
configMapKeyRef:
name: test-config
key: password

5.4.2 Volume挂载使用

命令行创建ConfigMap

1
2
echo 123 > index.html
kubectl create configmap web-config --from-file=index.html

pod使用volume挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: test-configmap-volume-pod
spec:
volumes:
- name: config-volume
configMap:
name: web-config
containers:
- name: test-container
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: config-volume
mountPath: /usr/share/nginx/html

Pod使用subPath挂在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: test-configmap-volume-pod
spec:
volumes:
- name: config-volume
configMap:
name: web-config
containers:
- name: test-container
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: config-volume
mountPath: /usr/share/nginx/html/index.html
subPath: index.html

5.5 Secret

5.5.1 环境变量使用

创建Secret

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 手动加密
echo -n 'admin' | base64

# 解密
echo 'YWRtaW4=' | base64 --decode

# 编写Yaml文件
apiVersion: v1
kind: Secret
metadata:
name: mysecret-env
type: Opaque
data:
username: YWRtaW4=
password: cmVkaGF0

pod使用envFrom导入环境变量

1
2
3
4
5
6
7
8
9
10
11
12
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: envfrom-secret
spec:
containers:
- name: envars-test-container
image: nginx
envFrom:
- secretRef:
name: test-secret

pod使用valueFrom导入环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: pod-env-secret
spec:
containers:
- name: mycontainer
image: radial/busyboxplus
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "echo \$(SECRET_USERNAME) \$(SECRET_PASSWORD); sleep 1000000" ]
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret-env
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret-env
key: password

5.5.2 Volume挂载

命令行创建Secret

1
2
echo 123 > index.html
kubectl create secret generic web-secret --from-file=index.html

pod使用volume挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: pod-volume-secret
spec:
containers:
- name: pod-volume-secret
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: test-web
mountPath: "/usr/share/nginx/html"
volumes:
- name: test-web
secret:
secretName: web-secret

Pod使用subPath挂在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: pod-volume-secret
spec:
containers:
- name: pod-volume-secret
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: test-web
mountPath: "/usr/share/nginx/html/index.html"
subPath: index.html
volumes:
- name: test-web
secret:
secretName: web-secret

5.5.3 secret docker-registory

部署Harbor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 下载离线安装包
wget https://github.com/goharbor/harbor/releases/download/v1.10.0/harbor-offline-installer-v1.10.0.tgz

# 下载docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

chmod +x v1.26.2-docker-compose-Linux-x86_64 && mv v1.26.2-docker-compose-Linux-x86_64 /usr/local/bin/docker-compose

# 修改docker daemon.json ,添加安全私有镜像仓库
"insecure-registries": ["172.31.53.128"],
systemctl restart docker

# 安装harbor之前需要在harbor安装目录下修改harbor.yml文件,编辑hostname,注释https
./install.sh

# 登陆web创建用户,设定密码,创建项目

# docker login 私有仓库
docker login http://172.31.53.128/

# 上传image到damon用户的私有仓库中
docker tag
docker push

创建secret

1
kubectl create secret docker-registry harbor-secret --docker-server=172.27.141.61 --docker-username=damon --docker-password=Damon@123 --docker-email=damon@qq.com

创建Pod,调用imagePullSecrets

1
2
3
4
5
6
7
8
9
10
11
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: u-demo
image: 172.31.53.96:18080/test/nginx:latest
imagePullSecrets:
- name: harbor-secret

5.6 emptyDir

5.6.1 emptyDir

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
labels:
app: myapp
spec:
volumes:
- name: storage
emptyDir: {}
containers:
- name: myapp1
image: radial/busyboxplus
imagePullPolicy: IfNotPresent
volumeMounts:
- name: storage
mountPath: /storage
command: ['sh', '-c', 'sleep 3600000']
- name: myapp2
image: radial/busyboxplus
imagePullPolicy: IfNotPresent
volumeMounts:
- name: storage
mountPath: /storage
command: ['sh', '-c', 'sleep 10000000']

5.6.2 emptyDir + init-containers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 编写Yaml文件
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
volumes:
- name: storage
emptyDir: {}
containers:
- name: myapp-containers
image: radial/busyboxplus
imagePullPolicy: IfNotPresent
volumeMounts:
- name: storage
mountPath: /storage
command: ['sh', '-c', 'if [ -f /storage/testfile ] ; then sleep 3600000 ; fi']
initContainers:
- name: init-containers
image: radial/busyboxplus
imagePullPolicy: IfNotPresent
volumeMounts:
- name: storage
mountPath: /storage
command: ['sh', '-c', 'touch /storage/testfile && sleep 10']