Deploy ingress, lego and dashboard

This commit is contained in:
Paul-Henri Froidmont 2018-09-26 04:40:24 +02:00
parent bf83e675f2
commit f468fd3e34
43 changed files with 1321 additions and 142 deletions

View file

@ -1,86 +1,88 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
37663365346233373132393332613765346537636630326332376263613730303537306265386435 34396532356664616238616439303637376436383835356365663962623232653431333838353833
3936383964313331373764623362326663353465633631340a663134343934386461623665316538 6265333930636437313962616132623535373831363462340a323431346162633731626161386162
61326266613537333930613231643635656335313964336632393566383231306232383966353061 37303239623761663639393130366563353961646261363032393437316434343237313164343137
6232363866653333350a343336663830663138323337336239646630643465356631353334363663 6330613465663433360a613864396335303430343133313164343133313632653430643439353632
64386533353534393931626631363361356431656232636232643166353861346337653435623165 35363432383436356564393362333066303936616634303064376662663331643039386330333332
34666439333738303336613833653664663766643865633361663738656466346465333836396235 30333563346237366165306464393532333738333336656537353237343835613865616137356132
38386166666331393666643435333232356531636436333864626461613664646334356439363064 63366631623535343339666335336365393065616233633033343966396235326165383565616666
64643864343032346437653363373531356538376433383832646365313664613534613430393032 31646437656438376263363337393331646466333231346332613863633865353564356631343362
32303536623164313834323463396464343337316665316662656163623030383331353366343434 39353431326363646265666533643364653563376333626562376461623264343836306362616237
63323031303561643030656161316130353738366439363139623461313665666233636362323363 34636632633130623131313463343730613265613232663131373334376466326133303630313863
35303934623562323435383262653932386438313730376638353035613961323831386438653736 38643862653335633964393432656336366465393566623830313235373034373166386165636535
64643538323438393737343235613631663831643761306566653038373934343965623831343831 32373637333735363936666135303531633265323831613738373466313536356439643139326666
65663666636132326538613430666239303863336134316665346565316266326231353361396238 39613431323735376431616165663661626334353466353731373830343935666164633239653838
30343632396135346238313639376631393233656534316332323330633335303233323466323331 30366331623662393264336238376434323065386235343933353364356536636165623231623162
66383437376435613530373136383539646265313461633533613536623635646532396336393465 37393330663836653661643161633763626338626531643561303962383934336564373332393561
38663231366636396636353861633965356162656334333031613138323233663339633439376231 33653935313437626361313661643934333934313432366232656338393732646366643965623135
61323165646630303434623034366661666133336163663138666465613466643932336338333336 64343664323664323538373637306439613465343638366238333437326563323531396666353635
37343364373464366634303836373636306133633831313835316236653630356330376535653439 38333934653332653336353330663763353534646261383261653934323963663038393135643565
30363836646562613633626538633535643531333233643566356636373331633338646639373430 36343031343263323632353734646633343534613739316633393238316332623262633065623237
39386138323766366461393534336334383138356330643730383163373634396235366564383637 32323832663761353332643331363835303039363231383264373733653935306361393634373837
32353131626365393161346437323162323562343961643766613032333130323536316137393332 36343536333530626238383866653136343034346666313866366330633439663665306361383436
63396235623631313934633337343430353563333933363339333964636334346437613033646234 36323833623136373038343435656465323835383236653039636436613461363437323162333433
37636336316331346435353232386262336637346536623533353464333338613339336230353230 63643864363261666138303931613938663561653430666238643036643635373831333536646130
65666536613961333334626239306437653364343230636232636536393962363134623230373262 37393532356435316136316239366538653331643663646662313032646133343562383663616131
65326438313033396466353833316565653037316638336163363233393330323531353031663231 62653838666432376630313031353030633834396166393364393239316366626339633233613831
35393765316432656432393932366133326334643337313264333762373037363463356661373539 35616363633131336137616436346232633963343332303464333764343462626232396336373033
34623864336365303732383033383961333038663862303961663130643730396239333930366331 64623135306432343233306562376564376334366631353330623462303466326265363031626662
37393031396533346633623364663530653937393934303463303137363734383031376538633561 33663131623964393531343036616531306336656561313832343865383061376566623330373962
64666531333436626434613935663137646533656431323539323965646137626261653536383961 35643231333066666437653033623736356137343764366130383864323432386135383965333533
36396130393633396631653034356530306565303034643233346436356530656665376433653936 35656637393239653234646538663434343331323435373838393138613739653362346364616336
63353636616163313237633133666238663862336530306636616464356535333438383864316235 64663934396332313163656464656537343234653533386535343238376630636334306635613438
37663238306132323434326235386361613834323832636431363561613464313164393339363537 65356161326666613830636566393864373766326664373363323765353032366435346264383263
34313066366636613932373766353931393239303335343839343330396633656630316164326465 37346433346565636531316466303834636166636131396534316664303834386362633337666130
33643337303064656638643934386365366539653666363834323434353738663537303265623438 32636538306464363064383036326363316630316266393239363332353733363263663139666432
30663137653039383566353235323239653834643661303330336130303331316366316464353062 32626464383463386636363465643637613335326235376462353136356234613262333861373236
61623463326533633533306638303661353334613662373763646234623535303633346664646538 39383935643633373161373437653338313764323536316461333466396138363962333936353133
63643635356430326437613834623662316535666533346135623537376531316330353634323361 34613132363334373461353461336535333030343964363931363562333961333938633765363936
31653138623136626135316564376636623530623938633134323561633037653834656363613634 38636162316333336536643138316332636536383865313632306334653561356331376162336332
64633739363166343434383631653833336336363336386166386561613332623662386534656132 62356166373362313033663836373437313932393461383637393137363961373331626334396231
64383939393762363133313438656530366463386135323634623634316132613663323866353031 37643564613633336234653135633231623063653431653933623230323265626236386338643631
35346661313331383664333433386438303836376634303238366461616131376534636334633332 39326264313462373563353535376365623163396633333163633161323538666639333938303966
65306665303631663462353838353763343330316430653037326137376530393766383531666666 38656362643437363265333032303231376631633462373730303235663232626231376438616266
35643564626132383964653932383934346265323231376334353137396534663931336432336665 66383266656563643836323037393238666164363133653838333138663631336532346135613732
34393138393763353034626234653837613463383137613033393839643437613032656232326634 32633765346364386365666163366263333461313535343837323764623237666166636166613730
37623165353633316337396639636638636530656531366362613535626565393966336461613434 65636131636561356663383439616530633362303037393935323031353464376338366565643330
32346635386462386431343237366463313833313262626436396637313865373166323164643131 66656139363461336632626364633930313139306263353434346662646339313739303762343261
37613338336165646635383935333765373063623938626265323761363261643161366630303839 39633762363430383963346639656263303437343536336163636265636335653265333833373665
35393132613231373263313332333064313638303762373561356630373433323230373633333434 30333462333566653837613832323430663364393535616533353038356136326366626562373736
36376664336231653262636532353338303037323963643162393434303132613364353133313634 63646536666166313038326261303839393235303730613762313063373437393431373261393839
32303465396337373961356635323733303538663436616435306338653936663733616236623261 32366230333139313138376662653765393336646532353534343437383330313237363636326239
62313631326561343537353765636666373466613538613537636466333339623730323462363064 64383165653163366637316465396135666466353538636236313532363462623032373565653934
38326662323530626365393837613539336134643935316334373432646234313836323663303532 34366238363938303630613635633164393030666333396166383963646165333237616261613030
63356432333632646365653538663136666364653464656163323832373432303939656261356334 35633164343232663238633563353534343532346265646561306437616262616532333535333364
31393634303638313465363636623464333964363066353035376638356663376331353633366663 38623934316537633164376639613564633036373334303131386166353737656131623066656162
30333434333538323432356533643736616134303664373361626438616334333535363237313535 65656439666233376337653865663465303032616538363364363239336431653139313265376332
64376261643638313562363464343235346166343939366639613564353035613964633931626634 39333131626336396261663530323335613839333833393333333665366266323535656633343465
66313066623338323833356334336531356666626466623361653764663531663739343636376631 62636461373832393939323763626332323536353762376366616136396665633033346539353034
64633230626231383234343532613233393361373563303836613332326636386361303135626439 33303465613434313166643431653836386466383732663630663138323466393963646331393962
33636237653135316631626330633233656463626263343131366261383838363431643737386230 35366331353839353835363035383662366130313864353433383837663161336465376262636231
33343931343264313632346463666433323437646439656433313961353461333337343461643434 66663038383039646561303235313930366263366365323863386335343730323534316666333237
39356166616364663761356338383364363730633963326337353264343333636134633932613765 31653166333132353533343637656238383137346231623232303166373436373833643439303037
61336166373266326336653733316530386163396436633036313831333533336435313264393339 34326237373866353632346465636636346463373364373461393266666434353434353536663463
32363961313135633937613036643538303261393734666163623466613930366131306662313339 38343366646630333662393463373763636339383562313533343332623831306634313737663630
37383334346636353966623666376136666236666564333466613462393031656331373532633262 66346638346366353537643436326538356661343638356334343739346438396434333330313066
30323432343761313233623763333833663561363336613063366637306666373666646162323431 37656235323039356165663361336461306265303264363434656165363663613663643639383462
34376163626537333137316539323934336364383130353264383837396635663536343761373733 61306334626336636134313066656463656363633862643564326330643435386433306232323863
66396430633133343030313730633432343661386338313162323732323838373134393432333533 37633239633366336266366233343031656439343666656130653366336332663439356131653236
64333738646135656437323134303038353130396266353136383561353066313432376231306335 64383761366239323038386535323933383466633864613066313230386535333363343830633234
35613437373430636261313130663531346635323861316461396361313163396265323734623438 64373436363831663437353335316531306437633937666133643665653662326263373431616561
62313061643835336136323561303866653130613365633163353031663365363566383662633333 66613230663136343330386231623634363763396365653734383938386364303064323933376639
38356232316565653435653832333564643163326537393664316634363361653537333037643565 37376663393065363661353232313030666535643633366133303639343031353938393430353432
62626164386439383862613937663632616533323634303532646663623331643066373030383237 62376165323737336132396361353037613832316562646663646539336132336236613336666431
61363737313863663832363766313037653066316564356330663830336162323630373733383737 66363232366434663936386465313634313639636633346633636433663165366361613861323062
61623933633962326133616165336632303938643735356439363730343261653661643535383762 62313836663364326365616139663066376531393135343933386236323165653334376265343238
62616638623235613739653564313430656265376132386332666134633530336639313165613134 39323466643031396663356237626364653462396264316233323838363563356663316335323261
35363566666434383062333835366131373366613861356362306235373664386461353864653863 61303335646265376261353330376165666462353635666338353036633533393764323831383536
65663235623433316239366336636266343265326238313937346239623033326563396138306365 39363431373831643637333337656539636433646665376336336632653135326461316232613037
39313361643463636665633531346137636265333833656534363666386339396334323831633035 36626465303439346635316536376163343638353639303636366163363633633965353033663964
34363362373630323964323734343235303761663766336136316139353238363338656335373033 64363032656633303139316165323538386461376238313630653264643963366130626263303934
36306436626335353834643231386263373361383431393864393235643135633033643065613031 33636335646663643666656133366536343162333036663134663034393735313830626339303139
65386538306638323537366439346166646231666638616534613064333266666237323232303033 36343932323539393061643063613736353035633336613839616238386234653634356661663637
38303030313162316338363064396633623365303562373233663433356263653033613234386231 32363439316662626430353435373030346465346339653733366539633566336537323433323665
31376533666139313564666566316266613234623034386162653336666436643239666130663636 36366162363030623139383962343964336131373764636433323165353534323232383666353965
39386265313562366538393839393232653736303736613232656139643236313132636337653430 65383865643538663561353666333430366165666263323432613736336565316338393935393838
6366 36356639363061663862373833613334666564343634616237346332376436626630373933383365
36336564626334356432643132623466633364663631616638363136376464386465656438303231
663039343938383434326237303934336564

