利用 S3FS 将 S3 作为共享存储挂载到 Kubernetes Pod

阅读数:137 2019 年 9 月 25 日 15:22

利用 S3FS 将 S3 作为共享存储挂载到 Kubernetes Pod

背景介绍:

Amazon S3 是互联网存储解决方案,能让客户访问同一个具备可扩展性、可靠性、安全性和性能优越、快速价廉的数据存储基础设施。Amazon S3 提供了简单的 REST API 服务接口,可用于随时在 互联网上的任何位置存储和检索任何数量的数据。开发人员可以利用 Amazon S3 提供的接口,命令行接口或者支持不同语言的 SDK 访问 S3 服务。

为什么要将 Amazon S3 以文件存储的方式挂载到 Kubernetes 平台?

对于原来使用本地目录访问数据的应用程序,比如使用本地磁盘或网络共享盘保存数据的应用系统,如果用户希望把数据放到 S3 上,则需要修改数据的访问方式,比如修改为使用 AWS SDK 或 CLI 访问 S3 中存储的数据。

同时在 AWS 上实现 kubernetes 集群是很多用户的需求,无论是使用托管服务还是自建 kubernetes 集群,存储都是 kubernetes 集群搭建的重点。并且 docker 的部署方式也让客户程序减少了对于底层环境的依赖。为了让用户原来的应用系统能在不做修改的情况下直接使用 Amazon S3 服务,需要把 S3 存储桶作为目录挂载到用户 EKS 集群中的 worker 结点上。本文主要介绍如何利用 S3fs 将 S3 存储桶在 EKS 平台上以“sidecar”方式挂载到 Amazon EKS 的 worker 实例上的 pod 中,挂载后需要读写此存储桶的 pod 都可以对此桶进行读写,以实现共享存储功能。

什么是 S3FS ?

S3fs 是基于 FUSE 的文件系统,允许 Linux 和 Mac Os X 挂载 S3 的存储桶在本地文件系统,S3fs 能够保持对象原来的格式,S3FS 是 POSIX 的大子集,包括读 / 写文件、目录、符号链接、模式、uid/gid 和扩展属性,与 AmazonS3、Google 云存储和其他基于 S3 的对象存储兼容。关于 S3fs 的详细介绍,请参见: https://github.com/s3fs-fuse/s3fs-fuse

Kubernetes pod 中使用 S3FS 架构图:

利用 S3FS 将 S3 作为共享存储挂载到 Kubernetes Pod

前提条件:

1. 已经搭建完成 kubernetes 集群。

2.Worker 结点具备相关的权限,如:操作 S3 等权限。

实施过程:

1. 下载 S3fs 代码到 kubectl 可与 kubernetes master 结点交互执行的机器上:

Git clone https://github.com/freegroup/kube-s3.git

2. 如果此结点没有安装 aws cli,请按以下文档进行安装:

https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli-chap-install.html

3. 搭建镜像仓库(如有可使用现有的)

本文档使用 AWS ECR 来做镜像仓库:

a. 可根据此文档来创建仓库:
https://docs.aws.amazon.com/zh_cn/AmazonECR/latest/userguide/ECR_GetStarted.html
利用 S3FS 将 S3 作为共享存储挂载到 Kubernetes Pod

b. 使用如下命令来登录镜像仓库:

复制代码
$aws ecr get-login --no-include-email --region <region>

返回结果类似:

docker login -u AWS -p eyJwYXlsb2FkIjoiY1o5MTNIQUErVkdNZmhvTS9JdFJuMWNJK05yVTFyVU53ZFRPcWlTMW1KaVRoQ0tPYkwxdDlOaEtNL3MvOWpyelgrYzBXMXdHbDlCanJkTkVRNGVVWVR5QldHZnNHL3U0NytQVVZOMzkvN3hWTHFmL0IxSVp0ak1Tbk4vRVFxZ3RGZ2k4LzgwSEhhR2lJalU1L0lCbm1EeXJUQzVhQW5kU1M4TzBaSkdieEdGZWp3b2FOZ2F2TThzbXdMcFU2cWdHM3FUZmN2N0tleG1YS00rNE90VlR5dDBHNUdUVXhDdmlvaTFaZ1Ura1NtSlZURWlnRFZvSzFLVUViTG1IcXVRZkNWQkN5QTgvOG5tZW81REtIKzlIQ1N2QlBkSG02VWJwZ3BYUm82Zk1weXcrd25VYU1sVkJWdHl6Ymo1ZkhyRjhkbkFhanFnZ3lUSDhBT3hOYVZHYzBUaVdldFhlRWwreU1Ha1ZKZm4rRlBaNWxDSkNiVUlvTUFWUXZQeU5SY3AyTmNHNVZxQ0pJcGU0T3h2eEIyeVFkaHBRaStoOC9VM25Yc1l1VG1qcmFmUU1WbVRwNjB5VjBUcHBadWI4a2JyYXYyWXlhdnZCWGFZWG8wL3hzbkxwR2c5dzI0UkNvdWhYaVpWdlhFTG5VeHNpSmRKZFVQTTlGd0RTZ1ZoK3c1eG5VRDMxaXYrMzdtRWpUZ29Pd01QK2VlbERwT2xsR3VydFQ4KzgzTHJoT3E0ckZBeDgrVGhyTnpMYXdrKzFUSmpjemJGeEpncnpWNWhsSlMrR2JXUkJiazVuUXdlOGo2UHREV2xjUmJ2VFI1V1JDelFNdzNNZkllOXVTbGRWQ3V0cjVYQ3djT1NMYTdLc3JWcG8vV0JaWWh2Z05obHl0alpPVEVxaWh1b1pyMCtnL0ROZ3hObUlybnVDNzlxZUgzSVU2NFE0aUZnS0tYMnpyTjVrbzBpYWlzRzMzc2M5eS94djJJcXZSYVJySXh2OEl3eUUzaDFQWHVwUmowaSsyNWtiUTVKWERWU3hiKzdHcWQ4aXhjb21jVFFTNE5QWm14RHFHWWRUdTlrUHHeTJnN2hOd3IvbkJuWG1XeVZ5MmtMTVhYb0t0eHhvPSIsImRhdGFrZXkiOiJBUUVCQUhod20wWWFJU0plUnRKbTVuMUc2dXFlZWtYdW9YWFBlNVVGY2U5UnE4LzE0d0FBQUg0d2ZBWUpLb1pJaHZjTkFRY0dvRzh3YlFJQkFEQm9CZ2txaGtpRzl3MEJCd0V3SGdZSllJWklBV1VEQkFFdU1CRUVESWFXTXdkQVJ5S0E2aCtSb1FJQkVJQTdlT2JnMWtWbVNwTDV0UkxNWlNEWW5iM1poRHFRT3RYK2JDZXl2YW82WEp6a3ZxdElCcTRYZ05qcWJPRUs5cFRhNGVWVUlzUFRnSWJ4SWpVPSIsInZlcnNpb24iOiIyIiwidHlwZSI6IkRBVEFfS0VZIiwiZXhwaXJhdGlvbiI6MTU2MzQ3NzMzNX0= https://154900008054.dkr.ecr.us-east-1.amazonaws.com

c. 运行上一步中返回的 docker login 命令。此命令提供一个在 12 小时内有效的授权令牌
利用 S3FS 将 S3 作为共享存储挂载到 Kubernetes Pod

4. 确保您已经在集群中创建了“imagepullsecret”。(此命令中的 username & password 也在上面的命令中)

复制代码
kubectl create secret docker-registry artifactory –docker-server=<YOUR-REGISTRY>.docker.repositories.sap.ondemand.com –docker-username=<USERNAME> –docker-password=<PASSWORD> –docker-email=<EMAIL> -n <NAMESPACE>

举例如下:(此处密码是上步中的返回)

