Terraform 0.11 - Getting Started with Kubernetes provider

कुबेरनेट्स प्रदाता के साथ शुरुआत करना




terraform

कुबेरनेट्स प्रदाता के साथ शुरुआत करना

Kubernetes

Kubernetes (K8S) कंटेनरीकृत अनुप्रयोगों पर ध्यान देने के साथ एक ओपन-सोर्स वर्कलोड शेड्यूलर है।

कुबेरनेट क्लस्टर पर अपने पहले कंटेनर को शेड्यूल करने में कम से कम 2 चरण शामिल हैं। आपको अपने सभी घटकों के साथ कहीं न कहीं कुबेरनेट समूह की आवश्यकता होती है और फिर कुबेरनेट संसाधनों को शेड्यूल करता है, जैसे पॉड्स, प्रतिकृति नियंत्रक, सेवाएँ आदि।

यह मार्गदर्शिका मुख्य रूप से बाद वाले हिस्से पर केंद्रित है और आपसे ठीक से कॉन्फ़िगर किए गए और चल रहे कुबेरनेट क्लस्टर की अपेक्षा करती है।

गाइड आपको एक क्लाउड प्रदाता पर क्लस्टर चलाने की भी उम्मीद करता है जहां कुबेरनेट्स स्वचालित रूप से लोड बैलेंसर का प्रावधान कर सकते हैं।

टेराफॉर्म क्यों?

जब आप kubectl या इसी तरह के सीएलआई-आधारित टूल का उपयोग कर सकते हैं, जो कि kubectl फाइल में वर्णित सभी कुबेरनेट संसाधनों के प्रबंधन के लिए एपीआई कॉल के लिए मैप किया गया है, टेराफॉर्म के साथ ऑर्केस्ट्रेशन कुछ लाभ प्रस्तुत करता है।

  • कुबेरनेट इन्फ्रास्ट्रक्चर को प्रोवाइड करने और उसमें एप्लिकेशन को तैनात करने के लिए उसी कॉन्फ़िगरेशन भाषा का उपयोग करें।
  • बहाव का पता लगाना - terraform plan हमेशा आपको एक निश्चित समय में वास्तविकता के बीच का अंतर पेश करेगी और आपको आवेदन करने के लिए कॉन्फ़िगर करेगी।
  • पूर्ण जीवनचक्र प्रबंधन - टेराफ़ॉर्म शुरू में केवल संसाधन नहीं बनाता है, लेकिन उन संसाधनों की पहचान करने के लिए एपीआई का निरीक्षण करने की आवश्यकता के बिना ट्रैक किए गए संसाधनों के निर्माण, अद्यतन और हटाने के लिए एक ही आदेश प्रदान करता है।
  • सिंक्रोनस फीडबैक - जबकि अतुल्यकालिक व्यवहार अक्सर उपयोगी होता है, कभी-कभी यह काउंटर-उत्पादक होता है क्योंकि ऑपरेशन के परिणाम (असफल संसाधन का विवरण या विवरण) का काम उपयोगकर्ता के लिए छोड़ दिया जाता है। उदाहरण के लिए आपके पास लोड बैलेंसर का IP / hostname नहीं है, जब तक कि वह प्रोविजनिंग खत्म नहीं कर देता, इसलिए आप इसे इंगित करने वाला कोई DNS रिकॉर्ड नहीं बना सकते।
  • रिश्तों का ग्राफ - टेराफॉर्म उन संसाधनों के बीच संबंधों को समझता है जो शेड्यूलिंग में मदद कर सकते हैं - जैसे कि यदि कोई विशेष वॉल्यूम से एक निरंतर वॉल्यूम क्लेम स्पेस क्लेम करता है तो पीवी बनाने में असफल होने पर भी पीवीसी बनाने का प्रयास नहीं करेगा।

प्रदाता सेटअप

प्रदाता को कॉन्फ़िगर करने का सबसे आसान तरीका एक डिफ़ॉल्ट स्थान ( ~/.kube/config ) में एक कॉन्फ़िगरेशन बनाना / उत्पन्न करना है। यह आपको प्रदाता ब्लॉक को पूरी तरह से खाली छोड़ने की अनुमति देता है।

provider "kubernetes" {}

यदि आप प्रदाता को वैधानिक रूप से कॉन्फ़िगर करना चाहते हैं तो आप ऐसा कर सकते हैं

