对于K8S这样一个云上服务管理集群来说

将文件等持久化数据放在本地存储是不可靠的,所以需要将数据放在远端持久化存储中

基本架构如下图

图片

容器通过挂载点和远端的存储进行沟通

而在Kubernetes中,支持的挂载存储多达28种数据卷类型

非持久化村存储,也就是服务器本地存储

emptyDir

HostPath

网络存储

SAN:iSCSI,ScaleIO Volumes FC

NFS: nfs,cfs

分布式存储

Glusterfs

RBD

CephFS

Portworx Volumes

Quobyte Volumes

云端存储

GCEPersistentDisk

AWSElasticBlockStore

AzureFile

AzureDisk

Cinder (OpenStack block storage)

VsphereVolume

StorageOS

以及配置相关的

Configmap

Secret

然后在其中,Secret和Configmap使我们需要说的

Secret用于保存敏感信息,比如密码,OAuth令牌,SSH秘钥等

将这些放在K8S中保存比明文更加灵活,类型主要包含下面

图片

关于如何创建和Secret和Pod如何使用Secret,是我们接下来要讲解的对象

1.      创建Secret

首先可以使用基本字符串

Kubectl create secret generic dev-db-secret \

–from-literal=username=devuser

–from-liternal=password=’S!B\*d$zDsb=’

这样我们创建的Secret中存储的数据,是被Base64加密过得

或者我们使用文件来创建Secret

echo -n ‘admin’ > ./username.txt

echo -n ‘1f2d1e2e67df’ > ./password.txt

kubectl create secret generic db-user-pass \

–from-file=./username.txt \

–from-file=./password.txt

这样创建出来的Secret 中数据也是被Base64加密过的

最后是使用yaml文件创造出来的

apiVersion: v1

kind: Secret

metadata:

name: dev-db-secret

data:

password: UyFCXCpkJHpEc2I9  ## base64编码了一下

username: ZGV2dXNlcg==

这样创建出来的Secret中存储的数据就是我们声明的数据

其次是关于Secret的挂载使用

我们之前说过了使用Secret来挂载访问Docekr私仓

即配置

Spec:

Containers:

–       Name: nginx

Image: xxxx

ImagePullSecrets:

–       Name :secretname

其次我们可以使用环境变量引用的方式来使用Secret

在对应的env中声明valueFrom,表明为secretKeyRef,从而使用secret的属性

# secret保存在集群的etcd里面

apiVersion: v1

kind: Pod

metadata:

name: “pod-secret”

namespace: default

labels:

app: “pod-secret”

spec:

containers:

– name: pod-secret

image: “busybox”

command: [“/bin/sh”,”-c”,”sleep 3600″]  ## echo $My_USR

resources:

limits:

cpu: 10m ###  1核代表1000m

requests:

cpu: 5m

env:

– name: MY_USR  ### 容器里的环境变量名字

valueFrom:

secretKeyRef: ## secret的内容

name:  dev-db-secret #指定secret名字

key: username  ### 自动base64解码

– name: POD_NAME

valueFrom:

fieldRef: ## 属性引用

fieldPath: metadata.name  ## 取出资源对象信息

– name: POD_LIMIT_MEM

valueFrom:

resourceFieldRef:

containerName: pod-secret  ## 取出指定容器的相关资源值

resource: limits.cpu

除此之外,还可以使用

ResourceFieldReg,来取出容器相关的资源之

比如limits.cpu

以及fieldRef,取出资源对象相关的信息

比如metadata.namespaces

但是有着对应的缺点,就是在Secret文件更新的时候,不会自动刷新环境变量

还有一种办法就是以文件的方式挂载到Pod的指定目录中

首先在pod的containers中同级的volumes

声明一个secret

Secret中可以配置项并不少

包含defaultmode,items这些

然后在containers中声明使用volumeMounts 使用

然后是configmap

其实使用方式和Secret类似,由于是不加密的,所以适合存储环境变量等信息

创建方式也是可以直接书写

kubectl create configmap my-config –from-literal=key1=config1 –from-literal=key2=config2或者通过指定key和文件

kubectl create configmap my-config –from-literal=key1=config1 –from-literal=key2=config2

以及通过yaml文件声明

apiVersion: v1

kind: ConfigMap

metadata:

name: game-demo

data:

# 类属性键;每一个键都映射到一个简单的值

player_initial_lives: “3”

ui_properties_file_name: “user-interface.properties”

# 类文件键

