当前位置: 首页 > 工具软件 > vault13 > 使用案例 >

Terraform + Vault 轻松构建Kubernetes 集群

袁青青
2023-12-01

本文主要介绍如果通过Terraform 和Vault 轻松构建Kubernetes 集群环境, 写作来源于 Kelsey Hightower 的Kubernetes The Hard Way, 主要介绍的是在Google Cloud上面的部署kubernetes过程,
在部署kubernets 环境的时候,相信大多数人都遇到过如下类似的问题:

  1. 证书创建过程繁琐
  2. 难以做到虚拟机创建过程标准化, 创建1,2 台开发环境手动可以搞,但是如果几十台,几百台如何来做呢
  3. 环境部署好之后,各个组件服务启动没有问题,但是无法使用
  4. 市面上各种kubernetes的安装部署工具,但是各个组建间是如何工作的, 通信关系,配置项具体什么含义无法理解

通过本次实验,可以加强对kubernetes 各个组件的关系会更加的深入了解

实验概述

通过Terraform 来在Mac OSX 宿主机的环境下批量创建以VirtualBox 为hypervisor的虚拟机, 同时利用了configdrive 来配置出来的虚拟机,主要是配置SSH 连接时需要的公钥。在基础环境准备结束之后,手动的配置各个服务组件来搭建kubernetes 集群环境。通过简单的案例,来测试kubernetes的功能

Cloud Init之Config Drive的创建

相信对于从事过云计算相关工作的人特别是IaaS的来说cloud-init 已经是非常的熟悉,我们看下官方的说法

Everything about cloud-init, a set of python scripts and utilities to make your cloud images be all they can be!

cloudinit 十分的强大,可以在机器启动之后对其进行再次的配置,举个例子,创建虚拟机都会有一个模版,其实就是(可能)预装了基础软件的仅包含操作系统的特殊的镜像文件,这些镜像文件会存储在镜像服务器当中,如果能够将其做的容量足够小,那么在存储镜像时占用的空间会尽可能的少,为了满足在批量通过镜像模版创建虚拟机时不同的需求,最主要的是磁盘的大小,譬如模版文件的磁盘容量是10G,但是有的客户想要200G的操作系统磁盘,怎么办呢? 这个时候就可以通过cloudinit结合hypervisor创建时给定的大的磁盘文件可以动态的对文件系统进行再次的空间划分,达到一个模版文件就可以批量创建统一操作系统类型,但是规格不同的虚拟机。
当然这只是cloudinit 一个基本的使用功能, 其它功能详情参见官方文档

回到我们的实验环境来,主要是通过confidrive的方式来加载到虚拟机中,在启动时cloudinit 通过读取configdrive 挂载到虚拟机内部后的配置文件进行虚拟机的再配置

$ mkdir configdrive

创建meta-data文件
$ touch configdrive/meta-data

创建user-data 文件, 根据实际情况修改ssh-authorized-keys
部分


$ cat > configdrive/user-data <<EOF                                                                                                              2.2.2   /Users/jiangytcn
heredoc> #cloud-config
groups:
  - cloud-users
system_info:
  default_user:
    name: default-user
    lock_passwd: true
    groups: cloud-users
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
# Add users to the system. Users are added after groups are added.
users:
  - name: yacloud
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: cloud-users
    shell: /bin/bash
    ssh-import-id: None
    lock_passwd: true
    ssh-authorized-keys:
      - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKVOom9IiXF9pN9XrEX3mz12Fr/HZbhd2Laz1a4FdeEhTbxnVwRV5N2JbxiB/ti1lN+wxs7OJTRpjEGcYnVybgDcKM8IlgTdv5Uy/aMYIUQHTam6qQX65bdDS94lt+FzEBj6sk8DAcNtZEIdkCvLvO1rjBZIW/mVoWVk13BoTaebnHx5o8mT/X+ub1KNoZv51ve0vZKDcPDU6b7d8LWxMby20ogPiLPtEQfZ+BSlYLL2/o4EtnIhee1/UQM6pzGI2Kyd8IL/JPoQ1mof5rRKBOfBbN6+J7nPzw8swUF7xjw+fZrQwDY6MMa7gH4X8mi6gJOC5dFLdEXt5jBu+A9e33 yacloud.inc@gmail.com"

runcmd:
  - [ 'sh', '-c', 'date > /tmp/ya_date.txt']

heredoc> EOF

创建configdrive iso 虚拟文件

hdiutil makehybrid -iso -joliet -default-volume-name cidata -o configdrive.iso configdrive

通过上述创建好的configdrive 文件,加载到装有cloudinit的虚拟机当中后,就可以通过yacloud 账户以ssh 秘钥的方式登录虚拟机当中

Terraform的使用

应该听说过Infrastructure as Code, 听到这个概念的时候,关注过terraform,Hashicorp 出品, 各个杰作啊。

WRITE
INFRASTRUCTURE AS CODE

PLAN 
PREVIEW CHANGES BEFORE APPLYING

CREATE
REPRODUCIBLE INFRASTRUCTURE

简单来说就是就是能够将底层的基础设施资源通过Terraform的模版文件来表示,之中不可缺少的概念就是 provider, 其实就是terraform 和底层基础设施之间的适配层,能够将Terraform中的语法规则,对资源的需求转述为对具体的底层资源的需求描述
本次实验中主要是使用了VirtualBox 做为环境
1. 生成provider 二进制文件

 
git clone https://github.com/jiangytcn/terraform-provider-virtualbox
cd terraform-provider-virtualbox
go get
mkdir -p ~/github.com/k8s-terraform-vault-easyway
mv terraform-provider-virtualbox ~/github.com/k8s-terraform-vault-easyway

