This commit is contained in:
Vassiliy Yegorov
2022-06-07 10:41:53 +07:00
commit 7f72d9883a
9 changed files with 492 additions and 0 deletions

43
.gitignore vendored Normal file
View File

@@ -0,0 +1,43 @@
# Created by https://www.toptal.com/developers/gitignore/api/terraform
# Edit at https://www.toptal.com/developers/gitignore?templates=terraform
### Terraform ###
# Local .terraform directories
**/.terraform/*
# .tfstate files
*.tfstate
*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Include override files you do wish to add to version control using negated pattern
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc
# End of https://www.toptal.com/developers/gitignore/api/terraform
output.json

24
.terraform.lock.hcl generated Normal file
View File

@@ -0,0 +1,24 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hetznercloud/hcloud" {
version = "1.31.1"
constraints = "~> 1.31.0"
hashes = [
"h1:CWXFFa9rOMqAKVBDLS1qrf4PILhF20hCG6lrIt26LOs=",
"zh:1ac55d8db278a85ee24a9269b0d85ee138242d9f8d9b9ba8b95dc4a02d659137",
"zh:4720d6d96f0603c988bd95c963aa014b0e1b07fdc0b2c76fe3cb521a7ba54f1a",
"zh:4c69e86d325de13247b887007b53f712ce53528d98c73f06ff0d757d1c6b52ac",
"zh:560517e62d6f14feda622268adc9cfc3045440367b58b73fdd954804b72ae4a3",
"zh:792e1b647dd583e42a5b65c104ffde7e8b77f173e08e62bf5ca6b4e901c10ff1",
"zh:8046990a2d7b5cb304a4d959196a5dc642b81fd158b1da50d1dd72039ba2093d",
"zh:885bb88cd934f68cbc2016c812b99a49fc3a358c19c82d14b9f3adde6d2497af",
"zh:9f8728f650a30afc5bba6c97d40decdb3fd846db35e68659a7967262427ffa6b",
"zh:a78b7369b6a077c8a82266515f1bbdfd1eaa98fc82fa3e34c1aa1bbadf4e5514",
"zh:aaf306f40b7c3f48732437f15366f4ce042e3885b914f19f4652ac9b600899b1",
"zh:af533eee1f85ce3126931f0c3c1fe455918f3525079e92e9d85ee391e42ff4fc",
"zh:b0ce67d5ee900127a14e616c1f7463b211204627742b4051c1b33f464b97679e",
"zh:b743cd1355ba7b37b60a66f79b0e779d8d6c8adc7bdec151d2b14994dec7b809",
"zh:cdb210a89af1bf1563f0c933acd14b86a6a01e6289231e317cf5704abf54c9e6",
]
}

26
README.md Normal file
View File

@@ -0,0 +1,26 @@
# Поднимаем кластер k8s в [любом] облаке
## Утилиты
- [terraform](https://www.terraform.io/downloads)
- [kubeone](https://github.com/kubermatic/kubeone/releases/)
## Видео к курсу
- [видео]()
## Ставим
- export HCLOUD_TOKEN="<YOUR HCLOUD TOKEN>"
- terraform init
- terraform apply
- terraform output -json > output.json
- kubeone apply --manifest kubeone.yaml --tfjson
## Сносим
- kubeone reset --manifest kubeone.yaml -t output.json
- terraform destroy
##### Автор
- **Vassiliy Yegorov** [vasyakrg](https://git.realmanual.ru)
- [школа](realmanual.ru)
- [youtube](youtube.com/realmanual)

23
kubeone.yaml Normal file
View File

@@ -0,0 +1,23 @@
apiVersion: kubeone.k8c.io/v1beta2
kind: KubeOneCluster
versions:
kubernetes: '1.21.12'
cloudProvider:
hetzner: {}
external: true
controlPlane:
hosts:
- sshPort: 22 # can be left out if using the default (22)
sshUsername: root
# You usually want to configure either a private key OR an
# agent socket, but never both. The socket value can be
# prefixed with "env:" to refer to an environment variable.
sshPrivateKeyFile: '~/.ssh/demo-cluster'
apiEndpoint:
host: ''
port: 6443
alternativeNames: []

161
main.tf Normal file
View File

@@ -0,0 +1,161 @@
/*
Copyright 2019 The KubeOne Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
resource "hcloud_ssh_key" "kubeone" {
name = "kubeone-${var.cluster_name}"
public_key = file(var.ssh_public_key_file)
}
resource "hcloud_network" "net" {
name = var.cluster_name
ip_range = var.ip_range
}
resource "hcloud_firewall" "cluster" {
name = "${var.cluster_name}-fw"
labels = {
"kubeone_cluster_name" = var.cluster_name
}
apply_to {
label_selector = "kubeone_cluster_name=${var.cluster_name}"
}
rule {
description = "allow ICMP"
direction = "in"
protocol = "icmp"
source_ips = [
"0.0.0.0/0",
]
}
rule {
description = "allow all TCP inside cluster"
direction = "in"
protocol = "tcp"
port = "any"
source_ips = [
var.ip_range,
]
}
rule {
description = "allow all UDP inside cluster"
direction = "in"
protocol = "udp"
port = "any"
source_ips = [
var.ip_range,
]
}
rule {
description = "allow SSH from any"
direction = "in"
protocol = "tcp"
port = "22"
source_ips = [
"0.0.0.0/0",
]
}
rule {
description = "allow NodePorts from any"
direction = "in"
protocol = "tcp"
port = "30000-32767"
source_ips = [
"0.0.0.0/0",
]
}
}
resource "hcloud_network_subnet" "kubeone" {
network_id = hcloud_network.net.id
type = "server"
network_zone = var.network_zone
ip_range = var.ip_range
}
resource "hcloud_server_network" "control_plane" {
count = var.control_plane_replicas
server_id = element(hcloud_server.control_plane.*.id, count.index)
subnet_id = hcloud_network_subnet.kubeone.id
}
resource "hcloud_placement_group" "control_plane" {
name = var.cluster_name
type = "spread"
labels = {
"kubeone_cluster_name" = var.cluster_name
}
}
resource "hcloud_server" "control_plane" {
count = var.control_plane_replicas
name = "${var.cluster_name}-control-plane-${count.index + 1}"
server_type = var.control_plane_type
image = var.image
location = var.datacenter
placement_group_id = hcloud_placement_group.control_plane.id
ssh_keys = [
hcloud_ssh_key.kubeone.id,
]
labels = {
"kubeone_cluster_name" = var.cluster_name
"role" = "api"
}
}
resource "hcloud_load_balancer_network" "load_balancer" {
load_balancer_id = hcloud_load_balancer.load_balancer.id
subnet_id = hcloud_network_subnet.kubeone.id
}
resource "hcloud_load_balancer" "load_balancer" {
name = "${var.cluster_name}-lb"
load_balancer_type = var.lb_type
location = var.datacenter
labels = {
"kubeone_cluster_name" = var.cluster_name
"role" = "lb"
}
}
resource "hcloud_load_balancer_target" "load_balancer_target" {
count = var.control_plane_replicas
type = "server"
load_balancer_id = hcloud_load_balancer.load_balancer.id
server_id = element(hcloud_server.control_plane.*.id, count.index)
use_private_ip = true
depends_on = [
hcloud_server_network.control_plane,
hcloud_load_balancer_network.load_balancer
]
}
resource "hcloud_load_balancer_service" "load_balancer_service" {
load_balancer_id = hcloud_load_balancer.load_balancer.id
protocol = "tcp"
listen_port = 6443
destination_port = 6443
}

83
output.tf Normal file
View File

@@ -0,0 +1,83 @@
/*
Copyright 2019 The KubeOne Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
output "kubeone_api" {
description = "kube-apiserver LB endpoint"
value = {
endpoint = hcloud_load_balancer.load_balancer.ipv4
apiserver_alternative_names = var.apiserver_alternative_names
}
}
output "ssh_commands" {
value = formatlist("ssh ${var.ssh_username}@%s", hcloud_server.control_plane.*.ipv4_address)
}
output "kubeone_hosts" {
description = "Control plane endpoints to SSH to"
value = {
control_plane = {
hostnames = hcloud_server.control_plane.*.name
cluster_name = var.cluster_name
cloud_provider = "hetzner"
private_address = hcloud_server_network.control_plane.*.ip
public_address = hcloud_server.control_plane.*.ipv4_address
network_id = hcloud_network.net.id
ssh_agent_socket = var.ssh_agent_socket
ssh_port = var.ssh_port
ssh_private_key_file = var.ssh_private_key_file
ssh_user = var.ssh_username
}
}
}
output "kubeone_workers" {
description = "Workers definitions, that will be transformed into MachineDeployment object"
value = {
# following outputs will be parsed by kubeone and automatically merged into
# corresponding (by name) worker definition
"${var.cluster_name}-pool1" = {
replicas = var.workers_replicas
providerSpec = {
sshPublicKeys = [file(var.ssh_public_key_file)]
operatingSystem = var.worker_os
operatingSystemSpec = {
distUpgradeOnBoot = false
}
cloudProviderSpec = {
# provider specific fields:
# see example under `cloudProviderSpec` section at:
# https://github.com/kubermatic/machine-controller/blob/master/examples/hetzner-machinedeployment.yaml
serverType = var.worker_type
location = var.datacenter
image = var.image
networks = [
hcloud_network.net.id
]
# Datacenter (optional)
# datacenter = ""
labels = {
"kubeone_cluster_name" = var.cluster_name
"${var.cluster_name}-workers" = "pool1"
}
}
}
}
}
}

3
terraform.tfvars.example Normal file
View File

@@ -0,0 +1,3 @@
cluster_name = "kubeone-cluster"
ssh_public_key_file = "~/.ssh/demo-cluster.pub"
ssh_private_key_file = "~/.ssh/demo-cluster"

120
variables.tf Normal file
View File

@@ -0,0 +1,120 @@
/*
Copyright 2019 The KubeOne Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
variable "cluster_name" {
description = "prefix for cloud resources"
type = string
validation {
condition = can(regex("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$", var.cluster_name))
error_message = "Value of cluster_name should be lowercase and can only contain alphanumeric characters and hyphens(-)."
}
}
variable "apiserver_alternative_names" {
description = "subject alternative names for the API Server signing cert."
default = []
type = list(string)
}
variable "worker_os" {
description = "OS to run on worker machines"
# valid choices are:
# * ubuntu
# * centos
default = "ubuntu"
type = string
}
variable "ssh_public_key_file" {
description = "SSH public key file"
default = "~/.ssh/demo-cluster.pub"
type = string
}
variable "ssh_port" {
description = "SSH port to be used to provision instances"
default = 22
type = number
}
variable "ssh_username" {
description = "SSH user, used only in output"
default = "root"
type = string
}
variable "ssh_private_key_file" {
description = "SSH private key file used to access instances"
default = "~/.ssh/demo-cluster"
type = string
}
variable "ssh_agent_socket" {
description = "SSH Agent socket, default to grab from $SSH_AUTH_SOCK"
default = "env:SSH_AUTH_SOCK"
type = string
}
# Provider specific settings
variable "control_plane_type" {
default = "cx21"
type = string
}
variable "control_plane_replicas" {
default = 1
type = number
}
variable "worker_type" {
default = "cx31"
type = string
}
variable "workers_replicas" {
default = 3
type = number
}
variable "lb_type" {
default = "lb11"
type = string
}
variable "datacenter" {
default = "nbg1"
type = string
}
variable "image" {
default = "ubuntu-20.04"
type = string
}
variable "ip_range" {
default = "192.168.0.0/16"
description = "ip range to use for private network"
type = string
}
variable "network_zone" {
default = "eu-central"
description = "network zone to use for private network"
type = string
}

9
versions.tf Normal file
View File

@@ -0,0 +1,9 @@
terraform {
required_version = ">= 1.0.0"
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.31.0"
}
}
}