Deploying Tanzu Kubernetes “guest” cluster in vSphere with Tanzu

https://cormachogan.com/2020/09/29/deploying-tanzu-kubernetes-guest-cluster-in-vsphere-with-tanzu/

Cormac Hogan

내가 올린 “vSphere with Tanzu” 포스트의 마지막 편에서, 첫 번째 탄즈 쿠베르네츠(TKG) 게스트 클러스터를 어떻게 만들 것인지에 대해 살펴볼 것이다. 이전 게시물에서는 vSphere with Tanzu를 VCF with Tanzu와 비교했으며, 사전 요구 사항을 다뤘다. 그런 다음 vSphere with Tanzu와 함께 로드 밸런서 서비스를 제공하기 위해 HA-Proxy를 배포하는 데 관련된 단계를 살펴보았다. 가장 최근 게시물에서는 워크로드 관리 활성화에 관련된 단계를 살펴보았다. 이제 이 모든 것이 갖춰졌으므로 TKG 클러스터를 구축하여 VMware 엔지니어링, VMware 지원, 컨포머셜, 쿠버네티스 클러스터를 제공할 수 있게 되었다.

참고: 이 절차는 제품의 릴리스되지 않은 버전을 사용하는 경우. 따라서 일부 스크린샷은 GA 이전에 변경될 수 있다. 그러나 배치 단계는 그대로 유지되어야 한다.

1단계 : 네임스페이스 생성

1단계 – 네임스페이스 만들기
Tanzu와 함께 vSphere는 네임스페이스 개념을 계속 지원하고 있다. 이를 통해 vSphere 관리자는 개발자 또는 개발자 팀이 Tanzu 구축 환경에서 작업할 때 사용할 수 있는 리소스를 제어할 수 있다. 이를 통해 개발자가 “야성”을 하고 기본 인프라 자원에 대한 공정한 분담보다 더 많은 비용을 소비하며 동일한 인프라에서 작업하는 다른 개발자 또는 개발자 팀에 영향을 미치거나 실제로 생산에 영향을 미치는 것을 방지할 수 있다. 시작하려면 작업량 관리에서 네임스페이스를 선택한 다음 아래 나온 것처럼 “네임스페이스 만들기”를 클릭하십시오.

네임스페이스를 생성할 때 네임스페이스를 생성할 클러스터를 선택한다. 나는 클러스터가 하나뿐이니까, 그것은 꽤 직관적이다. 네임스페이스의 이름을 제공해야 한다. 내 경우, cormac-ns라고 불렀다. 마지막으로, 이것은 새로운 것이다. 워크로드 네트워크를 선택해야 할 것이다. 워크로드 관리 활성화에 대한 이전 게시물을 기억한다면, 우리는 여러 개의 워크로드 네트워크를 만들 수 있었다. 나는 그 때 한 개만 만들었고, 그래서 이 단계는 쉽다. 선택적 설명이 추가되었으면 “Create” 버튼을 클릭한다.

네임스페이스는 아래와 같이 만들어질 것이다.

Tanzu Kubernetes 창에 네임스페이스에 이미 연결된 Content Library가 있음을 표시한다는 점에 유의하십시오. 이 작업은 이전에 Tanzu / Workload Management를 사용하여 vSphere를 구축하는 동안 Content Library를 포함했을 때 수행된 작업이었습니다. 사용 권한으로 아무것도 하지 않음 – 나중에 SSO 관리자 로그인을 사용할 것이며, 이 로그인은 이미 네임스페이스에 대한 전체 사용 권한을 암시적으로 가지고 있다. 용량 및 사용량 설정에 대해서는 아무 것도 하지 않을 것이다. 따라서 프로덕션 환경에서 이러한 설정을 검토하고 조정하기를 원할 것이다. 스토리지 섹션에 스토리지 정책을 추가하기만 하면 된다. “vSAN Default Storage Policy”을 추가하려는 경우 네임스페이스에 추가된 스토리지 정책은 영구 볼륨을 프로비저닝할 때 사용할 수 있는 Kubernetes 스토리지 클래스로 표시된다는 점에 유의한다. 나중에 vSphere with Tanzu에 로그인하고 TKG “guest” 클러스터를 구축하면 이 스토리지 클래스를 볼 수 있을 것이다.

