Search This Blog

Wednesday 17 March 2021

Ansible playbook loop with condition example

[osboxes@master ansible-playbooks]$ cat loopwithcondition.yml
- hosts: all
  tasks:
  - name: Ansible loop with conditional example
    debug:
      msg: "{{ item }}"
    loop:
      - "hello1"
      - "hello2"
      - "hello3"
    when: ansible_distribution == "CentOS"
[osboxes@master ansible-playbooks]$ ansible-playbook loopwithcondition.yml -i inventory.txt

PLAY [all] **************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [192.168.1.182]

TASK [Ansible loop with conditional example] ****************************************************************************************************************
ok: [192.168.1.182] => (item=hello1) => {
    "msg": "hello1"
}
ok: [192.168.1.182] => (item=hello2) => {
    "msg": "hello2"
}
ok: [192.168.1.182] => (item=hello3) => {
    "msg": "hello3"
}

PLAY RECAP **************************************************************************************************************************************************
192.168.1.182              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Tuesday 16 March 2021

Ansible when condition with "in" keyword

Task: Check the disk space of the file system When the operating system is "RedHat" or  "CentOS" or "Debian" using "when" condition and "in" keyword

[osboxes@master ansible-playbooks]$ cat conditions-in.yml
---
- name: check the disk space on the file system
  hosts: all
  vars:
    distributions:
      - RedHat
      - CentOS
      - Debian
  tasks:
    - name: Check the disk space on the each server
      shell: df -h
      register: result
    - debug:
        var: result.stdout_lines
      when: ansible_distribution in distributions


[osboxes@master ansible-playbooks]$ ansible-playbook conditions-in.yml -i inventory.txt

PLAY [check the disk space on the file system] **************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [192.168.1.182]

TASK [Check the disk space on the each server] **************************************************************************************************************
changed: [192.168.1.182]

TASK [debug] ************************************************************************************************************************************************
ok: [192.168.1.182] => {
    "result.stdout_lines": [
        "Filesystem      Size  Used Avail Use% Mounted on",
        "devtmpfs        887M     0  887M   0% /dev",
        "tmpfs           914M     0  914M   0% /dev/shm",
        "tmpfs           914M  9.2M  905M   1% /run",
        "tmpfs           914M     0  914M   0% /sys/fs/cgroup",
        "/dev/sda2       236G  6.9G  230G   3% /",
        "/dev/sda5       254G  1.9G  252G   1% /home",
        "/dev/sda1       976M  188M  722M  21% /boot",
        "tmpfs           183M  1.2M  182M   1% /run/user/42",
        "tmpfs           183M  4.0K  183M   1% /run/user/1000"
    ]
}

PLAY RECAP **************************************************************************************************************************************************
192.168.1.182              : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Monday 15 March 2021

Deploy an App on Docker Containers using docker-compose

Task:

The Nautilus Application development team recently finished development of one of the apps that they want to deploy on a containerized platform. The Nautilus Application development and DevOps teams met to discuss some of the basic pre-requisites and requirements to complete the deployment. The team wants to test the deployment on one of the app servers before going live and set up a complete containerized stack using a docker compose fie. Below are the details of the task:

On App Server 3 in Stratos Datacenter create a docker compose file /opt/finance/docker-compose.yml (should be named exactly).

The compose should deploy two services (web and DB), and each service should deploy a container as per details below:

For web service:

a. Container name must be php_host.

b. Use image php with any apache tag. Check here for more details https://hub.docker.com/_/php?tab=tags.

c. Map php_host container's port 80 with host port 5001

d. Map php_host container's /var/www/html volume with host volume /var/www/html.

For DB service:

a. Container name must be mysql_host.

b. Use image mariadb with any tag (preferably latest). Check here for more details https://hub.docker.com/_/mariadb?tab=tags.

c. Map mysql_host container's port 3306 with host port 3306

d. Map mysql_host container's /var/lib/mysql volume with host volume /var/lib/mysql.

e. Set MYSQL_DATABASE=database_host and use any custom user ( except root ) with some complex password for DB connections.

After running docker-compose up you can access the app with curl command curl <server-ip or hostname>:5001/
For more details check here: https://hub.docker.com/_/mariadb?tab=description

Step 1) Login to Application server 3 and switch to root user.

thor@jump_host /$ ssh banner@stapp03
banner@stapp03's password: 
[banner@stapp03 ~]$ sudo su -

Step 2) Create a docker-compose.yml file with the specifications given in the task.

[root@stapp03 ~]# cd /opt/finance/
[root@stapp03 finance]# ls -rlt
total 0
[root@stapp03 finance]# vi docker-compose.yml

  web:
     container_name: php_host
     image: php:apache
     ports:
       - 5001:80
     volumes:
       - /var/www/html:/var/www/html     
  db:
    container_name: mysql_host
    image: mariadb:latest
    ports:
    - 3306:3306
    volumes:
      - /var/lib/mysql:/var/lib/mysql
    environment:
      MYSQL_DATABASE: database_host
      MYSQL_ROOT_PASSWORD: abc#123
      MYSQL_USER: pavan
      MYSQL_PASSWORD: Wordpress#134

Step 3) Run the following command

