L’apologia dei progetti personali incompleti

Recentemente sono rientrato in un periodo di trasferte perpetue e ciò significa che ogni settimana passo almeno sette ore in treno cercando di dormire o di lavorare in totale tranquillità. A volte penso che ci vorrebbe un post su come sopravvivere in trasferta e che raccolga un po’ di dritte utili. Ad esempio, se ordinate del cibo in camera, chiedete sempre le posate.

Nella galassia di progetti personali interrotti per via della mia scarsezza nella progettazione di interfacce utente ho spesso ipotizzato di costruire cose che offrissero servizi alla community.

Riporto qualche esempio di progetti tristemente deceduti, ma non per questo meritevoli di una damnatio memoriae, e alcuni in via di sviluppo (tipo il bot Telegram per Openshift).

Olinuxc

Link al repo Github

Era figo ma dispendioso e poco comprensibile. Praticamente un cloud-linux-shell-provider libero solo per amanti e/o bisognosi di una shell effimera istantanea. Si inviava la propria chiave pubblica a OlinuxC per poter richiedere un container tramite ssh debian@olinuxc.org .

C’era la possibilità di scegliere tra “un botto” di distro Linux.

Screenshot 2018-11-22 at 21.24.29

Screenshot 2018-11-22 at 21.24.36

Il nome utente indicava la distribuzione Linux desiderata.

Screenshot 2018-11-22 at 21.11.32

Ziopinguino.it

Un clone di nip.io fatto con PowerDNS. Praticamente un wildcard dns per mappare qualsiasi ip.

Tipo, foobar.33.33.33.33.ziopinguino.it veniva risolto su internet con 33.33.33.33. Quindi per esperimenti vari, senza comprare alcun dominio si poteva usare ziopinguino.it

Congruit – Il configuration management tool che ama Bash

Piccola utility scritta in Go per configurare server in modo dichiarativo.

Link al repo GitHub

Funziona tipo così:

[
  {
   "places": ["debian","screen_is_not_installed"],
   "works": ["screen_package_apt"]
  },
  {
   "places": ["centos7","screen_is_not_installed"],
   "works": ["screen_package_yum"]
  }
]

Tutti gli oggetti all’interno della configurazione scritta in json richiamano alla fine degli utilissimi “bashoni” o per meglio dire script bash.

Se i place sono veri (quindi ritornano un exit code pari a 0) vengono eseguiti i works.

congruit

Openshift-Bot

Visto che ultimamente lavoro parecchio con Openshift ho deciso di scrivere un bot per Telegram e la cosa mi ha entusiasmato molto! Presto pubblicherò il codice su Github.

Cosa fa il bot nello specifico

Allo /starts ciò che il bot ci dice è questo:

Screenshot 2018-11-10 at 17.42.22

Il connubio tra “devo studiarmi come funzionano le API di Openshift” e il fatto che mi è sempre piaciuto offrire servizi alla community mi ha portato a implementare queste tre funzionalità di molto basilari.

Dockerize yourself!

La prima, “Build and expose a pod – picture version”, prende una foto scattata e la manda al bot che produce una build di tipo “strategy Docker”.

Praticamente inserisce la foto in un’immagine Docker molto semplice che espone un web-server Python minimale.

FROM ubuntu
USER root
RUN apt-get update
RUN apt-get -y install python
RUN apt-get clean

EXPOSE 8080
WORKDIR /

COPY index.html index.html
COPY server.py server.py
COPY from_telegram.jpg from_telegram.jpg
CMD [ "python","server.py" ]

Una volta terminata la build e ottenuto un pod running viene creata una route su Openshift e tramite nip.io l’url può essere risolta, e quindi raggiunta, ovunque.

Screenshot 2018-11-10 at 17.54.54

Si, come indicato sopra, il bot cancella tutto in 30 secondi. Non dispongo di molte risorse computazionali per cui devo liberare spazio per evitare che il mio server prenda fuoco.

Send index.html

Questa è stata un feature molto semplice che fa più o meno le stesse cose della prima, ma al posto di iniettare una foto in un’immagine Docker traporta un index.html inviato come file da Telegram.

  • creo un file index.html