스토리지 클래스를 선택하면 vSphere UI에 있는 네임스페이스 랜딩 페이지의 스토리지 섹션에 스토리지 클래스가 표시된다.

2단계 : vSphere with Tanzu에 로그인하고 TKG 배포

처음에 vSphere with Tanzu를 구축했을 때 Kubernetes CLI Tools 랜딩 페이지를 보여드렸다. 이는 슈퍼바이저 제어부 쿠버네티스 API 서버의 로드 밸런서 IP 주소에 연결하여 액세스할 수 있다. 실제로 네임스페이스의 상태 창에도 이 URL에 대한 링크가 있다. 이 페이지에서 우리는 네임스페이스에 접속하여 TKG를 배치하기 위해 kubectl, kubectl-login과 같은 다양한 도구를 다운로드할 수 있다.

이 도구를 사용하여 이전에 만들어진 cormac-ns 네임스페이스에 로그인하고 TKG – Tanzu Kubernetes 클러스터를 배포할 것이다.

2.1 네임스페이스 컨텍스트에 로그인

로그인하려면 kubectl-login 명령을 사용하여 서버를 슈퍼바이저 제어부 API 서버 IP 주소로 설정하십시오.

C:\bin>kubectl-vsphere.exe login --insecure-skip-tls-verify --vsphere-username \
administrator@vsphere.local --server=https://192.50.0.176
Password:********
Logged in successfully.

You have access to the following contexts:
   192.50.0.176
   cormac-ns

If the context you wish to use is not in this list, you may need to try
logging in again later, or contact your cluster administrator.


To change context, use `kubectl config use-context <workload name>`

C:\bin>kubectl config use-context cormac-ns
Switched to context "cormac-ns".

2.2 제어부 및 스토리지 클래스 확인

이 시점에서 3개의 제어부 노드가 준비 상태에 있는지, 앞서 네임스페이스에 할당한 스토리지 정책이 실제로 스토리지 클래스로 나타났는지 항상 확인하고 싶다. TKG 가상 머신 이미지가 보이고 이미지 저장에 사용되는 컨텐츠 라이브러리가 실제로 성공적으로 동기화되었는지 확인하는 데 유용한 다른 항목도 있다. 모든 것이 존재하고 올바른 것처럼 보인다.

C:\bin>kubectl get nodes
NAME                               STATUS   ROLES    AGE   VERSION
422425ad85759a5db789ec2120747d13   Ready    master   18m   v1.18.2-6+38ac483e736488
42242c84f294f9c38ecfe419ca601c6e   Ready    master   19m   v1.18.2-6+38ac483e736488
42249f93e32ea81ca8f03efa2465d67f   Ready    master   28m   v1.18.2-6+38ac483e736488


C:>kubectl get sc
NAME                          PROVISIONER              RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
vsan-default-storage-policy   csi.vsphere.vmware.com   Delete          Immediate           true                   57s


C:\bin>kubectl get virtualmachineimages
NAME                                                         VERSION                           OSTYPE
ob-15957779-photon-3-k8s-v1.16.8---vmware.1-tkg.3.60d2ffd    v1.16.8+vmware.1-tkg.3.60d2ffd    vmwarePhoton64Guest
ob-16466772-photon-3-k8s-v1.17.7---vmware.1-tkg.1.154236c    v1.17.7+vmware.1-tkg.1.154236c    vmwarePhoton64Guest
ob-16545581-photon-3-k8s-v1.16.12---vmware.1-tkg.1.da7afe7   v1.16.12+vmware.1-tkg.1.da7afe7   vmwarePhoton64Guest
ob-16551547-photon-3-k8s-v1.17.8---vmware.1-tkg.1.5417466    v1.17.8+vmware.1-tkg.1.5417466    vmwarePhoton64Guest

2.3 TKG 배포를 위한 매니페스트 파일 생성