View file

@ -2,6 +2,10 @@
ansible_user: root ansible_user: root
ansible_port: 22 ansible_port: 22
dashboard_subdomain: dashboard
scaleway_ipaddr: 51.158.77.6
scaleway_reverse_ipaddr: k8s.banditlair.com
harden_linux_sshd_settings_user: harden_linux_sshd_settings_user:
"^Port ": "Port 22" "^Port ": "Port 22"
harden_linux_ufw_rules: harden_linux_ufw_rules:

View file

@ -1,2 +1,3 @@
--- ---
vpn_ip: 192.168.66.{{ 0 +(inventory_hostname|regex_replace('\D+','')|int) }} vpn_ip: 192.168.66.{{ 0 +(inventory_hostname|regex_replace('\D+','')|int) }}
keepalived_ip: "192.168.66.254"

62
k8s.yml
View file

@ -15,56 +15,12 @@
roles: roles:
- role: kubernetes - role: kubernetes
tags: kubernetes tags: kubernetes
- hosts: k8s_masters:k8s_proxy
gather_facts: false
#- hosts: localhost roles:
# become: yes - role: ingress
# gather_facts: no tags: ingress
# roles: - role: lego
# - role: harden-linux tags: lego
# tags: role-harden-linux - role: kubernetes-dashboard
# - role: githubixx.peervpn tags: dashboard
# tags: role-peervpn
#- hosts: k8s
# vars:
# ansible_user: ubuntu
# gather_facts: no
# roles:
# - role: harden-linux
# tags: role-harden-linux
#- hosts: all
# become: yes
# roles:
# - role: peervpn
# tags: role-peervpn
#- hosts: k8s_ca
# become: yes
# gather_facts: no
# roles:
# - role: cfssl
# tags: role-cfssl
# - role: kubernetes-ca
# tags: role-kubernetes-ca
#- hosts: k8s_etcd
# become: yes
# gather_facts: no
# roles:
# - role: etcd
# tags: role-etcd
#- hosts: k8s_master
# gather_facts: no
# roles:
# - role: kubernetes-controller
# tags: role-kubernetes-controller
#- hosts: k8s_worker
# gather_facts: no
# roles:
# - role: githubixx.kubernetes-worker
# tags: role-kubernetes-worker
#- hosts: k8s
# gather_facts: no
# roles:
# - role: githubixx.flanneld
# tags: role-kubernetes-flanneld
# - role: githubixx.docker
# tags: role-docker

