Merge pull request #114 from scottslowe/kubeadm-etcd-template

Create an example of generating kubeadm configuration files from a template
This commit is contained in:
Scott S. Lowe 2018-07-16 16:30:18 -06:00 committed by GitHub
commit f6460442bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 1970 additions and 0 deletions

View file

@ -0,0 +1,2 @@
kubeadm-cfg-*.yaml
ec2-tmp

View file

@ -0,0 +1,29 @@
apiVersion: kubeadm.k8s.io/v1alpha2
kind: MasterConfiguration
kubernetesVersion: v1.11.0
api:
controlPlaneEndpoint: {{ api_lb_ip }}
advertiseAddress: {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
etcd:
local:
extraArgs:
listen-client-urls: "https://127.0.0.1:2379,https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2379"
advertise-client-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2379"
listen-peer-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2380"
initial-advertise-peer-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2380"
initial-cluster: "{%- for host in groups['masters'] -%}
{%- if loop.first -%}
{{ hostvars[host]['ansible_fqdn'] }}=https://{{ hostvars[host]['ansible_' + primary_interface]['ipv4']['address'] }}:2380{%- endif -%}
{%- endfor -%}"
serverCertSANs:
- {{ hostvars[inventory_hostname]['ansible_fqdn'] }}
- {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
peerCertSANs:
- {{ hostvars[inventory_hostname]['ansible_fqdn'] }}
- {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
networking:
podSubnet: {{ podSubnet }}
token: {{ kubeadmToken }}
apiServerCertSANs:
- {{ api_lb_ip }}
- {{ api_lb_dns }}

View file

@ -0,0 +1,32 @@
apiVersion: kubeadm.k8s.io/v1alpha2
kind: MasterConfiguration
kubernetesVersion: v1.11.0
api:
controlPlaneEndpoint: {{ api_lb_ip }}
advertiseAddress: {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
etcd:
local:
extraArgs:
listen-client-urls: "https://127.0.0.1:2379,https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2379"
advertise-client-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2379"
listen-peer-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2380"
initial-advertise-peer-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2380"
initial-cluster: "{%- for host in groups['masters'] -%}
{%- if loop.first -%}
{{ hostvars[host]['ansible_fqdn'] }}=https://{{ hostvars[host]['ansible_' + primary_interface]['ipv4']['address'] }}:2380,{%- endif -%}
{%- if (not loop.last and not loop.first) -%}
{{ hostvars[host]['ansible_fqdn'] }}=https://{{ hostvars[host]['ansible_' + primary_interface]['ipv4']['address'] }}:2380{%- endif %}
{%- endfor -%}"
initial-cluster-state: existing
serverCertSANs:
- {{ hostvars[inventory_hostname]['ansible_fqdn'] }}
- {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
peerCertSANs:
- {{ hostvars[inventory_hostname]['ansible_fqdn'] }}
- {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
networking:
podSubnet: {{ podSubnet }}
token: {{ kubeadmToken }}
apiServerCertSANs:
- {{ api_lb_ip }}
- {{ api_lb_dns }}

View file

@ -0,0 +1,32 @@
apiVersion: kubeadm.k8s.io/v1alpha2
kind: MasterConfiguration
kubernetesVersion: v1.11.0
api:
controlPlaneEndpoint: {{ api_lb_ip }}
advertiseAddress: {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
etcd:
local:
extraArgs:
listen-client-urls: "https://127.0.0.1:2379,https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2379"
advertise-client-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2379"
listen-peer-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2380"
initial-advertise-peer-urls: "https://{{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}:2380"
initial-cluster: "{%- for host in groups['masters'] -%}
{%- if loop.last -%}
{{ hostvars[host]['ansible_fqdn'] }}=https://{{ hostvars[host]['ansible_' + primary_interface]['ipv4']['address'] }}:2380
{%- else -%}
{{ hostvars[host]['ansible_fqdn'] }}=https://{{ hostvars[host]['ansible_' + primary_interface]['ipv4']['address'] }}:2380,
{%- endif -%}{%- endfor -%}"
initial-cluster-state: existing
serverCertSANs:
- {{ hostvars[inventory_hostname]['ansible_fqdn'] }}
- {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
peerCertSANs:
- {{ hostvars[inventory_hostname]['ansible_fqdn'] }}
- {{ hostvars[inventory_hostname]['ansible_' + primary_interface]['ipv4']['address'] }}
networking:
podSubnet: {{ podSubnet }}
token: {{ kubeadmToken }}
apiServerCertSANs:
- {{ api_lb_ip }}
- {{ api_lb_dns }}

View file

@ -0,0 +1,37 @@
# Using Ansible to Template a Kubeadm Configuration File with etcd Support
These files provide an example of how to use Ansible's `template` module to create a Kubeadm 1.11 configuration file (with local etcd support) from a Jinja2 template. The template and Ansible playbook were tested using Ansible 2.5 on Fedora 27, but should work on any recent version of Ansible on any supported platform.
**NOTE:** At this time, the `kubeadm` configuration files generated by this playbook have _not_ been verified to create a working, conformant Kubernetes cluster. Consider them to be for demonstration purposes only.
## Contents
* **1-kubeadm.conf.j2**: This Jinja2 template contains the framework for a Kubeadm configuration file. This template is for the first stacked master.
* **2-kubeadm.conf.j2**: This Jinja2 template contains the framework for a Kubeadm configuration file. This template is for the second stacked master.
* **3-kubeadm.conf.j2**: This Jinja2 template contains the framework for a Kubeadm configuration file. This template is for the third stacked master.
* **ansible.cfg**: This is an Ansible configuration file. You may need to edit this file based on the target systems you're using with this environment.
* **README.md**: The file you're currently reading.
* **template.yml**: This Ansible playbook takes a series of variables along with the `*-kubeadm.conf.j2` Jinja2 templates. The output is three different `kubeadm` configuration files.
## Instructions
These instructions assume that you have Ansible installed and functioning correctly on your system.
1. Place the files from the `ansible/kubeadm-etcd-template` directory of this GitHub repository into a directory on your local system. You can clone the entire "learning-tools" repository (using `git clone`) or just download the specific files from the `ansible/kubeadm-etcd-template` folder.
2. (Optional) Edit `template.yml` to specify different values for the variables defined in the playbook.
3. This environment was tested using a CentOS-based AMI running on AWS, and as such uses the EC2 dynamic inventory module. Edit `inventory/ec2.ini` and `inventory/hosts` as needed to ensure that this environment will work for your specific inventory. You may also need to edit `ansible.cfg`, depending on the Linux distribution you choose to use.
4. Run `ansible-playbook template.yml` to generate the three different `kubeadm` configuration files. They will be rendered in the same directory as `kubeadm-cfg-first.yaml`, `kubeadm-cfg-second.yaml`, and `kubeadm-cfg-third.yaml`, respectively.
Enjoy!
## License
This content is licensed under the MIT License.

View file

@ -0,0 +1,6 @@
[defaults]
inventory = ./inventory/
private_key_file = ~/.ssh/aws_rsa
remote_user = centos
host_key_checking = false
retry_files_enabled = false

View file

@ -0,0 +1,209 @@
# Ansible EC2 external inventory script settings
#
[ec2]
# to talk to a private eucalyptus instance uncomment these lines
# and edit edit eucalyptus_host to be the host name of your cloud controller
#eucalyptus = True
#eucalyptus_host = clc.cloud.domain.org
# AWS regions to make calls to. Set this to 'all' to make request to all regions
# in AWS and merge the results together. Alternatively, set this to a comma
# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2' and do not
# provide the 'regions_exclude' option. If this is set to 'auto', AWS_REGION or
# AWS_DEFAULT_REGION environment variable will be read to determine the region.
regions = auto
#regions_exclude = us-gov-west-1, cn-north-1
# When generating inventory, Ansible needs to know how to address a server.
# Each EC2 instance has a lot of variables associated with it. Here is the list:
# http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
# Below are 2 variables that are used as the address of a server:
# - destination_variable
# - vpc_destination_variable
# This is the normal destination variable to use. If you are running Ansible
# from outside EC2, then 'public_dns_name' makes the most sense. If you are
# running Ansible from within EC2, then perhaps you want to use the internal
# address, and should set this to 'private_dns_name'. The key of an EC2 tag
# may optionally be used; however the boto instance variables hold precedence
# in the event of a collision.
destination_variable = public_dns_name
# This allows you to override the inventory_name with an ec2 variable, instead
# of using the destination_variable above. Addressing (aka ansible_ssh_host)
# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
#hostname_variable = tag_Name
# For server inside a VPC, using DNS names may not make sense. When an instance
# has 'subnet_id' set, this variable is used. If the subnet is public, setting
# this to 'ip_address' will return the public IP address. For instances in a
# private subnet, this should be set to 'private_ip_address', and Ansible must
# be run from within EC2. The key of an EC2 tag may optionally be used; however
# the boto instance variables hold precedence in the event of a collision.
# WARNING: - instances that are in the private vpc, _without_ public ip address
# will not be listed in the inventory until You set:
# vpc_destination_variable = private_ip_address
vpc_destination_variable = ip_address
# The following two settings allow flexible ansible host naming based on a
# python format string and a comma-separated list of ec2 tags. Note that:
#
# 1) If the tags referenced are not present for some instances, empty strings
# will be substituted in the format string.
# 2) This overrides both destination_variable and vpc_destination_variable.
#
#destination_format = {0}.{1}.example.com
#destination_format_tags = Name,environment
# To tag instances on EC2 with the resource records that point to them from
# Route53, set 'route53' to True.
route53 = False
# To use Route53 records as the inventory hostnames, uncomment and set
# to equal the domain name you wish to use. You must also have 'route53' (above)
# set to True.
# route53_hostnames = .example.com
# To exclude RDS instances from the inventory, uncomment and set to False.
rds = False
# To exclude ElastiCache instances from the inventory, uncomment and set to False.
elasticache = False
# Additionally, you can specify the list of zones to exclude looking up in
# 'route53_excluded_zones' as a comma-separated list.
# route53_excluded_zones = samplezone1.com, samplezone2.com
# By default, only EC2 instances in the 'running' state are returned. Set
# 'all_instances' to True to return all instances regardless of state.
all_instances = False
# By default, only EC2 instances in the 'running' state are returned. Specify
# EC2 instance states to return as a comma-separated list. This
# option is overridden when 'all_instances' is True.
# instance_states = pending, running, shutting-down, terminated, stopping, stopped
# By default, only RDS instances in the 'available' state are returned. Set
# 'all_rds_instances' to True return all RDS instances regardless of state.
all_rds_instances = False
# Include RDS cluster information (Aurora etc.)
include_rds_clusters = False
# By default, only ElastiCache clusters and nodes in the 'available' state
# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
# to True return all ElastiCache clusters and nodes, regardless of state.
#
# Note that all_elasticache_nodes only applies to listed clusters. That means
# if you set all_elastic_clusters to false, no node will be return from
# unavailable clusters, regardless of the state and to what you set for
# all_elasticache_nodes.
all_elasticache_replication_groups = False
all_elasticache_clusters = False
all_elasticache_nodes = False
# API calls to EC2 are slow. For this reason, we cache the results of an API
# call. Set this to the path you want cache files to be written to. Two files
# will be written to this directory:
# - ansible-ec2.cache
# - ansible-ec2.index
cache_path = ./ec2-tmp
# The number of seconds a cache file is considered valid. After this many
# seconds, a new API call will be made, and the cache file will be updated.
# To disable the cache, set this value to 0
cache_max_age = 300
# Organize groups into a nested/hierarchy instead of a flat namespace.
nested_groups = False
# Replace - tags when creating groups to avoid issues with ansible
replace_dash_in_groups = True
# If set to true, any tag of the form "a,b,c" is expanded into a list
# and the results are used to create additional tag_* inventory groups.
expand_csv_tags = False
# The EC2 inventory output can become very large. To manage its size,
# configure which groups should be created.
group_by_instance_id = True
group_by_region = True
group_by_availability_zone = True
group_by_aws_account = False
group_by_ami_id = True
group_by_instance_type = True
group_by_instance_state = False
group_by_key_pair = True
group_by_vpc_id = True
group_by_security_group = True
group_by_tag_keys = True
group_by_tag_none = True
group_by_route53_names = True
group_by_rds_engine = True
group_by_rds_parameter_group = True
group_by_elasticache_engine = True
group_by_elasticache_cluster = True
group_by_elasticache_parameter_group = True
group_by_elasticache_replication_group = True
# If you only want to include hosts that match a certain regular expression
# pattern_include = staging-*
# If you want to exclude any hosts that match a certain regular expression
# pattern_exclude = staging-*
# Instance filters can be used to control which instances are retrieved for
# inventory. For the full list of possible filters, please read the EC2 API
# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
# Filters are key/value pairs separated by '=', to list multiple filters use
# a list separated by commas. See examples below.
# If you want to apply multiple filters simultaneously, set stack_filters to
# True. Default behaviour is to combine the results of all filters. Stacking
# allows the use of multiple conditions to filter down, for example by
# environment and type of host.
stack_filters = False
# Retrieve only instances with (key=value) env=staging tag
#instance_filters =
# Retrieve only instances with role=webservers OR role=dbservers tag
# instance_filters = tag:role=webservers,tag:role=dbservers
# Retrieve only t1.micro instances OR instances with tag env=staging
# instance_filters = instance-type=t1.micro,tag:env=staging
# You can use wildcards in filter values also. Below will list instances which
# tag Name value matches webservers1*
# (ex. webservers15, webservers1a, webservers123 etc)
# instance_filters = tag:Name=webservers1*
# An IAM role can be assumed, so all requests are run as that role.
# This can be useful for connecting across different accounts, or to limit user
# access
# iam_role = role-arn
# A boto configuration profile may be used to separate out credentials
# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
# boto_profile = some-boto-profile-name
[credentials]
# The AWS credentials can optionally be specified here. Credentials specified
# here are ignored if the environment variable AWS_ACCESS_KEY_ID or
# AWS_PROFILE is set, or if the boto_profile property above is set.
#
# Supplying AWS credentials here is not recommended, as it introduces
# non-trivial security concerns. When going down this route, please make sure
# to set access permissions for this file correctly, e.g. handle it the same
# way as you would a private SSH key.
#
# Unlike the boto and AWS configure files, this section does not support
# profiles.
#
# aws_access_key_id = AXXXXXXXXXXXXXX
# aws_secret_access_key = XXXXXXXXXXXXXXXXXXX
# aws_security_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXX

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
[tag_role_master]
[tag_role_worker]
[masters:children]
tag_role_master
[nodes:children]
tag_role_worker

View file

@ -0,0 +1,27 @@
---
- hosts: masters
vars:
api_lb_ip: 172.20.200.10
api_lb_dns: api.customdomain.com
podSubnet: 192.168.0.0/16
kubeadmToken: 8fcc26.83ab1665d9142018
primary_interface: eth0
tasks:
- name: Render kubeadm.conf template for first stacked master
local_action:
module: template
src: 1-kubeadm.conf.j2
dest: kubeadm-cfg-first.yaml
- name: Render kubeadm.conf template for second stacked master
local_action:
module: template
src: 2-kubeadm.conf.j2
dest: kubeadm-cfg-second.yaml
- name: Render kubeadm.conf template for third stacked master
local_action:
module: template
src: 3-kubeadm.conf.j2
dest: kubeadm-cfg-third.yaml