Kubernetes emptyDir 和符号链接
Kubernetes emptyDir and symlinks
上下文
我有一个包含两个容器的 pod:
main
其简单的工作是显示目录的内容
sidecar
其职责是将 blob 存储的内容同步到预定义的目录中
为了实现原子同步,sidecar
将 blob 存储内容下载到新的临时目录中,然后在目标目录中切换符号链接。
目标目录使用 emptyDir
卷在两个容器之间共享。
问题
main
有符号链接但不能列出后面的内容。
问题
如何获取最新同步的数据?
附加信息
原因
我尝试实现 Apache Airflow with Git-Sync but, instead of using Git, I need to synchronize files from an Azure Blob storage. This is necessary because (1) my content is mostly dynamic and (2) the azureFile
volume type has some serious performance issues 正在做的事情。
同步例程
declare -r container='https://mystorageaccount.dfs.core.windows.net/mycontainer'
declare -r destination='/shared/container'
declare -r temp_dir="$(mktemp -d)"
azcopy copy --recursive "$container/*" "$temp_dir"
declare -r temp_file="$(mktemp)"
ln -sf "$temp_dir" "$temp_file"
mv -Tf "$temp_file" "$destination"
我们最终得到的结果:
$ ls /shared
container -> /tmp/tmp.doGz2U0QNy
$ ls /shared/container
file1.txt file2.txt
解决方案
我最初的尝试有两个错误:
- 卷中不存在符号链接目标
- 符号链接目标指向 sidecar 容器中的绝对路径,因此从主容器的角度来看,该文件夹不存在
修改后的例程如下:
declare -r container='https://mystorageaccount.dfs.core.windows.net/mycontainer'
declare -r destination='/shared/container'
declare -r cache_dir="$(dirname $destination)"
declare -r temp_dir="$(mktemp -d -p $cache_dir)"
azcopy copy --recursive "$container/*" "$temp_dir"
ln -sf "$(basename $temp_dir)" "$cache_dir/symlink"
mv -Tf "$cache_dir/symlink" "$destination"
符号链接只是一种包含文件名的特殊文件;它实际上并不以任何有意义的方式包含文件内容,也不必指向存在的文件。 mktemp(1) 默认情况下在 /tmp
中创建目录,这可能不在共享卷中。
想象一下,把一个物理文件夹放在一个物理文件柜里,在一张Post-It 纸条上写上the third drawer at the very front
,然后开车去另一栋楼,把纸条交给同事。 Post-It 注释(符号链接)仍然存在,但在其他建筑物(容器文件系统)的上下文中,它命名的位置并不是特别有意义。
解决此问题的最简单方法是要求 mktemp
直接在目标卷中创建文件,然后创建相对路径符号链接。
# extract the volume location (you may already have this)
volume_dir=$(dirname "$destination")
# force the download location to be inside the volume
# (mktemp --tmpdir option)
temp_dir=$(mktemp -d --tmpdir "$volume_dir")
# actually do the download
azcopy copy --recursive "$container/*" "$temp_dir"
# set the symlink to a relative-path symlink, since the directory
# and the link are in the same place; avoids problems if the volume
# is mounted in different places in the two containers
ln -sf $(basename "$temp_dir") "$destination"
上下文
我有一个包含两个容器的 pod:
main
其简单的工作是显示目录的内容sidecar
其职责是将 blob 存储的内容同步到预定义的目录中
为了实现原子同步,sidecar
将 blob 存储内容下载到新的临时目录中,然后在目标目录中切换符号链接。
目标目录使用 emptyDir
卷在两个容器之间共享。
问题
main
有符号链接但不能列出后面的内容。
问题
如何获取最新同步的数据?
附加信息
原因
我尝试实现 Apache Airflow with Git-Sync but, instead of using Git, I need to synchronize files from an Azure Blob storage. This is necessary because (1) my content is mostly dynamic and (2) the azureFile
volume type has some serious performance issues 正在做的事情。
同步例程
declare -r container='https://mystorageaccount.dfs.core.windows.net/mycontainer'
declare -r destination='/shared/container'
declare -r temp_dir="$(mktemp -d)"
azcopy copy --recursive "$container/*" "$temp_dir"
declare -r temp_file="$(mktemp)"
ln -sf "$temp_dir" "$temp_file"
mv -Tf "$temp_file" "$destination"
我们最终得到的结果:
$ ls /shared
container -> /tmp/tmp.doGz2U0QNy
$ ls /shared/container
file1.txt file2.txt
解决方案
我最初的尝试有两个错误:
- 卷中不存在符号链接目标
- 符号链接目标指向 sidecar 容器中的绝对路径,因此从主容器的角度来看,该文件夹不存在
修改后的例程如下:
declare -r container='https://mystorageaccount.dfs.core.windows.net/mycontainer'
declare -r destination='/shared/container'
declare -r cache_dir="$(dirname $destination)"
declare -r temp_dir="$(mktemp -d -p $cache_dir)"
azcopy copy --recursive "$container/*" "$temp_dir"
ln -sf "$(basename $temp_dir)" "$cache_dir/symlink"
mv -Tf "$cache_dir/symlink" "$destination"
符号链接只是一种包含文件名的特殊文件;它实际上并不以任何有意义的方式包含文件内容,也不必指向存在的文件。 mktemp(1) 默认情况下在 /tmp
中创建目录,这可能不在共享卷中。
想象一下,把一个物理文件夹放在一个物理文件柜里,在一张Post-It 纸条上写上the third drawer at the very front
,然后开车去另一栋楼,把纸条交给同事。 Post-It 注释(符号链接)仍然存在,但在其他建筑物(容器文件系统)的上下文中,它命名的位置并不是特别有意义。
解决此问题的最简单方法是要求 mktemp
直接在目标卷中创建文件,然后创建相对路径符号链接。
# extract the volume location (you may already have this)
volume_dir=$(dirname "$destination")
# force the download location to be inside the volume
# (mktemp --tmpdir option)
temp_dir=$(mktemp -d --tmpdir "$volume_dir")
# actually do the download
azcopy copy --recursive "$container/*" "$temp_dir"
# set the symlink to a relative-path symlink, since the directory
# and the link are in the same place; avoids problems if the volume
# is mounted in different places in the two containers
ln -sf $(basename "$temp_dir") "$destination"