300
library/kube.py Normal file
View file

@ -0,0 +1,300 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
DOCUMENTATION = """
---
module: kube
short_description: Manage Kubernetes Cluster
description:
- Create, replace, remove, and stop resources within a Kubernetes Cluster
version_added: "2.0"
options:
name:
required: false
default: null
description:
- The name associated with resource
filename:
required: false
default: null
description:
- The path and filename of the resource(s) definition file.
kubectl:
required: false
default: null
description:
- The path to the kubectl bin
namespace:
required: false
default: null
description:
- The namespace associated with the resource(s)
resource:
required: false
default: null
description:
- The resource to perform an action on. pods (po), replicationControllers (rc), services (svc)
label:
required: false
default: null
description:
- The labels used to filter specific resources.
server:
required: false
default: null
description:
- The url for the API server that commands are executed against.
force:
required: false
default: false
description:
- A flag to indicate to force delete, replace, or stop.
all:
required: false
default: false
description:
- A flag to indicate delete all, stop all, or all namespaces when checking exists.
log_level:
required: false
default: 0
description:
- Indicates the level of verbosity of logging by kubectl.
state:
required: false
choices: ['present', 'absent', 'latest', 'reloaded', 'stopped']
default: present
description:
- present handles checking existence or creating if definition file provided,
absent handles deleting resource(s) based on other options,
latest handles creating or updating based on existence,
reloaded handles updating resource(s) definition using definition file,
stopped handles stopping resource(s) based on other options.
requirements:
- kubectl
author: "Kenny Jones (@kenjones-cisco)"
"""
EXAMPLES = """
- name: test nginx is present
kube: name=nginx resource=rc state=present
- name: test nginx is stopped
kube: name=nginx resource=rc state=stopped
- name: test nginx is absent
kube: name=nginx resource=rc state=absent
- name: test nginx is present
kube: filename=/tmp/nginx.yml
"""
class KubeManager(object):
def __init__(self, module):
self.module = module
self.kubectl = module.params.get('kubectl')
if self.kubectl is None:
self.kubectl = module.get_bin_path('kubectl', True)
self.base_cmd = [self.kubectl]
if module.params.get('server'):
self.base_cmd.append('--server=' + module.params.get('server'))
if module.params.get('log_level'):
self.base_cmd.append('--v=' + str(module.params.get('log_level')))
if module.params.get('namespace'):
self.base_cmd.append('--namespace=' + module.params.get('namespace'))
self.all = module.params.get('all')
self.force = module.params.get('force')
self.name = module.params.get('name')
self.filename = module.params.get('filename')
self.resource = module.params.get('resource')
self.label = module.params.get('label')
def _execute(self, cmd):
args = self.base_cmd + cmd
try:
rc, out, err = self.module.run_command(args)
if rc != 0:
self.module.fail_json(
msg='error running kubectl (%s) command (rc=%d): %s' % (' '.join(args), rc, out or err))
except Exception as exc:
self.module.fail_json(
msg='error running kubectl (%s) command: %s' % (' '.join(args), str(exc)))
return out.splitlines()
def _execute_nofail(self, cmd):
args = self.base_cmd + cmd
rc, out, err = self.module.run_command(args)
if rc != 0:
return None
return out.splitlines()
def create(self, check=True, force=True):
if check and self.exists():
return []
cmd = ['apply']
if force:
cmd.append('--force')
if not self.filename:
self.module.fail_json(msg='filename required to create')
cmd.append('--filename=' + self.filename)
return self._execute(cmd)
def replace(self, force=True):
cmd = ['apply']
if force:
cmd.append('--force')
if not self.filename:
self.module.fail_json(msg='filename required to reload')
cmd.append('--filename=' + self.filename)
return self._execute(cmd)
def delete(self):
if not self.force and not self.exists():
return []
cmd = ['delete']
if self.filename:
cmd.append('--filename=' + self.filename)
else:
if not self.resource:
self.module.fail_json(msg='resource required to delete without filename')
cmd.append(self.resource)
if self.name:
cmd.append(self.name)
if self.label:
cmd.append('--selector=' + self.label)
if self.all:
cmd.append('--all')
if self.force:
cmd.append('--ignore-not-found')
return self._execute(cmd)
def exists(self):
cmd = ['get']
if not self.resource:
return False
cmd.append(self.resource)
if self.name:
cmd.append(self.name)
cmd.append('--no-headers')
if self.label:
cmd.append('--selector=' + self.label)
if self.all:
cmd.append('--all-namespaces')
result = self._execute_nofail(cmd)
if not result:
return False
return True
def stop(self):
if not self.force and not self.exists():
return []
cmd = ['stop']
if self.filename:
cmd.append('--filename=' + self.filename)
else:
if not self.resource:
self.module.fail_json(msg='resource required to stop without filename')
cmd.append(self.resource)
if self.name:
cmd.append(self.name)
if self.label:
cmd.append('--selector=' + self.label)
if self.all:
cmd.append('--all')
if self.force:
cmd.append('--ignore-not-found')
return self._execute(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(),
filename=dict(),
namespace=dict(),
resource=dict(),
label=dict(),
server=dict(),
kubectl=dict(),
force=dict(default=False, type='bool'),
all=dict(default=False, type='bool'),
log_level=dict(default=0, type='int'),
state=dict(default='present', choices=['present', 'absent', 'latest', 'reloaded', 'stopped']),
)
)
changed = False
manager = KubeManager(module)
state = module.params.get('state')
if state == 'present':
result = manager.create(check=False)
elif state == 'absent':
result = manager.delete()
elif state == 'reloaded':
result = manager.replace()
elif state == 'stopped':
result = manager.stop()
elif state == 'latest':
result = manager.replace()
else:
module.fail_json(msg='Unrecognized state %s.' % state)
if result:
changed = True
module.exit_json(changed=changed,
msg='success: %s' % (' '.join(result))
)
from ansible.module_utils.basic import * # noqa
if __name__ == '__main__':
main()