[root@stapp03 finance]# docker-compose up
Pulling web (php:apache)...
apache: Pulling from library/php
6f28985ad184: Pull complete
db883aae18bc: Pull complete
ffae70ea03a9: Pull complete
1e8027612378: Pull complete
3ec32e53dce5: Pull complete
3bb74037bf77: Pull complete
feda0fbd85b1: Pull complete
08cbfcace66f: Pull complete
90e59842632d: Pull complete
5a29d8ab032c: Pull complete
5435aacb3255: Pull complete
57f9bba5897a: Pull complete
7c89fe480eda: Pull complete
Pulling db (mariadb:latest)...
latest: Pulling from library/mariadb
5d3b2c2d21bb: Pull complete
3fc2062ea667: Pull complete
75adf526d75b: Pull complete
62aa2722e098: Pull complete
756d25563a9f: Pull complete
2022ea4dab77: Pull complete
0ab4098b0f7c: Pull complete
d03413915fdf: Pull complete
fb8e671b1408: Pull complete
5e2452f3fb5c: Pull complete
c2da3a6fe532: Pull complete
153b7df268e7: Pull complete
Creating php_host   ... done
Creating mysql_host ... done
Attaching to mysql_host, php_host
mysql_host | 2021-03-16 01:43:25+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
mysql_host | 2021-03-16 01:43:25+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysql_host | 2021-03-16 01:43:25+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.9+maria~focal started.
mysql_host | 2021-03-16 01:43:25+00:00 [Note] [Entrypoint]: Initializing database files
php_host | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
php_host | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
php_host | [Tue Mar 16 01:43:28.007827 2021] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/8.0.3 configured -- resuming normal operations
php_host | [Tue Mar 16 01:43:28.007869 2021] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
mysql_host | 
mysql_host | 
mysql_host | PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !
mysql_host | To do so, start the server, then issue the following commands:
mysql_host | 
mysql_host | '/usr/bin/mysqladmin' -u root password 'new-password'
mysql_host | '/usr/bin/mysqladmin' -u root -h  password 'new-password'
mysql_host | 
mysql_host | Alternatively you can run:
mysql_host | '/usr/bin/mysql_secure_installation'
mysql_host | 
mysql_host | which will also give you the option of removing the test
mysql_host | databases and anonymous user created by default.  This is
mysql_host | strongly recommended for production servers.
mysql_host | 
mysql_host | See the MariaDB Knowledgebase at https://mariadb.com/kb or the
mysql_host | MySQL manual for more instructions.
mysql_host | 
mysql_host | Please report any problems at https://mariadb.org/jira
mysql_host | 
mysql_host | The latest information about MariaDB is available at https://mariadb.org/.
mysql_host | You can find additional information about the MySQL part at:
mysql_host | https://dev.mysql.com
mysql_host | Consider joining MariaDB's strong and vibrant community:
mysql_host | https://mariadb.org/get-involved/
mysql_host | 
mysql_host | 2021-03-16 01:43:28+00:00 [Note] [Entrypoint]: Database files initialized
mysql_host | 2021-03-16 01:43:28+00:00 [Note] [Entrypoint]: Starting temporary server
mysql_host | 2021-03-16 01:43:28+00:00 [Note] [Entrypoint]: Waiting for server startup
mysql_host | 2021-03-16  1:43:28 0 [Note] mysqld (mysqld 10.5.9-MariaDB-1:10.5.9+maria~focal) starting as process 96 ...
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Uses event mutexes
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Number of pools: 1
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
mysql_host | 2021-03-16  1:43:28 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Using Linux native AIO
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Initializing buffer pool, total size = 134217728, chunk size = 134217728
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Completed initialization of buffer pool
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: 128 rollback segments are active.
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Creating shared tablespace for temporary tables
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: 10.5.9 started; log sequence number 45130; transaction id 20
mysql_host | 2021-03-16  1:43:28 0 [Note] Plugin 'FEEDBACK' is disabled.
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
mysql_host | 2021-03-16  1:43:28 0 [Note] InnoDB: Buffer pool(s) load completed at 210316  1:43:28
mysql_host | 2021-03-16  1:43:28 0 [Warning] 'user' entry 'root@35db7c5d0517' ignored in --skip-name-resolve mode.
mysql_host | 2021-03-16  1:43:28 0 [Warning] 'proxies_priv' entry '@% root@35db7c5d0517' ignored in --skip-name-resolve mode.
mysql_host | 2021-03-16  1:43:28 0 [Note] Reading of all Master_info entries succeeded
mysql_host | 2021-03-16  1:43:28 0 [Note] Added new Master_info '' to hash table
mysql_host | 2021-03-16  1:43:28 0 [Note] mysqld: ready for connections.
mysql_host | Version: '10.5.9-MariaDB-1:10.5.9+maria~focal'  socket: '/run/mysqld/mysqld.sock'  port: 0  mariadb.org binary distribution
mysql_host | 2021-03-16 01:43:29+00:00 [Note] [Entrypoint]: Temporary server started.
mysql_host | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
mysql_host | Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it.
mysql_host | Warning: Unable to load '/usr/share/zoneinfo/tzdata.zi' as time zone. Skipping it.
mysql_host | 2021-03-16  1:43:31 5 [Warning] 'proxies_priv' entry '@% root@35db7c5d0517' ignored in --skip-name-resolve mode.
mysql_host | 2021-03-16 01:43:31+00:00 [Note] [Entrypoint]: Creating database database_host
mysql_host | 2021-03-16 01:43:31+00:00 [Note] [Entrypoint]: Creating user pavan
mysql_host | 2021-03-16 01:43:31+00:00 [Note] [Entrypoint]: Giving user pavan access to schema database_host
mysql_host | 
mysql_host | 2021-03-16 01:43:31+00:00 [Note] [Entrypoint]: Stopping temporary server
mysql_host | 2021-03-16  1:43:31 0 [Note] mysqld (initiated by: root[root] @ localhost []): Normal shutdown
mysql_host | 2021-03-16  1:43:31 0 [Note] Event Scheduler: Purging the queue. 0 events
mysql_host | 2021-03-16  1:43:31 0 [Note] InnoDB: FTS optimize thread exiting.
mysql_host | 2021-03-16  1:43:31 0 [Note] InnoDB: Starting shutdown...
mysql_host | 2021-03-16  1:43:31 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
mysql_host | 2021-03-16  1:43:31 0 [Note] InnoDB: Buffer pool(s) dump completed at 210316  1:43:31
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Shutdown completed; log sequence number 45142; transaction id 21
mysql_host | 2021-03-16  1:43:32 0 [Note] mysqld: Shutdown complete
mysql_host | 
mysql_host | 2021-03-16 01:43:32+00:00 [Note] [Entrypoint]: Temporary server stopped
mysql_host | 
mysql_host | 2021-03-16 01:43:32+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
mysql_host | 
mysql_host | 2021-03-16  1:43:32 0 [Note] mysqld (mysqld 10.5.9-MariaDB-1:10.5.9+maria~focal) starting as process 1 ...
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Uses event mutexes
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Number of pools: 1
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
mysql_host | 2021-03-16  1:43:32 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Using Linux native AIO
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Initializing buffer pool, total size = 134217728, chunk size = 134217728
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Completed initialization of buffer pool
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: 128 rollback segments are active.
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Creating shared tablespace for temporary tables
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: 10.5.9 started; log sequence number 45142; transaction id 20
mysql_host | 2021-03-16  1:43:32 0 [Note] Plugin 'FEEDBACK' is disabled.
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
mysql_host | 2021-03-16  1:43:32 0 [Note] InnoDB: Buffer pool(s) load completed at 210316  1:43:32
mysql_host | 2021-03-16  1:43:33 0 [Note] Server socket created on IP: '::'.
mysql_host | 2021-03-16  1:43:33 0 [Warning] 'proxies_priv' entry '@% root@35db7c5d0517' ignored in --skip-name-resolve mode.
mysql_host | 2021-03-16  1:43:33 0 [Note] Reading of all Master_info entries succeeded
mysql_host | 2021-03-16  1:43:33 0 [Note] Added new Master_info '' to hash table
mysql_host | 2021-03-16  1:43:33 0 [Note] mysqld: ready for connections.
mysql_host | Version: '10.5.9-MariaDB-1:10.5.9+maria~focal'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution


php_host | 172.16.238.3 - - [16/Mar/2021:01:49:57 +0000] "GET / HTTP/1.1" 200 358 "-" "curl/7.29.0"



 

Monday 8 March 2021

Ansible when condition examples

 Task: Install http package using yum module and load services, enable services, start services when Operating system is "CentOS"

[osboxes@master ansible-playbooks]$ cat conditions.yml
---
- name: Install packages
  hosts: all
  become: true
  become_user: root
  tasks:
    - name: Install httpd
      yum:
        name: httpd
        state: present

    - name: load apache service
      systemd: daemon_reload=yes name=httpd
      when: (ansible_distribution == "CentOS")

    - name: enable apache service
      service: name=httpd enabled=yes
      when: (ansible_distribution == "CentOS")

    - name: start apache service
      service: name=httpd state=started
      when: (ansible_distribution == "CentOS")


[osboxes@master ansible-playbooks]$ ansible-playbook conditions.yml -i inventory.txt --syntax-check

playbook: conditions.yml

[osboxes@master ansible-playbooks]$ ansible-playbook conditions.yml -i inventory.txt

PLAY [Install packages] *************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [192.168.1.182]

TASK [Install httpd] ****************************************************************************************************************************************
ok: [192.168.1.182]

TASK [load apache service] **********************************************************************************************************************************
changed: [192.168.1.182]

TASK [enable apache service] ********************************************************************************************************************************
ok: [192.168.1.182]

TASK [start apache service] *********************************************************************************************************************************
changed: [192.168.1.182]

PLAY RECAP **************************************************************************************************************************************************
192.168.1.182              : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Puppet Setup NTP Server

 Task:

While troubleshooting one of the issue on app servers in Stratos Datacenter DevOps team identified the root cause that the time isn't synchronized properly among all app servers which cause issues sometimes. So team has decided to use a specific time server for all app servers so that they all remain in sync. This task needs to be done using Puppet so as per details mentioned below please compete the task:

Create a puppet programming file apps.pp under /etc/puppetlabs/code/environments/production/manifests directory on puppet master node i.e on Jump Server. Within the programming file define a custom class ntpconfig to install and configure ntp server on all app servers.

Also add NTP Server server 1.africa.pool.ntp.org in default configuration file on all app servers.

Please note that do not try to start/restart/stop ntp service as we already have a scheduled restart for this service tonight and we don't want these changes to be applied right now.

Note: Please perform this task using apps.pp only, do not try to create any separate inventory file.

Step 1) Create puppet class file apps.pp on jump host where puppet master is running

root@jump_host /etc/puppetlabs/code/environments/production/manifests# cat apps.pp 
class ntpconfig {
#Installing NTP Package
package {"ntp":
        ensure => 'present',
        }
#Add content to ntp configuration file
file {"/etc/ntp.conf":
     ensure => "present",
     content => "server 1.africa.pool.ntp.org",
     }
#Start NTP Services
service {"ntpd":
        ensure => "running",
        }

}

node 'stapp01.stratos.xfusioncorp.com', 'stapp02.stratos.xfusioncorp.com', 'stapp03.stratos.xfusioncorp.com' {
include ntpconfig
}

Step 2) Validate the syntax 

root@jump_host /etc/puppetlabs/code/environments/production/manifests# puppet parser validate apps.pp

Step 3) Run puppet agent -tv on app server 1, Server 2 and Server 3 and validate if ntp server is running.

[root@stapp01 ~]# puppet agent -tv
[root@stapp01 ~]# ps -ef | grep ntp
ntp        413     1  0 00:50 ?        00:00:00 /usr/sbin/ntpd -u ntp:ntp -g
root       416   164  0 00:50 pts/0    00:00:00 grep --color=auto ntp

[root@stapp02 ~]# puppet agent -tv
[root@stapp02 ~]# ps -ef | grep ntp
ntp        413     1  0 00:50 ?        00:00:00 /usr/sbin/ntpd -u ntp:ntp -g
root       416   164  0 00:50 pts/0    00:00:00 grep --color=auto ntp

[root@stapp03 ~]# puppet agent -tv
[root@stapp03 ~]# ps -ef | grep ntp
ntp        413     1  0 00:50 ?        00:00:00 /usr/sbin/ntpd -u ntp:ntp -g
root       416   164  0 00:50 pts/0    00:00:00 grep --color=auto ntp


Saturday 6 March 2021

Rolling Updates in Kunbernetes

 Task:

We have an application running on Kubernetes cluster using nginx web server. The Nautilus application development team has pushed some of the latest features to prod branch and those need be deployed. The Nautilus DevOps team has created an image nginx:1.18 with latest changes.

Perform a rolling update for this application and incorporate nginx:1.18 image. The deployment name is nginx-deployment

Make sure all pods are up and running after the update.
Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.

Step 1) Check if the deployment nginx-deployment is present

thor@jump_host ~$ kubectl get deployment 
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           8m19s

Step 2) Check if the pods are running

thor@jump_host ~$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-74fb588559-7447s   1/1     Running   0          8m37s
nginx-deployment-74fb588559-ch6mm   1/1     Running   0          8m37s
nginx-deployment-74fb588559-g9cm7   1/1     Running   0          8m37s

Step 3) Check what deployment version is running on the container

thor@jump_host ~$ kubectl get deployment -o wide
NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS        IMAGES       SELECTOR
nginx-deployment   3/3     3            3           8m56s   nginx-container   nginx:1.16   app=nginx-app

Step 4) Update the image version to nginx:1.18 from nginx:1.16

thor@jump_host ~$ kubectl set image deployment/nginx-deployment nginx-container=nginx:1.18 --record=true
deployment.apps/nginx-deployment image updated

Step 5)  Check the status of the pods and wait until they come back to running state

thor@jump_host ~$ kubectl get pods 
NAME                                READY   STATUS              RESTARTS   AGE
nginx-deployment-74fb588559-7447s   1/1     Running             0          14m
nginx-deployment-74fb588559-ch6mm   0/1     Terminating         0          14m
nginx-deployment-74fb588559-g9cm7   1/1     Running             0          14m
nginx-deployment-7b6877b9b5-6qcw6   0/1     ContainerCreating   0          2s
nginx-deployment-7b6877b9b5-l8v6c   1/1     Running             0          9s

thor@jump_host ~$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7b6877b9b5-6qcw6   1/1     Running   0          46s
nginx-deployment-7b6877b9b5-776br   1/1     Running   0          44s
nginx-deployment-7b6877b9b5-l8v6c   1/1     Running   0          53s

thor@jump_host ~$ kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE    IP           NODE     NOMINATED NODE   READINESS GATES
nginx-deployment-7b6877b9b5-6qcw6   1/1     Running   0          109s   10.244.1.7   node01   <none>           <none>
nginx-deployment-7b6877b9b5-776br   1/1     Running   0          107s   10.244.1.8   node01   <none>           <none>
nginx-deployment-7b6877b9b5-l8v6c   1/1     Running   0          116s   10.244.1.6   node01   <none>           <none>

Step 6) Check the rollout history 

thor@jump_host ~$ kubectl rollout history deployment 
deployment.apps/nginx-deployment 
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment/nginx-deployment nginx-container=nginx:1.18 --record=true

Step 7) Check the image version now

thor@jump_host ~$ kubectl get deployment -o wide
NAME               READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS        IMAGES       SELECTOR
nginx-deployment   3/3     3            3           16m   nginx-container   nginx:1.18   app=nginx-app





Friday 5 March 2021

GIT - Working with Remote repository GITHUB

Setup SSH Authentication with GITHUB Repository

Generate ssh keys on your linux machine

[osboxes@master ansible-playbooks]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/osboxes/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/osboxes/.ssh/id_rsa.
Your public key has been saved in /home/osboxes/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:iDSkhURVA9g/UILBIkV4mAdjdkr6QpF2iHFMhCPsrqk osboxes@linuxhost
The key's randomart image is:
+---[RSA 3072]----+
|*^%O*++          |
|/B%=o. .         |
|*Bo oo           |
|.o . oo.         |
|o . . ..S        |
| o               |
|..               |
|o                |
|E                |
+----[SHA256]-----+

[osboxes@master ansible-playbooks]$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHsN99astKP+jnHdSu6EtiY072Rllo4ILiZ4wwU5KISwjKVnUy9XGjVmMbFdQAJOczBRtw7AVmuo1vh5ieKa+BRvdJe1Sa7fZQVyHWqKxk+wkA1Mt6sSIkz3zzdte8hE9Ojmuqrqw3evjcwBywzf2Tz03JqSN2hhaXeQl8eK/DbO4y+NQXM2nOhVAGhpj1JWSCwXS9a1hWBF2OSHpJsmvcqVyDDWZvpjDoAwvJjd+n2XuZqyns/PVTy1WPq7AfWBigiGI8OTi/K97MKtDrSv0JgjX/aTVz5sirWxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxqIzrPkq+MfpKDMtORfjjbzIdwuRgngZLUtPDI1EywCy2gNhaWwoeG3CTQ/aR1OsMDs/74u/S5ECcQTYW7Vpb/slQhm8I+yvyfqUky7M9zuLMaMZyfRwdawrMExtU= osboxes@master

Create a new github account if you don't have one 

https://github.com

Go to Settings -> SSH and GPG keys -> SSH keys -> Click on New SSH Key

Copy the id_rsa.pub key from linux machine and paste it here 











Enter the following command on your Linux Machine

[osboxes@master ansible-playbooks]$ ssh -T git@github.com

The authenticity of host 'github.com (140.82.114.4)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com,140.82.114.4' (RSA) to the list of known hosts.
Hi pavanbandaru! You've successfully authenticated, but GitHub does not provide shell access.

Create a repository on your local system and commit the changes to local repository before pushing your code to GITHUB

[osboxes@master ansible-playbooks]$ git init
Initialized empty Git repository in /home/osboxes/ansible-playbooks/.git/
[osboxes@master ansible-playbooks]$ git add .
[osboxes@master ansible-playbooks]$ git commit -m "My First commit to ansible playbooks"
[master (root-commit) e8f579c] My First commit to ansible playbooks
 15 files changed, 236 insertions(+)
 create mode 100644 addusers.yml
 create mode 100644 apache-install.yml
 create mode 100644 create_dir.yml
 create mode 100644 dict.yml
 create mode 100644 install-packages.yml
 create mode 100644 install-packages_1.yml
 create mode 100644 inventory-loops.yml
 create mode 100644 inventory.txt
 create mode 100644 iterating-loops.yml
 create mode 100644 limit-output.yml
 create mode 100644 linux-user.yml
 create mode 100644 mynewplaybook
 create mode 100644 new_inventory.txt
 create mode 100644 password.txt
 create mode 100644 register.yml