TKG “게스트” 클러스터를 vSphere with Tanzu에 생성하는 것은 매우 간단하다. 클러스터 이름, 제어부 노드 수, 작업자 노드 수, 리소스 관점(클래스)에서 노드 크기, 사용할 스토리지 클래스(스토리지클래스) 및 노드(버전)에 사용할 이미지(버전)에 대한 정보를 자세히 설명하는 YAML의 간단한 매니페스트 파일만 있으면 된다. 단일 제어부 노드, 2 x worker 노드, 이미지 버전 1.17.7을 지정하여 사용한 예제를 소개한다. 이러한 버전 번호 사용은 이전에 컨텐츠 라이브러리 목록에서 사용할 Photon OS 이미지를 지정하는 속기 방법이다. v1.17.x 이미지에만 Antrea CNI가 포함되어 있다는 점에 유의한다.

C:\bin>type cluster.yaml
apiVersion: run.tanzu.vmware.com/v1alpha1
kind: TanzuKubernetesCluster
metadata:
name: tkg-cluster-01
spec:
topology:
   controlPlane:
     count: 1
     class: guaranteed-small
     storageClass: vsan-default-storage-policy
   workers:
     count: 2
     class: guaranteed-small
     storageClass: vsan-default-storage-policy
distribution:
   version: v1.17.7

다양한 클래스에 할당된 리소스에 대해 자세히 알아보려면 다음 명령을 사용하여 쿼리하십시오. 설명 출력 하단의 ‘Spec’ 세부 정보를 참조한다.

C:\bin>kubectl get virtualmachineclass
NAME                  AGE
best-effort-2xlarge   2d16h
best-effort-4xlarge   2d16h
best-effort-8xlarge   2d16h
best-effort-large     2d16h
best-effort-medium    2d16h
best-effort-small     2d16h
best-effort-xlarge    2d16h
best-effort-xsmall    2d16h
guaranteed-2xlarge    2d16h
guaranteed-4xlarge    2d16h
guaranteed-8xlarge    2d16h
guaranteed-large      2d16h
guaranteed-medium     2d16h
guaranteed-small      2d16h
guaranteed-xlarge     2d16h
guaranteed-xsmall     2d16h


C:\bin>kubectl describe virtualmachineclass guaranteed-small
Name:         guaranteed-small
Namespace:
Labels:       <none>
Annotations:  API Version:  vmoperator.vmware.com/v1alpha1
Kind:         VirtualMachineClass
Metadata:
  Creation Timestamp:  2020-09-25T15:25:56Z
  Generation:          1
  Managed Fields:
    API Version:  vmoperator.vmware.com/v1alpha1
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .:
          f:kubectl.kubernetes.io/last-applied-configuration:
      f:spec:
        .:
        f:hardware:
          .:
          f:cpus:
          f:memory:
        f:policies:
          .:
          f:resources:
            .:
            f:requests:
              .:
              f:cpu:
              f:memory:
    Manager:         kubectl
    Operation:       Update
    Time:            2020-09-25T15:25:56Z
  Resource Version:  2939
  Self Link:         /apis/vmoperator.vmware.com/v1alpha1/virtualmachineclasses/guaranteed-small
  UID:               4a547922-0ecf-4899-a8b8-12cc6dbd78e8
Spec:
  Hardware:
    Cpus:    2
    Memory:  4Gi
  Policies:
    Resources:
      Requests:
        Cpu:     2000m
        Memory:  4Gi
Events:          <none>

CPU 및 메모리에 대한 “Request” 값이 “Spec”과 일치한다.”Spec.Hardware” 항목은 best effort이 아니라 이러한 자원이 guaranteed된다는 것을 의미한다. 물론 앞서 살펴본 바와 같이 best effort도 가상 머신 클래스로 이용할 수 있다.

2.4 TKG 매니페스트 적용 및 배치 모니터링

이 시점에서는 앞에서 제시한 매니페스트를 적용하여 TKG 클러스터를 구축하면 된다. 그런 다음 다양한 명령을 사용하여 배포를 모니터링할 수 있다. 설명 명령은 매우 길 수 있으므로 클러스터가 배포된 시점의 출력만 표시하지만 설명 명령을 반복적으로 사용하여 TKG 클러스터 배포 상태를 모니터링할 수 있다.

C:\bin>kubectl apply -f cluster.yaml
tanzukubernetescluster.run.tanzu.vmware.com/tkg-cluster-01created


C:\bin>kubectl get cluster
NAME             PHASE
tkg-cluster-01   Provisioned