View file

@ -0,0 +1,10 @@
replicas_default_backend: 1
image_default_backend: gcr.io/google_containers/defaultbackend
version_default_backend: 1.4
nginx_ingress_controller_image: gcr.io/google_containers/nginx-ingress-controller
nginx_ingress_controller_version: 0.9.0-beta.15
scaleway_servername1: proxy1
scaleway_servername2: proxy2
scaleway_ipaddr: "" # set this in the inventory file
scaleway_reverse_ipaddr: "" # set this in the inventory file

View file

@ -0,0 +1,97 @@
---
- name: nginx_ingress_controller | Getting node labels
command: "kubectl get nodes -l role=ingress-controller"
register: nodes
when: inventory_hostname == initial_master
- name: nginx_ingress_controller | Printing nodes
debug: var=nodes
when: inventory_hostname == initial_master
- name: nginx_ingress_controller | Labelling proxy nodes with role=ingress_controller
command: "kubectl label node {{ hostvars[item].ansible_hostname }} role=ingress-controller"
with_items:
- "{{ groups['k8s_proxy'] }}"
when:
- inventory_hostname == initial_master
- hostvars[item].ansible_hostname not in nodes.stdout
- name: nginx_ingress_controller | Templating manifests
template:
src: "{{ item }}"
dest: "/tmp/{{ item | regex_replace('.j2', '') }}"
with_items:
- default-backend-controller.yml.j2
- default-backend-service.yml.j2
- nginx-ingress-clusterolebinding.yml.j2
- nginx-ingress-configmap.yml.j2
- nginx-ingress-sa.yml.j2
- nginx-ingress-clusterole.yml.j2
- nginx-ingress-controller.yml.j2
- nginx-ingress-service.yml.j2
when: inventory_hostname == initial_master
- name: nginx_ingress_controller | Deploy the nginx_ingress_controller
kube:
name: "{{ item.name }}"
resource: "{{ item.type }}"
filename: "{{ item.file }}"
state: latest
with_items:
- { 'name': 'default-http-backend', 'type': 'deploy', 'file': '/tmp/default-backend-controller.yml' }
- { 'name': 'default-http-backend', 'type': 'svc', 'file': '/tmp/default-backend-service.yml' }
- { 'name': 'ingress', 'type': 'clusterrolebinding', 'file': '/tmp/nginx-ingress-clusterolebinding.yml' }
- { 'name': 'system:ingress', 'type': 'clusterrole', 'file': '/tmp/nginx-ingress-clusterole.yml' }
- { 'name': 'ingress', 'type': 'sa', 'file': '/tmp/nginx-ingress-sa.yml' }
- { 'name': 'nginx-ingress-cfg', 'type': 'configmap', 'file': '/tmp/nginx-ingress-configmap.yml' }
- { 'name': 'nginx-ingress-controller', 'type': 'deploy', 'file': '/tmp/nginx-ingress-controller.yml' }
- { 'name': 'nginx-ingress', 'type': 'svc', 'file': '/tmp/nginx-ingress-service.yml' }
when: inventory_hostname == initial_master
- name: nginx_ingress_controller | Removing manifest
file:
path: "/tmp/{{ item }}"
state: absent
with_items:
- default-backend-controller.yml
- default-backend-service.yml
- nginx-ingress-clusterolebinding.yml
- nginx-ingress-configmap.yml
- nginx-ingress-sa.yml
- nginx-ingress-clusterole.yml
- nginx-ingress-controller.yml
- nginx-ingress-service.yml
when: inventory_hostname == initial_master
- name: nginx_ingress_controller | Creating directory for scaleway-ipmove
file:
path: /usr/local/bin/scaleway-ipmove
state: directory
when: "'k8s_proxy' in group_names"
- name: nginx_ingress_controller | Getting scaleway-ipmove.py
git:
repo: https://github.com/chmod666org/scaleway-ipmove
dest: /usr/local/bin/scaleway-ipmove
force: yes
when: "'k8s_proxy' in group_names"
- name: nginx_ingress_controller | notify.sh
template:
src: notify.sh.j2
dest: /usr/local/bin/scaleway-ipmove/notify.sh
mode: 0500
owner: root
group: root
when: "'k8s_proxy' in group_names"
# this runs keepalived on proxy nodes
- name: nginx_ingress_controller | Templating keepalived on proxy node
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
with_items:
- { 'src': 'keepalived.yml.j2', 'dest': '/etc/kubernetes/manifests/keepalived.yml' }
when:
- "'k8s_proxy' in group_names"
- groups.k8s_proxy|length > 1