sh-3.2# cat > index.html < foo > EOF
sh-3.2#
  • lo invio al bot

Screenshot 2018-11-10 at 18.02.44

  • curl verso il sito esposto
sh-3.2# curl http://sample-app-i50b6v.94.23.211.122.nip.io

foo

La comodità è con poche righe di codice posso inviare file di log agli utenti. Tipo questo, che serve per far vedere come è andata la build.

Screenshot 2018-11-10 at 18.07.35

Screenshot 2018-11-10 at 18.05.54

Oppure, per chi è curioso di sapere da cosa è composta un’applicazione su Openshift/Kubernetes invio un json contenente tutti gli oggetti creati.

Screenshot 2018-11-10 at 18.09.46

Link ad un progetto Docker su GitHub

L’ultima feature è ancora in beta per cui non la sponsorizzo più di tanto. Di base prende in input un link ad un progetto Docker su Github e lo compila. È ovvio che manca ancora molto su questo fronte. Ci sarebbero da aggiungere tutte le build strategy che Openshift offre e la possibilità di passare al bot le variabili d’ambiente del proprio container.

Lo scopo di questo post qual’è?

Lato tecnico per parlare di quando è figo fare bot e di quanto sono comode le API di Openshift.

Molte delle operazioni svolte le ho applicate nell’implementazione di alcune catene di CI/CD nell’ambito di vari progetti enterprise. Sono fortemente convinto che fare esperimenti in ambiti non lavorativi sia la base per ritrovarsi allenati e pronti alle sfide che ci si propongono nel lavoro di tutti i giorni.

Lo scopo di questo post è ribadire che nel nostro lavoro è fondamentale “smanettare” e non perchè ci sia dietro un profondo discorso filosofico, ma perchè se si fa parte di quella categoria di persone che sui libri non ci sa stare, l’unico modo per apprendere è sperimentare.

Un laboratorio per Rancher, K8s, GlusterFS e la soluzione “del ferro economico” al quesito “dove provo tutta sta roba” #1

Ieri, per delle robe un po’ urgenti, mi occorreva avere uno stack ben definito intorno a Kubernetes.

Siccome siamo DevOps Engineer fighi ho scritto un po’ di moduli Terraform e in due minuti ho fatto tutto…

Non è vero c’ho messo tipo mezza giornata e l’ho fatto anche un po’ “a manella”.

Mi piace molto Kubernetes ma, da ormai svariato tempo, preferisco usarlo tramite Openshift soprattutto nell’ambito enterprise. Tuttavia, Rancher mi è piaciuto e lo vedo come una valida soluzione da proporre in determinati casi (magari produrrò un post del tipo Openshift Vs Rancher).

Non è comunque un’alternativa ad Openshift perchè sono due prodotti diversi.

Giuro che non ho abbandonato l’utilizzo sfrenato di Vagrant in locale sulla mia workstation ma, questa volta, ho adottato la soluzione “del ferro economico” al quesito “dove provo tutta sta roba”.

Si, alla fine ho preso in affitto una macchina su Kimsufi con Proxmox 5 che uso come laboratorio da molto tempo.

Screen Shot 2018-09-08 at 10.44.38.png

Ci provo svariate cose come diverse versioni di Openshift e la piattaforma che racconterò in questo post.

La configurazione del nodo fisico è molto semplice:

  1. Proxmox 5 (già installato da Kimsufi).
  2. Una rete locale 10.10.10.0/24 su cui attesto le virtual machine e le faccio uscire su internet.
  3. Un HaProxy installato direttamente sul nodo fisico in modo da inoltrare il traffico sulla 10.10.10.0/24 e farmi accedere da fuori.
  4. Spengo e accendo le diverse “sub-platforms” (me lo sono inventato al volo questo termine…) a seconda delle risorse che mi servono e le raggiungo tranquillamente tramite il reverse proxy.
  5. No, non è come in cloud che spengo e accendo come mi pare con la confortevole sensazione del risparmio pay as you go. Spendo sempre gli stessi soldi.
  6.  Per entrare direttamente sulle vm dal mio computer naturalmente ho impostato gli Host nella configurazione ssh.
Host gluster01
HostName 10.10.10.16
User root
ProxyCommand ssh -W %h:%p -lroot kimsufi

Host gluster02
HostName 10.10.10.17
User root
ProxyCommand ssh -W %h:%p -lroot kimsufi

Host gluster03
HostName 10.10.10.18
User root
ProxyCommand ssh -W %h:%p -lroot kimsufi

Tutto questo anche visto che il mio mac MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports) quando faccio cose DevOps si scalda e accende la ventola che è abbastanza fastidiosa. Inoltre ti esponi al rischio “collega simpatico” che ti fa battute tipo << che fa decolla? >>.

Mi serviva avere questo stack in poco tempo per testare cose:

  1. Un cluster Kubernetes.
  2. Un’istanza Rancher per gestirlo.
  3. Un cluster GlusterFS in replica 3.

Screen Shot 2018-09-08 at 10.55.41

Per creare le VMs?

Volevo provare un plugin di Vagrant per Proxmox, ma non avevo tempo cui ho svolto “a manella” l’installazione di un nodo CentOS Linux release 7.5.1804 (Core) con cloning per le altre 2 virtual machine.

  • gluster01 (10.10.10.16)
  • gluster02 (10.10.10.17)
  • gluster03 (10.10.10.18)

Per installare velocemente Kubernetes?

Assolutamente KubeSpray!

È andata più o meno così

    1. Come installare Python3 su Centos 7.5 visto qui
    2. yum install git ansible
      git clone https://github.com/kubernetes-incubator/kubespray.git
      mkdir inventory/mycluster
      cp -rfp inventory/sample/* inventory/mycluster
      declare -a IPS=(10.10.10.16 10.10.10.17 10.10.10.18)
      CONFIG_FILE=inventory/mycluster/hosts.ini python3.6 contrib/inventory_builder/inventory.py ${IPS[@]}
      
    3. Prova di connessione ai nodi con ‘ansible all -i inventory/mycluster/hosts.ini -m shell -a “whoami”‘
    4. Inizio installazione
      ansible-playbook -i inventory/mycluster/hosts.ini cluster.yml

Devo dire che è andato tutto bene senza troppi intoppi.

Kubernetes cluster up and running!

[root@gluster01 kubespray]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
node1 Ready master,node 4m v1.11.2
node2 Ready master,node 4m v1.11.2
node3 Ready node 3m v1.11.2

 

Installazione di Rancher

Rancher si installa facilmente e basta dargli in pasto un cluster Kubernetes per vederlo all’opera. Nel mio caso gira come container Docker con persistenza.

 docker run -d --restart=unless-stopped -p 80:80 -p 443:443 -v /host/rancher:/var/lib/rancher rancher/rancher:latest

This slideshow requires JavaScript.

#creazione di un service account con diritti per amministrare il cluster k8s
[root@gluster01 ~]# kubectl create -f admin-user.yaml
serviceaccount/admin-user created
[root@gluster01 ~]# kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user admin-user
clusterrolebinding.rbac.authorization.k8s.io/cluster-admin-binding created

Dopo un po’ di “smanettamenti” lato reverse proxy e DNS finalmente il cluster è in stato waiting…

Screen Shot 2018-09-08 at 15.51.53

Dopo altri “smanettamenti ” il cluster si è “joinato” correttamente a Rancher. Anzi più che “joinato” forse è meglio dire che Rancher ha eseguito un takeover su k8s.

Però ho dovuto importare un certificato nel container di Rancher con:

 docker cp /etc/pki/ca-trust/source/anchors/kube-ca.crt $idcontainerdirencher:/etc/ssl/certs/

È una cosa temporanea eh… dopo metto apposto…

Questi sono i pod attivi sul cluster nel namespace creato per Rancher

[root@node1 ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
cattle-system cattle-cluster-agent-6b8df4755-8tfxg 1/1 Running 0 2m
cattle-system cattle-node-agent-48bcq 1/1 Running 0 2m
cattle-system cattle-node-agent-928wl 1/1 Running 0 1m
cattle-system cattle-node-agent-t6cs6 1/1 Running 0 2m

Screen Shot 2018-09-08 at 16.48.38Screen Shot 2018-09-08 at 16.48.44

Installazione di GlusterFS

Sui tre nodi Gluster01,02,03 dove avevo installato Kubernetes controllato da Rancher dovevo aggiungere anche GlusterFS.

Per l’installazione niente di più semplice di questa guida

[root@node1 ~]# gluster volume info

Volume Name: gv0
Type: Replicate
Volume ID: 2a111687-5d26-4051-b0a8-8d4a67efc87f
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: gluster02:/bricks/brick1/gv0
Brick2: gluster03:/bricks/brick1/gv0
Options Reconfigured:
performance.client-io-threads: off
nfs.disable: on
transport.address-family: inet

#Lista nodi dei peer dal node1
[root@node1 ~]# gluster peer status
Number of Peers: 2

Hostname: gluster02
Uuid: 2cb83c74-ebc3-4dca-a62f-799433d198ae
State: Peer in Cluster (Connected)

Hostname: gluster03
Uuid: 6918282f-23f8-4627-b9b4-e7b9d521b32d
State: Peer in Cluster (Connected)

 

Una volta completato tutto ho potuto eseguire delle simulazioni utili per alcuni problemi su un’altra piattaforma.

Al momento sto girando dei pod con GlusterFS come persistent volume e nei prossimi articoli scenderò più nel dettaglio sull’utilizzo di Rancher.

Bella

Cos’è che fa di un Devops un Devops, signor Lebowski?

Vorrei parlare dei principi base del Devops che negli ultimi 5 anni ho potuto assimilare lungo il cammino.
Questo perchè dovevo preparare delle noiosissime slide. Mi serviva uno scopo, e un post sul blog ci sta tutto.

Inoltre, ho preso il dominio ziopinguino.it e sto pensando di migrare tutto il blog lì…

Quali sono i caratteri distintivi dell’area Devops?
Quali sono gli stereotipi e le considerazioni ricorrenti tipiche degli ambiti innovativi a cavallo tra buzzword e vera innovazione?

Cos’è che fa di un devops un devops, signor Lebowski?

Essere una BaaS? Buzzword as a service?

Lo era sicuramente all’inizio una buzzword, ma ora non più.
Lo è se si legge solo nei blog di Devops, se non si è potuto toccarne con mano i benefici e i risultati.

Nei contesti dove c’è stata una vera rivoluzione, la parola “Devops” descrive perfettamente figure professionali che svolgono attività di collegamento tra i…

View original post 798 more words

Autenticazione con Ansible. Esempi di vari casi (ssh key, sudo, su, password,…)

Spesso, a seconda dell’environment in cui ci troviamo e delle restrizioni che dobbiamo affrontare lato sicurezza, dobbiamo effettuare un tuning del nostro inventory file.

Riporto in questo post un po’ di casi diversi che possono essere utili come esempi di configurazione base.

Sono casi molto semplici ma uniti insieme possono essere una visione d’insieme rapida sui parametri disponibili da usare nell’inventory.

Scambio chiavi ssh

Il default user per le connessioni ssh è root. La chiave pubblica dell’utente da cui sto lanciando Ansible è stata inserita in /root/.ssh/authorized_keys di root in ocslave35.

#inventory
[nodes]
ocslave35 openshift_hostname=ocslave35
ansible nodes -m ping
ocslave35 | SUCCESS => {
"changed": false,
"ping": "pong"
}

Autenticazione con password

Definisco la password di root di ocslave35.

#inventory
[nodes]
ocslave35 openshift_hostname=ocslave35 ansible_ssh_pass=supersecret_password
ansible nodes -m ping
ocslave35 | SUCCESS => {
"changed": false,
"ping": "pong"
}

Utilizzo utente operatore con password

Definisco un utente operatore con relativa password.

#inventory
[nodes]
ocslave35 openshift_hostname=ocslave35 ansible_user=operatore ansible_ssh_pass=foobar.123
[root@ocmaster35 ~]# ansible nodes -m shell -a "whoami"
ocslave35 | SUCCESS | rc=0 >>
operatore

become_method sudo

L’utente operatore diventa root tramite sudo

[root@ocslave35 ~]# cat /etc/sudoers.d/operatore
operatore ALL=(ALL) ALL
#inventory
[nodes]
ocslave35 openshift_hostname=ocslave35 ansible_user=operatore ansible_ssh_pass=foobar.123 ansible_become_user=root ansible_become=yes ansible_become_method=sudo ansible_become_pass=foobar.123
[root@ocmaster35 ~]# ansible nodes -m shell -a "whoami"
ocslave35 | SUCCESS | rc=0 >>
root

become_method su

L’utente operatore diventa root tramite il comando su con password definita nell’inventory.

#inventory
[nodes]
ocslave35 openshift_hostname=ocslave35 ansible_user=operatore ansible_ssh_pass=foobar.123 ansible_become_user=root ansible_become=yes ansible_become_method=su ansible_become_pass=supersecret_password
[root@ocmaster35 ~]# ansible nodes -m shell -a "whoami"
ocslave35 | SUCCESS | rc=0 >>
root

 

Accesso locale

Il nodo da cui lanciamo Ansible è lo stesso a cui vogliamo connetterci. Non c’è bisogno di ssh quindi.

[nodes]
ocmaster35 ansible_connection=local

ciao!

DNS Server Master/Slave tramite Ansible

Devo mettere in piedi un DNS server master/slave e mi trovo davanti al solito quesito sulle opzioni per l’implementazione. Come lo faccio?

  1. a manina
  2. Chef
  3. Ansible

L’opzione numero uno (ogni tanto e soprattutto per i miei ambienti di laboratorio) inizia a sembrarmi quella più rapida, ma per tenersi allenati su IaC è bene usare la 2 o la 3.

Siccome il DNS mi serve per un cluster Openshift direi di procedere con la 3, così farò tutto con Ansible.

1_hdwjXl1x4Q3VXmL7UG1XrQ

Ho preso in affitto una macchina fisica su Kimsufi con sopra Proxmox come hypervisor.

Screen Shot 2018-07-15 at 11.27.50

La rete è configurata così.

ocmaster39 (eth0: 10.10.10.10/24, eth1: 192.168.56.10/16)

ocslave39 (eth0: 10.10.10.11/24, eth1: 192.168.56.11/16)

Il nostro DNS ascolterà sulla 192.168.0.0 mentre sulla 10.10.10.0 attesterò i servizi di OC.

Una volta completato l’inventory file che è veramente molto scarno in questo caso eseguirò i playbook.

[dns_master]
192.168.56.10 ansible_connection=local

[dns_slave]
192.168.56.11



Eseguiamo qualche comando per vedere che la comunicazione funzioni…

[root@ocmaster39 ansible-role-bind]# ansible all -a 'whoami' -m shell
192.168.56.10 | SUCCESS | rc=0 >>
root

192.168.56.11 | SUCCESS | rc=0 >>
root

Ok si.. tutti usano il ping e quindi lo userò anche io,

[root@ocmaster39 ansible-role-bind]# ansible all -m ping
192.168.56.10 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
192.168.56.11 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}

Convergenza del master (sotto è riportato il playbook usato)

ansible-playbook master.yml

Convergenza slave

ansible-playbook slave.yml

A questo punto Bind è installato e configurato, per cui interroghiamo il master…

[root@ocmaster39 ~]# dig @192.168.56.10 google.it | grep -n1 "ANSWER SECTION"
13-
14:;; ANSWER SECTION:
15-google.it. 188 IN A 172.217.18.195
[root@ocmaster39 ~]# dig @192.168.56.10 ocslave39.openshift.local | grep -n1 "ANSWER SECTION"
13-
14:;; ANSWER SECTION:
15-ocslave39.openshift.local. 1209600 IN A 192.168.56.11

… ora lo slave …

[root@ocmaster39 ~]# dig @192.168.56.11 ocslave39.openshift.local | grep -n1 "ANSWER SECTION"
13-
14:;; ANSWER SECTION:
15-ocslave39.openshift.local. 1209600 IN A 192.168.56.11

Ho forkato il playbook originale per una PR dove ho aggiunto i playbook usati e un po’ di doc.

Trovate l’esempio usato qui

Ciao!