Day 15 - Rancher 与 Infrastructure as Code

本文将於赛後同步刊登於笔者部落格

有兴趣学习更多 Kubernetes/DevOps/Linux 相关的资源的读者,欢迎前往阅读

更多相关科技的技术分享,欢迎追踪 矽谷牛的耕田笔记

对於 Kubernetes 与 Linux Network 有兴趣的可以参阅笔者的线上课程

前言

前篇探讨了各式各样透过 Rancher UI 来管理 Rancher, Kubernetes 的各种方式,所有的操作基本上都是基於 UI 点击而完成的。

试想下列情境,是否会觉得某些情况还是有点卡?

  1. 公司想要有针对不同环境有不同的 Rancher 丛集,譬如 Production 跟其他要分开
  2. 希望能够减少管理员透过 UI 管理的频率,毕竟透过 UI 点选创建有时并不会有太完善的稽核性
  3. 有快速重复部署 RKE 丛集的需求,某些情况还需要删除重建

上述这些要求全部都可以用之前分享的方式慢慢处理,不过会不会有更好的方式处理?
这几年流行的 IaC 架构, Infrastructure as Code 的概念能不能套用到 Rancher 身上?
试想一下如果可以透过程序码的方式定义 Rancher,对於开发者与管理者来说可以达到什麽样的好处

  1. 当 Rancher 整个损毁,需要重新安装或是需要部署类似环境时,可以非常快的部署,不需要重新透过手动的方式去重新设定所有细节
  2. 所有重大操作都以程序码为基础去设定,减少任何人为操作的可能性,同时有任何出错时可以基於程序码重新部署来修复环境。
  3. 复制程序码就可以复制环境,修改一些变数就可以创建出类似的丛集

更重要的是,如果将这些 IaC 的概念与 CI/CD 流程整合,还可以透过 Code Review 的方式来合作检视所有 Rancher 上的修改,同时透过自动化的方式去维护 Rancher 服务。
有任何不适当的修改想要复原也可以透过 Git Revert 的方式来回复到之前的状态。
这种状况下 Rancher 会变得更加容易维护与管理。

IaC

IaC 的工具非常的多,当人们讲到跟 Cloud Infrastructure 有关时,大部分人都会提到 Terraform 这套解决方案,而近年 Pulumi 的声势也渐渐提昇,愈来愈多人尝试使用 Pulumi 来取代 Terraform,两者最大的差别在於撰写方式。
Terraform 有自己设计一套语法,意味使用 Terraform 就要使用该语法,而 Pulumi 则是基於不同的程序语言提供不同的 API 来使用ㄓ,所以开发者可以使用自己习惯的程序语言去撰写。

本篇文章将介绍如何透过 Terraform 来管理我们的 Rancher,之後的章节有机会的话也会顺便展示一下使用 Terraform 的写法。

Terraform

关於 Terraform 的使用方式推荐参阅我好朋友 [David 所撰写的 Terraform 系列文章]
(xxx)

本篇文章就不会探讨太多 Terraform 的基本概念与使用方式,会更加专注於如何透过 Terraform 来管理 Rancher。

Terraform 官网中有非常详细的资讯探讨 Rancher 所有 API 的使用方式,有兴趣可以参阅Rancher2 Provider

为了要能够跟 Rancher 沟通,必须要先获得一组 Access/Secrey Key 来存取 Rancher,这组 Key 可以从 Rancher 的使用者帐号去取得。

首先用一个可以管理 Rancher 的帐号登入到 Rancher UI,接者於右上方使用者那边去点选 API & Keys,如下图。

进去之後可以看到系统预设有一些 Key,这些忽略即可。
要注意的是,每组 Key 产生後都会得到一组对应的 Secret Key,该 Key 是没有办法透过 UI 找回来的,这意味如果你当下忘了储存或是之後不见了,那这把 secret key 就再也没有办法找回。

点选右上方的 Add Key 可以看到如下的画面,该画面可以先设定该 Key 会不会自动过期的时间,以及使用范围。

设定名称後就会看到如下图的画面,画面中有四种相关不同的资讯,分别是

  1. Access Endpoint: 存取的 API 位置
  2. Access Key
  3. Secret Key(只有这边会出现,一但按下 Close 就再也拿不回来了)
  4. 针对 HTTP 需求譬如 kubectl 是有机会直接使用最後一个 Bearer Token 使用

这次的 Terraform 要使用前三组资讯,这边不考虑任何 Terraform 的撰写技巧与 Style,单纯用最简单的风格来介绍如何将 Terraform 与 Rancher 整合。

以下示范是基於 Terraform 1.0 与 Rancher Provider 1.17.0 的版本

首先准备一个 main.tf 的档案,内容如下

╰─$ cat main.tf
terraform {
  required_providers {
    rancher2 = {
      source = "rancher/rancher2"
      version = "1.17.0"
    }
  }
}

provider "rancher2" {
  api_url    = "https://rancher.hwchiu.com"
  access_key = "token-ng6df"
  secret_key = "l8kjh7w5mdb5s5nzmp56c5rctpt59p9bcq9wbw2g8b66wsdchrkdv2"
}

接者透过 Terraform init 先初始化相关模组

╰─$ terraform init
Initializing the backend...

Initializing provider plugins...
- Finding rancher/rancher2 versions matching "1.17.0"...
- Installing rancher/rancher2 v1.17.0...
- Installed rancher/rancher2 v1.17.0 (signed by a HashiCorp partner, key ID 2EEB0F9AD44A135C)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

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.

