본문 바로가기
Kubernetes

[미니프로젝트] - metal LB 사용하여 WordPress와 MySQL을 퍼시스턴트 볼륨에 배포 (with 시크릿)

by Nirah 2023. 1. 4.

개념 공부

 

아래 쿠버네티스 공식문서를 그대로 따라하기만해서는 잘 되지 않기때문에 많은 검색과 트러블슈팅을 요구한다.

아래 글에 더해서 metal LB를 사용하는 방법을 따로 찾아봐야 한다.

 

 

전체 개요

https://kubernetes.io/ko/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/

 

예시: WordPress와 MySQL을 퍼시스턴트 볼륨에 배포하기

이 튜토리얼은 WordPress 사이트와 MySQL 데이터베이스를 Minikube를 이용하여 어떻게 배포하는지 보여준다. 애플리케이션 둘 다 퍼시스턴트 볼륨과 퍼시스턴트볼륨클레임을 데이터를 저장하기 위해

kubernetes.io

 

 

 

PersistentVolumes

WordPress와 MySQL 둘 다 퍼시스턴트 볼륨과 퍼시스턴트볼륨클레임을 데이터를 저장하기 위해 사용한다.

알다 싶이 퍼시스턴트볼륨은 파드 라이프사이클과 독립적이며 재시작, 재스케줄링이나 파드를 삭제할 때에도

데이터를 보존한다.

 

pv와 pvc에 대한 이해를 높이려면 아래 공식페이지 예제의 언어가 제일 이해가 쉬웠다.

사라지고 재배치되는 nginx pod의 index파일을 쉽게 고정하기 위해 pv를 쓰는 내용들이다.

https://kubernetes.io/ko/docs/tasks/configure-pod-container/configure-persistent-volume-storage/

 

스토리지로 퍼시스턴트볼륨(PersistentVolume)을 사용하도록 파드 설정하기

이 페이지는 스토리지에 대해 퍼시스턴트볼륨클레임(PersistentVolumeClaim)을 사용하도록 파드를 설정하는 방법을 보여준다. 과정의 요약은 다음과 같다. 클러스터 관리자로서, 물리적 스토리지와

kubernetes.io

 

 

 

 

 

 

Metal LB

공식 설치글

https://metallb.universe.tf/installation/

 

MetalLB, bare metal load-balancer for Kubernetes

Installation Before starting with installation, make sure you meet all the requirements. In particular, you should pay attention to network addon compatibility. If you’re trying to run MetalLB on a cloud platform, you should also look at the cloud compat

metallb.universe.tf

AWS나 GCP 같은 퍼블릭 클라우드 플랫폼에서는 기본적으로 쿠버네티스에서 로드밸런서를 지원하지만

로컬에 설치된 K8S는 로드밸런서를 사용할 수 없다.

가장 큰 불편한점은 ingress controller 접속 방법이다.

ingress controller은 서비스 타입이 로드밸런서를 사용하지 않으면 <노드IP>:<nodeport>로 접근해야 하는데,

마치 google.com을 접속하기 위해 google.com:32000 을 입력하는 것이 필요햐다.

 

오픈소스 로드밸런서 프로젝트인 metal lb를 설치해야  loadbalancer type을 사용할 수 있다.

그래야 서비스를 외부에 노출시킬 수 있다.

MetalLB는 2가지 모드를 지한다. 이 글에서는 L2모드를 채택하겠다.

  • L2
  • BGP

 

 

 

 

 

 

 

목차

  • Metal LB 설치
  • 퍼시스턴트볼륨클레임과 퍼시스턴트볼륨 생성
  • 다음을 포함하는 kustomization.yaml 생성
    • 시크릿 생성자
    • MySQL 리소스 구성
    • WordPress 리소스 구성
  • kubectl apply -k ./로 생성한 kustomization 을 적용

 

 

 

 

Metal LB 설치

 

kubectl edit configmap -n kube-system kube-proxy

에서 아래와 같이 수정하면 된다.

구조가 아래와 같이 깔끔하지 않으므로 strictARP 를 찾아서 수정해 볼것.

apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true

 

위 작업을 자동으로 좀더 쉽게 하려면 아래 sed 코드를 입력하면 한번에 해결이다.

# 적용 전 변경사항 확인용
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system

# 적용
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system

MetalLB를 설치하려면 매니페스트를 적용한다.

최신버전에 role 관련 부분이 없어 구버전 매니페스트 한번 더 적용해준다.

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml

 

이렇게 하면 metallb-system 네임스페이스 아래 클러스터에 MetalLB가 배포된다.

 

mkdir /mp

 

 

 externalIP주소를 설정 / 레이어 2 구성

맨 밑의 addresses: 는 Workcernode IP 등 노드가 갖고 있는 ip를 사용하는것이 정석이며

 externalIP로 사용할 범위를 적어주면 그 범위로 로드밸런싱이 된다.

만약 현재의 host가 고정 ip를 사용하고 있으며, ip의 여유가 없는 경우 host ip를 중복해서 넣어주면 된다.

cat << EOF > /mp/metalLBconfig.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.108.100-192.168.108.200
EOF

 

k apply -f /mp/metalLBconfig.yaml

다음과 같이 네임스페이스를 확인하면 metallb-system Active 상태 확인 가능

 

MetalLB 파드 5개 확인 중 컨트롤러 1개, speaker 3개 확인

 

자세한 옵션과 설정은 실행되고 있는 컨피그맵의 yaml 확인 명령어인 -o yaml 사용

