You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Terraform Kubectl Provider将Kubernetes资源部署到指定Namespace的正确实践及问题排查

How to Properly Deploy Resources to a Specific Namespace with Terraform Kubectl Provider

Let's break down what's going on here and fix your issue. First off, the NotFound error you're getting when running kubectl logs is likely because you're not specifying the target namespace—kubectl defaults to the default namespace unless told otherwise. But let's also make sure your Terraform setup is correct for targeting a custom namespace.

First: Fix the Immediate Logs Error

Before diving into Terraform configs, let's resolve the logs issue to confirm your pods actually exist. Run this command instead, replacing <your-namespace> with the name of the namespace you're targeting:

kubectl logs example-6878fd468-9vgkm -n <your-namespace>

You can also list all pods in the namespace to verify they're running:

kubectl get pods -n <your-namespace>

If the pods show up here, then your deployment is working—you just forgot to specify the namespace in your kubectl command.

Correct Usage of Terraform Kubectl Provider for Custom Namespaces

Both of your approaches are valid, but each has a small detail you might have missed. Let's walk through the correct implementation for each:

This approach is great if you want to keep your YAML manifests namespace-agnostic (so you can reuse them across different environments). Here's what you need to fix:

  1. Fix the file path typo: You have a comma instead of a slash in file("${path.cwd},deploy.yaml")—it should be ${path.cwd}/deploy.yaml.
  2. Remove namespace fields from your YAML: If your deploy.yaml has namespace specified in metadata, the override_namespace setting might not take precedence (depending on your provider version). Keep your YAML clean of namespace declarations.
  3. Ensure the namespace exists first: Explicitly depend on your namespace resource to make sure it's created before your manifests.

Corrected Terraform code:

# First, create the target namespace
resource "kubernetes_namespace_v1" "example_ns" {
  metadata {
    name = "my-custom-namespace"
  }
}

# Deploy your manifests with namespace override
resource "kubectl_manifest" "example" {
  # Ensure namespace is created first
  depends_on = [kubernetes_namespace_v1.example_ns]
  
  override_namespace = kubernetes_namespace_v1.example_ns.metadata[0].name
  # Fixed file path with slash
  yaml_body = file("${path.cwd}/deploy.yaml")
}

Corresponding deploy.yaml (no namespace field):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example
# No namespace field here
spec:
  replicas: 1
  selector:
    matchLabels:
      app: example
  template:
    metadata:
      labels:
        app: example
    spec:
      containers:
      - name: example
        image: nginx:alpine
---
apiVersion: v1
kind: Service
metadata:
  name: example
# No namespace field here
spec:
  type: ClusterIP
  selector:
    app: example
  ports:
  - port: 80
    targetPort: 80

Option 2: Hardcode Namespace in YAML Manifests

If you prefer to have the namespace directly in your YAML, that works too—but you need to make sure:

  1. The namespace exists before deploying the manifests (use the same kubernetes_namespace_v1 resource as above).
  2. The namespace name in your YAML exactly matches the one created by Terraform (no typos!).

Example deploy.yaml with namespace:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example
  namespace: my-custom-namespace # Exact match to your Terraform-created namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      app: example
  template:
    metadata:
      labels:
        app: example
    spec:
      containers:
      - name: example
        image: nginx:alpine
---
apiVersion: v1
kind: Service
metadata:
  name: example
  namespace: my-custom-namespace # Exact match here too
spec:
  type: ClusterIP
  selector:
    app: example
  ports:
  - port: 80
    targetPort: 80

Terraform code for this option:

resource "kubernetes_namespace_v1" "example_ns" {
  metadata {
    name = "my-custom-namespace"
  }
}

resource "kubectl_manifest" "example" {
  depends_on = [kubernetes_namespace_v1.example_ns]
  yaml_body = file("${path.cwd}/deploy.yaml")
}

Key Takeaways

  • Always verify resources in the correct namespace with -n <namespace> in kubectl commands.
  • For override_namespace to work, keep your YAMLs free of namespace declarations and fix any path typos.
  • When hardcoding namespaces in YAML, ensure the namespace exists first and the name matches exactly.

内容的提问来源于stack exchange,提问作者Matt - Block-Farms.io

火山引擎 最新活动