2. 创建Terraform 模版文件
 
resource "virtualbox_vm" "node" {
count = 3
name = "${format("k8s-terraform-vault-easyway-%02d", count.index+1)}"
image = "/Users/jiangytcn/github.com/k8s-terraform-vault-easyway/xenial-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "1024 Mib",
network_adapter {
type = "hostonly",
device = "IntelPro1000MTDesktop",
host_interface = "vboxnet1", //hostonlyif
}
network_adapter {
type = "nat",
device = "IntelPro1000MTDesktop",
}
optical_disks = ["/Users/jiangytcn/github.com/k8s-terraform-vault-easyway/configdrive.iso"]
}
output "master" {
value = "${element(virtualbox_vm.node.*.network_adapter.0.ipv4_address, 1)}"
}
output "slave1" {
value = "${element(virtualbox_vm.node.*.network_adapter.0.ipv4_address, 2)}"
}
output "slave2" {
value = "${element(virtualbox_vm.node.*.network_adapter.0.ipv4_address, 3)}"
}

  1. 下载Ubuntu 镜像文件
    https://app.vagrantup.com/ubuntu/boxes/xenial64 下载一box,更名为
    k8s-terraform-vault-easyway/xenial-server-cloudimg-amd64-vagrant.box

    PS: 其中的目录根据实际情况进行修改

  2. 创建虚拟机
    cd ~/github.com/k8s-terraform-vault-easyway
    terraform init
    terraform apply

….
….
Apply complete! Resources: 0 added, 3 changed, 0 destroyed.

Outputs:

master = 192.168.57.3
slave1 = 192.168.57.4
slave2 = 192.168.57.5

这样三台虚拟机就创建成功了

$ VBoxManage list runningvms                                                            2.2.2   /Users/jiangytcn
"k8s-terraform-vault-easyway-03" {bf361fac-aeac-49e9-8293-483523ff84c5}
"k8s-terraform-vault-easyway-02" {e2a88427-81aa-457a-a9e0-254a87f6e50f}
"k8s-terraform-vault-easyway-01" {502f47cb-e7ff-406e-ac16-43496061545c}

Vault的使用即证书创建

相信使用过openssl创建过SSL 证书的同学会有相似的经历, 对于里面的参数不是十分了解,Vault 提供了一种ssl 的密码后端引擎,以提供证书的颁发,配置,变更, 主要通过单机开发环境的vault 来提供证书创建功能, 关于更多功能请参考

  1. 下载Vault 软件包
    https://www.vaultproject.io/downloads.html, 选择与实验环境对应的平台
  2. 启动开发模式
$ ./vault server -dev 
==> Vault server configuration:

             Api Address: http://127.0.0.1:8200
                     Cgo: disabled
         Cluster Address: https://127.0.0.1:8201
              Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", tls: "disabled")
               Log Level: info
                   Mlock: supported: false, enabled: false
                 Storage: inmem
                 Version: Vault v0.10.3
             Version Sha: c69ae68faf2bf7fc1d78e3ec62655696a07454c7

WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.

You may need to set the following environment variable:

    $ export VAULT_ADDR='http://127.0.0.1:8200'

The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.

Unseal Key: yzDDBRsxjw2E4yjT2hCJVoLom2hSMiCSp1wxWBv4pso=
Root Token: a95bb2c6-2641-d0be-820e-3ad27c06f800

Development mode should NOT be used in production installations!

==> Vault server started! Log data will stream in below:
....
....
....
....

其中主要的是Root Token 和 VAULT_ADDR
3. 登录到vault 环境中


$ export VAULT_ADDR='http://127.0.0.1:8200'
$ ./vault login a95bb2c6-2641-d0be-820e-3ad27c06f800
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token a95bb2c6-2641-d0be-820e-3ad27c06f800
token_accessor 984b3111-3168-2524-df8d-4f9e9fe176fb
token_duration ∞
token_renewable false
token_policies [root]

ps: vault 二进制文件既是api server 软件,也是cli 客户端软件

配置Vault PKI secret backend 以及CA 等信息

  vault secrets enable pki
  vault secrets tune -max-lease-ttl=87600h pki

  # 10 years for CA
  vault write --format=json pki/root/generate/exported \
    common_name="int.yacloud.io" \
    ttl=87600h > ca_certs.json

  cat ca_certs.json | jq -r .data.certificate > ca.pem
  cat ca_certs.json | jq -r .data.private_key > ca.key

  vault write pki/config/urls \
    issuing_certificates="http://127.0.0.1:8200/v1/pki/ca" \
    crl_distribution_points="http://127.0.0.1:8200/v1/pki/crl"

  # one year for the certs
  vault write pki/roles/k8s-certs-yacloudio \
    allow_any_name=true \
    allow_subdomains=true \
    enforce_hostnames=false \
    allowed_domains="yacloud.io" \
    organization=system:masters,system:nodes,system:node-proxier,Kubernetes \
    max_ttl=8760h

Kubernetes 服务配置

自签名证书的容器镜像服务器安装配置

服务发布与滚动升级

 类似资料: