KubeInvaders on Openshift 4.1

Just add new special input key for KubeInvaders. Press ‘n’ to jump between namespaces!

ezgif-1-e88ad3f7a1e0

Recently I released a gamified chaos engineering tool for Kubernetes (it has been added in https://github.com/dastergon/awesome-chaos-engineering some days ago) and I would like deploy it on Openshift 4.1.

First of all, follow these two guides:

Openshift 4 Install Experience

Cluster Install

A today,  for trying Openshift 4 the best choise is by using AWS.  The openshift-install-linux utility installs a ready to use cluster through Terraform.

Screenshot 2019-05-02 at 21.01.55

The installation is very easy and after the execution of openshift-install-linux-amd64 I had just to follow instructions for connecting to my new Openshift cluster.

time="2019-05-02T10:58:45Z" level=debug msg="OpenShift console route is created"
time="2019-05-02T10:58:45Z" level=info msg="Install complete!"
time="2019-05-02T10:58:45Z" level=info msg="Run 'export KUBECONFIG=/root/auth/kubeconfig' to manage the cluster with 'oc', the OpenShift CLI."
time="2019-05-02T10:58:45Z" level=info msg="The cluster is ready when 'oc login -u kubeadmin -p xxxx succeeds (wait a few minutes)."
time="2019-05-02T10:58:45Z" level=info msg="Access the OpenShift web-console here: https://console-openshift-console.apps.kubeclu.kubeinvaders.io"
time="2019-05-02T10:58:45Z" level=info msg="Login to the console with user: kubeadmin, password: xxxx"

Screenshot 2019-05-02 at 21.06.28

Before to deploy KubeInvaders create a sample namespace in which run, for example, NodeJS applications. You can deploy it directly from the Openshift catalog.

Let’s install KubeInvaders.

# Clone KubeInvaders
git clone https://github.com/lucky-sideburn/KubeInvaders.git
# Do the following commands. 
# Same and updated guide on https://github.com/lucky-sideburn/KubeInvaders#install-kubeinvaders-on-openshift

# The namespace you want to stress
TARGET_NAMESPACE=foobar

# Choose route host for your kubeinvaders instance.
ROUTE_HOST=kubeinvaders.apps.kubeclu.kubeinvaders.io

# Please add your source ip IP_WHITELIST. This will add haproxy.router.openshift.io/ip_whitelist in KubeInvaders route
# https://docs.openshift.com/container-platform/3.9/architecture/networking/routes.html#whitelist
IP_WHITELIST="10.10.10.10"

oc new-project kubeinvaders --display-name='KubeInvaders'
oc create sa kubeinvaders -n kubeinvaders
oc create sa kubeinvaders -n $TARGET_NAMESPACE
oc adm policy add-role-to-user edit -z kubeinvaders -n $TARGET_NAMESPACE

TOKEN=$(oc describe secret -n $TARGET_NAMESPACE $(oc describe sa kubeinvaders -n $TARGET_NAMESPACE | grep Tokens | awk '{ print $2}') | grep 'token:'| awk '{ print $2}')
oc process -f openshift/KubeInvaders.yaml -p ROUTE_HOST=$ROUTE_HOST -p TARGET_NAMESPACE=$TARGET_NAMESPACE -p TOKEN=$TOKEN | oc create -f -

Open routes and go to KubeInvaders location

Screenshot 2019-05-02 at 21.11.53Screenshot 2019-05-02 at 21.12.12

Scale pods of foobar namespace to 20 replicas.

oc scale dc testapp --replicas=20 -n foobar

Screenshot 2019-05-02 at 21.18.58

I deployed also https://github.com/hjacobs/kube-ops-view because I find it very cool for watching pods distributed across node workers.

Screenshot 2019-05-02 at 21.31.26

This is how KubeInvaders works with Openshift 4.1.

 

Bye!

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

#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

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!

Come dare fastidio a chi ascolta la radio in spiaggia ( a volume molto alto ) e interrompe il vostro momento zen

Un saluto estivo a tutti i lettori di devopsrecipes.info 😉

Le mie vacanze si avvicinano e presto potrò finalmente allontanarmi dal caos cittadino… Nel mio zaino, oltre ad set di birre ricercatissime ( una paio di Peroni da 66 ) quest’anno ci sarà anche un trasmettitore radio FM pirata, nel caso qualcuno disturbi il mio sonno sentendo la radio ad alto volume… Se vi siete drogati, è molto probabile che la musica che sentite non è trasmessa da alcun vicino, per cui andate a prendervi un Calippo.

listening-to-old-time-radio-on-the-beach

Procuratevi più o meno le seguenti cose, oppure compratevi un trasmettitore radio su Amazon ( però sappiate che è poco fico comprarlo già fatto o scaricare app )

  1. Un Raspberry PI
  2. Un alimentatore portatile per smartphone ( meglio se ad energia solare)
  3. Una pennetta wireless
  4. Uno script in php per la gestione tramite interfaccia web (https://github.com/lucky-sideburn/piratepiwave.git)
  5. Il software https://github.com/rm-hull/pifm per l’erogazione del segnale FM
  6. Il vostro smartphone

Perchè il punto 4?

Non mi andava assolutamente di smanettare troppo con le GPIO per collegare uno schermo LCD e un regolatore di frequenza, per cui ho preferito controllare il trasmettitore tramite il mio telefono.

  1. Per prima cosa installiamo un web-server Apache + Php sulla nostra Raspbian Jessie Lite ( naturalmente ognuno è libero di usare il sistema operativo e/o web-server che preferisce )
  2. Se siete pigri potete anche prendere il mio script php https://github.com/lucky-sideburn/piratepiwave.git ( non sono un web-developer quindi si, l’interfaccia grafica non è cool )
  3. Installate https://github.com/rm-hull/pifm in /usr/local/pifm ( nella documentazione trovate a quale GPIO agganciare un’antenna fatta con un filo )
  4. configurate scheda di rete di Wifi per collegarsi all’hotspot del vostro smartphone ( dal pannello di amministrazione ricaverete l’ip assegnato )
  5. mettete tutto in autostart al boot, agganciate batteria esterna al raspino e dal vostro smartphone date un http://$ipdelraspberry

Cosa facciamo suonare sulla radio del “disturbatore momento zen”?

Copiate le vostre tracce audio preferite ( pure teknone spinto ) in /usr/local/pifm/sounds e modificate il puntamento al file audio che troverete nello script php.

Come seleziono le frequenze FM?

Potete usare la comodissima barra in alto

Screen Shot 2016-08-15 at 11.25.27.png

Oppure farvi dei tastini tipo questi con le frequenze radio già impostate

Screen Shot 2016-08-15 at 11.28.20.png

Questo è il risultato finale

IMG_20160815_113020

buone vacanze!

Docker images pruning with Openshift Origin

openshift-card

In order to test the Docker images pruning with Openshift Origin I made the following test.

Environment:

  • Two nodes, one master + infra and a workload node.
  • Cluster version: Openshift Origin 3.6

First of all I have built a Docker image based on NodeJS within a large file. The file.out is of 50M and after compression it decreases little.

Structure of my NodeJS app

[root@origin-master nodeapp]# ls -lhas

total 51M

 0 drwxr-xr-x. 2 root root 106 May 27 16:41 .

 0 drwx------. 6 vagrant vagrant 228 May 27 09:09 ..

4.0K -rw-r--r--. 1 root root 136 May 27 16:22 Dockerfile

4.0K -rw-r--r--. 1 root root 261 May 27 16:18 create_fake_images.sh

 50M -rw-r--r--. 1 root root 50M May 27 16:18 file.out

4.0K -rw-r--r--. 1 root root 265 May 27 09:09 package.json

4.0K -rw-r--r--. 1 root root 539 May 27 15:19 server.js

The Dockerfile is very simple!

[root@origin-master nodeapp]# cat Dockerfile

FROM node

# Create app directory

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8080

CMD [ "npm", "start" ]

The following script helped me to generate many images with additional and differents layers. Each iterations copy the 50M file inside the image.

for i in $(seq 1 1000)

do

 echo "RUN echo $i" >> Dockerfile

 echo "COPY file.out ./$i.out" >> Dockerfile

 docker build -t docker-registry-default.origin.local/test/nodeapp:latest .

 docker push docker-registry-default.origin.local/test/nodeapp:latest

done

Let's see how the Docker registry folder increase size during create_fake_images.sh execution.

1a4c7633d886: Pushing [=======> ] 8.325 MB/52.43 MB

e36035decad2: Pushing [=======> ] 7.768 MB/52.43 MB

bb1e26b5f124: Pushing [=======> ] 7.768 MB/52.43 MB

13c3d2712668: Pushing [===========> ] 11.67 MB/52.43 MB

dbc4876ab96c: Pushing [=======> ] 8.327 MB/52.43 MB

[root@origin-master vagrant]# du -chs /data/origin/

 782M /data/origin/

 782M total

[root@origin-master vagrant]# du -chs /data/origin/

 956M /data/origin/

 956M total

[root@origin-master vagrant]# du -chs /data/origin/

 1.2G /data/origin/

 1.2G total

Describing image stream nodeapp we can see the latest images pushed to the registry

[root@origin-master nodeapp]# oc describe is

Name: nodeapp

Namespace: test

Created: 2 hours ago

Labels: <none>

Annotations: <none>

Docker Pull Spec: docker-registry.default.svc:5000/test/nodeapp

Image Lookup: local=false

Unique Images: 5

Tags: 1

latest

 pushed image

* docker-registry.default.svc:5000/test/nodeapp@sha256:6f517f2bd667280587daebd57c456c723df4e97d72903100cad441821203e4ec

 22 seconds ago

 docker-registry.default.svc:5000/test/nodeapp@sha256:421155780252a908de9c4968c65a508c65b12b259a6248278b73dd20edee20fb

 About a minute ago

 docker-registry.default.svc:5000/test/nodeapp@sha256:b26f1d2cac95a73632891a6cfec875baed0b1a4165c381e59e0ce4d1bfc403f9

 About a minute ago

 docker-registry.default.svc:5000/test/nodeapp@sha256:6d6f63093aae64198fb1d7af2cd2a361cec991817c8e6944910cb84420a52c1b

 20 minutes ago

 docker-registry.default.svc:5000/test/nodeapp@sha256:6e82ae61a154788ff70ff3ed69cf3a088845e0c7c2d1441de4123c213a0f0116

 23 minutes ago

I changed the Dockerfile in order to have an image that does not import large file. So I have built and pushed the following Docker image

[root@origin-master nodeapp]# cat Dockerfile

FROM node

# Create app directory

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8080

CMD [ "npm", "start" ]

Let’s start to prune

tree-pruning1

  1. Delete old deployments
[root@origin-master nodeapp]# oc adm prune deployments --orphans --keep-complete=1 --keep-failed=1 --keep-younger-than=1m

Dry run enabled - no modifications will be made. Add --confirm to remove deployments

NAMESPACE NAME

test nodeapp2-23

test nodeapp2-22

test nodeapp2-21

test nodeapp2-20
  1. Prune the unused images and keep only one revision
[root@origin-master nodeapp]# oc adm prune images --keep-tag-revisions=1 --keep-younger-than=1m --confirm

Deleting references from image streams to images ...

STREAM IMAGE TAGS

test/nodeapp sha256:6e82ae61a154788ff70ff3ed69cf3a088845e0c7c2d1441de4123c213a0f0116 latest

test/nodeapp sha256:421155780252a908de9c4968c65a508c65b12b259a6248278b73dd20edee20fb latest

test/nodeapp sha256:b26f1d2cac95a73632891a6cfec875baed0b1a4165c381e59e0ce4d1bfc403f9 latest

Deleting registry repository layer links ...

REPO LAYER LINK

test/nodeapp sha256:3de138bf364bf3e2684c78468d07a0e2ca786ba08f83bd1b7e3373a1e0b407e5

test/nodeapp sha256:a75ed4d808fc563081de632debf91580a6dbe6d694971ca6888b5be4433f55cc

test/nodeapp sha256:677e3bfb00ad311212b46be4ddb20f5b762765fef676c6d4a85e5dbcb943c4a4

test/nodeapp sha256:29510362ff8e174edf88563f6099141b9e82efd5cd48b14aeaa74fea532e6d43

test/nodeapp sha256:35dc109c74dfcab9f1f027ccc1404e7ef3f524d6efea226e3920959051819f2c

test/nodeapp sha256:f3d40164b23c42356d717da92b91774402632a8df22cd5ddfb7926fc3a7292f6

test/nodeapp sha256:fe03b24c2c84648d09331dbd72a8065b8ed550be991155edc72ad1166f1ef666

test/nodeapp sha256:8eaf1a821a6b8a2e325cebce83311c5d3b33427140d84954f504ed59bab51109

test/nodeapp sha256:684c30e67a270d2115cb4be1c9712193bf0b4393ffa04b3c625e76fadd6bda12

test/nodeapp sha256:7d6ad63a8e94a938a95fa1e27106bbc7ecfa3680b3ff3a11c7bdb43ae610eb18

test/nodeapp sha256:e1614bf81372b99eb86c74ac9c023c01077061db81c4daeaf6683e27299e48cc

test/nodeapp sha256:a92bff6ede96a89a94fe2ca794115e1c374312d05e895698e6b1638c3b647645

test/nodeapp sha256:2d9ccccdee639671c6cb24110e529b738535453a3ccdf68989ac31ea6894929d

test/nodeapp sha256:1e920f3f2676bc50c60a95c9d8710cb91429ab07278616c02680b0f38af2d224

test/nodeapp sha256:90b58c4583c3de52b6f6762c83a02d42dd18747a2541bafb483a9cdbc5e55f8b

test/nodeapp sha256:d041de45e8895ee77b4e6ba112959e361d888b5694910b44f54fb88f0ef3fb4f

Deleting registry layer blobs ...

BLOB

sha256:3de138bf364bf3e2684c78468d07a0e2ca786ba08f83bd1b7e3373a1e0b407e5

sha256:a75ed4d808fc563081de632debf91580a6dbe6d694971ca6888b5be4433f55cc

sha256:677e3bfb00ad311212b46be4ddb20f5b762765fef676c6d4a85e5dbcb943c4a4

sha256:29510362ff8e174edf88563f6099141b9e82efd5cd48b14aeaa74fea532e6d43

sha256:35dc109c74dfcab9f1f027ccc1404e7ef3f524d6efea226e3920959051819f2c

sha256:f3d40164b23c42356d717da92b91774402632a8df22cd5ddfb7926fc3a7292f6

sha256:fe03b24c2c84648d09331dbd72a8065b8ed550be991155edc72ad1166f1ef666

sha256:8eaf1a821a6b8a2e325cebce83311c5d3b33427140d84954f504ed59bab51109

sha256:684c30e67a270d2115cb4be1c9712193bf0b4393ffa04b3c625e76fadd6bda12

sha256:7d6ad63a8e94a938a95fa1e27106bbc7ecfa3680b3ff3a11c7bdb43ae610eb18

sha256:e1614bf81372b99eb86c74ac9c023c01077061db81c4daeaf6683e27299e48cc

sha256:a92bff6ede96a89a94fe2ca794115e1c374312d05e895698e6b1638c3b647645

sha256:2d9ccccdee639671c6cb24110e529b738535453a3ccdf68989ac31ea6894929d

sha256:1e920f3f2676bc50c60a95c9d8710cb91429ab07278616c02680b0f38af2d224

sha256:90b58c4583c3de52b6f6762c83a02d42dd18747a2541bafb483a9cdbc5e55f8b

sha256:d041de45e8895ee77b4e6ba112959e361d888b5694910b44f54fb88f0ef3fb4f

Deleting registry repository manifest data ...

REPO IMAGE

test/nodeapp sha256:6e82ae61a154788ff70ff3ed69cf3a088845e0c7c2d1441de4123c213a0f0116

test/nodeapp sha256:421155780252a908de9c4968c65a508c65b12b259a6248278b73dd20edee20fb

test/nodeapp sha256:b26f1d2cac95a73632891a6cfec875baed0b1a4165c381e59e0ce4d1bfc403f9

Deleting images from server ...

IMAGE

sha256:6e82ae61a154788ff70ff3ed69cf3a088845e0c7c2d1441de4123c213a0f0116

sha256:421155780252a908de9c4968c65a508c65b12b259a6248278b73dd20edee20fb

sha256:b26f1d2cac95a73632891a6cfec875baed0b1a4165c381e59e0ce4d1bfc403f9

Check the size of  registry folder

[root@origin-master nodeapp]# du -chs /data/origin/
608M /data/origin/
608M total

Ok from 1.6gb we went down to 608M !