View file

@ -0,0 +1,39 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend
labels:
k8s-app: default-http-backend
namespace: kube-system
spec:
replicas: {{ replicas_default_backend }}
template:
metadata:
labels:
k8s-app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissable as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: {{ image_default_backend }}:{{ version_default_backend }}
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
nodeSelector:
role: ingress-controller

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: kube-system
labels:
k8s-app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
k8s-app: default-http-backend

View file

@ -0,0 +1,37 @@
apiVersion: v1
kind: Pod
metadata:
name: keepalived
namespace: kube-system
spec:
hostNetwork: true
volumes:
- hostPath:
path: /usr/local/bin/scaleway-ipmove/
name: scaleway-moveip
containers:
- name: keepalived
image: chmod666/keepalived:latest
# if tag is latest imagePullPolicy is always
# but when keepalived is backup a proxy may have no connection to the internet
# to avoid keepalived not starting in that case, we're putting imagePullPolicy: IfNotPresent
# assuming the image was already be pulled at cluster creation. Neat.
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/mnt"
name: scaleway-moveip
securityContext:
capabilities:
add:
- NET_ADMIN
env:
- name: KEEPALIVED_INTERFACE
value: tun0
- name: KEEPALIVED_UNICAST_PEERS
value: "#PYTHON2BASH:['{{ groups['k8s_proxy'] | map('extract', hostvars, ['vpn_ip']) | join("', '") }}']"
- name: KEEPALIVED_VIRTUAL_IPS
value: "#PYTHON2BASH:['{{ keepalived_ip }}']"
- name: KEEPALIVED_PRIORITY
value: "{{ groups['k8s_proxy'].index(inventory_hostname) + 1 }}"
- name: KEEPALIVED_NOTIFY
value: "/mnt/notify.sh"

View file

@ -0,0 +1,14 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: system:ingress
rules:
- apiGroups:
- ""
resources: ["configmaps","secrets","endpoints","events","services"]
verbs: ["list","watch","create","update","delete","get"]
- apiGroups:
- ""
- "extensions"
resources: ["services","nodes","ingresses","pods","ingresses/status"]
verbs: ["list","watch","create","update","delete","get"]

View file

