안녕하세요, 클라우드로입니다!
앞으로 5회에 걸쳐 Terraform으로 Kubernetes 리소스를 구성하고 서비스를 호스팅하는 방법에 대해 다뤄보고자 합니다.
회차별 주제는 아래와 같습니다.
- Kubrernetes Provider 사용 방법, 기본 오브젝트 생성하기(Namespace, Pod, Service, Secret)
- 볼륨 리소스 다루기(CSP별 Blob 및 configmap mount)
- 네트워크 리소스 다루기(Ingress, Nginx-Ingress(Helm Chart))
- DNS 연동 및 인증서 발급(Let's Encrypt 및 Cert Manager(Helm))
- CloudStudio로 위 1~4 구성하기
그럼 바로 시작해볼까요?
첫번째, Kubrernetes Provider 사용 방법, 기본 오브젝트 생성하기(Namespace, Pod, Service, Secret)
1. Kubernetes Provider 설정하기
먼저 terraform block을 선언하고 사용할 required_providers를 정의해 주세요.(CSP의 Cluster를 불러와 사용하려면 각 CSP별 Provider를 작성해주어야합니다.)
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "<사용할 version>"
}
}
}
다음 Terraform으로 Kubernetes 리소스를 다루기 위해 다른 CSP와 마찬가지로 Provider를 선언해주어야 합니다.
Terraform Kubernetes Repository
- 로컬 환경에 저장되어 있는 config를 불러와서 설정하려면 아래와 같이 설정할 수 있습니다.
provider "kubernetes" {
config_path = "~/.kube/config"
config_context = "<context 이름>" # kubectl config get-contexts
}
- 원격으로 Kubernetes 정보를 불러와서 설정하려면 아래와 같이 설정할 수 있습니다
provider "kubernetes" {
host = "<원격 cluster 주소>"
client_certificate = file("~/.kube/client-cert.pem")
client_key = file("~/.kube/client-key.pem")
cluster_ca_certificate = file("~/.kube/cluster-ca-cert.pem")
}
- CSP별 구성되어 있는 Cluster를 불러와서 설정하려면 data block을 사용하여 아래와 같이 설정할 수 있습니다. CSP별로 큰 차이는 없지만 구성이 다르기 때문에 사용하는 값이 다를 수 있습니다.
- Azure AKS
provider "azurerm" {
tenant_id = "<tenant id>"
subscription_id = "<subscription id>"
client_id = "<app client id>"
client_secret = "<app secret>"
}
data "azurerm_kubernetes_cluster" "aks" {
name = "<cluster 이름>"
resource_group_name = "<cluster가 속한 resource group 이름>"
}
provider "kubernetes" {
host = data.azurerm_kubernetes_cluster.aks.kube_config.0.host
client_certificate = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate)
client_key = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.client_key)
cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate)
}
- AWS EKS
provider "aws" {
region = "<region>"
access_key = "<access key>"
secret_key = "<secret key>"
}
data "aws_eks_cluster" "cloudraw" {
name = "<Cluster 이름>"
}
data "aws_eks_cluster_auth" "cloudraw" {
name = "<Cluster 이름>"
}
provider "kubernetes" {
host = data.aws_eks_cluster.cloudraw.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cloudraw.certificate_authority[0].data)
token = data.aws_eks_cluster_auth.cloudraw.token
}
- NCloud NKS
provider "ncloud" {
region = "<region>"
access_key = "<access key>"
secret_key = "<secret key>"
support_vpc = true
}
data "ncloud_nks_kube_config" "cloudraw" {
cluster_uuid = "<cluster uuid>"
}
provider "kubernetes" {
host = data.ncloud_nks_kube_config.cloudraw.host
token = "<cluster service account 토큰>"
cluster_ca_certificate = base64decode(data.ncloud_nks_kube_config.cloudraw.cluster_ca_certificate)
}
※ cluster service account token은 다음 명령으로 조회 할 수 있으며 적절한 권한이 할당되어 있어야합니다.
kubectl describe secret $(kubectl describe serviceaccount default --namespace=default | grep Token | awk '{print $2}') --namespace=default
provider 및 data block 작성 후 Terrafrom 명령을 실행(init, plan, apply)하면 terraform.tfstate파일이 생성되며 연결된 Cluster의 정보를 확인 할 수 있으며 연결된 클러스터상 오브젝트를 생성 할 수 있습니다.
2. Kubernetes 기본 오브젝트 생성하기(Namespace, Pod, Service, Secret)
다음으로 위에서 설정된 Cluster Provider에 기본 오브젝트를 생성해 보겠습니다.
각 리소스별 작성하는 값은 기존 Kubernetes에 사용하는 Yaml 파일과 유사하며 자세한 내용은 Kubernetes Docs Concept 과 Terraform Kubernetes Docs에서 확인 할 수 있습니다.
기본 오브젝트는 Terraform Kubernetes Docs의 Core/v1에서 확인할 수 있습니다.
*각 리소스별 옵션은 필수 값 위주로 최소화하여 작성하겠습니다.
- Namespace 생성하기(Terraform Kubernetes Namespace)
resource "kubernetes_namespace_v1" "cloudraw" {
metadata {
annotations = {}
labels = {}
name = "cloudraw-namespace" #생성할 namespace 이름
}
}
- Pod 생성하기(Terraform Kubernetes Pod)
Pod는 CloudStudio프론트엔드 이미지를 Private Repository에서 불러와서 생성하겠습니다.
resource "kubernetes_pod_v1" "cloudraw" {
metadata {
name = "cloudraw-pod" # 생성할 pod 이름
namespace = kubernetes_namespace_v1.cloudraw.metadata[0].name # pod를 생성할 namespace
annotations = {}
labels = {
app = "cloudraw-pod" # service와 연동을 위한 라벨
}
}
spec {
container {
name = "server" # container 이름
image = "cloudraw.azurecr.io/cloudstudio:sha..." # 이미지 이름 및 태그
args = []
command = []
port {
container_port = "80" # container port
}
}
image_pull_secrets {
name = kubernetes_secret_v1.cloudraw.metadata[0].name # image pull에 사용되는 secret 이름, public image 사용시 불필요
}
}
}
- Service 생성하기(Terraform Kubernetes Service)
Service는 외부 서비스 노출 및 향 후 Ingress와의 연결을 위해 생성하여 Pod와 연결하겠습니다.
resource "kubernetes_service_v1" "cloudraw" {
metadata {
name = "cloudraw-service" # 생성할 service 이름
namespace = kubernetes_namespace_v1.cloudraw.metadata[0].name # service를 생성할 namespace 이름
annotations = {}
labels = {}
}
spec {
selector = {
app = "cloudraw-pod" # 연결할 pod의 라벨
}
session_affinity = "None"
port {
name = "http"
protocol = "TCP"
port = "80"
target_port = "80"
}
type = "ClusterIP"
}
}
- Secret 생성하기(Terraform Kubernetes Secret)
Secert은 여러 종류가 있지만 그 중 Pod에 사용하는 이미지를 원격 레지스트리에서 불러오기 위한 imagePullSecret을 생성하여 Pod에 적용해 보겠습니다.
resource "kubernetes_secret_v1" "cloudraw" {
metadata {
name = "cloudraw-secret" # 생성할 secret 이름
namespace = kubernetes_namespace_v1.cloudraw.metadata[0].name # secret을 생성할 namespace 이름
annotations = {}
labels = {}
}
type = "kubernetes.io/dockerconfigjson" # secret type
data = {
".dockerconfigjson" = jsonencode(
{
"auths" = {
"<repository url>" = {
"auth" = base64encode(format("%s:%s", "<registry username>", "<registry password>"))
}
}
}
)
}
}
위와 같이 구성한 Terraform 템플릿을 Plan, Apply과정을 거쳐 생성해보겠습니다.
- plan 결과 4개의 오브젝트가 추가되는 것임을 확인할 수 있습니다.
- apply 결과 4개의 오브젝트가 생성된 것을 확인 할 수 있습니다.
- 생성된 각 오브젝트는 terraform.tfstate파일 및 kubectl describe 명령을 통해 상세내용을 확인 할 수 있습니다.
※ 위에서 작성한 오브젝트는 terraform destroy 명령을 사용하여 제거할 수 있습니다.
이번 시간에는 Terraform 을 활용하여 Kubernetes를 연결하고, 기본 오브젝트를 생성해 보았습니다.
다음 시간에는 Volume과 관련된 오브젝트 및 Volume Mount하는 방법에 대해 다뤄보겠습니다.
감사합니다.
Cloudraw는 쉽게 클라우드 인프라를 그리고 사용할 수 있는 서비스를 제공하기 위해 노력하고 있습니다.
클라우드가 있는 곳 어디든 Cloudraw가 함께합니다.
📨 help@cloudraw.kr
'IaC' 카테고리의 다른 글
[IaC] Terraform import 개념 및 사용방법 (0) | 2024.06.03 |
---|---|
[IaC] Terraform 작성 및 배포(2) - for_each, flatten, local values (1) | 2024.03.05 |
[IaC] Terraform 작성 및 배포(1) - provider block, resource block, dynamic block, data block, depends_on (0) | 2024.03.04 |
[IaC] Terraform 개념 및 작성방법 (0) | 2024.02.08 |