[osboxes@master ansible-playbooks]$ git status
On branch master
nothing to commit, working tree clean

Create a new repository on GITHUB and click on Code -> SSH and copy the URL link.












Go to your Linux machine and execute the following commands

[osboxes@master ansible-playbooks]$ git remote add origin git@github.com:pavanbandaru/ansible-playbooks.git

[osboxes@master ansible-playbooks]$ git remote -v
origin  git@github.com:pavanbandaru/ansible-playbooks.git (fetch)
origin  git@github.com:pavanbandaru/ansible-playbooks.git (push)

[osboxes@master ansible-playbooks]$ git push -u origin master

Warning: Permanently added the RSA host key for IP address '140.82.112.4' to the list of known hosts.
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (17/17), 3.34 KiB | 285.00 KiB/s, done.
Total 17 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), done.
remote:
remote: Create a pull request for 'master' on GitHub by visiting:
remote:      https://github.com/pavanbandaru/ansible-playbooks/pull/new/master
remote:
To github.com:pavanbandaru/ansible-playbooks.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.


Go to GITHUB and verify the changes




Make some changes to our local repository and push the changes to remote repository
( I have made changes to inventory-loops.yml file and I am going to push these changes to remote repository)

Check the status

[osboxes@master ansible-playbooks]$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   inventory-loops.yml

no changes added to commit (use "git add" and/or "git commit -a")

Check the difference

[osboxes@master ansible-playbooks]$ git diff
diff --git a/inventory-loops.yml b/inventory-loops.yml
index dba93c1..d50904f 100644
--- a/inventory-loops.yml
+++ b/inventory-loops.yml
@@ -1,5 +1,5 @@
 ---
-- name:  looping over inventory
+- name:  looping over inventory example
   hosts: all
   become: true
   become_user: root

Add file and commit the changes

[osboxes@master ansible-playbooks]$ git commit -am "updated inventory-loops.yml"
[master 10207db] updated inventory-loops.yml
 1 file changed, 1 insertion(+), 1 deletion(-)

Pull the remote repository to local before pushing into remote as a best practice. Changes would have been made to the remote repository by others. So to avoid conflicts, pull the repository before pushing it to remote. 

[osboxes@master ansible-playbooks]$ git pull origin master
warning: Pulling without specifying how to reconcile divergent branches is
discouraged. You can squelch this message by running one of the following
commands sometime before your next pull:

  git config pull.rebase false  # merge (the default strategy)
  git config pull.rebase true   # rebase
  git config pull.ff only       # fast-forward only

You can replace "git config" with "git config --global" to set a default
preference for all repositories. You can also pass --rebase, --no-rebase,
or --ff-only on the command line to override the configured default per
invocation.

Warning: Permanently added the RSA host key for IP address '140.82.114.3' to the list of known hosts.
From github.com:pavanbandaru/ansible-playbooks
 * branch            master     -> FETCH_HEAD
Already up to date.

Now push the changes to remote repository

[osboxes@master ansible-playbooks]$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 314 bytes | 314.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:pavanbandaru/ansible-playbooks.git
   e8f579c..10207db  master -> master

We can see the changes on the remote repository





Install and configure GIT on Linux and working with local repository

Install git 

 [root@linuxhost ~]# yum install git -y

Step 2) Configure global configurations for any repository that we use in future.

[osboxes@linuxhost ~]$ git config --global user.name "Pavan Bandaru"
[osboxes@linuxhost ~]$ git config --global user.email "pavankumarbandaru@hotmail.com"
[osboxes@linuxhost ~]$ git config --global --list
user.name=Pavan Bandaru
user.email=pavankumarbandaru@hotmail.com

It created a config file under user home directory

[osboxes@linuxhost ~]$  cat ~/.gitconfig
[user]
        name = Pavan Bandaru
        email = pavankumarbandaru@hotmail.com

You can also check what Git thinks a specific key’s value is by typing git config <key>:

[osboxes@linuxhost ansible-playbooks]$ git config user.name
Pavan Bandaru
.
Create a projects directory

[osboxes@linuxhost ~]$ pwd
/home/osboxes
[osboxes@linuxhost ~]$ cd projects/
[osboxes@linuxhost projects]$ ls -rlt
total 0

Initialize a git repository

Create a new repository: By default Git will create a branch called master when you create a new repository with git init

[osboxes@linuxhost projects]$ git init sample-repo
Initialized empty Git repository in /home/osboxes/projects/sample-repo/.git/

[osboxes@linuxhost projects]$ ls -rlt
total 0
drwxrwxr-x. 3 osboxes osboxes 18 Mar  5 15:47 sample-repo

[osboxes@linuxhost projects]$ cd sample-repo/
[osboxes@linuxhost sample-repo]$ ls -rlt
total 0
[osboxes@linuxhost sample-repo]$ pwd
/home/osboxes/projects/sample-repo

[osboxes@linuxhost sample-repo]$ ls -lart
total 0
drwxrwxr-x. 3 osboxes osboxes  25 Mar  5 15:47 ..
drwxrwxr-x. 3 osboxes osboxes  18 Mar  5 15:47 .
drwxrwxr-x. 7 osboxes osboxes 119 Mar  5 15:47 .git
[osboxes@linuxhost sample-repo]$

Initialize git repository on existing project: I have an existing project ansible-playbooks and I wanted to create a repository with an existing project name. Run "git init" command under your project name directory.

/home/osboxes/projects/ansible-playbooks
[osboxes@linuxhost ansible-playbooks]$ ls -rlt
total 52
-rw-------. 1 osboxes osboxes    0 Feb 27 09:41 linux-user.yml.txt
-rw-------. 1 osboxes osboxes   10 Mar  3 15:59 password.txt
-rw-------. 1 osboxes osboxes  355 Mar  3 15:59 mynewplaybook
-rw-------. 1 osboxes osboxes 1197 Mar  3 15:59 linux-user.yml
-rw-------. 1 osboxes osboxes  259 Mar  3 15:59 install-packages.yml
-rw-------. 1 osboxes osboxes  491 Mar  3 15:59 create_dir.yml
-rw-------. 1 osboxes osboxes  654 Mar  3 15:59 apache-install.yml
-rw-------. 1 osboxes osboxes   14 Mar  3 15:59 inventory.txt
-rw-------. 1 osboxes osboxes  311 Mar  3 15:59 install-packages_1.yml
-rw-------. 1 osboxes osboxes  342 Mar  3 15:59 addusers.yml
-rw-------. 1 osboxes osboxes  295 Mar  3 16:19 dict.yml
-rw-------. 1 osboxes osboxes  716 Mar  3 19:39 register.yml
-rw-------. 1 osboxes osboxes  429 Mar  3 20:15 limit-output.yml
-rw-------. 1 osboxes osboxes  508 Mar  3 20:18 inventory-loops.yml

[osboxes@linuxhost ansible-playbooks]$ git init
Initialized empty Git repository in /home/osboxes/projects/ansible-playbooks/.git/


Check the status of your files (We are on the master branch and have not added any files)

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        addusers.yml
        apache-install.yml
        create_dir.yml
        dict.yml
        install-packages.yml
        install-packages_1.yml
        inventory-loops.yml
        inventory.txt
        limit-output.yml
        linux-user.yml
        linux-user.yml.txt
        mynewplaybook
        password.txt
        register.yml

nothing added to commit but untracked files present (use "git add" to track)

Add the file to the git repository and commit the changes.  ( Now we added a file addusers.yml file and did not commit the changes. git status will track the changes)

[osboxes@linuxhost ansible-playbooks]$ git add addusers.yml
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   addusers.yml

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        apache-install.yml
        create_dir.yml
        dict.yml
        install-packages.yml
        install-packages_1.yml
        inventory-loops.yml
        inventory.txt
        limit-output.yml
        linux-user.yml
        linux-user.yml.txt
        mynewplaybook
        password.txt
        register.yml

commit the changes

[osboxes@linuxhost ansible-playbooks]$ git commit -m "First commit"
[master (root-commit) 51a789e] First commit
 1 file changed, 15 insertions(+)
 create mode 100644 addusers.yml

Use git add *  or git add . incase if you want to add all the files

[osboxes@linuxhost ansible-playbooks]$ git add *
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   apache-install.yml
        new file:   create_dir.yml
        new file:   dict.yml
        new file:   install-packages.yml
        new file:   install-packages_1.yml
        new file:   inventory-loops.yml
        new file:   inventory.txt
        new file:   limit-output.yml
        new file:   linux-user.yml
        new file:   linux-user.yml.txt
        new file:   mynewplaybook
        new file:   password.txt
        new file:   register.yml

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .remote-sync.json

commit the changes 

[osboxes@linuxhost ansible-playbooks]$ git commit -m "Second commit - Added all the files"
[master 2debee7] Second commit - Added all the files
 13 files changed, 191 insertions(+)
 create mode 100644 apache-install.yml
 create mode 100644 create_dir.yml
 create mode 100644 dict.yml
 create mode 100644 install-packages.yml
 create mode 100644 install-packages_1.yml
 create mode 100644 inventory-loops.yml
 create mode 100644 inventory.txt
 create mode 100644 limit-output.yml
 create mode 100644 linux-user.yml
 create mode 100644 linux-user.yml.txt
 create mode 100644 mynewplaybook
 create mode 100644 password.txt
 create mode 100644 register.yml

Check the status now. There are no new file to commit.

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
nothing to commit, working tree clean

Modify an existing file and check the status ( I have modified a file addusers.yml )

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   addusers.yml

no changes added to commit (use "git add" and/or "git commit -a")

Now you have two options to add and commit the changes

1) git add adduser.yml 
     git commit -m "Second commit on addusers"
2) git commit -am "Second commit on addusers" ( -a is for adding, -m is for commit message )

I used option 2 for adding and commit  my changes

[osboxes@linuxhost ansible-playbooks]$ git commit -am "Second commit on addusers"
[master ea3b865] Second commit on addusers
 1 file changed, 1 insertion(+), 1 deletion(-)
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
nothing to commit, working tree clean

Now modify an existing file and create a new file and check the status

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   addusers.yml

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        dictionary.yml

no changes added to commit (use "git add" and/or "git commit -a")

Now add a file adduser.yml and don't add the new file and check the status ( Here one file addusers.yml is in staging area )

[osboxes@linuxhost ansible-playbooks]$ git add addusers.yml
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   addusers.yml

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        dictionary.yml

Add the second file and check the status ( Both the file are in  "to be commited" state which is staging area )

[osboxes@linuxhost ansible-playbooks]$ git add dictionary.yml
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   addusers.yml
        new file:   dictionary.yml

commit the change

[osboxes@linuxhost ansible-playbooks]$ git commit -m "Changes to adduser and added new file dictionar"
[master 34f1071] Changes to adduser and added new file dictionar
 2 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 dictionary.yml
[osboxes@linuxhost ansible-playbooks]$

Un stage the added file ( Now I have modified the file and added but I don't want to commit the changes rather I wanted to un stage the file from Staging area. Use git restore --staged <file> command to revert the change )

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   addusers.yml

no changes added to commit (use "git add" and/or "git commit -a")

[osboxes@linuxhost ansible-playbooks]$ git add addusers.yml
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   addusers.yml

Unstage the changes

[osboxes@linuxhost ansible-playbooks]$ git restore --staged addusers.yml

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   addusers.yml

no changes added to commit (use "git add" and/or "git commit -a")
[osboxes@linuxhost ansible-playbooks]$

Use the following command incase if you want to discard the changes in your working directory:
git restore <file>

[osboxes@linuxhost ansible-playbooks]$ git restore addusers.yml

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
nothing to commit, working tree clean

Display the history of commits are part of the current  repository. ( User git log command )

[osboxes@linuxhost ansible-playbooks]$ git log

commit 34f107160fd8ded3fd8a0e8edbd2088faa6570f6 (HEAD -> master)
Author: Pavan Bandaru <pavankumarbandaru@hotmail.com>
Date:   Fri Mar 5 16:51:49 2021 -0500

    Changes to adduser and added new file dictionar

commit ea3b86521585d7406d7d85e5448f9ea94dee3290
Author: Pavan Bandaru <pavankumarbandaru@hotmail.com>
Date:   Fri Mar 5 16:35:04 2021 -0500

    Second commit on addusers

commit 2debee75efcf276445cadbe2937e646c13166e6e
Author: Pavan Bandaru <pavankumarbandaru@hotmail.com>
Date:   Fri Mar 5 16:23:39 2021 -0500

    Second commit - Added all the files

commit 51a789e2399329a799245f90d63327f4a9b4715b
Author: Pavan Bandaru <pavankumarbandaru@hotmail.com>
Date:   Fri Mar 5 16:19:50 2021 -0500

    First commit


[osboxes@linuxhost ansible-playbooks]$ git log --oneline --graph --decorate --color
* 34f1071 (HEAD -> master) Changes to adduser and added new file dictionar
* ea3b865 Second commit on addusers
* 2debee7 Second commit - Added all the files
* 51a789e First commit

Revert already committed changes or remove files from git repository ( File has been deleted when we enter git rm <file> how ever the changes are is still in staging area. So commit the changes you have made )

[osboxes@linuxhost ansible-playbooks]$ git rm dictionary.yml
rm 'dictionary.yml'
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    dictionary.yml

[osboxes@linuxhost ansible-playbooks]$ git commit -m "remove the file dictionary"
[master 1dc84bb] remove the file dictionary
 1 file changed, 14 deletions(-)
 delete mode 100644 dictionary.yml
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
nothing to commit, working tree clean

Another way of removing the files using git add -u

[osboxes@linuxhost ansible-playbooks]$ rm dict.yml
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    dict.yml

no changes added to commit (use "git add" and/or "git commit -a")

osboxes@linuxhost ansible-playbooks]$ git add -u
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    dict.yml

[osboxes@linuxhost ansible-playbooks]$ git commit -m " remove file dict.yml "
[master dbdb1e4]  remove file dict.yml
 1 file changed, 14 deletions(-)
 delete mode 100644 dict.yml

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
nothing to commit, working tree clean

Moving files using git mv command

[osboxes@linuxhost ansible-playbooks]$ git mv addusers.yml new
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        renamed:    addusers.yml -> new/addusers.yml

[osboxes@linuxhost ansible-playbooks]$ git commit -m " addusers file moved to a different location "
[master 8f5dcd5]  addusers file moved to a different location
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename addusers.yml => new/addusers.yml (100%)
[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
nothing to commit, working tree clean
[osboxes@linuxhost ansible-playbooks]$

Ignoring Files

The rules for the patterns you can put in the .gitignore file are as follows:
  • Blank lines or lines starting with # are ignored.
  • Standard glob patterns work, and will be applied recursively throughout the entire working tree.
  • You can start patterns with a forward slash (/) to avoid recursivity.
  • You can end patterns with a forward slash (/) to specify a directory.
  • You can negate a pattern by starting it with an exclamation point (!).
Glob patterns are like simplified regular expressions that shells use. An asterisk (*) matches zero or more characters; [abc] matches any character inside the brackets (in this case a, b, or c); a question mark (?) matches a single character; and brackets enclosing characters separated by a hyphen ([0-9]) matches any character between them (in this case 0 through 9). You can also use two asterisks to match nested directories; a/**/z would match a/z, a/b/z, a/b/c/z, and so on.

Here is another example .gitignore file:
# ignore all .a files
*.a

# but do track lib.a, even though you're ignoring .a files above
!lib.a

# only ignore the TODO file in the current directory, not subdir/TODO
/TODO

# ignore all files in any directory named build
build/

# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt

# ignore all .pdf files in the doc/ directory and any of its subdirectories
doc/**/*.pdf

Example: I want to ignore files ending with .log

[osboxes@linuxhost ansible-playbooks]$ cat .gitignore
*.log

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore

nothing added to commit but untracked files present (use "git add" to track)

[osboxes@linuxhost ansible-playbooks]$ git add .gitignore

[osboxes@linuxhost ansible-playbooks]$ git commit -m "added gitignore file"
[master 8e582b3] added gitignore file
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore

Viewing Your Staged and Unstaged Changes using git diff command ( git status will not show you exactly what is changed. git diff --staged command compares your staged changes to your last commit )

[osboxes@linuxhost ansible-playbooks]$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   register-new.yml

[osboxes@linuxhost ansible-playbooks]$ git diff --staged
diff --git a/register-new.yml b/register-new.yml
index 96dea29..8986d05 100644
--- a/register-new.yml
+++ b/register-new.yml
@@ -1,6 +1,6 @@

 ---
-- name: Register loop variable results
+- name: Register loop example^M
   hosts: all
   become: true
   become_user: root

I have remove few lines of code in loop.yml in working directory. use git diff to see the changes in the file that are staged and the changes that are unstaged.

[osboxes@linuxhost ansible-playbooks]$ git diff
diff --git a/loops.yml b/loops.yml
index dba93c1..a628e21 100644
--- a/loops.yml
+++ b/loops.yml
@@ -13,8 +13,3 @@
       debug:
         msg: "{{ item }}"
       loop: "{{ ansible_play_batch }}"
-
-    - name: Show all the hosts in the inventory
-      debug:
-        msg: "{{ item }}"
-      loop: "{{ query('inventory_hostnames', 'all') }}"




Kubernetes

Kubernetes Tasks


Kubernetes Interview Questions




Deploy tomcat app on Kubernetes

Task: Deploy Tomcat App on Kubernetes 

Task Details

A new java-based application is ready to be deployed on a Kubernetes cluster. The development team had a meeting with the DevOps team share requirements and application scope. The team is ready to setup an application stack for it under their existing cluster. Below you can find the details for this:

Create a namespace named tomcat-namespace-nautilus.

Create a deployment for tomcat app which should be named tomcat-deployment-nautilus under the same namespace you created. Replicas count should be 1, the container should be named as tomcat-container-nautilus, its image should be gcr.io/kodekloud/centos-ssh-enabled:tomcat and its container port should be 8080.

Create a service for tomcat app which should be named as tomcat-service-nautilus under the same namespace you created. Service type should be NodePort. Port's protocol should be TCP, port should be 80, targetPort should be 8080 and nodePort should be 32227.

Before clicking on Finish button please make sure the application is up and running.

You can use any labels as per your choice.

Note: The kubectl on jump_host has been configured to work with the kubernetes cluster.


1. Run the following commands on the jump server to list namespaces and services

thor@jump_host /$ kubectl get namespace
NAME              STATUS   AGE
default           Active   12m
kube-node-lease   Active   12m
kube-public       Active   12m
kube-system       Active   12m

thor@jump_host /$ kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   12m

2. Create namespace as per the task request.

thor@jump_host /$ kubectl create namespace tomcat-namespace-nautilus
namespace/tomcat-namespace-nautilus created

thor@jump_host /$ kubectl get namespace
NAME                        STATUS   AGE
default                     Active   13m
kube-node-lease             Active   13m
kube-public                 Active   13m
kube-system                 Active   13m
tomcat-namespace-nautilus   Active   9s

3. Create deploy.yaml file using --dry-run command and modify later as per your requirements.

thor@jump_host ~$ kubectl create deploy tomcat-namespace-nautilus --image=gcr.io/kodekloud/centos-ssh-enabled:tomcat --dry-run=client -o yaml > deploy.yaml

deploy.yml file would look like below after modification

thor@jump_host ~$ vi deploy.yaml 
thor@jump_host ~$ cat deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment-nautilus
  namespace: tomcat-namespace-nautilus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat-deployment-nautilus
  template:
    metadata:
      labels:
        app: tomcat-deployment-nautilus
    spec:
      containers:
      - image: gcr.io/kodekloud/centos-ssh-enabled:tomcat
        name: tomcat-container-nautilus
        ports:
        - containerPort: 8080


Create a deployment 

thor@jump_host ~$ kubectl apply -f deploy.yaml
deployment.apps/tomcat-deployment-nautilus created

thor@jump_host ~$ kubectl get deploy --all-namespaces
NAMESPACE                   NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
kube-system                 coredns                      2/2     2            2           19m
tomcat-namespace-nautilus   tomcat-deployment-nautilus   1/1     1            1           106s

thor@jump_host ~$ kubectl get pods --all-namespaces
NAMESPACE                   NAME                                          READY   STATUS    RESTARTS   AGE
kube-system                 coredns-f9fd979d6-4t9x6                       1/1     Running   0          19m
kube-system                 coredns-f9fd979d6-pwfp2                       1/1     Running   0          19m
kube-system                 etcd-controlplane                             1/1     Running   0          19m
kube-system                 kube-apiserver-controlplane                   1/1     Running   0          19m
kube-system                 kube-controller-manager-controlplane          1/1     Running   0          19m
kube-system                 kube-flannel-ds-amd64-hx7nz                   1/1     Running   0          19m
kube-system                 kube-flannel-ds-amd64-rb26q                   1/1     Running   0          19m
kube-system                 kube-proxy-4qwmv                              1/1     Running   0          19m
kube-system                 kube-proxy-dc7zt                              1/1     Running   0          19m
kube-system                 kube-scheduler-controlplane                   1/1     Running   0          19m
tomcat-namespace-nautilus   tomcat-deployment-nautilus-59c4c6c6bd-657pd   1/1     Running   0          2m17s

4. Create service.yaml file using --dry-run command and modify file service.yaml as per your requirements.

thor@jump_host ~$ kubectl expose deploy tomcat-deployment-nautilus --namespace=tomcat-namespace-nautilus --name=tomcat-service-nautilus --type=NodePort --port=80 --target-port=8080 --dry-run=client -o yaml > service.yaml

service.yaml file would look like below after modification

thor@jump_host ~$ vi service.yaml 
thor@jump_host ~$ cat service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: tomcat-service-nautilus
  namespace: tomcat-namespace-nautilus
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 32227
  selector:
    app: tomcat-deployment-nautilus
  type: NodePort

Create a service

thor@jump_host ~$ kubectl apply -f service.yaml
service/tomcat-service-nautilus unchanged

thor@jump_host ~$ kubectl get service --all-namespaces
NAMESPACE                   NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
default                     kubernetes                ClusterIP   10.96.0.1        <none>        443/TCP                  29m
kube-system                 kube-dns                  ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   29m
tomcat-namespace-nautilus   tomcat-service-nautilus   NodePort    10.100.134.191   <none>        80:32227/TCP             46s

Validations:

thor@jump_host ~$ kubectl get no -o wide
NAME           STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
controlplane   Ready    master   30m   v1.19.0   172.17.0.11   <none>        Ubuntu 18.04.5 LTS   4.15.0-122-generic   docker://19.3.13
node01         Ready    <none>   29m   v1.19.0   172.17.0.14   <none>        Ubuntu 18.04.5 LTS   4.15.0-122-generic   docker://19.3.13

thor@jump_host ~$ curl 172.17.0.14:32227
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
    <head>
        <title>SampleWebApp</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <h2>Welcome to xFusionCorp Industries!</h2>
        <br>
    
    </body>
</html>