@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: ingress
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:ingress
subjects:
- kind: ServiceAccount
name: ingress
namespace: kube-system

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-ingress-cfg
namespace: kube-system
labels:
app: nginx-ingress-cfg
data:
enable-sticky-sessions: 'true' ## use ROUTE cookie to provide session affinity
enable-vts-status: 'true' ## Allows the replacement of the default status page nginx-module-vts

View file

@ -0,0 +1,66 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
labels:
k8s-app: nginx-ingress-controller
namespace: kube-system
spec:
# on replica per proxy
replicas: {{ groups['k8s_proxy'] | length }}
template:
metadata:
labels:
k8s-app: nginx-ingress-controller
annotations:
prometheus.io/port: '10254'
prometheus.io/scrape: 'true'
spec:
# hostNetwork makes it possible to use ipv6 and to preserve the source IP correctly regardless of docker configuration
# however, it is not a hard dependency of the nginx-ingress-controller itself and it may cause issues if port 10254 already is taken on the host
# that said, since hostPort is broken on CNI (https://github.com/kubernetes/kubernetes/issues/31307) we have to use hostNetwork where CNI is used
# like with kubeadm
# hostNetwork: true
serviceAccountName: ingress
terminationGracePeriodSeconds: 60
#https://github.com/kubernetes/contrib/issues/2135
# CNI and hostPort does not work using hostNetwork
hostNetwork: true
containers:
- image: {{ nginx_ingress_controller_image }}:{{ nginx_ingress_controller_version }}
name: nginx-ingress-controller
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 1
ports:
- containerPort: 80
#hostPort: 80
- containerPort: 443
#hostPort: 443
- containerPort: 18080
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-ingress-cfg
nodeSelector:
# node must be labelled with roles=ingress-controller
role: ingress-controller

View file

@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: ingress
namespace: kube-system

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress
namespace: kube-system
spec:
ports:
- port: 80
name: http
- port: 443
name: https
- port: 18080
name: http-mgmt
selector:
k8s-app: nginx-ingress-controller

View file

@ -0,0 +1,35 @@
#!/bin/bash
# for ANY state transition.
# "notify" script is called AFTER the
# notify_* script(s) and is executed
# with 3 arguments provided by keepalived
# (ie don't include parameters in the notify line).
# arguments
# $1 = "GROUP"|"INSTANCE"
# $2 = name of group or instance
# $3 = target state of transition
# ("MASTER"|"BACKUP"|"FAULT")
TYPE=$1
NAME=$2
STATE=$3
case $STATE in
"MASTER") echo "I'm the MASTER! Whup whup." > /proc/1/fd/1
echo "Here is the master"
# this put the public ip on the master using the scaleway api
/mnt/scaleway-ipmove.py {{ scaleway_token }} {{ scaleway_servername1 }} {{ scaleway_servername2 }} {{ scaleway_ipaddr }} {{ scaleway_reverse_ipaddr }} {{ scaleway_orga }}
exit 0
;;
"BACKUP") echo "Ok, i'm just a backup, great." > /proc/1/fd/1
echo "Here is the backup"
exit 0
;;
"FAULT") echo "Fault, what ?" > /proc/1/fd/1
exit 0
;;
*) echo "Unknown state" > /proc/1/fd/1
exit 1
;;
esac

View file

@ -0,0 +1,15 @@
---
# set basic_auth_user as non-empty to enforce basic auth
basic_auth_user: ""
basic_auth_password: ""
# e.g. the fqdn would be k8s.yourdomain.tld if
# dashboard_subdomain=k8s
# scaleway_reverse_ipaddr=yourdomain.tld
dashboard_subdomain: k8s
dashboard_image: gcr.io/google_containers/kubernetes-dashboard-amd64
dashboard_version: v1.10.0
init_dashboard_image: gcr.io/google_containers/kubernetes-dashboard-init-amd64
init_dashboard_version: v1.0.1

View file

@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard-crb
roleRef:
apiGroup: ""
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system

View file

@ -0,0 +1,20 @@
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
# Allow Dashboard to create and watch for changes of 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "watch"]
- apiGroups: [""]
resources: ["secrets"]
# Allow Dashboard to get, update and delete 'kubernetes-dashboard-key-holder' secret.
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]

View file

@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system

View file

@ -0,0 +1,7 @@
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kube-system
type: Opaque

View file

@ -0,0 +1,13 @@
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
ports:
- port: 80
targetPort: 9090
selector:
k8s-app: kubernetes-dashboard

View file

@ -0,0 +1,16 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: heapster
labels:
k8s-addon: monitoring-standalone.addons.k8s.io
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:heapster
subjects:
- kind: ServiceAccount
name: heapster
namespace: kube-system

View file

@ -0,0 +1,77 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: heapster
namespace: kube-system
labels:
k8s-addon: monitoring-standalone.addons.k8s.io
k8s-app: heapster
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
version: v1.7.0
spec:
replicas: 1
selector:
matchLabels:
k8s-app: heapster
version: v1.7.0
template:
metadata:
labels:
k8s-app: heapster
version: v1.7.0
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
spec:
serviceAccountName: heapster
containers:
- image: gcr.io/google_containers/heapster:v1.4.0
name: heapster
livenessProbe:
httpGet:
path: /healthz
port: 8082
scheme: HTTP
initialDelaySeconds: 180
timeoutSeconds: 5
resources:
# keep request = limit to keep this container in guaranteed class
limits:
cpu: 100m
memory: 300Mi
requests:
cpu: 100m
memory: 300Mi
command:
- /heapster
- --source=kubernetes.summary_api:''
- image: gcr.io/google_containers/addon-resizer:2.0
name: heapster-nanny
resources:
limits:
cpu: 50m
memory: 100Mi
requests:
cpu: 50m
memory: 100Mi
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
command:
- /pod_nanny
- --cpu=80m
- --extra-cpu=0.5m
- --memory=140Mi
- --extra-memory=4Mi
- --deployment=heapster
- --container=heapster
- --poll-period=300000
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"

