Kubernetes

nginx ingress controller tcp 설정

seulseul 2022. 12. 26. 11:56

개발자는 DBeaver , MySQL Workbench 와 같은 DataBase Tool 을 이용하여 Table 의 schema , Data 를 확인하기 때문에 db 접근이 가능해야한다. (pod 내에서 shell로 가능하긴하지만.. 매우 불편하다.)

 

 

k8s 에 띄운 service 는 ingress 를 설정한 후 외부에서 접근할 수 있게 되지만

mysql 은 ingress만 생성한다고 외부에서 접근하여 DB connection 을 이용할 수 있는 것은 아니다.

 

# TCP 를 사용하는 port 를 ingress controller 에 설정해줄것

 

방법 설명 요약

k8s Ingress 객체는 TCP, UDP port로 routing하기 위한 service를 지원하지 않는다.

때문에 Ingress controller는 이를 지원하기 위해 --tcp-services-configmap, --udp-services-configmap flag를 지원하고 있다.

config map을 미리 생성해 그것을 mount하고 provisioning된 ingress controller의 몇 가지 설정을 바꿔서 가능하도록 하는 방법이 있다.

 

  • 선행 조건
    • ingress controller 설치 >> 본문에서는 nginx ingress controller 기준으로 설명

 

 

목차

 

    1. mysql pv , pvc , deploy , service 생성

    kind: PersistentVolume
    apiVersion: v1
    metadata:
      name: pv-mysql
      labels:
        type: local
    spec:
      capacity:
        storage: "4Gi"
      accessModes:
        - ReadWriteOnce
      hostPath:
        path: "/mysql/data" 
    ---
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc-mysql
      namespace: db
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: "4Gi" 
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: mysql-svc
      namespace: db
      labels:
        app: mysql
    spec:
      selector:
        app: mysql
      ports:
      - protocol: TCP
        port: 3306 
        targetPort: mysql
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mysql
      namespace: db
      labels:
        app: mysql
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mysql
      template:
        metadata:
          labels:
            app: mysql
        spec:
          containers:
            - image: mysql:5.7
              name: mysql
              env:
                - name: MYSQL_ROOT_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: mysql
                      key: root.password
                - name: MYSQL_ROOT_HOST # 접근 호스트
                  value: '%'
    
                - name: MYSQL_DATABASE # 구성할 database명
                  value: sampledb
                - name: MYSQL_USER # database에 권한이 있는 user
                  valueFrom:
                    secretKeyRef:
                      name: mysql
                      key: user.name
                - name: MYSQL_PASSWORD # database에 권한이 있는 user의 패스워드
                  valueFrom:
                    secretKeyRef:
                      name: mysql
                      key: user.password
              ports:
                - containerPort: 3306
                  name: mysql
              volumeMounts:
                - name: mysql-persistent-storage
                  mountPath: /var/lib/mysql
          volumes:
            - name: mysql-persistent-storage
              persistentVolumeClaim:
                claimName: pvc-mysql

     

    2. mysql ingress

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: mysql-ingress
      namespace: db
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/server-alias: "mysql.192.168.56.10.sslip.io"
    spec:
      rules:
        - host: "mysql.192.168.56.10.sslip.io"
          http:
            paths:
              - pathType: Prefix
                path: "/"
                backend:
                  service:
                    name: mysql-svc
                    port:
                      number: 3306

    여기까지하면 일반적인 app 의 service ~ deployment ~ ingress 순서입니다.

    3. configmap

    my-tcp-services.yml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-tcp-services
      namespace: ingress-nginx
    data:
      3306: "db/mysql-svc:3306"
      # 3306: "네임스페이스 명/외부 노출된 서비스 명:연결할 port 번호""

    mysql 은 기본적으로 TCP 통신을 사용하기 때문에 cluster 와 연결하기 위해 configmap 을 apply 해줘야합니다.

    4. nginx ingress controller 수정

    4.1. nginx ingress controller - deploy 수정

    # nginx controller 의 deploy manifest 에 직접 접속
    kubectl edit deploy ingress-nginx-controller -n ingress-nginx
    
    
    # .spec.containers[0].args에 다음 설정을 추가
    - --tcp-services-configmap=ingress-nginx/my-tcp-services

    4.2. nginx ingress controller - service 수정

    # nginx controller 의 service manifest 에 직접 접속
    kubectl edit svc ingress-nginx-controller -n ingress-nginx
    # .spec.ports에 array형태로 다음 형식의 문구를 추가
      - appProtocol: https
        name: {외부로 노출한 redis cluster service명}
        port: {ingress controller service가 사용할 container port}
        protocol: TCP
        targetPort: {ingress controller service가 routing할 목적지 container port}

    저는 3306 으로 넣어줬습니다.

      - appProtocol: http
        name: mysql-svc
        port: 3306
        protocol: TCP
        targetPort: 3306

    4.3. Ingress 확인

    vagrant@test-vm1:~/yamls$ k get svc -n ingress-nginx
    NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                     AGE
    ingress-nginx-controller-admission   ClusterIP      10.43.171.128   <none>        443/TCP                                     7d22h
    ingress-nginx-controller             LoadBalancer   10.43.168.56    10.0.2.15     80:30388/TCP,443:32112/TCP,3306:31910/TCP   7d22h

    ingress-nginx-controller service 에 3306 port 가 추가된 것을 확인할 수 있습니다.

     

    5. DB Connection 확인

     

    최종 목적인 DB Tool 을 통해 DB Connection을 확인해보겠습니다.