kubectl create secret docker-registry artifactory – docker-server=154998728054.dkr.ecr.us-east-1.amazonaws.com/respository –docker-username=aws –docker-password=eyJwYXlsb2FkIjoiOWtlY3ZSQnY4VGpEbkw4cFFlblZKS1VLbzJJVUpQeXVzMW1keEF2NmZ6ZjA1ZDFaMHA5T282R1ZsR2VEdjJEWEVzNXZ0TFZSYWhOUlZKK2JzdHk3a0xWTnNXZTIwL2ZGZ1lWaEdlaFN4Wjk2WGdrSDNrMDgweXAwV2VnSm9NSXlDT2x5RjB1d0RFc2Z4TDI3VGpYcUdrU0d5WHdVZmdCZnhJUU1NT2wrQ25SbE1rTUtxMDVlQk0zbU9ENXJ3N3E2c2p3MUZsTDliMmNyS29zQ1RRbVdCblcwZEs0cEtvZVhOcHc4eGZWZGxwMjdHaDNTWWtlRDl0S3Q4OUx3MURvSm1VbUtEVGVRV2lqTzRuWnV3SEI1NWVGdG1veUYycTd2cmdPOGlZQ29Nb3Y3SVpuV2NxaEQ4eTJUajlYUTVlamNmUit2TDk3dFV0R0c1WkFpVGlHWDlRc2JkUFMvdzB0ZEFUck5BaWhjQU56aEFnZDZpWmRTQ0Z0b3dMNS9Id0tPMXMrbjQrYXI3RlNMQjIyVnlxOXR3Ujl0cS9FZk1pcnNLY3ZEYU9peUxLYkxtd3hXMXltUTcvYzFGNFBxZ0Z0dFhjVis0dmVqRWRtRjJacnRzMnRUTWM5ZEtVK1JVWU02ZDBCOFpxZG9PRWNibUdUdTZJL0hFN0xtT25yVGFlOEdWSDkzQ0FWTVFGZFl2YzBXV2FDazFHeVhDcURYZXB6MGRidjdYYWpQRUNrc1ltNExtcW9PdytLN0tyM3pVTTJSbTlZOWRlTmFZUXoxRjhmYUlEaEgyWkJoT0dJQlBQUGlVWWJmVWgwNG1ZTWRIUVltRjRsSWlaVTllbEd4ZzVIY2ZLOUJyZkVrcmYvTVBRVWxVVm4rc1JzdjdPc3EvU3JvLytuNlBaRmh2VmZZQldIL3dPdjNIWklVb0pqV043S0FWb1VKVi9TNEpLaXJzbHU4SlR2YWEyZHRYT3FkVXQrOHF1bjIvb3VMMDVlVXovZDJ4MlBKM0pTZDViQkRSUUpkLzRNTmFtVlRTUjd1WHpCWUQvNGdlN29mZDBBY09hMlZkMitpRGkzVU85YmYydm9aY2k0R3NKd3R6WDRaMEtTcWxBK205ZTk5a01uZkxML0U1V3FwRVNSczFBNFB3cFNZajNKVDRvcTVJOTRXQ3F4WiszdWxxa3Nva1ZSNGFhMENZaWpkRmlWUWtoR0RzU1V2Mjk2dnBaUC9rb3hLYzlycDVBTzFEQUVhbS9McWFSQ1ZVUWtUMFA5bUpGUkJzQU5MQVJFK2I5QUlRYnNDc1FZcjVQUzZvUjhTUVRVWDRuR1dNU1d3enkvRTA3anBiRjVVNUllOUNKcVcvM3pOUVFXZVFnQjArWTdqN3NFK0ROS3ZIU0pQSWNFVmlqQVgrTnU1dDVQZjdSMVFyWjBuS09tS0FyY0FpVXB2N1Y2emNzdythVVhNN0IvT3dUNVZDaUdEazhqeFd6c2M3Sk5PQUJuNndoQS9IMjljSXpJVHgyb1QvK1RMRnpIQkhpaTdhR1plMWdOUENHRm5DRFBZZlJwQS93VUNnOTZvT0l6VlpBMko4QkpKbXBCTytPZ3NuNndKSnVkcGhIOUhCTXJIQVdjM0lvZXRiTGtFQ2tib1VoRW1pZUV3Q0F5ektuOGRkRzMrS3hxdVRIRURkSjVVQmdIS1dvV0JWYkVRTEtZQXg4V2lmK3dtOU1CREpEeWswZ3psNjNMVnBIWlNlbG01SFQ4U3RCREJJVGdQYTRsM1kyMElySFpJazFDYWtkcFhMVUxvQjE1cm1hOXRIbVFVaGI5T3U4L0RKRjM4WWJuWVZlN2NxYW0rbDJqZXJZYzNaYWFIQ0kwbHdKeEJwYkxNbjVsZDNvWjNjSW5wOVBRbThFa0ZoeWE5elhvQnl1R0pKMS93djIrYjFSekxHVWhyUTR4V0ZqZUxaMWhKaHVOdEFVR0J5NGYwbWljQ2xMbklYVmVKczVMSy9MN1dURGVBeG1DOHozbzA3NElONnNsdVUxdnBocUNJR1ByM0Z3Q05WR281N3VVdklIazd3VnIzYlBMT0QrUEx1dVlCeUVETXhlS2NYU083b3p4WkxqdGJRV1pBekp0ZTRnSnhRMkkwaVBYWHZBST0iLCJkYXRha2V5IjoiQVFFQkFIaHdtMFlhSVNKZVJ0Sm01bjFHNnVxZWVrWHVvWFhQZTVVRmNlOVJxOC8xNHdBQUFINHdmQVlKS29aSWh2Y05BUWNHb0c4d2JRSUJBREJvQmdrcWhraUc5dzBCQndFd0hnWUpZSVpJQVdVREJBRXVNQkVFREd9