C:\bin>kubectl get tanzukubernetescluster
NAME             CONTROL PLANE   WORKER   DISTRIBUTION                     AGE    PHASE
tkg-cluster-01   1               2        v1.17.7+vmware.1-tkg.1.154236c   3m7s   creating

다음은 설명 명령어로부터의 전체 출력이다. Antrea를 CNI로 사용, 노드 및 VM 상태, 클러스터 API 끝점(부하 분산 장치에서, IP 주소의 프런트엔드 네트워크 범위)과 같은 많은 유용한 정보가 있다.

C:\bin>kubectl describe tanzukubernetescluster
Name:         tkg-cluster-01
Namespace:    cormac-ns
Labels:       <none>
Annotations:  API Version:  run.tanzu.vmware.com/v1alpha1
Kind:         TanzuKubernetesCluster
Metadata:
  Creation Timestamp:  2020-09-23T15:41:25Z
  Finalizers:
    tanzukubernetescluster.run.tanzu.vmware.com
  Generation:  1
  Managed Fields:
    API Version:  run.tanzu.vmware.com/v1alpha1
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .:
          f:kubectl.kubernetes.io/last-applied-configuration:
      f:spec:
        .:
        f:distribution:
          .:
          f:version:
        f:topology:
          .:
          f:controlPlane:
            .:
            f:class:
            f:count:
            f:storageClass:
          f:workers:
            .:
            f:class:
            f:count:
            f:storageClass:
    Manager:      kubectl
    Operation:    Update
    Time:         2020-09-23T15:41:25Z
    API Version:  run.tanzu.vmware.com/v1alpha1
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:finalizers:
          .:
          v:"tanzukubernetescluster.run.tanzu.vmware.com":
      f:status:
        .:
        f:addons:
          .:
          f:authsvc:
            .:
            f:name:
            f:status:
            f:version:
          f:cloudprovider:
            .:
            f:name:
            f:status:
            f:version:
          f:cni:
            .:
            f:name:
            f:status:
            f:version:
          f:csi:
            .:
            f:name:
            f:status:
            f:version:
          f:dns:
            .:
            f:name:
            f:status:
            f:version:
          f:proxy:
            .:
            f:name:
            f:status:
            f:version:
          f:psp:
            .:
            f:name:
            f:status:
            f:version:
        f:clusterApiStatus:
          .:
          f:apiEndpoints:
          f:phase:
        f:nodeStatus:
          .:
          f:tkg-cluster-01-control-plane-sn85m:
          f:tkg-cluster-01-workers-csjd7-554668c497-vtf68:
          f:tkg-cluster-01-workers-csjd7-554668c497-z8vjt:
        f:phase:
        f:vmStatus:
          .:
          f:tkg-cluster-01-control-plane-sn85m:
          f:tkg-cluster-01-workers-csjd7-554668c497-vtf68:
          f:tkg-cluster-01-workers-csjd7-554668c497-z8vjt:
    Manager:         manager
    Operation:       Update
    Time:            2020-09-23T15:52:45Z
  Resource Version:  22469
  Self Link:         /apis/run.tanzu.vmware.com/v1alpha1/namespaces/cormac-ns/tanzukubernetesclusters/tkg-cluster-01
  UID:               9ede742d-c7e3-4715-ac7e-89d2ed312a16
Spec:
  Distribution:
    Full Version:  v1.17.7+vmware.1-tkg.1.154236c
    Version:       v1.17.7
  Settings:
    Network:
      Cni:
        Name:  antrea
      Pods:
        Cidr Blocks:
          192.168.0.0/16
      Service Domain:  cluster.local
      Services:
        Cidr Blocks:
          10.96.0.0/12
  Topology:
    Control Plane:
      Class:          guaranteed-small
      Count:          1
      Storage Class:  vsan-default-storage-policy
    Workers:
      Class:          guaranteed-small
      Count:          2
      Storage Class:  vsan-default-storage-policy