provider "kubernetes" {
  host     = "https://104.196.242.174"
  username = "ClusterMaster"
  password = "MindTheGap"

  client_certificate     = "${file("~/.kube/client-cert.pem")}"
  client_key             = "${file("~/.kube/client-key.pem")}"
  cluster_ca_certificate = "${file("~/.kube/cluster-ca-cert.pem")}"
}

प्रदाता को निर्दिष्ट करने के बाद अब हम कुबेरनेट्स प्रदाता के नवीनतम संस्करण को डाउनलोड करने के लिए निम्नलिखित कमांड चला सकते हैं।

$ terraform init


Initializing provider plugins...
- Downloading plugin for provider "kubernetes"...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

एक सरल अनुप्रयोग निर्धारण

किसी भी Kubernetes आवेदन में मुख्य वस्तु एक पोड है । पॉड में एक या अधिक कंटेनर होते हैं जो सीपीयू या मेमोरी उपलब्धता के आधार पर क्लस्टर नोड्स पर रखे जाते हैं।

यहाँ हम एक कंटेनर बनाते हैं जिसमें नग्नेक्स वेब सर्वर चल रहा है, जो कि पोर्ट 80 (HTTP) को उजागर करता है जिसे बाद में लोड बैलेंसर के माध्यम से वास्तविक उपयोगकर्ता के सामने लाया जा सकता है।

इस सरल उदाहरण के विपरीत, आप आमतौर पर उत्पादन में अपने आवेदन के एक से अधिक उदाहरणों को चलाने के लिए उच्च उपलब्धता तक पहुंचेंगे और लेबल जोड़कर कुबेरनेट्स को उजागर बंदरगाह पर यातायात को आगे बढ़ाने के उद्देश्य से सभी पॉड्स (उदाहरणों) को खोजने की अनुमति देगा।

resource "kubernetes_pod" "nginx" {
  metadata {
    name = "nginx-example"
    labels {
      App = "nginx"
    }
  }

  spec {
    container {
      image = "nginx:1.7.8"
      name  = "example"

      port {
        container_port = 80
      }
    }
  }
}

Service माध्यम से उपयोगकर्ताओं के लिए अपने आवेदन को उजागर करने का सबसे सरल तरीका है। सेवा कुछ क्लाउड प्रदाताओं में लोड-बैलेंसर को प्रोवाइड करने और पॉड्स के बीच संबंध को प्रबंधित करने में सक्षम है और नए पॉड्स के रूप में लोड बैलेंसर लॉन्च किए जाते हैं और अन्य किसी भी कारण से मर जाते हैं।

resource "kubernetes_service" "nginx" {
  metadata {
    name = "nginx-example"
  }
  spec {
    selector {
      App = "${kubernetes_pod.nginx.metadata.0.labels.App}"
    }
    port {
      port = 80
      target_port = 80
    }

    type = "LoadBalancer"
  }
}

हम एक आउटपुट भी जोड़ सकते हैं जो उपयोगकर्ता को आईपी पते को उजागर करेगा

output "lb_ip" {
  value = "${kubernetes_service.nginx.load_balancer_ingress.0.ip}"
}

कृपया ध्यान दें कि यह एक क्लाउड प्रदाता है जो आईपी-आधारित लोड बैलेंसर (जैसे Google क्लाउड प्लेटफॉर्म) का प्रावधान करता है। यदि आप एक प्रदाता पर होस्टनाम-आधारित लोड बैलेंसर (जैसे अमेज़न वेब सेवा) चलाते हैं, तो आपको इसके बजाय निम्नलिखित स्निपेट का उपयोग करना चाहिए।

output "lb_ip" {
  value = "${kubernetes_service.nginx.load_balancer_ingress.0.hostname}"
}

योजना आपको नियोजित परिवर्तनों का अवलोकन प्रदान करेगी, इस मामले में हमें 2 संसाधनों (पोड + सेवा) को जोड़ा जाना चाहिए। जैसे-जैसे आपका इन्फ्रास्ट्रक्चर बढ़ता जाता है और यह अधिक उपयोगी होता जाता है और यह एक दूसरे के आधार पर अधिक घटकों के साथ और अधिक जटिल होता जाता है और यह अपडेट के दौरान विशेष रूप से सहायक होता है।