game.properties: |

enemy.types=aliens,monsters

player.maximum-lives=5

user-interface.properties: |

color.good=purple

color.bad=yellow

allow.textmode=true

上面我们使用:冒号后面跟着一个 |来表示

这个key后面跟着多个value,这种方式方便我们未来进行挂载

对于使用来说

也是可以进行设置为环境变量

也和上面的使用方式一样

在pod.spec.containers.port中,有可填项 configMapKeyRef

– name: PLAYER_INITIAL_LIVES # 请注意这里和 ConfigMap 中的键名是不一样的

valueFrom:

configMapKeyRef:

name: game-demo           # 这个值来自 ConfigMap

key: player_initial_lives # 需要取值的键

name仍然为ConfigMap

key为要取值的键

同样,缺点在于如果环境变量,是没有办法进行热更新的

其次是通过volume方式进行挂载

仍然是在containers同级中volumes中声明一个volume

 volumes:

# 你可以在 Pod 级别设置卷,然后将其挂载到 Pod 内的容器中

– name: config

configMap:

# 提供你想要挂载的 ConfigMap 的名字

name: game-demo

# 来自 ConfigMap 的一组键,将被创建为文件

items:

– key: “game.properties”

path: “game.properties”

– key: “user-interface.properties”

path: “user-interface.properties”

其中我们制定了

挂载的configmap的name

然后是可选项的item

其中有key和path是必填的

Key指定了configMap中的key,path指定了具体挂载的路径

这一点可以触发自动更新

之后是关于Kuberentes中的临时存储

分为了emptyDir 和 hostPath

首先是emptyDir

EmptyDir是K8S随机生成的宿主机上的目录,供不同的容器进行读写

在Pod被删除的时候,其中的数据也会被永久删除

但是当容器被删除的时候,数据不会发生改变

一个典型的声明了挂载emptyDir的yaml文件如下

apiVersion: v1

kind: Pod

metadata:

name: “multi-container-pod”

namespace: default

labels:

app: “multi-container-pod”

spec:

volumes:    ### 以后见到的所有名字 都应该是一个合法的域名方式

– name: nginx-vol

emptyDir: {}  ### docker匿名挂载,外部创建一个位置  /abc

containers:  ## kubectl exec -it podName  -c nginx-container(容器名)– /bin/sh

– name: nginx-container

image: “nginx”

volumeMounts:  #声明卷挂载  -v

– name: nginx-vol

mountPath: /usr/share/nginx/html

– name: content-container

image: “alpine”

command: [“/bin/sh”,”-c”,”while true;do sleep 1; date > /app/index.html;done;”]

volumeMounts:

– name: nginx-vol

mountPath: /app

无论是hostPath还是emptyDir

都是可以在volumeMount中配置subPath

但是需要注意,如果configMap或者Secret配置了subPath,那么当上述两者发生变化的时候,不会自动更新

图片

而在emptyDir中,还有些可选配置项

其中medium选项可以配置””空字符串或者memory

如果配置为空字符串,那么就生成一个临时文件夹,设置为memory,就是将文件放在内存中

SizeLimit 配合上面的memory 使用的,设置内存大小

其次是hostPath

就是讲容器内部和宿主机做一个映射

基本的yaml如下

apiVersion: v1

kind: Pod

metadata:

name: test-pd

spec:

containers:

– image: k8s.gcr.io/test-webserver

name: test-container

volumeMounts:

– mountPath: /test-pd

name: test-volume

volumes:

– name: test-volume

hostPath:

# 宿主上目录位置

path: /data

# 此字段为可选

type: Directory

就是在hostPath上声明一个宿主机路径,将其挂载到容器内部的目录中

下面的type为Directory,表示是一个目录,除了这个type还有一些如下

图片

在hostPath的最后,来看一个典型案例

apiVersion: v1

kind: Pod

metadata:

name: busy-box-test

namespace: default

spec:

restartPolicy: OnFailure

containers:

– name: busy-box-test

image: busybox

imagePullPolicy: IfNotPresent

volumeMounts:

– name: date-config

mountPath: /etc/localtime

command: [“sleep”, “60000”]

volumes:

– name: date-config

hostPath:

path: /etc/localtime

将宿主机的时间分享给容器内部,保证时间一致,类似的还有,将宿主机上的docker socket分享给容器内部,让容器可以调用宿主机的docker 接口

发表评论

邮箱地址不会被公开。 必填项已用*标注