Status:
  Addons:
    Authsvc:
      Name:     authsvc
      Status:   applied
      Version:  0.1-65-ge3d8be8
    Cloudprovider:
      Name:     vmware-guest-cluster
      Status:   applied
      Version:  0.1-77-g5875817
    Cni:
      Name:     antrea
      Status:   applied
      Version:  v0.7.2_vmware.1
    Csi:
      Name:     pvcsi
      Status:   applied
      Version:  v0.0.1.alpha+vmware.73-4a26ce0
    Dns:
      Name:     CoreDNS
      Status:   applied
      Version:  v1.6.5_vmware.5
    Proxy:
      Name:     kube-proxy
      Status:   applied
      Version:  1.17.7+vmware.1
    Psp:
      Name:     defaultpsp
      Status:   applied
      Version:  v1.17.7+vmware.1-tkg.1.154236c
  Cluster API Status:
    API Endpoints:
      Host:  192.50.0.177
      Port:  6443

    Phase:   Provisioned
  Node Status:
    tkg-cluster-01-control-plane-sn85m:             ready
    tkg-cluster-01-workers-csjd7-554668c497-vtf68:  ready
    tkg-cluster-01-workers-csjd7-554668c497-z8vjt:  ready
  Phase:                                            running
  Vm Status:
    tkg-cluster-01-control-plane-sn85m:             ready
    tkg-cluster-01-workers-csjd7-554668c497-vtf68:  ready
    tkg-cluster-01-workers-csjd7-554668c497-z8vjt:  ready
Events:                                             <none>


C:\bin>kubectl get tanzukubernetescluster
NAME             CONTROL PLANE   WORKER   DISTRIBUTION                     AGE   PHASE
tkg-cluster-01   1               2        v1.17.7+vmware.1-tkg.1.154236c   11m   running


C:\bin>kubectl get cluster
NAME             PHASE
tkg-cluster-01   Provisioned

관심 있는 것은 API Endpoints인데, 이는 로드 밸런서 IP 주소 범위에서 다른 IP 주소 입니다. 네트워킹 측면에서 볼 때 NAT의 구현은 다음과 유사한 것으로 보인다.

마지막으로 주목할 점은 vSphere Client UI로 다시 전환하여 네임스페이스를 조사하면 Tanzu Kubernetes 창에 클러스터 하나가 구축되었음을 보여주는 업데이트가 있음을 알 수 있다는 점이다. 인벤토리에서 왼쪽을 보면 TKG 클러스터를 vSphere에서 인벤토리 항목으로 볼 수도 있다.

2.5 로그아웃 후 TKG 클러스터 컨텍스트에 로그인

위의 모든 작업은 Tanzu Supervisor 클러스터가 설치된 vSphere의 네임스페이스 컨텍스트에서 수행되었다. 다음 단계는 슈퍼바이저 컨텍스트에서 로그아웃하고 TKG 게스트 클러스터 컨텍스트에 로그인하는 것이다. 이를 통해 우리는 슈퍼바이저 클러스터에 있는 쿠베르네츠 API 서버가 아닌 TKG 클러스터 API 서버에서 kubectl 명령을 지시할 수 있다. KUBECONFIG 환경변수 설정을 통해 이를 달성할 수 있는 다른 방법도 있지만, 간단히 로그아웃하고 다시 로그인하는 것이 더 쉽다는 것을 알게 되었다.

C:\bin>kubectl-vsphere.exe logout
Your KUBECONFIG context has changed.
The current KUBECONFIG context is unset.
To change context, use `kubectl config use-context <workload name>`
Logged out of all vSphere namespaces.

C:\bin>kubectl-vsphere.exe login \
--insecure-skip-tls-verify \
--vsphere-username administrator@vsphere.local \
--server=https://192.50.0.176 \
--tanzu-kubernetes-cluster-namespace cormac-ns \
--tanzu-kubernetes-cluster-name tkg-cluster-01
Password: ********
Logged in successfully.

You have access to the following contexts:
   192.50.0.176
   cormac-ns
   tkg-cluster-01

If the context you wish to use is not in this list, you may need to try
logging in again later, or contact your cluster administrator.

To change context, use `kubectl config use-context <workload name>`

2.6 TKG 클러스터 컨텍스트 검증

우리는 우리가 현재 올바른 맥락에서 일하고 있는지 확인하기 위해 몇 가지 kubectl 명령을 실행할 수 있다. 노드를 표시하면 클러스터를 배포할 때 매니페스트에 지정된 1 x control 노드와 2 x worker 노드가 표시되는 것을 볼 수 있다. 또한 클러스터에 배포된 모든 포드를 표시할 수 있어야 하며 네트워킹용 Antrea 에이전트와 스토리지용 CSI 노드 에이전트도 모두 관찰할 수 있어야 한다. 또한 TKG 클러스터에서 모든 것이 준비/실행 상태에 들어갔는지 확인할 수 있는 좋은 기회다.