5. 配置 configmap

a.cd kube-s3/yaml/

b. 将 configmap_secrets_template.yaml 复制到 configmap_secrets.yaml 并将您的 aksk 放置在正确的位置,如下:

复制代码
apiVersion: v1
kind: ConfigMap
metadata:
name: s3-config
data:
S3_BUCKET: <YOUR-S3-BUCKET-NAME>
AWS_KEY: <YOUR-AWS-TECH-USER-ACCESS-KEY>
AWS_SECRET_KEY: <YOUR-AWS-TECH-USER-SECRET>

6. 构建和部署

a. 修改 build.sh 文件,增加如下内容:

复制代码
#replace version
REPOSITORY1=<ECR 对应的 repository>
PROJECT1=kube-s3

b. 修改 Dockerfile, 注意红色字体:

复制代码
/usr/bin/s3fs $S3_BUCKET $MNT_POINT -f -o endpoint=${S3_REGION},nonempty,allow_other,use_cache=/tmp,max_stat_cache_size=1000,stat_cache_expire=900,retries=5,connect_timeout=10
ENV S3_REGION 'us-east-2'
修改后整体文件如下:
VERSION=$1
PROJECT=kube-s3
REPOSITORY=154998728054.dkr.ecr.us-east-1.amazonaws.com
#replace version
REPOSITORY1=cp-enablement.docker.repositories.sap.ondemand.com
PROJECT1=kube-s3
# causes the shell to exit if any subcommand or pipeline returns a non-zero status.
set -e
########################################################################################################################
# build the new docker image
########################################################################################################################
#
echo '>>> Building new image'
# Due to a bug in Docker we need to analyse the log to find out if build passed (see https://github.com/dotcloud/docker/issues/1875)
docker build --no-cache=true -t $REPOSITORY/$PROJECT:$VERSION . | tee /tmp/docker_build_result.log
RESULT=$(cat /tmp/docker_build_result.log | tail -n 1)
if [[ "$RESULT" != *Successfully* ]];
then
exit -1
fi
########################################################################################################################
# push the docker image to your registry
########################################################################################################################
#
echo '>>> Push new image'
docker push $REPOSITORY/$PROJECT:$VERSION
########################################################################################################################
# deploy your YAML files into your kubernetes cluster
########################################################################################################################
kubectl apply -f ./yaml/configmap_secrets.yaml
# Apply the YAML passed into stdin and replace the version string first
cat ./yaml/daemonset.yaml | sed "s/$REPOSITORY1\/$PROJECT1/$REPOSITORY\/$PROJECT:$VERSION/g" | kubectl apply -f -

b. 运行如下命令:

复制代码
./build.sh 1.0

c. 运行如下命令检查 pod 是否正常运行

复制代码
kubectl get pods

7. 创建 demo pod 来验证 S3fs 是否可以正常工作:

a. kubectl apply -f ./yaml/example_pod.yaml

b. kubectl get pods

c. kubectl exec -ti test-pd sh

d. ls -la /var/s3

e. 创建一个文件

利用 S3FS 将 S3 作为共享存储挂载到 Kubernetes Pod

8. 在 S3 和 host 中去验证,此文件是否存在。

利用 S3FS 将 S3 作为共享存储挂载到 Kubernetes Pod

注:详情请参考: https://github.com/freegroup/kube-s3

注意

如果对于性能有很强的需求并且要求和传统文件系统的体验一致,那么此方案并不适用,可以考虑使用 AWS 的 EBS 来做 kubernetes 的持久存储。

一般情况下 S3 不能提供像本地文件系统一样的功能。具体如下:

  • 随机写或追加写需要重写整个文件;
  • 由于网络延迟,所以元数据的操作如列出目录等的性能较差;
  • 最终一致性会暂时产生中间数据(AMAZON S3 数据一致性模型);
  • 没有文件和目录的原子重命名;
  • 安装相同存储桶的多个客户端之间没有协调;
  • 没有硬链接;

作者介绍:

王建利,AWS 解决方案架构师,主要负责企业级大客户的上云工作,服务客户涵盖从能源,互联网,传统生产制造,擅长 DevOps 和容器领域。具备 15 年 IT 专业服务经验,历任程序设计师、项目经理、解决方案架构师。

本文转载自 AWS 技术博客。

原文链接:
https://amazonaws-china.com/cn/blogs/china/use-u3fs-as-shared-storage-to-kubernetes-pod/

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布