내가 지정한 로드밸런싱용 ip 범위와 인증서 해시 등등의 정보가 잘 들어가 있다.

 kubectl get pods -n metallb-system -o yaml

 

 

 

 

 

퍼시스턴트볼륨클레임과 퍼시스턴트볼륨 생성

많은 클러스터 환경에서 설치된 기본 스토리지클래스(StorageClass)가 있다. 퍼시스턴트볼륨클레임에 스토리지클래스를 지정하지 않으면 클러스터의 기본 스토리지클래스를 사용한다.

퍼시스턴트볼륨클레임이 생성되면 퍼시스턴트볼륨이 스토리지클래스 설정을 기초로 동적으로 프로비저닝된다.

 

Pods 에서 Persistent volume 을 사용하기 위해 각 Node 마다 50GB 볼륨을 할당하고 한 디렉토리에 마운트 한다.

mkdir /data001/{pv0001,pv0002}

 

지금 구성에서는 K8S Cluster 를 스스로 운영하기 때문에 PV 설정이 필요하고, GKE 와 같이 Cluster 를 구성해 주는 서비스의 경우 PVC 만 설정해서 사용하면 된다.

 

 

pv 설정 (한 서비스당 25G씩 할당한다)

cat > /mp/pv.yaml <<EOF

# wordpress
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv0001
  labels:
    type: local
spec:
  capacity:
    storage: 25Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data001/pv0001"
---
# mysql
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv0002
  labels:
    type: local
spec:
  capacity:
    storage: 25Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data001/pv0002"
EOF

 

kubectl apply -f /mp/pv.yaml 

kubectl get pv

 

 

 

 

PVC (Persistent Volume Claim) 생성 

 

PVC 는 사용자가 Pod 를 만들면서 요청하는 스토리지로 PV 가 있어야 생성된다. 

Wordpress 와 MySQL 이 각각 다른 PVC 를 사용하도록 생성한다.

별도로 PV 를 지정하지 않아도  PV 에 알아서 할당된다.

 

cat > /mp/pvc.yaml <<EOF

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: wordpress-volumeclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-volumeclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
EOF

 

kubectl apply -f /mp/pvc.yaml

kubectl get pvc

 

진짜로 다시 pv쪽을 확인하면 pvc가 알아서 짝 맞춰서 바운딩돼있다.

kubectl get pv

 

 

 

 

Password secret 설정

mySQL Root 패스워드를 해쉬 암호화한다.

mysql root 패스워드를 secret object 에 저장한다.

cat > /secret-mysql.yaml << EOF

#secret-mysql.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysql-root
type: Opaque
data:
  password: SXQx
EOF

확인해보자.

kubectl describe secret

 

 

 

MySQL Pod/Service 배포

 

MySQL 이 설치된 Pod 를 배포하면서 Database , User, User password 도 함께 설정해준다.

아까 설정한 pvc에 대한 내용도 넣자.

cat > /mp/mysql.yaml << EOF

# Pods 배포
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-root
                  key: password
            - name: MYSQL_DATABASE # 구성할 database명
              value: k8sdb
            - name: MYSQL_USER # database에 권한이 있는 user
              value: k8suser
            - name: MYSQL_ROOT_HOST # 접근 호스트
              value: '%'  
            - name: MYSQL_PASSWORD # database에 권한이 있는 user의 패스워드
              value: admin
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-volumeclaim
---
# Service 배포
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  type: ClusterIP
  ports:
    - port: 3306
  selector:
    app: mysql
    
EOF

kubectl apply -f /mp/mysql.yaml

확인

 

Wordpress Pod/Service 배포

ordpress pod 배포 파일에는 MySQL 접근이 가능한 정보가 포함되어야 한다. 

 

cat > /mp/wordpress.yaml << EOF

# Pod 배포
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
        - image: wordpress
          name: wordpress
          env:
          - name: WORDPRESS_DB_HOST
            value: mysql:3306
          - name: WORDPRESS_DB_NAME
            value: k8sdb
          - name: WORDPRESS_DB_USER
            value: k8suser
          - name: WORDPRESS_DB_PASSWORD
            value: admin
          ports:
            - containerPort: 80
              name: wordpress
          volumeMounts:
            - name: wordpress-persistent-storage
              mountPath: /var/www/html
      volumes:
        - name: wordpress-persistent-storage
          persistentVolumeClaim:
            claimName: wordpress-volumeclaim
---
# Service 배포
apiVersion: v1
kind: Service
metadata:
  labels:
    app: wordpress
  name: wordpress
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    app: wordpress
    
EOF

kubectl apply -f /mp/wordpress.yaml

 

Wordpress 웹 접속

아래와 같이 워드프레스의 pods ip로 curl을 하면 내용물이 잘 뜬다.

curl 172.16.51.70/wp-admin/install.php

 

Wordpress 가 기동된 Pod 의 노드 IP 와 Wordpress 서비스의 external-ip 로 웹 브라우저를 통해 접속한다.

아래와 같은 화면이 뜨면성공이다.

 

 

 

 

 

 

 

 

 

 

 

'Kubernetes' 카테고리의 다른 글

[미니프로젝트] Nginx 소스 Statefulset  (0) 2023.01.29
프로젝트 구상도  (0) 2023.01.19
ingress  (0) 2023.01.04
secret  (0) 2023.01.04
ConfigMap (환경변수)  (0) 2023.01.04