一切都准备完毕後,接下来示范一下如何透过 Rancher 来创造一些 Rancher 的资源,譬如说来创造一个 RKE Template

这边直接参考范例将下列内容写入到 main.tf 中
该范例会创建一个 RKE Template 并且针对 etcd 以及一些更新策略进行设定。

$ cat main.tf
terraform {
  required_providers {
    rancher2 = {
      source = "rancher/rancher2"
      version = "1.17.0"
    }
  }
}

provider "rancher2" {
  api_url    = "https://rancher.hwchiu.com"
  access_key = "token-ng6df"
  secret_key = "l8kjh7w5mdb5s5nzmp56c5rctpt59p9bcq9wbw2g8b66wsdchrkdv2"
}

resource "rancher2_cluster_template" "foo" {
  name = "ithome_terraforn"
  template_revisions {
    name = "V1"
    cluster_config {
      rke_config {
        network {
          plugin = "canal"
        }
        services {
          etcd {
            creation = "6h"
            retention = "24h"
          }
        }
        upgrade_strategy {
          drain = true
          max_unavailable_worker = "20%"
        }
      }
    }
    default = true
  }
  description = "Terraform cluster template foo"
}

接者透过 terraform apply 去更新

$ terraform apply
...
              + rke_config {
                  + addon_job_timeout     = 0
                  + ignore_docker_version = true
                  + kubernetes_version    = (known after apply)
                  + prefix_path           = (known after apply)
                  + ssh_agent_auth        = false
                  + ssh_cert_path         = (known after apply)
                  + ssh_key_path          = (known after apply)
                  + win_prefix_path       = (known after apply)

                  + network {
                      + mtu     = 0
                      + options = (known after apply)
                      + plugin  = "canal"
                    }

                  + services {
                      + etcd {
                          + ca_cert    = (known after apply)
                          + cert       = (sensitive value)
                          + creation   = "6h"
                          + extra_args = (known after apply)
                          + gid        = 0
                          + image      = (known after apply)
                          + key        = (sensitive value)
                          + path       = (known after apply)
                          + retention  = "24h"
                          + snapshot   = false
                          + uid        = 0
                        }
                    }

                  + upgrade_strategy {
                      + drain                        = true
                      + max_unavailable_controlplane = "1"
                      + max_unavailable_worker       = "20%"
                    }
                }
            }
        }
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

rancher2_cluster_template.foo: Creating...
rancher2_cluster_template.foo: Creation complete after 2s [id=cattle-global-data:ct-rtd4f]

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

一切创造完毕後就可以移动到 Rancher UI 中,从 RKE Template 可以看到多出了一个新的 RKE Template,名称为 ithome_terraform,与我们前述 main.tf 中描述的一样。

点进去该 RKE Template 就可以看到详细的设定,这边要补充一下, Rancher 大部分的物件都提供两种阅览模式,一种是友善的 UI 介面另一种则是纯 YAML 的描述档案。
按照下方的方式点选 View as a Form 来看看基於 YAML 的内容。

从 YAML 内就可以看到 Terraform 描述的设定都有正确的写进来。

透过这样简单的方式,就可以使用程序码的方式来管理 Rancher,除了 RKE Template 之外, Cloud Credential, Node Template, Cluster 也都可以透过 Terraform 的方式来管理,这样有另外一个好处就是系统管理员只要撰写好这些资源後,接下来的使用者就不需要接触到这些太细节的机密资讯,能够专心的目标资源与逻辑去描述与创造即可。

最後这边要再补充一个使用 API 沟通 Rancher 的好处,事实上, Rancher UI 没有办法展现 Rancher 100% 的能力, RKE 内有非常多的设定可以处理,但是有些处理实际上没有办法透过 UI 去设定,譬如说想要针对 Kubelet 给一些额外参数的话,这些设定是没有办法从 Rancher UI 完成的,但是如果是透过 Rancher API 来设定的话就没有问题。

Rancher API 有很多方式可以处理,不论是直接撰写应用程序沟通 Rancher 或是使用 Terraform/Pulumi 等工具都可以,透过这类型工具去描述 Rancher 实际上可以将 Rancher 使用的更灵活与更强大,设定的东西也更多元化。

如果团队有意愿长期使用 Rancher,会非常推荐使用 IaC 的工具来维护与管理 Rancher,期带来得好非常的多。


<<:  Day 03 安装python、需要的package以及VS Code等环境建置

>>:  [Java Day04] 1.2. 型别

<Day25> 永丰金iLeader — 查询报价

● 这章会大致介绍永丰金iLeader及如何透过它查询报价 "永丰金iLeader&quo...

# Day27--我是谁?我在哪?终於离开Vim了

不知不觉commit了很多东西,今天要来面对的,就是这些纪录的修改。 这个篇章大概会分成两个部分: ...

Day23 jQuery 基本教学(三)

Method 操作方法 在熟悉 selector 後,就可以开始采用物件连结的方式进行各种作业 最基...

[Day4] - RESTful API 介绍

前两天花了些时间介绍了一下前端後端的概念,希望大家对前端後端,以期本系列要介绍的内容有一个大轮廓的理...

VisualStudio 2019 Angular mat-table 笔记

恩..这边主要是自己的笔记 自己最近想弄一些作品 MVC是已经会的东西 於是想自学一下Angular...