세미프로젝트 - 쿠버네티스 오브젝트 생성 (3/9)

최수환·2023년 3월 10일
0

Kubernetes

목록 보기
54/75
post-thumbnail

세미프로젝트 개요

  • 이번 세미프로젝트는 하루정도로 아주 간단한 프로젝트로 진행할 것이다.
  • 프로젝트에서 해야할 것은 Wordpress App 구축, Mysql App 구축 이다.
  • 주로 App을 구성하는 각 기능에 대해 YAML파일을 작성하는 프로젝트이다.

프로젝트 목표

  • 이번 프로젝트는 간단하게 기능별로 YAML파일을 작성하는 것이고 프로젝트 기간도 하루이다. 따라서 거창하게 아키텍처를 설계하고 구축하는 것보다는 기존의 강사님의 코드나, 구글링 등을 최대한 보지 않고 Explain command와 쿠버네티스 공식문서를 이용해 스스로 YAML파일을 작성해보는 것을 중점으로 두었다.
  • 가능한 구성조건을 모두 만족하는 App을 구축한다.
  • 팀원 모두가 동일하게 모든 구성요건에 대해서 완성시키는 것을 목표로 했다.

App 구성 조건

  • Wordpress App

    • 디플로이먼트로 배포
    • 프로브와 리소스를 정의해야한다.
    • HPA를 사용하여 Autoscailing이 가능하게 한다.
    • Secret과 ConfigMap을 사용
    • PVC를 부착하여 스토리지와 연결한다
    • 네트워크 : 서비스와 Ingress 리소스를 사용
  • Mysql App

    • statefulset으로 배포
    • 프로브와 리소스 정의
    • 이중화를 위한 Read Replica생성
    • ConfigMap과 Secret 사용
    • PVC를 이용하여 스토리지와 연결
    • 네트워크 : 서비스 리소스 사용

Wordpress 구축

Deployment 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  labels:
    apps: wordpress
spec:
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  minReadySeconds: 20
  selector:
    matchLabels:
      apps: wordpress
      tier: frontend
  replicas: 3
  template:
    metadata:
      name: myapp-pod
      labels:
        apps: wordpress
        tier: frontend
    spec:
      containers:
      - name: nginx
        image: wordpress:5.9.1-php8.1-apache
        ports:
        - containerPort: 80
          protocol: TCP
        volumeMounts:
        - name: myapp-volume
          mountPath: /var/www/html/
        livenessProbe:
          httpGet:
            path: /
            port: 80
        startupProbe:
          httpGet:
            path: /
            port: 80
        readinessProbe:
          httpGet:
            path: /
            port: 80
        resources:
          requests:
            memory: "128Mi"
            cpu: "500m"
      volumes:
      - persistentVolumeClaim:
          claimName: myapp-pvc
        name: myapp-volume
  • 워드프레스 이미지로 생성된 컨테이너를 가지고 있는 파드를 총 세개 생성한다.
  • 생성한 PVC를 마운트해서 동적으로 PV를 생성하여 NFS스토리지 연결하였다.
  • Request는 cpu 500밀리코어로 설정했다.
  • Probe는 총 세개를 설정하였고, 모두 httpGet방식으로 설정했다.

PVC 생성

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myapp-pvc
  labels:
    apps: wordpress
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs-client
  • PVC가 PV를 동적으로 생성해서 PV에 요청하는 자원은 1G로 설정
  • 스토리지 클래스는 nfs-client 설정

Ingress 생성

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ing
spec:
  tls:
  - secretName: myapp-tls-secret
  defaultBackend:
    service:
      name: myapp-svc
      port:
        number: 80
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-svc
            port:
              number: 80
  • L7에서 동작하는 네트워크 리소스 Ingress 생성
  • 외부에서 호스트IP만을 가지고 접속할 수 있도록 하는 역할

Service 생성

apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
  labels:
    apps: wordpress
spec:
  ports:
  - port: 80
    targetPort: 80
    nodePort: 31111
  type: NodePort
  selector:
    apps: wordpress
    tier: frontend
  • Ingress뒤에 L4에서 작동할 Nodeport타입의 서비스 생성

HPA 생성

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deploy
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  • 세개의 파드의 request cpu를 기준으로 100%를 설정한다.
  • 세개의 파드의 cpu활성화율의 평균을 측정을 해서 70%가 넘어가면 Auto Scailing을 한다.

Ingress-termination 생성

apiVersion: v1
kind: Secret
metadata:
  name: myapp-tls-secret
