前言
某個案子,要整個翻掉重做,這次要讓VM的機器跟GKE的pod能夠同時存取一個儲存空間,
預計使用Google Cloud Storage,踩了一個早上的坑。
正文
預計做兩個項目
-
在VM上面掛載gcs的資料夾
-
在GKE 上面的pod同時掛載 gcs的資料夾
-
在VM上面掛載gcs的資料夾
安裝方式,目前我的vm是 RedHat 所以用下面的方式,CentOS也是用同樣的方式 -
Configure the gcsfuse repo:
sudo tee /etc/yum.repos.d/gcsfuse.repo > /dev/null <<EOF
[gcsfuse]
name=gcsfuse (packages.cloud.google.com)
baseurl=https://packages.cloud.google.com/yum/repos/gcsfuse-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
- Install gcsfuse:
sudo yum install gcsfuse
完成,其他安裝方式,請參考GoogleCloudPlatform/gcsfuse/install.md
登入使用,
這邊先使用 gcloud auth login 做測試
先建立資料夾 mkdir upload
掛載 gcsfuse my-bucket upload
卸除掛載 fusermount -u upload
Debug用
gcsfuse --foreground --debug_gcs --debug_http --debug_fuse --debug_invariants --key-file=/home/user/Downloads/my-key.json mybucket /upload
永久加入GOOGLE_APPLICATION_CREDENTIALS變數
開啟 /etc/profiles
新增 export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/my-key.json"
修改檔案後要想馬上生效還要執行#
source /etc/profile不然只能在下次重進此使用者時生效。
ref.Linux系統環境變數和別名設定(永久生效和臨時生效)
附註,json檔案的取得在 IAM角色內的服務賬戶
ref.創建和管理服務帳號密鑰。
新增完GCS,記得把權限給服務賬戶。記得選擇完整權限
(Fig. 1)
自動掛載
有權限了已後,再來就是自動掛載了。
到/etc/fstab上,輸入
my_bucket /home/ezio/upload gcsfuse key_file=key/key.json,rw,user,allow_other,uid=1008,gid=1009 0 0
重開機測試看看,收工。
ref.
How to use mount command in fstab file
gcsfuse automount on a non root user
查詢目前登入使用者的uid 跟 gid
id $(whoami)
如果要看全部使用者的話,
cat /etc/passwd
ref.Linux 的帳號與群組
-
在GKE 上面的pod同時掛載 gcs的資料夾
基本的方式,
先自己產生一個 image
FROM golang:1.14-alpine AS build-env
ENV GO111MODULE on
# WORKDIR /工作名錄名稱 當前的工作目錄名稱,若是不存在則會新建該目錄,
# 需要注意的是copy跟run的指令都是以WORKDIR為當前目錄下去跑的,
# 運用的時候需要注意相對位置。
WORKDIR $GOPATH/src
RUN go get -u github.com/googlecloudplatform/gcsfuse
COPY key.json .
FROM alpine:3.6
RUN apk add --no-cache ca-certificates fuse && rm -rf /tmp/*
COPY --from=build-env /go/bin/gcsfuse /usr/local/bin
COPY --from=build-env /go/src/key.json /
WORKDIR /
佈署 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: gcs-fuse
version: v1
namespace: debug
name: gcsfuse-test
spec:
replicas: 1
selector:
matchLabels:
app: gcs-fuse
version: v1
template:
metadata:
labels:
app: gcs-fuse
version: v1
spec:
containers:
- name: gcsfuse-test
image: gcr.io/your-project/gcsfuse:v1.2
# image: golang:1.14-alpine
# command: [ "/bin/sh", "-c", "--" ]
# args: [ "while true; do sleep 600; done;" ]
securityContext:
privileged: true
command:
- "/bin/sh"
- "-c"
- "while true; do mkdir /upload ; gcsfuse --key-file=key.json your-bucket /folder; sleep 600; done; "
如果跟現有的程式整合的話,
由於要執行多行指令,需使用shellScript的方式執行指令。
可能會遇到下列情況
"exec: “/init.sh”: permission denied
在Dockerfile上修改權限
RUN chmod +x /init.sh
ref.
getting permission denied in docker run
exec user process caused “exec format error”
有人說在sh的頂端加上
#!/bin/bash
但我試了沒用,在猜想可能是alpine linux沒有bash導致
所以改用下面這個
ENTRYPOINT ["sh","/run.sh"]
ref. standard_init_linux.go:178: exec user process caused “exec format error”
執行sh時卡住,debug方式
用if else檢查
if mkdir /upload; then
echo "mkdir directory! Success" 1>&2
gcsfuse --key-file=key.json yellow-video /upload
else
echo "Could not mkdir directory!" 1>&2
exit 1
fi
另外,最後找出來原因是因為先執行go的程式,導致後續卡住,所以先建立資料夾後,再執行go
沒有留言:
張貼留言