CSI (Container Storage Interface) 정보
CSIsms Kubernetes와 같은 컨테이너 오케스트레이션 시스템(CO)의 컨테이너화 된 워크로드에 임의 블록 및 파일 스토리지 시스템을 노출하기 위한 표준이다.
CSI를 사용하면 타사 스토리지 제공 업체가 핵심 Kubernetes 코드를 건드리지 않고도 Kubernetes에서 새로운 스토리지 시스템을 노출하는 플러그인을 작성하고 배포할 수 있다.
Amazon EBS CSI Driver 정보
따라서 Amazon Elastic Block Store (Amazon EBS) CSI (Container Storage Interface) 드라이버를 통해 EKS 클러스터가 Persistent Volume에 대한 Amazon EBS Volume의 Life Cycle을 관리할 수 있는 CSI 인터페이스를 제공한다.
1. IAM 정책 구성
export EBS_CSI_POLICY_NAME="Amazon_EBS_CSI_Driver"
mkdir ${HOME}/environment/ebs_statefulset
cd ${HOME}/environment/ebs_statefulset
# download the IAM policy document
curl -sSL -o ebs-csi-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/docs/example-iam-policy.json
# Create the IAM policy
aws iam create-policy \
--region ${AWS_REGION} \
--policy-name ${EBS_CSI_POLICY_NAME} \
--policy-document file://${HOME}/environment/ebs_statefulset/ebs-csi-policy.json
# export the policy ARN as a variable
export EBS_CSI_POLICY_ARN=$(aws --region ${AWS_REGION} iam list-policies --query 'Policies[?PolicyName==`'$EBS_CSI_POLICY_NAME'`].Arn' --output text)
2. 서비스 Account에 대한 IAM 역할 구성
# Create an IAM OIDC provider for your cluster
eksctl utils associate-iam-oidc-provider \
--region=$AWS_REGION \
--cluster=tango-bmt-eks \
--approve
# Create a service account
eksctl create iamserviceaccount \
--cluster tango-bmt-eks \
--name ebs-csi-controller-irsa \
--namespace kube-system \
--attach-policy-arn $EBS_CSI_POLICY_ARN \
--override-existing-serviceaccounts \
--approve
3. Amazon EBS CSI 드라이버 배포
# add the aws-ebs-csi-driver as a helm repo
helm repo add aws-ebs-csi-driver https://kubernetes-sigs.github.io/aws-ebs-csi-driver
설치할 aws-ebs-csi-driver 버전 검색
$ helm search repo aws-ebs-csi-driver
NAME CHART VERSION APP VERSION DESCRIPTION
aws-ebs-csi-driver/aws-ebs-csi-driver 1.0.0 1.0.0 A Helm chart for AWS EBS CSI Driver
위에서 나온 1.0.0 으로 설치
helm upgrade --install aws-ebs-csi-driver \
--version=1.0.0 \
--namespace kube-system \
--set serviceAccount.controller.create=false \
--set serviceAccount.snapshot.create=false \
--set enableVolumeScheduling=true \
--set enableVolumeResizing=true \
--set enableVolumeSnapshot=true \
--set serviceAccount.snapshot.name=ebs-csi-controller-irsa \
--set serviceAccount.controller.name=ebs-csi-controller-irsa \
aws-ebs-csi-driver/aws-ebs-csi-driver
Release "aws-ebs-csi-driver" does not exist. Installing it now.
NAME: aws-ebs-csi-driver
LAST DEPLOYED: Sat May 8 13:45:47 2021
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
To verify that aws-ebs-csi-driver has started, run:
kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-ebs-csi-driver,app.kubernetes.io/instance=aws-ebs-csi-driver"
$ kubectl -n kube-system rollout status deployment ebs-csi-controller
Waiting for deployment "ebs-csi-controller" rollout to finish: 0 of 2 updated replicas are available...
Waiting for deployment "ebs-csi-controller" rollout to finish: 1 of 2 updated replicas are available...
deployment "ebs-csi-controller" successfully rolled out
정상적으로 설치가 완료되었다.
이제 이 EBS를 위한 StorageClass를 정의한다.
아래 예시는 mysql을 위한 gp2 storage class 구성 예시이다.
cat << EoF > ${HOME}/environment/ebs_statefulset/mysql-storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: mysql-gp2
provisioner: ebs.csi.aws.com # Amazon EBS CSI driver
parameters:
type: gp2
encrypted: 'true' # EBS volumes will always be encrypted by default
reclaimPolicy: Delete
mountOptions:
- debug
EoF
- storage class name은 mysql-gp2
- provisioner는 ebs.csi.aws.com
- volume type: General Purpose SSD volumes (gp2)
- encrypted: true
kubectl 명령어로 storage class를 생성한다.
kubectl create -f mysql-storageclass.yaml
$ kubectl describe sc mysql-gp2
Name: mysql-gp2
IsDefaultClass: No
Annotations: <none>
Provisioner: ebs.csi.aws.com
Parameters: encrypted=true,type=gp2
AllowVolumeExpansion: <unset>
MountOptions:
debug
ReclaimPolicy: Delete
VolumeBindingMode: Immediate
Events: <none>
실제 pod에서 이 storageclass를 통해 volumeClaim을 생성할 수 있다.
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: mysql-gp2
resources:
requests:
storage: 10Gi
실제 예시
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: mysql
name: mysql
spec:
selector:
matchLabels:
app: mysql
serviceName: mysql
replicas: 2
template:
metadata:
labels:
app: mysql
spec:
initContainers:
- name: init-mysql
image: mysql:5.7
command:
- bash
- "-c"
- |
set -ex
# Generate mysql server-id from pod ordinal index.
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
echo [mysqld] > /mnt/conf.d/server-id.cnf
# Add an offset to avoid reserved server-id=0 value.
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
# Copy appropriate conf.d files from config-map to emptyDir.
if [[ $ordinal -eq 0 ]]; then
cp /mnt/config-map/master.cnf /mnt/conf.d/
else
cp /mnt/config-map/slave.cnf /mnt/conf.d/
fi
volumeMounts:
- name: conf
mountPath: /mnt/conf.d
- name: config-map
mountPath: /mnt/config-map
- name: clone-mysql
image: gcr.io/google-samples/xtrabackup:1.0
command:
- bash
- "-c"
- |
set -ex
# Skip the clone if data already exists.
[[ -d /var/lib/mysql/mysql ]] && exit 0
# Skip the clone on leader (ordinal index 0).
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
[[ $ordinal -eq 0 ]] && exit 0
# Clone data from previous peer.
ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
# Prepare the backup.
xtrabackup --prepare --target-dir=/var/lib/mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "1"
ports:
- name: mysql
containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 500m
memory: 1Gi
livenessProbe:
exec:
command: ["mysqladmin", "ping"]
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
exec:
# Check we can execute queries over TCP (skip-networking is off).
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
initialDelaySeconds: 5
periodSeconds: 2
timeoutSeconds: 1
- name: xtrabackup
image: gcr.io/google-samples/xtrabackup:1.0
ports:
- name: xtrabackup
containerPort: 3307
command:
- bash
- "-c"
- |
set -ex
cd /var/lib/mysql
# Determine binlog position of cloned data, if any.
if [[ -f xtrabackup_slave_info ]]; then
# XtraBackup already generated a partial "CHANGE MASTER TO" query
# because we're cloning from an existing follower.
mv xtrabackup_slave_info change_master_to.sql.in
# Ignore xtrabackup_binlog_info in this case (it's useless).
rm -f xtrabackup_binlog_info
elif [[ -f xtrabackup_binlog_info ]]; then
# We're cloning directly from leader. Parse binlog position.
[[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
rm xtrabackup_binlog_info
echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
fi
# Check if we need to complete a clone by starting replication.
if [[ -f change_master_to.sql.in ]]; then
echo "Waiting for mysqld to be ready (accepting connections)"
until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done
echo "Initializing replication from clone position"
# In case of container restart, attempt this at-most-once.
mv change_master_to.sql.in change_master_to.sql.orig
mysql -h 127.0.0.1 <<EOF
$(<change_master_to.sql.orig),
MASTER_HOST='mysql-0.mysql',
MASTER_USER='root',
MASTER_PASSWORD='',
MASTER_CONNECT_RETRY=10;
START SLAVE;
EOF
fi
# Start a server to send backups when requested by peers.
exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
"xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 100m
memory: 100Mi
volumes:
- name: conf
emptyDir: {}
- name: config-map
configMap:
name: mysql-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: mysql-gp2
resources:
requests:
storage: 10Gi
'TANGO > 기본 환경 구성' 카테고리의 다른 글
Prometheus와 Grafana 구성 (0) | 2021.05.08 |
---|---|
Amazon EFS CSI Driver (0) | 2021.05.08 |
AWS Load Balancer Controller (Ingress Controller) 설치 (0) | 2021.05.08 |
kube-ops-view 설치 (0) | 2021.05.08 |
ELB 서비스 Role 확인 (0) | 2021.05.08 |