C:\bin>kubectl get nodes
NAME                                            STATUS   ROLES    AGE     VERSION
tkg-cluster-01-control-plane-sn85m              Ready    master   8m40s   v1.17.7+vmware.1
tkg-cluster-01-workers-csjd7-554668c497-vtf68   Ready    <none>   2m16s   v1.17.7+vmware.1
tkg-cluster-01-workers-csjd7-554668c497-z8vjt   Ready    <none>   2m16s   v1.17.7+vmware.1


C:\bin>kubectl get pods -A
NAMESPACE                      NAME                                                         READY   STATUS    RESTARTS   AGE
kube-system                    antrea-agent-7zphw                                           2/2     Running   0          2m23s
kube-system                    antrea-agent-mvczg                                           2/2     Running   0          2m23s
kube-system                    antrea-agent-t6qgc                                           2/2     Running   0          8m11s
kube-system                    antrea-controller-76c76c7b7c-4cwtm                           1/1     Running   0          8m11s
kube-system                    coredns-6c78df586f-6d77q                                     1/1     Running   0          7m55s
kube-system                    coredns-6c78df586f-c8rtj                                     1/1     Running   0          8m14s
kube-system                    etcd-tkg-cluster-01-control-plane-sn85m                      1/1     Running   0          7m24s
kube-system                    kube-apiserver-tkg-cluster-01-control-plane-sn85m            1/1     Running   0          7m12s
kube-system                    kube-controller-manager-tkg-cluster-01-control-plane-sn85m   1/1     Running   0          7m30s
kube-system                    kube-proxy-frpgn                                             1/1     Running   0          2m23s
kube-system                    kube-proxy-lchkq                                             1/1     Running   0          2m23s
kube-system                    kube-proxy-m2xjn                                             1/1     Running   0          8m14s
kube-system                    kube-scheduler-tkg-cluster-01-control-plane-sn85m            1/1     Running   0          7m27s
vmware-system-auth             guest-cluster-auth-svc-lf2nf                                 1/1     Running   0          8m2s
vmware-system-cloud-provider   guest-cluster-cloud-provider-7788f74548-cfng4                1/1     Running   0          8m13s
vmware-system-csi              vsphere-csi-controller-574cfd4569-kfdz8                      6/6     Running   0          8m12s
vmware-system-csi              vsphere-csi-node-hvzpg                                       3/3     Running   0          8m12s
vmware-system-csi              vsphere-csi-node-t4w8p                                       3/3     Running   0          2m23s
vmware-system-csi              vsphere-csi-node-t6rdw                                       3/3     Running   0          2m23s

좋은 것 같군요. 우리는 TKG 게스트 클러스터를 Tanzu와 함께 vSphere에 성공적으로 구축했다.

요약

마지막 블로그 게시물들에서 다음 사항을 살펴보았다.

  • 네트워크 요구 사항을 포함하여 vSphere with Tanzu와 VCF의 차이점 또한 vSphere with Tanzu를 성공적으로 구축하기 위해 필요한 다양한 사전 요구 사항도 살펴보았다.
  • HA-Proxy를 구축하는 방법과 vSphere with Tanzu에 로드 밸런서 서비스를 제공하는 방법에 대해 살펴보았다.
  • 워크로드 관리를 지원하고 vSphere with Tanzu와 협력하는 방법을 살펴보았다.
  • 마지막으로 이 게시물에서 TKG ‘게스트’ 클러스터를 vSphere with Tanzu에 구축하는 방법을 살펴보았다.

이를 통해 귀하의 vSphere 환경에서 vSphere with Tanzu를 검토할 수 있는 충분한 정보를 얻었기를 바란다. 나는 항상 무엇이 효과가 있는지, 무엇이 효과가 없는지 등 당신의 피드백을 듣는 데 관심이 있다. 소셜 미디어에 자유롭게 댓글을 남기거나 나에게 연락 바란다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

You May Also Like