View file

@ -0,0 +1,24 @@
# Heapster's pod_nanny monitors the heapster deployment & its pod(s), and scales
# the resources of the deployment if necessary.
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: system:pod-nanny
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- "extensions"
resources:
- deployments
verbs:
- get
- update

View file

@ -0,0 +1,16 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: heapster-binding
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: system:pod-nanny
subjects:
- kind: ServiceAccount
name: heapster
namespace: kube-system

View file

@ -0,0 +1,7 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: heapster
namespace: kube-system
labels:
k8s-addon: monitoring-standalone.addons.k8s.io

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: heapster
namespace: kube-system
labels:
k8s-addon: monitoring-standalone.addons.k8s.io
kubernetes.io/name: "Heapster"
kubernetes.io/cluster-service: "true"
spec:
ports:
- port: 80
targetPort: 8082
selector:
k8s-app: heapster

View file

@ -0,0 +1,105 @@
---
- block:
- name: Installing python-passlib
apt:
name: python-passlib
state: latest
register: result
retries: 3
until: result is success
- name: Creating htpasswd file if k8s has basic auth
htpasswd:
path: /tmp/auth
name: "{{ basic_auth_user }}"
password: "{{ basic_auth_password }}"
when: inventory_hostname == initial_master
- name: Getting secrets
command: kubectl get secrets --namespace=kube-system
register: secrets
when: inventory_hostname == initial_master
- name: Creating secret
command: kubectl create secret generic dashboard-basic-auth --namespace=kube-system --from-file=/tmp/auth
when:
- inventory_hostname == initial_master
- '"dashboard-basic-auth" not in secrets.stdout'
- name: Deleting basic_auth file
file:
path: /tmp/auth
state: absent
when: inventory_hostname == initial_master
when: basic_auth_user | length > 0
- name: Templating manifests
template:
src: "{{ item }}"
dest: "/tmp/{{ item | regex_replace('.j2', '') }}"
with_items:
- dashboard-ingress.yml.j2
- dashboard-deployment.yml.j2
when: inventory_hostname == initial_master
- name: Copying manifests files
copy:
src: "{{ item }}"
dest: "/tmp/{{ item }}"
with_items:
- dashboard-rolebinding.yml
- dashboard-role.yml
- dashboard-sa.yml
- dashboard-clusterrolebinding.yml
- dashboard-secret.yml
- dashboard-service.yml
- heapster-rolebinding.yml
- heapster-clusterrolebinding.yml
- heapster-role.yml
- heapster-sa.yml
- heapster-service.yml
- heapster-deployment.yml
when: inventory_hostname == initial_master
- name: Deploying kubernetes-dashboard
kube:
name: "{{ item.name }}"
resource: "{{ item.type }}"
filename: "{{ item.file }}"
state: latest
with_items:
- { 'name': 'kubernetes-dashboard', 'type': 'sa', 'file': '/tmp/dashboard-sa.yml' }
- { 'name': 'kubernetes-dashboard', 'type': 'clusterrolebinding', 'file': '/tmp/dashboard-clusterrolebinding.yml' }
- { 'name': 'kubernetes-dashboard', 'type': 'secret', 'file': '/tmp/dashboard-secret.yml' }
- { 'name': 'kubernetes-dashboard', 'type': 'service', 'file': '/tmp/dashboard-service.yml' }
- { 'name': 'kubernetes-dashboard', 'type': 'deployment', 'file': '/tmp/dashboard-deployment.yml' }
- { 'name': 'kubernetes-dashboard', 'type': 'ingress', 'file': '/tmp/dashboard-ingress.yml' }
- { 'name': 'heapster', 'type': 'sa', 'file': '/tmp/heapster-sa.yml' }
- { 'name': 'heapster', 'type': 'clusterrolebinding', 'file': '/tmp/heapster-clusterrolebinding.yml' }
- { 'name': 'heapster', 'type': 'rolebinding', 'file': '/tmp/heapster-rolebinding.yml' }
- { 'name': 'heapster', 'type': 'role', 'file': '/tmp/heapster-role.yml' }
- { 'name': 'heapster', 'type': 'service', 'file': '/tmp/heapster-service.yml' }
- { 'name': 'heapster', 'type': 'deployment', 'file': '/tmp/heapster-deployment.yml' }
when: inventory_hostname == initial_master
- name: Removing manifest
file:
path: "/tmp/{{ item }}"
state: absent
with_items:
- dashboard-ingress.yml.j2
- dashboard-deployment.yml.j2
- dashboard-clusterrolebinding.yml
- dashboard-rolebinding.yml
- dashboard-role.yml
- dashboard-sa.yml
- dashboard-secret.yml
- dashboard-service.yml
- heapster-rolebinding.yml
- heapster-clusterrolebinding.yml
- heapster-role.yml
- heapster-sa.yml
- heapster-service.yml
- heapster-deployment.yml
when: inventory_hostname == initial_master

View file

@ -0,0 +1,47 @@
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: {{ dashboard_image }}:{{ dashboard_version }}
ports:
- containerPort: 9090
protocol: TCP
args:
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
path: /
port: 9090
initialDelaySeconds: 30
timeoutSeconds: 30
volumes:
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule

View file

@ -0,0 +1,30 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: kube-system
name: kubernetes-dashboard
annotations:
# enable kube-lego for this ingress
kubernetes.io/tls-acme: "true"
{% if basic_auth_user | length > 0 %}
ingress.kubernetes.io/auth-type: basic
# name of the secret that contains the user/password definitions
ingress.kubernetes.io/auth-secret: dashboard-basic-auth
# message to display with an appropiate context why the authentication is required
ingress.kubernetes.io/auth-realm: "Authentication is required to access the k8s dashboard "
{% endif %}
spec:
# this enables tls for the specified domain names
tls:
- hosts:
- {{ dashboard_subdomain }}.{{ scaleway_reverse_ipaddr }}
secretName: dashboard-tls
rules:
- host: {{ dashboard_subdomain }}.{{ scaleway_reverse_ipaddr }}
http:
paths:
- path: /
backend:
serviceName: kubernetes-dashboard
servicePort: 80

View file

@ -24,7 +24,7 @@
shell: "ping {{ api_floating_ip }} -c 1" shell: "ping {{ api_floating_ip }} -c 1"
register: result register: result
changed_when: no changed_when: no
failed_when: ('100.0% packet loss' in result.stdout) failed_when: ('100% packet loss' in result.stdout)
- include: packages.yml - include: packages.yml

View file

@ -0,0 +1,4 @@
---
lego_email: deckard@chmod666.org
lego_image: jetstack/kube-lego
lego_version: 0.1.5

40
roles/lego/tasks/main.yml Normal file
View file

@ -0,0 +1,40 @@
---
- name: kube_lego | Templating manifests
template:
src: "{{ item }}"
dest: "/tmp/{{ item | regex_replace('.j2', '') }}"
with_items:
- lego-sa.yml.j2
- lego-clusterolebinding.yml.j2
- lego-clusterole.yml.j2
- lego-configmap.yml.j2
- lego-controller.yml.j2
when: inventory_hostname == initial_master
- name: kube_lego | Deploying kube-lego
kube:
name: "{{ item.name }}"
resource: "{{ item.type }}"
filename: "{{ item.file }}"
state: latest
with_items:
- { 'name': 'kube-lego', 'type': 'sa', 'file': '/tmp/lego-sa.yml' }
- { 'name': 'kube-lego', 'type': 'clusterrolebingind', 'file': '/tmp/lego-clusterolebinding.yml' }
- { 'name': 'kube-lego', 'type': 'clusterrole', 'file': '/tmp/lego-clusterole.yml' }
- { 'name': 'kube-lego', 'type': 'configmap', 'file': '/tmp/lego-configmap.yml' }
- { 'name': 'kube-lego', 'type': 'deploy', 'file': '/tmp/lego-controller.yml' }
when: inventory_hostname == initial_master
- name: kube_lego | Removing manifest
file:
path: "/tmp/{{ item }}"
state: absent
with_items:
- lego-namespace.yml
- lego-sa.yml
- lego-clusterolebinding.yml
- lego-clusterole.yml
- lego-configmap.yml
- lego-controller.yml
when: inventory_hostname == initial_master

View file

@ -0,0 +1,14 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: system:kube-lego
rules:
- apiGroups:
- ""
resources: ["configmaps","secrets","endpoints","events","services"]
verbs: ["list","watch","create","update","delete","get"]
- apiGroups:
- ""
- "extensions"
resources: ["services","nodes","ingresses","pods","ingresses/status"]
verbs: ["list","watch","create","update","delete","get"]

View file

@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kube-lego
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-lego
subjects:
- kind: ServiceAccount
name: kube-lego
namespace: kube-system

View file

@ -0,0 +1,10 @@
apiVersion: v1
metadata:
name: kube-lego
namespace: kube-system
data:
# modify this to specify your address
lego.email: "{{ lego_email }}"
# configure letsencrypt's production api
lego.url: "https://acme-v01.api.letsencrypt.org/directory"
kind: ConfigMap

View file

@ -0,0 +1,48 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kube-lego
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
app: kube-lego
spec:
serviceAccountName: kube-lego
containers:
- name: kube-lego
image: "{{ lego_image }}:{{ lego_version }}"
imagePullPolicy: Always
ports:
- containerPort: 8080
env:
- name: LEGO_EMAIL
valueFrom:
configMapKeyRef:
name: kube-lego
key: lego.email
- name: LEGO_URL
valueFrom:
configMapKeyRef:
name: kube-lego
key: lego.url
- name: LEGO_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LEGO_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 1
nodeSelector:
# node must be labelled with roles=ingress-controller
role: ingress-controller

View file

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: kube-lego

View file

@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-lego
namespace: kube-system

View file

@ -78,7 +78,8 @@ class SCWInventory(object):
for host, variables in self.response['_meta']['hostvars'].items(): for host, variables in self.response['_meta']['hostvars'].items():
if host != 'proxy1': if host != 'proxy1':
variables['ansible_ssh_common_args'] = '-o ProxyCommand="ssh -W %h:%p -q root@' + \ variables['ansible_ssh_common_args'] = '-o ProxyCommand="ssh -W %h:%p -q root@' + \
self.response['_meta']['hostvars']['proxy1']['public_ip'] + '"' self.response['_meta']['hostvars']['proxy1'][
'public_ip'] + ' -o StrictHostKeyChecking=no"'
def _add_to_response(self, group, hostname): def _add_to_response(self, group, hostname):
""" """