【kubernetes/k8s源码分析】 k8s hostpath storage 源码分析
hostPath允许挂载Node上的文件系统到Pod里面去。如果Pod有需要使用Node上的东西,可以使用hostPathhostPath的用途如下:运行需要访问 Docker 内部的容器;使用/var/lib/docker的hostPath在容器中运行 cAdvisor;使用/dev/cgroups的hostPath为hostPath卷指...
hostPath允许挂载Node上的文件系统到Pod里面去。如果Pod有需要使用Node上的东西,可以使用hostPath
hostPath
的用途如下:
- 运行需要访问 Docker 内部的容器;使用
/var/lib/docker
的hostPath
- 在容器中运行 cAdvisor;使用
/dev/cgroups
的hostPath
为 hostPath
卷指定 type
值 | 行为 |
---|---|
空字符串(默认)用于向后兼容,在挂载 hostPath 卷之前不会执行任何检查 | |
DirectoryOrCreate | 将根据需要在那里创建一个空目录,权限设置为 0755,与 Kubelet 具有相同的组和权限 |
Directory | 给定的路径下必须存在目录 |
FileOrCreate | 会根据需要创建一个空文件,权限设置为 0644,与 Kubelet 具有相同的组和权限 |
File | 给定的路径下必须存在文件 |
Socket | 给定的路径下必须存在 UNIX 套接字 |
CharDevice | 给定的路径下必须存在字符设备 |
BlockDevice | 给定的路径下必须存在块设备 |
$ cat hostpath.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-hostpath
labels:
app: wordpress-hostpath
tier: mysql-hostpath
spec:
selector:
matchLabels:
app: wordpress-hostpath
tier: mysql-hostpath
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress-hostpath
tier: mysql-hostpath
spec:
containers:
- image: mysql:5.6
name: mysql-hostpath
env:
- name: MYSQL_ROOT_PASSWORD
value: changeme
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
hostPath:
path: /tmp/mysql
插件名称:kubernetes.io/host-path
1. NewMounter
实例化 hostPathMounter,包括路径,类型,是否只读等
func (plugin *hostPathPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, opts volume.VolumeOptions) (volume.Mounter, error) {
hostPathVolumeSource, readOnly, err := getVolumeSource(spec)
if err != nil {
return nil, err
}
path := hostPathVolumeSource.Path
pathType := new(v1.HostPathType)
if hostPathVolumeSource.Type == nil {
*pathType = v1.HostPathUnset
} else {
pathType = hostPathVolumeSource.Type
}
return &hostPathMounter{
hostPath: &hostPath{path: path, pathType: pathType},
readOnly: readOnly,
mounter: plugin.host.GetMounter(plugin.GetPluginName()),
}, nil
}
path 支持的 type,上面表格有解释
// For backwards compatible, leave it empty if unset HostPathUnset HostPathType = "" // If nothing exists at the given path, an empty directory will be created there // as needed with file mode 0755, having the same group and ownership with Kubelet. HostPathDirectoryOrCreate HostPathType = "DirectoryOrCreate" // A directory must exist at the given path HostPathDirectory HostPathType = "Directory" // If nothing exists at the given path, an empty file will be created there // as needed with file mode 0644, having the same group and ownership with Kubelet. HostPathFileOrCreate HostPathType = "FileOrCreate" // A file must exist at the given path HostPathFile HostPathType = "File" // A UNIX socket must exist at the given path HostPathSocket HostPathType = "Socket" // A character device must exist at the given path HostPathCharDev HostPathType = "CharDevice" // A block device must exist at the given path HostPathBlockDev HostPathType = "BlockDevice"
2. SetUp
这个实现如果使用mount就是多此一举,直接创建目录就好了,看看怎么实现的,如果类型为设置为“”,则不处理,创建则直接交给docker daemon就好了
// SetUp does nothing.
func (b *hostPathMounter) SetUp(fsGroup *int64) error {
err := validation.ValidatePathNoBacksteps(b.GetPath())
if err != nil {
return fmt.Errorf("invalid HostPath `%s`: %v", b.GetPath(), err)
}
if *b.pathType == v1.HostPathUnset {
return nil
}
return checkType(b.GetPath(), b.pathType, b.mounter)
}
如果设置则检查什么类型的,则如下处理,无非就是创建目录,文件等操作
func checkTypeInternal(ftc hostPathTypeChecker, pathType *v1.HostPathType) error {
switch *pathType {
case v1.HostPathDirectoryOrCreate:
if !ftc.Exists() {
return ftc.MakeDir()
}
fallthrough
case v1.HostPathDirectory:
if !ftc.IsDir() {
return fmt.Errorf("hostPath type check failed: %s is not a directory", ftc.GetPath())
}
case v1.HostPathFileOrCreate:
if !ftc.Exists() {
return ftc.MakeFile()
}
fallthrough
case v1.HostPathFile:
if !ftc.IsFile() {
return fmt.Errorf("hostPath type check failed: %s is not a file", ftc.GetPath())
}
case v1.HostPathSocket:
if !ftc.IsSocket() {
return fmt.Errorf("hostPath type check failed: %s is not a socket file", ftc.GetPath())
}
case v1.HostPathCharDev:
if !ftc.IsChar() {
return fmt.Errorf("hostPath type check failed: %s is not a character device", ftc.GetPath())
}
case v1.HostPathBlockDev:
if !ftc.IsBlock() {
return fmt.Errorf("hostPath type check failed: %s is not a block device", ftc.GetPath())
}
default:
return fmt.Errorf("%s is an invalid volume type", *pathType)
}
return nil
}
参考:
更多推荐
所有评论(0)