type: kubernetes.io/tls
data:
  tls.crt: # base64로 인코딩된 crt 삽입
  tls.key: # base64로 인코딩된 key 삽입 
  • key와 crt를 생성하여 인코딩 후 secret 리소스에 삽입한다
  • ingress-termination을 구현하기 위해 ingress의 tls에 생성한 secret을 추가
  • ingress외부에서 암호화 통신(https)을 하고, ingress를 통해 내부로 들어오면 평문통신(http)을 하게끔 Ingress-termination을 설정

  • https 통신이 되는 것을 확인
  • CA기관에서 인증받은 인증서로 생성한 https통신이 아니기 때문에 안전하지 않은 페이지가 뜨는 것을 확인

  • '안전하지 않음으로 이동'을 클릭하면 정상적으로 Wordpress가 뜨는 것을 볼 수 있다.

Mysql 구축

Statefulset 생성

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mydb-statefulset
  labels:
    apps: wordpress
spec:
  selector:
    matchLabels:
      apps: wordpress
      tier: mysql
  replicas: 1
  serviceName: mysql-svc
  template:
    metadata:
      labels:
        apps: wordpress
        tier: mysql
      name: mydb
    spec:
      containers:
      - name: database
        image: mysql:5.7
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        volumeMounts:
        - name: mysql-volume
          mountPath: /var/lib/mysql
        startupProbe:
          exec:
            command:
            - mysqladmin
            - ping
        livenessProbe:
          exec:
            command: ['mysqladmin','ping']
      volumes:
      - name: mysql-volume
        persistentVolumeClaim:
          claimName: mysql-pvc
  • 스테이트 풀셋 리소스에서 mysql:5.7 이미지로 생성한 컨테이너를 갖고 있는 파드를 한개 생성
  • 환경변수로 MYSQL 접속에 필요한 패스워드를 지정한다
  • Probe설정에서 exec타입으로 health를 체크한다.
  • 생성한 PVC를 마운트한다.

PVC 생성

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  labels:
    apps: wordpress
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs-client
  • PV에 요청할 리소스를 1G로 설정
  • Wordpress와 마찬가지로 스토리지클래스를 nfs-client로 설정함에 따라 동일한 NFS스토리지에 연결되어 있다.

Service 생성

apiVersion: v1
kind: Service
metadata:
  name: mysql-svc
  labels:
    apps: wordpress
spec:
  ports:
  - port: 3306
  clusterIP: None
  selector:
    apps: wordpress
    tier: mysql
  • MYSQL DB를 담당하는 파드에 서비스리소스에서 클러스터IP를 None으로 지정함에 따라 헤드리스 서비스를 연결한다.
  • 헤드리스 서비스에 셀렉터를 설정을 하여 뒤에 있는 파드의 레이블과 일치시켰기 때문에 파드의 IP가 직접 노출이된다. 즉 , 파드가 레코드 A( = IP)를 반환한다. 다시말해, 파드가 직접 노출된다.
  • 다른 서비스와 연결하기 위해서는 파드앞의 서비스를 통해서 네트워크 연결을 하는 것이 아니라, 직접 노출된 파드를 연결하는 것이다 = 헤드리스 서비스의 특징

개선점

1 . 이번 프로젝트에서 기존의 코드를 참조하지 않고 explain command와 쿠버네티스 공식문서를 이용하여 YAML파일 대부분을 작성한 것은 매우 만족스러웠다. 하지만 MYSQL App 구축에서 Read Replica를 이용하여 DB이중화를 하지 못하였다. 강사님이 만들어놓은 코드가 있긴하지만 참조를 안하고 생각으로 구축하려다보니 감이 안잡혀서 결국 성공하지 못했다. 추후에 강사님의 코드나 , 공식문서 등을 참조해서 완성해볼 것이다.

2 . 가장 아쉬웠던 점으로 , MYSQL App과 Wordpress App의 구성 조건을 모두 만족하여 구성했지만 두개의 App을 연동시키지 못하였다. MYSQL App의 서비스는 헤드리스 서비스로 생성을 하였고 셀렉터를 지정했기 때문에 MYSQL DB를 담당하는 파드의 ip가 집적 노출된다. 따라서 서비스가 아닌 파드를 집적 연결하는 것이 가능해지는데, 문제는 이 파드 자체를 Wordpress와 연결하는 방법을 찾지 못하였다. 추후에 더 연구해서 연동하는 것까지 완성 시킬 것이다.

profile
성실하게 열심히!

0개의 댓글