本文主要介绍如果通过Terraform 和Vault 轻松构建Kubernetes 集群环境, 写作来源于 Kelsey Hightower 的Kubernetes The Hard Way, 主要介绍的是在Google Cloud上面的部署kubernetes过程,
在部署kubernets 环境的时候,相信大多数人都遇到过如下类似的问题:
通过本次实验,可以加强对kubernetes 各个组件的关系会更加的深入了解
通过Terraform 来在Mac OSX 宿主机的环境下批量创建以VirtualBox 为hypervisor的虚拟机, 同时利用了configdrive 来配置出来的虚拟机,主要是配置SSH 连接时需要的公钥。在基础环境准备结束之后,手动的配置各个服务组件来搭建kubernetes 集群环境。通过简单的案例,来测试kubernetes的功能
相信对于从事过云计算相关工作的人特别是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 秘钥的方式登录虚拟机当中
应该听说过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
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)}"
}
下载Ubuntu 镜像文件
在 https://app.vagrantup.com/ubuntu/boxes/xenial64 下载一box,更名为
k8s-terraform-vault-easyway/xenial-server-cloudimg-amd64-vagrant.box
PS: 其中的目录根据实际情况进行修改
创建虚拟机
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}
相信使用过openssl创建过SSL 证书的同学会有相似的经历, 对于里面的参数不是十分了解,Vault 提供了一种ssl 的密码后端引擎,以提供证书的颁发,配置,变更, 主要通过单机开发环境的vault 来提供证书创建功能, 关于更多功能请参考
$ ./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