$ terraform plan

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

  + kubernetes_pod.nginx
      metadata.#:                                  "1"
      metadata.0.generation:                       "<computed>"
      metadata.0.labels.%:                         "1"
      metadata.0.labels.App:                       "nginx"
      metadata.0.name:                             "nginx-example"
      metadata.0.namespace:                        "default"
      metadata.0.resource_version:                 "<computed>"
      metadata.0.self_link:                        "<computed>"
      metadata.0.uid:                              "<computed>"
      spec.#:                                      "1"
      spec.0.automount_service_account_token:      "<computed>"
      spec.0.container.#:                          "1"
      spec.0.container.0.image:                    "nginx:1.7.8"
      spec.0.container.0.image_pull_policy:        "<computed>"
      spec.0.container.0.name:                     "example"
      spec.0.container.0.port.#:                   "1"
      spec.0.container.0.port.0.container_port:    "80"
      spec.0.container.0.port.0.protocol:          "TCP"
      spec.0.container.0.resources.#:              "<computed>"
      spec.0.container.0.stdin:                    "false"
      spec.0.container.0.stdin_once:               "false"
      spec.0.container.0.termination_message_path: "/dev/termination-log"
      spec.0.container.0.tty:                      "false"
      spec.0.dns_policy:                           "ClusterFirst"
      spec.0.host_ipc:                             "false"
      spec.0.host_network:                         "false"
      spec.0.host_pid:                             "false"
      spec.0.hostname:                             "<computed>"
      spec.0.image_pull_secrets.#:                 "<computed>"
      spec.0.node_name:                            "<computed>"
      spec.0.restart_policy:                       "Always"
      spec.0.service_account_name:                 "<computed>"
      spec.0.termination_grace_period_seconds:     "30"

  + kubernetes_service.nginx
      load_balancer_ingress.#:     "<computed>"
      metadata.#:                  "1"
      metadata.0.generation:       "<computed>"
      metadata.0.name:             "nginx-example"
      metadata.0.namespace:        "default"
      metadata.0.resource_version: "<computed>"
      metadata.0.self_link:        "<computed>"
      metadata.0.uid:              "<computed>"
      spec.#:                      "1"
      spec.0.cluster_ip:           "<computed>"
      spec.0.port.#:               "1"
      spec.0.port.0.node_port:     "<computed>"
      spec.0.port.0.port:          "80"
      spec.0.port.0.protocol:      "TCP"
      spec.0.port.0.target_port:   "80"
      spec.0.selector.%:           "1"
      spec.0.selector.App:         "nginx"
      spec.0.session_affinity:     "None"
      spec.0.type:                 "LoadBalancer"


Plan: 2 to add, 0 to change, 0 to destroy.

जैसा कि हम योजनागत उत्पादन से खुश हैं कि हम प्रस्तावित परिवर्तनों को लागू कर सकते हैं। terraform apply सभी कठिन terraform apply करेगा जिसमें सही क्रम में API के माध्यम से संसाधन बनाना, आवश्यक के रूप में किसी भी चूक की आपूर्ति करना और संसाधनों के लिए प्रतीक्षा करना इस बिंदु पर प्रावधान समाप्त करने के लिए है जब यह उपयोगी विशेषताओं या विफलता (कारण के साथ) प्रस्तुत कर सकता है उपभोक्ता।

$ terraform apply

kubernetes_pod.nginx: Creating...
  metadata.#:                                  "" => "1"
  metadata.0.generation:                       "" => "<computed>"
  metadata.0.labels.%:                         "" => "1"
  metadata.0.labels.App:                       "" => "nginx"
  metadata.0.name:                             "" => "nginx-example"
  metadata.0.namespace:                        "" => "default"
  metadata.0.resource_version:                 "" => "<computed>"
  metadata.0.self_link:                        "" => "<computed>"
  metadata.0.uid:                              "" => "<computed>"
  spec.#:                                      "" => "1"
  spec.0.automount_service_account_token:      "" => "<computed>"
  spec.0.container.#:                          "" => "1"
  spec.0.container.0.image:                    "" => "nginx:1.7.8"
  spec.0.container.0.image_pull_policy:        "" => "<computed>"
  spec.0.container.0.name:                     "" => "example"
  spec.0.container.0.port.#:                   "" => "1"
  spec.0.container.0.port.0.container_port:    "" => "80"
  spec.0.container.0.port.0.protocol:          "" => "TCP"
  spec.0.container.0.resources.#:              "" => "<computed>"
  spec.0.container.0.stdin:                    "" => "false"
  spec.0.container.0.stdin_once:               "" => "false"
  spec.0.container.0.termination_message_path: "" => "/dev/termination-log"
  spec.0.container.0.tty:                      "" => "false"
  spec.0.dns_policy:                           "" => "ClusterFirst"
  spec.0.host_ipc:                             "" => "false"
  spec.0.host_network:                         "" => "false"
  spec.0.host_pid:                             "" => "false"
  spec.0.hostname:                             "" => "<computed>"
  spec.0.image_pull_secrets.#:                 "" => "<computed>"
  spec.0.node_name:                            "" => "<computed>"
  spec.0.restart_policy:                       "" => "Always"
  spec.0.service_account_name:                 "" => "<computed>"
  spec.0.termination_grace_period_seconds:     "" => "30"
kubernetes_pod.nginx: Creation complete (ID: default/nginx-example)
kubernetes_service.nginx: Creating...
  load_balancer_ingress.#:     "" => "<computed>"
  metadata.#:                  "" => "1"
  metadata.0.generation:       "" => "<computed>"
  metadata.0.name:             "" => "nginx-example"
  metadata.0.namespace:        "" => "default"
  metadata.0.resource_version: "" => "<computed>"
  metadata.0.self_link:        "" => "<computed>"
  metadata.0.uid:              "" => "<computed>"
  spec.#:                      "" => "1"
  spec.0.cluster_ip:           "" => "<computed>"
  spec.0.port.#:               "" => "1"
  spec.0.port.0.node_port:     "" => "<computed>"
  spec.0.port.0.port:          "" => "80"
  spec.0.port.0.protocol:      "" => "TCP"
  spec.0.port.0.target_port:   "" => "80"
  spec.0.selector.%:           "" => "1"
  spec.0.selector.App:         "" => "nginx"
  spec.0.session_affinity:     "" => "None"
  spec.0.type:                 "" => "LoadBalancer"
kubernetes_service.nginx: Still creating... (10s elapsed)
kubernetes_service.nginx: Still creating... (20s elapsed)
kubernetes_service.nginx: Still creating... (30s elapsed)
kubernetes_service.nginx: Still creating... (40s elapsed)
kubernetes_service.nginx: Creation complete (ID: default/nginx-example)

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path:

Outputs:

lb_ip = 35.197.9.247

अब आप अपने पसंदीदा ब्राउज़र में उस IP पते को दर्ज कर सकते हैं और आपको nginx का स्वागत पृष्ठ देखना चाहिए।

Kubernetes UI पॉड और सेवा दोनों की जांच करने का एक और तरीका प्रदान करता है, जब वे निर्धारित होते हैं।

स्केलेबिलिटी और उपलब्धता तक पहुँचना

प्रतिकृति नियंत्रक आपको पॉड्स को दोहराने की अनुमति देता है। यह उपयोगकर्ता के लिए आपके आवेदन की समग्र उपलब्धता और मापनीयता को बनाए रखने के लिए उपयोगी है।

हम अपने पॉड को आरसी के साथ पिछले कॉन्फ़िगरेशन से बदल सकते हैं और सेवा को वहां रख सकते हैं।

resource "kubernetes_replication_controller" "nginx" {
  metadata {
    name = "scalable-nginx-example"
    labels {
      App = "ScalableNginxExample"
    }
  }

  spec {
    replicas = 2
    selector {
      App = "ScalableNginxExample"
    }
    template {
      container {
        image = "nginx:1.7.8"
        name  = "example"

        port {
          container_port = 80
        }

        resources {
          limits {
            cpu    = "0.5"
            memory = "512Mi"
          }
          requests {
            cpu    = "250m"
            memory = "50Mi"
          }
        }
      }
    }
  }
}

resource "kubernetes_service" "nginx" {
  metadata {
    name = "nginx-example"
  }
  spec {
    selector {
      App = "${kubernetes_replication_controller.nginx.metadata.0.labels.App}"
    }
    port {
      port = 80
      target_port = 80
    }

    type = "LoadBalancer"
  }
}

आप देख सकते हैं कि हमने यह भी निर्दिष्ट किया है कि हम सीपीयू और मेमोरी की कितनी मात्रा का उपभोग करने के लिए उस एप्लिकेशन के एकल उदाहरण की अपेक्षा करते हैं। यह कुबेरनेट्स के लिए अविश्वसनीय रूप से सहायक है क्योंकि यह अंडर-प्रोविजनिंग या ओवर-प्रोविजनिंग से बचने में मदद करता है जिसके परिणामस्वरूप अप्रयुक्त संसाधन (पैसे खर्च करना) या संसाधनों की कमी (जिससे ऐप क्रैश या धीमा हो जाता है) हो सकता है।

$ terraform plan

# ...

Plan: 2 to add, 0 to change, 0 to destroy.
$ terraform apply

kubernetes_replication_controller.nginx: Creating...
# ...
kubernetes_replication_controller.nginx: Creation complete (ID: default/scalable-nginx-example)
kubernetes_service.nginx: Creating...
# ...
kubernetes_service.nginx: Still creating... (10s elapsed)
kubernetes_service.nginx: Still creating... (20s elapsed)
kubernetes_service.nginx: Still creating... (30s elapsed)
kubernetes_service.nginx: Still creating... (40s elapsed)
kubernetes_service.nginx: Still creating... (50s elapsed)
kubernetes_service.nginx: Creation complete (ID: default/nginx-example)

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path:

Outputs:

lb_ip = 35.197.9.247

पिछले उदाहरण के विपरीत, यहां आईपी पता क्लस्टर में निर्धारित 2 पॉड में से एक को ट्रैफ़िक को निर्देशित करेगा।

विन्यास अद्यतन करना

जैसे-जैसे हमारा एप्लिकेशन उपयोगकर्ता-आधार बढ़ता है, हमें अनुसूचित होने के लिए और उदाहरणों की आवश्यकता हो सकती है। इसे प्राप्त करने का सबसे आसान तरीका तदनुसार विन्यास में replicas बढ़ाना है।

resource "kubernetes_replication_controller" "example" {
# ...

  spec {
    replicas = 5

# ...

}

आप एपीआई को हिट करने से पहले सत्यापित कर सकते हैं कि आप केवल वही बदल रहे हैं जिसे आप बदलने का इरादा रखते हैं और किसी और ने आपके द्वारा पहले बनाए गए संसाधन को संशोधित नहीं किया है।

$ terraform plan

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

kubernetes_replication_controller.nginx: Refreshing state... (ID: default/scalable-nginx-example)
kubernetes_service.nginx: Refreshing state... (ID: default/nginx-example)

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

  ~ kubernetes_replication_controller.nginx
      spec.0.replicas: "2" => "5"


Plan: 0 to add, 1 to change, 0 to destroy.

जैसा कि हम प्रस्तावित योजना से खुश हैं, हम बस उस बदलाव को लागू कर सकते हैं।

$ terraform apply

और 3 और प्रतिकृतियां निर्धारित और लोड बैलेंसर से जुड़ी होंगी।

बोनस: प्रबंध कोटा और सीमाएँ

क्लस्टर का प्रबंधन करने वाले ऑपरेटर के रूप में आप संभवतः टीमों के भीतर और जिम्मेदारी से क्लस्टर का उपयोग करने के लिए भी जिम्मेदार हैं।

रिसोर्स कोटा और लिमिट रेंज दोनों ही सीपीयू, मेमोरी, डिस्क स्पेस और अन्य संसाधनों के आस-पास की बाधाओं को दूर करने के तरीके पेश करते हैं जो क्लस्टर उपयोगकर्ताओं द्वारा उपभोग किए जाएंगे।

संसाधन कोटा पूरे नामस्थान को बाधित कर सकता है

resource "kubernetes_resource_quota" "example" {
  metadata {
    name = "terraform-example"
  }
  spec {
    hard {
      pods = 10
    }
    scopes = ["BestEffort"]
  }
}

जबकि लिमिट रेंज एक विशिष्ट संसाधन प्रकार (जैसे पॉड या परसेंट वॉल्यूम क्लेम) पर सीमाएं लगा सकती है।

resource "kubernetes_limit_range" "example" {
    metadata {
        name = "terraform-example"
    }
    spec {
        limit {
            type = "Pod"
            max {
                cpu = "200m"
                memory = "1024M"
            }
        }
        limit {
            type = "PersistentVolumeClaim"
            min {
                storage = "24M"
            }
        }
        limit {
            type = "Container"
            default {
                cpu = "50m"
                memory = "24M"
            }
        }
    }
}
$ terraform plan
$ terraform apply

निष्कर्ष

टेराफॉर्म आपको अपने कुबेरनेट क्लस्टर और कुबेरनेट संसाधनों के लिए दोनों गणना करने का एक प्रभावी तरीका प्रदान करता है। मेनू से जुड़े कुबेरनेट्स प्रदाता के व्यापक प्रलेखन की जाँच करें।