<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DevOps, auteur/autrice sur dbi Blog</title>
	<atom:link href="https://www.dbi-services.com/blog/author/devops/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.dbi-services.com/blog/author/devops/</link>
	<description></description>
	<lastBuildDate>Tue, 09 Jul 2024 08:22:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/05/cropped-favicon_512x512px-min-32x32.png</url>
	<title>DevOps, auteur/autrice sur dbi Blog</title>
	<link>https://www.dbi-services.com/blog/author/devops/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Ansible loops: A guide from basic to advanced examples</title>
		<link>https://www.dbi-services.com/blog/ansible-loops-a-guide-from-basic-to-advanced-examples/</link>
					<comments>https://www.dbi-services.com/blog/ansible-loops-a-guide-from-basic-to-advanced-examples/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 09 Jul 2024 08:22:30 +0000</pubDate>
				<category><![CDATA[Ansible]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[devops]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=33446</guid>

					<description><![CDATA[<p>If you are writing roles with Ansible, you must already have thought about implementing a loop, a loop of loops with Ansible, and wonder how. The ability to execute tasks in loops is primordial. This guide will provide multiple loop examples in Ansible, starting with a basic loop and progressing to more advanced scenarios. Basic [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/ansible-loops-a-guide-from-basic-to-advanced-examples/">Ansible loops: A guide from basic to advanced examples</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">If you are writing roles with Ansible, you must already have thought about implementing a loop, a loop of loops with Ansible, and wonder how. The ability to execute tasks in loops is primordial. This guide will provide multiple loop examples in Ansible, starting with a basic loop and progressing to more advanced scenarios.</p>



<h2 class="wp-block-heading" id="h-basic-loop">Basic loop</h2>



<p class="wp-block-paragraph">Let&#8217;s start with the most basic loop as an introduction. </p>



<p class="wp-block-paragraph">In the following playbook, called playbook.yml, a list of numbers is created, from 1 to 5. Then a loop on the debug task displays each number.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# playbook.yml
- name: Loop examples
  hosts: localhost
  connection: local
  gather_facts: False
  tasks:
  - set_fact:
      numbers: &#x5B;1,2,3,4,5]
  
  - name: Most basic loop
    debug:
      msg: &#039;{{ item }}&#039;
    loop: &#039;{{ numbers }}&#039;
</pre></div>


<p class="wp-block-paragraph">You can test it by running the command &#8220;ansible-playbook playbook.yml&#8221;.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ ansible-playbook playbook.yml 

PLAY &#x5B;Use vars from dbservers] ****************************************************************************************************************************************************************

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;Most basic loop] ************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; (item=1) =&gt; {
    &quot;msg&quot;: 1
}
ok: &#x5B;localhost] =&gt; (item=2) =&gt; {
    &quot;msg&quot;: 2
}
ok: &#x5B;localhost] =&gt; (item=3) =&gt; {
    &quot;msg&quot;: 3
}
ok: &#x5B;localhost] =&gt; (item=4) =&gt; {
    &quot;msg&quot;: 4
}
ok: &#x5B;localhost] =&gt; (item=5) =&gt; {
    &quot;msg&quot;: 5
}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
</pre></div>


<h2 class="wp-block-heading" id="h-loop-of-loops">Loop of loops</h2>



<p class="wp-block-paragraph">In most use cases, you want to loop multiple tasks sequentially. The first thought is to use a block statement, but a block doesn&#8217;t accept a loop. The solution is to use &#8220;ansible.builtin.include_tasks&#8221; and loop on the task file.</p>



<p class="wp-block-paragraph">The usage of loop_control is recommended to rename the loop_var name and not use &#8220;item&#8221;. See below the example with the &#8220;playbook.yml&#8221; and &#8220;loop.yml&#8221; files.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# playbook.yml
- name: Loop examples
  hosts: localhost
  connection: local
  gather_facts: False
  tasks:
  - set_fact:
      numbers: &#x5B;1,2,3,4,5]

  - name: loop multiple tasks with include_task
    ansible.builtin.include_tasks:
      file: loop.yml
    loop: &#039;{{ numbers }}&#039;
    loop_control:
      loop_var: number
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# loop.yml
- debug:
    msg: &#039;First task of loop.yml&#039;

- debug:
    var: number
</pre></div>


<p class="wp-block-paragraph">The results of running the playbook should be as below.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ ansible-playbook playbook.yml

PLAY &#x5B;Loop examples] **************************************************************************************************************************************************************************

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;loop multiple tasks with include_task] **************************************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/loop.yml for localhost =&gt; (item=1)
included: /Users/kke/dbi/blog/ansible_loop/loop.yml for localhost =&gt; (item=2)
included: /Users/kke/dbi/blog/ansible_loop/loop.yml for localhost =&gt; (item=3)
included: /Users/kke/dbi/blog/ansible_loop/loop.yml for localhost =&gt; (item=4)
included: /Users/kke/dbi/blog/ansible_loop/loop.yml for localhost =&gt; (item=5)

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;First task of loop.yml&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 1
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;First task of loop.yml&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 2
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;First task of loop.yml&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 3
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;First task of loop.yml&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 4
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;First task of loop.yml&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 5
}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=16   changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
</pre></div>


<h2 class="wp-block-heading" id="h-conditional-on-include-tasks">Conditional on include_tasks</h2>



<p class="wp-block-paragraph">Adding a condition on the include_tasks is only evaluated once. It means that if the condition is True, it will iterate until the end even though the condition might become False, which is the intended result of the condition of include_tasks. See the following example.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# playbook.yml
- name: Loop examples
  hosts: localhost
  connection: local
  gather_facts: False
  tasks:

  - set_fact:
      numbers: &#x5B;1,2,3,4,5]

  - set_fact: 
      continue_task: true

  - when: continue_task == true
    name: When on include task only (evaluted at the beginning)
    ansible.builtin.include_tasks:
      file: condition.yml
    loop: &#039;{{ numbers }}&#039;
    loop_control:
      loop_var: number
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# condition.yml
- debug:
    var: number

- when: number &gt;= 3
  set_fact:
    continue_task: false

- debug:
    msg: &#039;current number: {{ number }}. Condition.yml running on number &lt; 3&#039;
</pre></div>


<p class="wp-block-paragraph">Results of the running playbook.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ ansible-playbook playbook.yml

PLAY &#x5B;Loop examples] **************************************************************************************************************************************************************************

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;When on include task only (evaluted at the beginning)] **********************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=1)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=2)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=3)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=4)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=5)

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 1
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 1. Condition.yml running on number &lt; 3&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 2
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 2. Condition.yml running on number &lt; 3&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 3
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 3. Condition.yml running on number &lt; 3&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 4
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 4. Condition.yml running on number &lt; 3&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 5
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 5. Condition.yml running on number &lt; 3&quot;
}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=20   changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
</pre></div>


<p class="wp-block-paragraph">If you want the condition to apply on every task, you can either add the statement &#8220;when&#8221; on every task in &#8220;condition.yml&#8221;, or you can use the statement &#8220;apply&#8221; on &#8220;ansible.builtin.include_tasks&#8221;. Choose the solution that suits the best for the role or tasks you are writing.</p>



<p class="wp-block-paragraph">The below example will use the statement &#8220;apply&#8221;.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# playbook.yml

- name: Loop examples
  hosts: localhost
  connection: local
  gather_facts: False
  tasks:

  - set_fact:
      numbers: &#x5B;1,2,3,4,5]

  - set_fact: 
      continue_task: true

  - name: When applied on all tasks included (evaluated each time)
    ansible.builtin.include_tasks:
      file: condition.yml
      apply:  
        when: continue_task == true
    loop: &#039;{{ numbers }}&#039;
    loop_control:
      loop_var: number
</pre></div>


<p class="wp-block-paragraph">Output of the playbook. The results should print the number until &#8220;3&#8221; but not the second debug message  &#8220;current number 3. Condition.yml running on number &lt; 3&#8221;. </p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ ansible-playbook playbook.yml

PLAY &#x5B;Loop examples] **************************************************************************************************************************************************************************

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;When applied on all tasks included (evalued each time)] *********************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=1)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=2)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=3)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=4)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=5)

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 1
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 1. Condition.yml running on number &lt; 3&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 2
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 2. Condition.yml running on number &lt; 3&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 3
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=13   changed=0    unreachable=0    failed=0    skipped=9    rescued=0    ignored=0   
</pre></div>


<h2 class="wp-block-heading" id="h-advanced-loop-do-tasks-until-succeed-or-fail-at-xth-attempt">Advanced loop: do tasks until succeed, or fail at Xth attempt</h2>



<p class="wp-block-paragraph">In this last example, I want to make a loop of tasks. The problem is that multiple tasks may fail for multiple reasons (network, unavailability of external services, awaiting process from external services, etc.). Therefore I want to retry the task at least 5th times, before exiting the playbook run. </p>



<p class="wp-block-paragraph">The example will include a commented task, to provide a more concrete real use case example. The real example is the following. Fetch the ID of an item from an external service, use this ID to fetch its status to the external service, and only proceed if the item status is completed (successful, completed) or fail the task if it returns a failure state. The task may fail on the fetch of ID (due to network issues or unavailability of the external service) and on the status fetching if it is still ongoing, which will result in retrying the whole task. Note that it is not completely optimized to make it simpler to understand and read (for example we could ignore the fetching of ID if it was already gotten in a previous iteration).</p>



<p class="wp-block-paragraph">For the simplicity of the setup, a simple condition on &#8220;number&#8221; is used instead, to showcase the retry of tasks and failure of the play. It causes the playbook&#8217;s execution to fail if the number is above 3.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# playbook.yml

- name: Loop examples
  hosts: localhost
  connection: local
  gather_facts: False
  tasks:

  - set_fact:
      numbers: &#x5B;1,2,3,4,5]

  - set_fact: 
      continue_task: true


  - name: Example of a complex loop. Loop on number, do function(number) until suceed, or fail at the fifth attempt
    ansible.builtin.include_tasks:
      file: function.yml
    loop: &#039;{{ numbers }}&#039;
    loop_control:
      loop_var: number
  
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# function.yml
- block:
    - when: init_count | default(true)
      ansible.builtin.set_fact:
        retry_count: 0

    - debug:
        msg: &#039;Current number is {{ number }}, and current retry count is {{ retry_count }}&#039;

    # Do an action, use the result to do another action or checks (for example a wget, curl, or another request to get an ID)
    # For the simplicity of the example, I simply do an echo
    - name: API - get ID
      ansible.builtin.shell: &#039;echo {{ number }}&#039;
      register: _api_result

    # Use the result from the precedent task
    - name: Use the ID to check another API if process is succesful 
      ## An exemple of a use case, using the id
      # ansible.builtin.uri:
      #   url: &#039;https://example.com/status?id={{ _api_result.stdout }}&#039;
      #   method: GET
      #   status_code: 200
      # register: _check_status
      # until:
      #   - _check_status.json is defined
      #   - _check_status.json.status in &#x5B;&quot;SUCCESSFUL&quot;, &quot;COMPLETED&quot;, &quot;FAILURE&quot;]
      # failed_when: _check_status.json is not defined or _check_status.json.status in &#x5B;&quot;FAILURE&quot;]
      # delay: &#039;5&#039;
      # retries: &#039;3&#039;

      ## For the simplicity, I just used a failed_when on debug
      debug:
        msg: &#039;Testing that api result is a &gt; 3&#039;
      failed_when: _api_result.stdout|int &gt; 3

  rescue:
    - when: _check_status.json is defined and _check_status.json.status in &#x5B;&quot;FAILURE&quot;]
      name: Fail if process return Failure
      ansible.builtin.fail:
        msg: status failure

    - name: Fail Task in case of total failure after a certain amount of retry
      ansible.builtin.fail:
        msg: &quot;5 retries attempted, failed perform desired result&quot;
      when: retry_count | int &gt;= 5 

    # Pause the playbook if necessary.
    # - ansible.builtin.pause:
    #     seconds: &#039;5&#039;

    - name: Increment Retry Count
      ansible.builtin.set_fact:
        retry_count: &quot;{{ retry_count | int + 1 }}&quot;

    # Retry the function.yml and indicate to increment the counter.
    - name: Retry function
      ansible.builtin.include_tasks: function.yml
      vars:
        init_count: false
</pre></div>


<p class="wp-block-paragraph">Result of the execution.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ ansible-playbook playbook.yml

PLAY &#x5B;Loop examples] **************************************************************************************************************************************************************************

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;When applied on all tasks included (evalued each time)] *********************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=1)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=2)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=3)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=4)
included: /Users/kke/dbi/blog/ansible_loop/condition.yml for localhost =&gt; (item=5)

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 1
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 1. Condition.yml running on number &lt; 3&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 2
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;current number: 2. Condition.yml running on number &lt; 3&quot;
}

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;number&quot;: 3
}

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
skipping: &#x5B;localhost]

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=13   changed=0    unreachable=0    failed=0    skipped=9    rescued=0    ignored=0   

kke@DBI-LT-KKE ansible_loop % ansible-playbook playbook.yml

PLAY &#x5B;Loop examples] **************************************************************************************************************************************************************************

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;set_fact] *******************************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;Example of a complex loop. Loop on number, do function(number) until suceed, or fail at the fifth attempt] ******************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost =&gt; (item=1)
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost =&gt; (item=2)
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost =&gt; (item=3)
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost =&gt; (item=4)
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost =&gt; (item=5)

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 1, and current retry count is 0&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 2, and current retry count is 0&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 3, and current retry count is 0&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 4, and current retry count is 0&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
fatal: &#x5B;localhost]: FAILED! =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;Fail if process return Failure] *********************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Fail Task in case of total failure after a certain amount of retry] *********************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Increment Retry Count] ******************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;Retry function] *************************************************************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 4, and current retry count is 1&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
fatal: &#x5B;localhost]: FAILED! =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;Fail if process return Failure] *********************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Fail Task in case of total failure after a certain amount of retry] *********************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Increment Retry Count] ******************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;Retry function] *************************************************************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 4, and current retry count is 2&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
fatal: &#x5B;localhost]: FAILED! =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;Fail if process return Failure] *********************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Fail Task in case of total failure after a certain amount of retry] *********************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Increment Retry Count] ******************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;Retry function] *************************************************************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 4, and current retry count is 3&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
fatal: &#x5B;localhost]: FAILED! =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;Fail if process return Failure] *********************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Fail Task in case of total failure after a certain amount of retry] *********************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Increment Retry Count] ******************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;Retry function] *************************************************************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 4, and current retry count is 4&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
fatal: &#x5B;localhost]: FAILED! =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;Fail if process return Failure] *********************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Fail Task in case of total failure after a certain amount of retry] *********************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Increment Retry Count] ******************************************************************************************************************************************************************
ok: &#x5B;localhost]

TASK &#x5B;Retry function] *************************************************************************************************************************************************************************
included: /Users/kke/dbi/blog/ansible_loop/function.yml for localhost

TASK &#x5B;ansible.builtin.set_fact] ***************************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;debug] **********************************************************************************************************************************************************************************
ok: &#x5B;localhost] =&gt; {
    &quot;msg&quot;: &quot;Current number is 4, and current retry count is 5&quot;
}

TASK &#x5B;API - get ID] ***************************************************************************************************************************************************************************
changed: &#x5B;localhost]

TASK &#x5B;Use the ID to check another API if process is succesful] ********************************************************************************************************************************
fatal: &#x5B;localhost]: FAILED! =&gt; {
    &quot;msg&quot;: &quot;Testing that api result is a &gt; 3&quot;
}

TASK &#x5B;Fail if process return Failure] *********************************************************************************************************************************************************
skipping: &#x5B;localhost]

TASK &#x5B;Fail Task in case of total failure after a certain amount of retry] *********************************************************************************************************************
fatal: &#x5B;localhost]: FAILED! =&gt; {&quot;changed&quot;: false, &quot;msg&quot;: &quot;5 retries attempted, failed perform desired result&quot;}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=42   changed=9    unreachable=0    failed=1    skipped=16   rescued=6    ignored=0   

</pre></div>


<h2 class="wp-block-heading" id="h-conclusion">Conclusion</h2>



<p class="wp-block-paragraph">Loop is a necessity in IT, the base for automation. At first, it might be disorientating with Ansible, but it becomes quite easy to understand and use with a little practice. The <a href="https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html">official documentation</a> provided by Ansible also covers a lot and explains well the concept of loop, it will be your best friend in your journey to master Ansible.</p>



<h2 class="wp-block-heading" id="h-links">Links</h2>



<p class="wp-block-paragraph">Ansible &#8211; <a href="https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html">Official documentation</a><br>Blog &#8211; <a href="https://www.dbi-services.com/blog/faster-ansible/">Faster Ansible</a><br>Blog &#8211; <a href="https://www.dbi-services.com/blog/ansible-automates-event-driven-lightspeed/">Ansible Automates – Event Driven &amp; Lightspeed</a><br>Blog &#8211; <a href="https://www.dbi-services.com/blog/specify-hosts-in-ansible-playbook-command-line/">Specify hosts in ansible-playbook command line</a><br>Blog &#8211; <a href="https://www.dbi-services.com/blog/ansible-event-driven-automation/">Ansible Event Driven Automation</a><br>Blog &#8211; <a href="https://www.dbi-services.com/blog/create-and-manage-ansible-execution-environments/">Create and manage Ansible Execution Environments</a></p>
<p>L’article <a href="https://www.dbi-services.com/blog/ansible-loops-a-guide-from-basic-to-advanced-examples/">Ansible loops: A guide from basic to advanced examples</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/ansible-loops-a-guide-from-basic-to-advanced-examples/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>My first day at SUSECON 2024</title>
		<link>https://www.dbi-services.com/blog/my-first-day-at-susecon-2024/</link>
					<comments>https://www.dbi-services.com/blog/my-first-day-at-susecon-2024/#comments</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 18 Jun 2024 06:00:00 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Operating systems]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[neuvector]]></category>
		<category><![CDATA[Rancher]]></category>
		<category><![CDATA[SuSE]]></category>
		<category><![CDATA[SUSECON2024]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=33690</guid>

					<description><![CDATA[<p>It is mid-June, and I have the opportunity with my colleague Arnaud Berbier to go to Berlin. Not for visiting the city, not for sightseeing, but for a business conference. This year, SUSECON set its location in the German capital, and as a partner, it was a kind of must for dbi services to be [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/my-first-day-at-susecon-2024/">My first day at SUSECON 2024</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">It is mid-June, and I have the opportunity with my colleague <a href="https://www.dbi-services.com/blog/author/arnaud-berbier/">Arnaud Berbier</a> to go to Berlin. Not for visiting the city, not for sightseeing, but for a business conference. This year, <a href="https://www.suse.com/susecon/">SUSECON</a> set its location in the German capital, and as a partner, it was a kind of must for dbi services to be next to SUSE.</p>



<p class="wp-block-paragraph">SUSECON, the annual global conference organized by SUSE, is a convention for IT professionals like us to explore the latest developments in open-source software and SUSE technologies. This event features keynotes, technical sessions, and hands-on labs, providing a platform for learning, networking, and collaboration.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="576" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_094031706-1024x576.jpg" alt="" class="wp-image-33692" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_094031706-1024x576.jpg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_094031706-300x169.jpg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_094031706-768x432.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_094031706-1536x864.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_094031706-2048x1152.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Just the time to arrive in front of the Estrel building, we were warmly welcomed by <a href="https://www.linkedin.com/in/nicolamberti/">Nico Lamberti</a>, Partner Executive ALPS at SUSE. A quick photo, and we headed inside the building. Then we met <a href="https://www.linkedin.com/in/opensourceexpert/">Emiel Brok</a>. A quick chat, and he already pointed the mic to me, and we started a short interview. I&#8217;m quite shy (so I won&#8217;t put any link to it .. sorry Emiel <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ) and not used to such an improvised kind of speaking, but I knew I had to push through my hesitation for this important event!</p>



<p class="wp-block-paragraph">The registration desk then, and all was well organized. Step by step, we registered, changed to the following desk to get our badge, and another desk to get our swag bag. Finally, we were fully prepared for the event.</p>



<p class="wp-block-paragraph">The partner summit was going to happen at 2 p.m. So we had time to attend a session.</p>



<h2 class="wp-block-heading" id="h-how-you-can-contribute-to-high-quality-documentation"><strong>&#8220;How YOU can contribute to high-quality documentation&#8221;</strong> </h2>



<p class="wp-block-paragraph">This was the <a href="https://www.suse.com/susecon/sessions/?search=meike#/session/1707840537525001Llv9">first session I attended</a>. Led by <a href="https://www.linkedin.com/in/meike-chabowski-52948b1/">Meike Chabowski</a>, I was interested in how SUSE was driving their documentation. Which kind of technology, which kind of organization,</p>



<p class="wp-block-paragraph">She highlighted first the goal of documentation (at least at SUSE): to produce and deliver high quality documentation. What for? To provide added value, to drive custom, partner, and community (yes, open-source philosophy is there). And then she enumerated first the different sort of documentation at SUSE:</p>



<ul class="wp-block-list">
<li>Release notes, for a brief description of new technologies and features,</li>



<li>Technical Reference Documentation, to describe and explain design, setup and configuration of SUSE products,</li>



<li>SUSE Best Practices, practical, issue-focused, and solution-focused documentation,</li>



<li>Product documentation, aka Technical documentation for all products,</li>



<li>Topic based article.</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="576" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_105416704.MP_-1024x576.jpg" alt="" class="wp-image-33691" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_105416704.MP_-1024x576.jpg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_105416704.MP_-300x169.jpg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_105416704.MP_-768x432.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_105416704.MP_-1536x864.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_105416704.MP_-2048x1152.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">I was really curious how SUSE manage their documentation. At dbi services, in the DevOps team, and even for personal documentation or notes based system, we use Markdown.</p>



<p class="wp-block-paragraph">At SUSE, they use <a href="https://docbook.org/">DocBookXML</a> and <a href="https://asciidoc.org/">AsciiDoc</a>. While the first is a derivative of XML for documentation purpose, I see the second as very close to <a href="https://www.markdownguide.org/">Markdown</a> at first glance. They use XSLT stylesheets for defining the layout.</p>



<p class="wp-block-paragraph">In term of infrastructure, documentation requests are managed through Jira or Bugzilla, and everything is versioned in git.</p>



<p class="wp-block-paragraph">What I liked is how she highlighted contribution. We evolve in an open-source environment, and contributing is one key aspect. Working on the documentation is one way to contribute, and it&#8217;s a great way to give back to the community. This can be done quite easily. You can either report an issue in the SUSE Best Practices or Technical Reference Documentation, or propose your change to the Product documentation. Once reviewed, and maybe approved, your changes will be included.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="576" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_110825250.MP_-1024x576.jpg" alt="" class="wp-image-33693" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_110825250.MP_-1024x576.jpg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_110825250.MP_-300x169.jpg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_110825250.MP_-768x432.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_110825250.MP_-1536x864.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_110825250.MP_-2048x1152.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-exploring-the-technology-showcase">Exploring the Technology showcase</h2>



<p class="wp-block-paragraph">In between sessions and talks, I spent time in the technology showcase, which was a hub of activity. Booths from various exhibitors showcased cutting-edge technologies, solutions, and products. I had the chance to speak with some exhibitors, had for instance a great detailed description of what is Confidential Computing (encryption EVERYWHERE, even the memory is encrypted on the fly!). This place was also a good opportunity to meet people, whether you knew them or not.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="576" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_100323924-1024x576.jpg" alt="" class="wp-image-33694" style="width:840px;height:auto" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_100323924-1024x576.jpg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_100323924-300x169.jpg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_100323924-768x432.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_100323924-1536x864.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_100323924-2048x1152.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">This morning.</figcaption></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_170454238-1024x576.jpg" alt="" class="wp-image-33695" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_170454238-1024x576.jpg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_170454238-300x169.jpg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_170454238-768x432.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_170454238-1536x864.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/06/PXL_20240617_170454238-2048x1152.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Tonight <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></figcaption></figure>
<p>L’article <a href="https://www.dbi-services.com/blog/my-first-day-at-susecon-2024/">My first day at SUSECON 2024</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/my-first-day-at-susecon-2024/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Investigative look into cloud-native hyper-converged infrastructure with Harvester (2)</title>
		<link>https://www.dbi-services.com/blog/investigative-look-into-cloud-native-hyper-converged-infrastructure-with-harvester-2/</link>
					<comments>https://www.dbi-services.com/blog/investigative-look-into-cloud-native-hyper-converged-infrastructure-with-harvester-2/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Thu, 30 May 2024 06:01:04 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[OMrun]]></category>
		<category><![CDATA[harvesterhci]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[kubevirt]]></category>
		<category><![CDATA[longhorn]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[scheduling]]></category>
		<category><![CDATA[SDN]]></category>
		<category><![CDATA[SuSE]]></category>
		<category><![CDATA[virtualization]]></category>
		<category><![CDATA[windows server 2022]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=32913</guid>

					<description><![CDATA[<p>In this second blog, we will see how we can deploy a Microsoft Windows Server 2022 virtual machine on Harvester, and play a little bit with scheduling.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/investigative-look-into-cloud-native-hyper-converged-infrastructure-with-harvester-2/">Investigative look into cloud-native hyper-converged infrastructure with Harvester (2)</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the previous <a href="https://www.dbi-services.com/blog/cloud-native-hyper-converged-infrastructure-with-harvester/">episode</a>, we took a look together at an overview of <a href="https://harvesterhci.io/">Harvester</a>. We looked at its components and explored the concepts behind Harvester, its cloud-native architecture, and the installation process. Now, let&#8217;s delve deeper into the main purpose of it: scheduling your workload. Let&#8217;s start!</p>



<p class="wp-block-paragraph">Note: we expanded the Harvester cluster to three nodes. I would like to play with a bit of scheduling, so let&#8217;s add two worker nodes.</p>



<h2 class="wp-block-heading" id="h-virtual-machine-provisioning">Virtual machine provisioning</h2>



<p class="wp-block-paragraph">Practical experience is the most effective method to grasp a concept, process, or product. I suggest that we proceed in the same manner.</p>



<p class="wp-block-paragraph">As part of a larger consolidation and modernization project, imagine we just received the request to integrate a Microsoft Windows Server 2022 application into our new infrastructure. If you ever wonder how to control the quality of your data, there is, at dbi services, <a href="https://www.dbi-services.com/products/omrun/">OMrun</a>. OMrun is a Windows based application that includes test steps, scenarios, and of course, data adaptors. Let&#8217;s take this application as a workload example. </p>



<p class="wp-block-paragraph">We are not going to automate anything here, as exploring the application is the main focus, so expect provisioning the virtual machine in a wizard based manner.</p>



<p class="wp-block-paragraph">Log into Harvester web interface by entering the IP mentioned in the console of your node. Take the cluster URL, not the node&#8217;s IP.</p>



<p class="wp-block-paragraph">In order to provision and run a Windows based application, you need first to add the ISO file of the operating system. I&#8217;ve already downloaded the file (using the following <a href="https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2022" target="_blank" rel="noreferrer noopener">URL</a> on the Microsoft web site).</p>



<p class="wp-block-paragraph">For this, left-hand menu, select Images and then Create.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="614" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085238-1024x614.png" alt="" class="wp-image-33067" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085238-1024x614.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085238-300x180.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085238-768x460.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085238-1536x921.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085238.png 1900w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Upload the file and select Create.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="614" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085410-1024x614.png" alt="" class="wp-image-33068" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085410-1024x614.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085410-300x180.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085410-768x460.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085410-1536x921.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085410.png 1900w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="76" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085518-1024x76.png" alt="" class="wp-image-33069" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085518-1024x76.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085518-300x22.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085518-768x57.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085518-1536x113.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_085518.png 1613w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Once uploaded, any virtual machine using the infrastructure can use the file as of right now.</p>



<p class="wp-block-paragraph">It is now time to create the VM. On the left-hand side, select &#8220;Virtual Machines&#8221;. You&#8217;ll be presented with a set of fields and options. First of all, as we are dealing here with a Windows-based VM, tick the box &#8220;Use VM Template:&#8221; and select the option &#8220;harvester-public/windows-iso-image-base-template&#8221;. As stated by SUSE in their <a target="_blank" rel="noreferrer noopener" href="https://docs.harvesterhci.io/v1.3/vm/create-windows-vm#header-section">documention</a>, it is used to add a volume, a disk so, where all the necessary optimised drivers will be stored, so you can refer to that when installing the operating system. If you already used KVM for virtualization, you are on familiar ground. We are talking about paravirtualized <a target="_blank" rel="noreferrer noopener" href="https://www.linux-kvm.org/page/Virtio">VirtIO</a> drivers.</p>



<p class="wp-block-paragraph">We start to see some Kubernetes references: a namespace is required in order to group the corresponding Kubernetes objects. Reminder: The Kubernetes backend will be in charge of managing your VM. For that, a new set of CRDs (CustomResourceDefinition) were added to handle that.</p>



<p class="wp-block-paragraph">For instance, here is the definition of a VM: <a target="_blank" rel="noreferrer noopener" href="https://kubevirt.io/api-reference/main/definitions.html#_v1_virtualmachineinstance">VirtualMachineInstance</a>.<br>We create a new namespace; let&#8217;s call it omrun. We also set the name, as well as a short description. Based on your application requirements, specify the CPU and memory resources.</p>



<p class="wp-block-paragraph">Here, I&#8217;m not going to implement a production ready instance of OMrun, so I won&#8217;t be greedy on that: 4 CPUs and 8GB of memory.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="371" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_161727-1024x371.png" alt="" class="wp-image-33070" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_161727-1024x371.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_161727-300x109.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_161727-768x278.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_161727-1536x556.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_161727.png 1632w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Move on to the storage. By selecting the &#8220;Volumes&#8221; item, we will be able to setup all disks and virtual CD-ROM. Since we use a VM template, we can see that Harvester already provisioned for us some storage devices:</p>



<ul class="wp-block-list">
<li>a cdrom-disk: obviously used for acting as virtual CD-ROM drive,</li>



<li>Root disk: the main disk drive of your VM</li>



<li>virtio-container-disk: an ephemeral type of storage, used when you don&#8217;t want any kind of persistence of data. For instance, read-only data, configuration files, or binaries, this is used here for the VirtIO drivers.</li>
</ul>



<p class="wp-block-paragraph">The next item is &#8220;Networks&#8221;. This part deserved its own blog; for ease of comprehension, we are going to leave this as default.</p>



<h2 class="wp-block-heading" id="h-a-scheduling-strategy">A scheduling strategy?</h2>



<p class="wp-block-paragraph">The following two options are showing, for sure, the connection with Kubernetes. The first one, &#8220;Node Scheduling&#8221; is there to specify the scheduling strategy of the VM across the cluster. Either on any available node, specific named nodes, or Kubernetes labels assigned to nodes. We would like to preferably run the VM only on nodes with the label omrun set to true.</p>



<p class="wp-block-paragraph">First, we label the node:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv01:~ $ kubectl label nodes harv02 omrun=true 
node/harv02 labeled
</pre></div>


<p class="wp-block-paragraph">Then, on Harvester interface, your inputs shoud look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="319" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_171927-1024x319.png" alt="" class="wp-image-33071" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_171927-1024x319.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_171927-300x93.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_171927-768x239.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_171927-1536x478.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240508_171927.png 1604w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The next item is still related to scheduling, &#8220;VM Scheduling&#8221;. This time, you can specify, for instance, if your workload needs to run on the same node as already existing workloads (for an increase in performance, perhaps ?) or the opposite: you want to ensure that your workload is properly separated from other specific ones.</p>



<p class="wp-block-paragraph">All this is managed using the same kind of affinity / anti-affinity concepts, dear to Kubernetes.</p>



<p class="wp-block-paragraph">If you want to know more about that, jump <a target="_blank" rel="noreferrer noopener" href="https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity">here</a>.</p>



<p class="wp-block-paragraph">In the following configuration items, in Advanced Options, you&#8217;ll be ask to set the behavior of the scheduler, Kubernetes then, on the run strategy of your virtual machine. What would need to happen in case your VM crashed for instance. What should happen if you manually stop your VM. No need to carbon copying the <a target="_blank" rel="noreferrer noopener" href="https://docs.harvesterhci.io/v1.2/vm/index/#run-strategy">SUSE Harvester documentation</a>.</p>



<p class="wp-block-paragraph">By the way, this is reminds me the restart policy in the <a target="_blank" rel="noreferrer noopener" href="https://docs.docker.com/config/containers/start-containers-automatically/">Docker</a> run command, we just discovered less than a decade ago <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Once done, you can go forward, and click on the Create button at the bottom right corner.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="304" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145325-1024x304.png" alt="" class="wp-image-33347" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145325-1024x304.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145325-300x89.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145325-768x228.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145325-1536x456.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145325.png 1823w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The spin up of the VM takes a bit of time. Especially on my home lab I&#8217;m currently using <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">But wait.. We are running a Kubernetes cluster here.. Why not going directly on it and trying to see what&#8217;s going on? Using our lovely kubectl ?</p>



<p class="wp-block-paragraph">Well, again it&#8217;s quite easy and straight forward. You remember the namespace we created initially ? I&#8217;m logged on my Harvester cluster, in SSH.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv01:~ $ kubectl get vm -n omrun
NAME             AGE   STATUS     READY
omrun-instance   19d   Starting   False
harv01:~ $ kubectl get vmi -n omrun
NAME             AGE   PHASE       IP    NODENAME  
omrun-instance   17s   Scheduled         harv02             
</pre></div>


<p class="wp-block-paragraph">The virtual machine is currently being started. The VirtualMachine object has status Starting, the VirtualMachineInstance got the Scheduled status.</p>



<p class="wp-block-paragraph">State of your VM is reflected directly across Kubernetes objects.</p>



<p class="wp-block-paragraph">We can add the usual -o yaml flag, as we do for pods:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv01:~ $ kubectl get vm -n omrun -o wide -o yaml
apiVersion: v1
items:
- apiVersion: kubevirt.io/v1
 kind: VirtualMachine
 metadata:
   annotations:
     field.cattle.io/description: An OMrun instance running on Harvester
     harvesterhci.io/reservedMemory: 256Mi
...
        architecture: amd64
        domain:
          cpu:
            cores: 1
          devices:
            disks:
            - bootOrder: 1
              cdrom:
                bus: sata
              name: cdrom-disk
            - bootOrder: 2
              disk:
                bus: virtio
              name: rootdisk
...
</pre></div>


<p class="wp-block-paragraph">All the configuration you&#8217;ve made in the UI, is there!</p>



<p class="wp-block-paragraph">The virtual machine is running now, and as specified, on the second node. The time now is to install the operating system and then, the application. And for that, as we are dealing with a Windows-based virtual machine, it&#8217;s more than ssh-ing into a Linux box.</p>



<p class="wp-block-paragraph">The first try is to use what is proposed by Harvester. Based on my experience with a previous cluster I&#8217;ve build with a KubeVirt stack on it, connecting to it on Harvester is a dream. In your list of virtual machines, select the &#8220;console&#8221; button, and then &#8220;Open in WebVNC&#8221;.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="874" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145508-1024x874.png" alt="" class="wp-image-33342" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145508-1024x874.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145508-300x256.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145508-768x655.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145508.png 1124w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Then, what is following is nothing else but a standard Microsoft Windows Server 2022 installation. The only point of attention here would be to select the paravirtualized <a target="_blank" rel="noreferrer noopener" href="https://www.linux-kvm.org/page/Virtio">VirtIO</a> drivers.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="874" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145637-1024x874.png" alt="" class="wp-image-33343" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145637-1024x874.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145637-300x256.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145637-768x655.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240509_145637.png 1124w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">With the power of this blog and some magic, I will fast-forward the installation of OMRun and show you the running application.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="662" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_175142-1024x662.png" alt="" class="wp-image-33344" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_175142-1024x662.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_175142-300x194.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_175142-768x497.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_175142-1536x993.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_175142-2048x1324.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Strangely, I didn&#8217;t manage to get the RDP protocol available. This is probably due to the network settings I&#8217;ve left default at the creation. Something to look for in the next part of this blog series.</p>



<p class="wp-block-paragraph">I haven&#8217;t installed the dashboard of OMRun for now, which is accessible from the client through a web browser.</p>



<h2 class="wp-block-heading" id="h-the-power-of-scheduling">The power of scheduling <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a5.png" alt="💥" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<p class="wp-block-paragraph">What if we mess around with this part? What if we simulate a downtime from one of the nodes in our cluster?</p>



<p class="wp-block-paragraph">Sadly, this unexpected, unfortunate event could occur on the node that runs, specifically, our Windows Server instance. How will Harvester, KubeVirt, and Kubernetes react?</p>



<p class="wp-block-paragraph">We can first assign the label omrun=true to our first node.</p>



<p class="wp-block-paragraph">Then, we simply power off our second node, with the VM running (naughty, I know). And we watch <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">First, the second node is set unavailable, cordoned using Kubernetes terms.</p>



<figure class="wp-block-image"><img decoding="async" src="https://storage.googleapis.com/co-writer/images/V7ReIW1mhVXsmYQvV7PN1wdHdXf2/-1717007772823.webp" alt="IMAGE" /></figure>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv01:~ $ kubectl get nodes
NAME     STATUS     ROLES                       AGE   VERSION
harv01   Ready      control-plane,etcd,master   21d   v1.27.10+rke2r1
harv02   NotReady   &lt;none&gt;                      21d   v1.27.10+rke2r1
harv03   Ready      &lt;none&gt;                      21d   v1.27.10+rke2r1
</pre></div>


<p class="wp-block-paragraph">At the same time, the virtual machine is set as not ready, but still, scheduled on harv02. On the Kubernetes side, the same.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv01:~ $ kubectl get vm -n omrun  
NAME             AGE   STATUS    READY  
omrun-instance   20d   Running   False  
harv01:~ $ kubectl get vmi -n omrun  
NAME             AGE     PHASE     IP            NODENAME   READY  
omrun-instance   6m32s   Running   10.52.1.122   harv02     False
</pre></div>


<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="111" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_183546-1024x111.png" alt="" class="wp-image-33341" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_183546-1024x111.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_183546-300x32.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_183546-768x83.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_183546-1536x166.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_183546.png 1580w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Let&#8217;s wait for the timeouts do their jobs and wait a bit.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv01:~ $ kubectl get vm -n omrun
NAME             AGE   STATUS    READY
omrun-instance   20d   Running   True
harv01:~ $ kubectl get vmi -n omrun
NAME             AGE   PHASE     IP           NODENAME   READY
omrun-instance   24m   Running   10.52.0.84   harv01     True
</pre></div>


<p class="wp-block-paragraph">Harvester, Kubernetes and KubeVirt in the background, have rescheduled the virtual machine to the next node that fits the constraint we asked for (label omrun=true) which was the harv01 (the master node was not the best idea I had).</p>



<p class="wp-block-paragraph">Thanks to the replication on the storage backend, Longhorn had replicas for each PersistentVolumes created (defaulted to 3). That means we didn&#8217;t lose any data when the second node failed.</p>



<p class="wp-block-paragraph">We can try to start the VNC console. And voila!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="630" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_205043-1024x630.png" alt="" class="wp-image-33340" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_205043-1024x630.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_205043-300x184.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_205043-768x472.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_205043-1536x944.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/05/Screenshot_20240529_205043-2048x1259.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Our virtual machine is running, OMrun is still able to start.</p>



<p class="wp-block-paragraph">I will for sure continue my exploration of Harvester, and probably, this time, explore the networking aspects of it!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/investigative-look-into-cloud-native-hyper-converged-infrastructure-with-harvester-2/">Investigative look into cloud-native hyper-converged infrastructure with Harvester (2)</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/investigative-look-into-cloud-native-hyper-converged-infrastructure-with-harvester-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Detect XZ Utils CVE 2024-3094 with Tetragon</title>
		<link>https://www.dbi-services.com/blog/detect-xz-utils-cve-2024-3094-with-tetragon/</link>
					<comments>https://www.dbi-services.com/blog/detect-xz-utils-cve-2024-3094-with-tetragon/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Wed, 24 Apr 2024 07:21:23 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[tetragon]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=32762</guid>

					<description><![CDATA[<p>How to use Tetragon to detect XZ Utils backdoor CVE 2024-3094 before it was known. Apply the Zero Trust security strategy.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/detect-xz-utils-cve-2024-3094-with-tetragon/">Detect XZ Utils CVE 2024-3094 with Tetragon</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">The recent discovery of the XZ Utils backdoor, classified as CVE 2024-3094, has been now well documented. Detecting it with <a href="https://isovalent.com/projects/tetragon/" target="_blank" rel="noreferrer noopener">Tetragon</a> from Isovalent (now part of Cisco) has been explained in this <a href="https://isovalent.com/blog/post/ebpf-tetragon-xz-utils-cve-policy/?utm_content=288397416&amp;utm_medium=social&amp;utm_source=linkedin&amp;hss_channel=lcp-34714411" target="_blank" rel="noreferrer noopener">blog post</a>. I also did some research and experimented with this vulnerability. I wondered how we could leverage Tetragon capabilities to detect it before it was known. There are other vulnerabilities out there, so we need to be prepared for the unknown. For this we have to apply a security strategy called Zero Trust. I wrote <a href="https://www.dbi-services.com/blog/enhance-containers-security-prevent-encrypted-data-exfiltration-with-neuvector/" target="_blank" rel="noreferrer noopener">another blog post</a> on this topic with another example and another tool if you want to have a look. Let&#8217;s build an environment on which we can experiment and learn more about it. Follow along!</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Evil_Fawkes1.jpeg" alt="How to use Tetragon to detect " class="wp-image-32798" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Evil_Fawkes1.jpeg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Evil_Fawkes1-300x300.jpeg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Evil_Fawkes1-150x150.jpeg 150w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Evil_Fawkes1-768x768.jpeg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-setup-an-environment-for-cve-2024-3094">Setup an environment for CVE 2024-3094</h2>



<p class="wp-block-paragraph">We have learned that this vulnerability needs an x86 architecture to be exploited and that it targets several Linux distribution (source <a href="https://jfrog.com/blog/xz-backdoor-attack-cve-2024-3094-all-you-need-to-know/" target="_blank" rel="noreferrer noopener">here</a>). I&#8217;ve used an Ubuntu 22.04 virtual machine in Azure to setup the environment. To exploit this vulnerability, we&#8217;re going to use the GitHub resource <a href="https://github.com/amlweems/xzbot" target="_blank" rel="noreferrer noopener">here</a>.</p>



<p class="wp-block-paragraph">This vulnerability is related to the library <strong>liblzma.so</strong> used by the ssh daemon so let&#8217;s switch to the root user and install openssh-server along with other packages we will use later:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
azureuser@Ubuntu22:~$ sudo -i

root@Ubuntu22:~# apt-get update &amp;&amp; apt-get install -y golang-go curl openssh-server net-tools python3-pip wget vim git file bsdmainutils jq
</pre></div>


<p class="wp-block-paragraph">Let&#8217;s use ssh key authentication (as this is how the vulnerable library can be exploited), start the ssh daemon and see which version of the library it uses:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [16]; title: ; notranslate">
root@Ubuntu22:~# which sshd
/usr/sbin/sshd
root@Ubuntu22:~# sed -E -i &#039;s/^#?PasswordAuthentication .*/PasswordAuthentication no/&#039; /etc/ssh/sshd_config

root@Ubuntu22:~# service ssh status
 * sshd is not running
root@Ubuntu22:~# service ssh start
 * Starting OpenBSD Secure Shell server sshd
root@Ubuntu22:~# service ssh status
 * sshd is running

root@Ubuntu22:~# ldd /usr/sbin/sshd|grep liblzma
	liblzma.so.5 =&gt; /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007ae3aac37000)

root@Ubuntu22:~# file /lib/x86_64-linux-gnu/liblzma.so.5
/lib/x86_64-linux-gnu/liblzma.so.5: symbolic link to liblzma.so.5.2.5
</pre></div>


<p class="wp-block-paragraph">Here it uses version 5.2.5, sometimes it uses version 5.4.5 from the tests I did on other distributions. The vulnerable versions are 5.6.0 and 5.6.1. So by default our machine is not vulnerable. To make it so, we need to upgrade this library to one of these vulnerable versions as shown below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [6]; title: ; notranslate">
root@Ubuntu22:~# wget https://snapshot.debian.org/archive/debian/20240328T025657Z/pool/main/x/xz-utils/liblzma5_5.6.1-1_amd64.deb

root@Ubuntu22:~# apt-get install --allow-downgrades --yes ./liblzma5_5.6.1-1_amd64.deb

root@Ubuntu22:~# file /lib/x86_64-linux-gnu/liblzma.so.5
/lib/x86_64-linux-gnu/liblzma.so.5: symbolic link to liblzma.so.5.6.1
</pre></div>


<p class="wp-block-paragraph">We are now using the vulnerable library in version 5.6.1. Next we can use the files and xzbot tool from the GitHub project as shown below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@Ubuntu22:~# git clone https://github.com/amlweems/xzbot.git
root@Ubuntu22:~# cd xzbot/
</pre></div>


<p class="wp-block-paragraph">To be able to exploit this vulnerability we can&#8217;t just use the vulnerable library. In fact the backdoor uses a hardcoded ED448 public key for signature and we don&#8217;t have the associated private key. To be able to trigger that backdoor, the author of the tool xzbot replaced them with their own key pair they&#8217;ve generated. We then need to replace the vulnerable library with the patched one using these keys as follows:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@Ubuntu22:~# cp ./assets/liblzma.so.5.6.1.patch /lib/x86_64-linux-gnu/liblzma.so.5.6.1
</pre></div>


<p class="wp-block-paragraph">Now everything is ready to exploit this vulnerability with the xzbot tool. We just need to compile it with the go package we installed at the beginning:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@Ubuntu22:~# go build

root@Ubuntu22:~# ./xzbot -h
Usage of ./xzbot:
  -addr string
    	ssh server address (default &quot;127.0.0.1:2222&quot;)
  -cmd string
    	command to run via system() (default &quot;id &gt; /tmp/.xz&quot;)
  -seed string
    	ed448 seed, must match xz backdoor key (default &quot;0&quot;)
</pre></div>


<h2 class="wp-block-heading" id="h-detecting-the-backdoor-with-tetragon">Detecting the backdoor with Tetragon</h2>



<p class="wp-block-paragraph">Let&#8217;s see now how we could use Tetragon to detect something by applying a Zero Trust strategy. At this stage we consider we don&#8217;t know anything about this vulnerability and we are using Tetragon as a security tool for our environment. Here we don&#8217;t use Kubernetes, we just have a Ubuntu 22.04 host but we can still use Tetragon by running it into a docker container.</p>



<p class="wp-block-paragraph">We install docker in our machine by following the instructions described <a href="https://docs.docker.com/engine/install/ubuntu/" target="_blank" rel="noreferrer noopener">here</a>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@Ubuntu22:~# sudo apt-get install ca-certificates curl
root@Ubuntu22:~# sudo install -m 0755 -d /etc/apt/keyrings
root@Ubuntu22:~# sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
root@Ubuntu22:~# sudo chmod a+r /etc/apt/keyrings/docker.asc

root@Ubuntu22:~# echo \
  &quot;deb &#x5B;arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release &amp;&amp; echo &quot;$VERSION_CODENAME&quot;) stable&quot; | \
  sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null
root@Ubuntu22:~# sudo apt-get update

root@Ubuntu22:~# sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
</pre></div>


<p class="wp-block-paragraph">Then we install Tetragon in a docker container by following the instructions <a href="https://tetragon.io/docs/installation/container/" target="_blank" rel="noreferrer noopener">here</a>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@Ubuntu22:~# docker run --name tetragon --rm -d \
    --pid=host --cgroupns=host --privileged \
    -v /sys/kernel:/sys/kernel \
    quay.io/cilium/tetragon:v1.0.3 \
    /usr/bin/tetragon --export-filename /var/log/tetragon/tetragon.log
</pre></div>


<h3 class="wp-block-heading" id="h-tetragon-backdoor-detection">Tetragon &#8211; Backdoor detection</h3>



<p class="wp-block-paragraph">Now everything is ready and we can trigger the backdoor and see what Tetragon can observe. We open a new shell by using the azureuser. We jump into the Tetragon container and monitor the log file for anything related to ssh as shown below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
azureuser@Ubuntu22:~$ sudo docker exec -it 76dc8c268caa bash
76dc8c268caa:/# tail -f /var/log/tetragon/tetragon.log | grep ssh
</pre></div>


<p class="wp-block-paragraph">In another shell (the one with the root user), we can start the exploit by using the xzbot tool. We execute the command <strong>sleep 60</strong> so we can observe in real time what is happening:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@Ubuntu22:~/xzbot# ./xzbot -addr 127.0.0.1:22 -cmd &quot;sleep 60&quot;
</pre></div>


<p class="wp-block-paragraph">This is an example of a malicious actor connecting through the backdoor to get a shell on our compromised Ubuntu machine. Below is what we can see in our Tetragon shell (the output has been copied and pasted for being parsed with jq to provide a better reading and we&#8217;ve kept only the process execution event):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
{
  &quot;process_exec&quot;: {
    &quot;process&quot;: {
      &quot;exec_id&quot;: &quot;OjIwNjAyNjc1NDE0MTU2OjE1NDY0MA==&quot;,
      &quot;pid&quot;: 154640,
      &quot;uid&quot;: 0,
      &quot;cwd&quot;: &quot;/&quot;,
      &quot;binary&quot;: &quot;/usr/sbin/sshd&quot;,
      &quot;arguments&quot;: &quot;-D -R&quot;,
      &quot;flags&quot;: &quot;execve rootcwd clone&quot;,
      &quot;start_time&quot;: &quot;2024-04-23T12:03:08.447280556Z&quot;,
      &quot;auid&quot;: 4294967295,
      &quot;parent_exec_id&quot;: &quot;OjE0MTYwMDAwMDAwOjc0Mg==&quot;,
      &quot;tid&quot;: 154640
    },
    &quot;parent&quot;: {
      &quot;exec_id&quot;: &quot;OjE0MTYwMDAwMDAwOjc0Mg==&quot;,
      &quot;pid&quot;: 742,
      &quot;uid&quot;: 0,
      &quot;cwd&quot;: &quot;/&quot;,
      &quot;binary&quot;: &quot;/usr/sbin/sshd&quot;,
      &quot;flags&quot;: &quot;procFS auid rootcwd&quot;,
      &quot;start_time&quot;: &quot;2024-04-23T06:19:59.931865800Z&quot;,
      &quot;auid&quot;: 4294967295,
      &quot;parent_exec_id&quot;: &quot;OjM4MDAwMDAwMDox&quot;,
      &quot;tid&quot;: 742
    }
  },
  &quot;time&quot;: &quot;2024-04-23T12:03:08.447279856Z&quot;
}
...
{
  &quot;process_exec&quot;: {
    &quot;process&quot;: {
      &quot;exec_id&quot;: &quot;OjIwNjAyOTk4NzY3ODU0OjE1NDY0Mg==&quot;,
      &quot;pid&quot;: 154642,
      &quot;uid&quot;: 0,
      &quot;cwd&quot;: &quot;/&quot;,
      &quot;binary&quot;: &quot;/bin/sh&quot;,
      &quot;arguments&quot;: &quot;-c \&quot;sleep 60\&quot;&quot;,
      &quot;flags&quot;: &quot;execve rootcwd clone&quot;,
      &quot;start_time&quot;: &quot;2024-04-23T12:03:08.770634054Z&quot;,
      &quot;auid&quot;: 4294967295,
      &quot;parent_exec_id&quot;: &quot;OjIwNjAyNjc1NDE0MTU2OjE1NDY0MA==&quot;,
      &quot;tid&quot;: 154642
    },
    &quot;parent&quot;: {
      &quot;exec_id&quot;: &quot;OjIwNjAyNjc1NDE0MTU2OjE1NDY0MA==&quot;,
      &quot;pid&quot;: 154640,
      &quot;uid&quot;: 0,
      &quot;cwd&quot;: &quot;/&quot;,
      &quot;binary&quot;: &quot;/usr/sbin/sshd&quot;,
      &quot;arguments&quot;: &quot;-D -R&quot;,
      &quot;flags&quot;: &quot;execve rootcwd clone&quot;,
      &quot;start_time&quot;: &quot;2024-04-23T12:03:08.447280556Z&quot;,
      &quot;auid&quot;: 4294967295,
      &quot;parent_exec_id&quot;: &quot;OjE0MTYwMDAwMDAwOjc0Mg==&quot;,
      &quot;tid&quot;: 154640
    }
  },
  &quot;time&quot;: &quot;2024-04-23T12:03:08.770633854Z&quot;
}
</pre></div>


<p class="wp-block-paragraph">Here we have all the interesting information about the process as well as the link to its parent process. With Tetragon Entreprise we could have a graphical view of these linked processes. As we are using the Community Edition, we can use the <strong>ps</strong> command instead here to get a more graphical view as shown below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [3,5]; title: ; notranslate">
azureuser@Ubuntu22:~$ ps -ef --forest
root         742       1  0 06:19 ?        00:00:00 sshd: /usr/sbin/sshd -D &#x5B;listener] 1 of 10-100 startups
root      154640     742  2 12:03 ?        00:00:00  \_ sshd: root &#x5B;priv]
sshd      154641  154640  0 12:03 ?        00:00:00      \_ sshd: root &#x5B;net]
root      154642  154640  0 12:03 ?        00:00:00      \_ sh -c sleep 60
root      154643  154642  0 12:03 ?        00:00:00          \_ sleep 60
</pre></div>


<p class="wp-block-paragraph">The 2 processes highlighted above are those related to the Tetragon output. Let&#8217;s now see what Tetragon displays in case of a normal ssh connection.</p>



<h3 class="wp-block-heading" id="h-tetragon-normal-ssh-connection">Tetragon &#8211; Normal ssh connection</h3>



<p class="wp-block-paragraph">We first need to setup a pair of keys for the root user (to better compare it with the output above):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@Ubuntu22:~# ssh-keygen

root@Ubuntu22:~# cat ~/.ssh/id_rsa.pub &gt; ~/.ssh/authorized_keys

root@Ubuntu22:~# ssh root@127.0.0.1
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 6.5.0-1017-azure x86_64)
</pre></div>


<p class="wp-block-paragraph">For the key generation we use the default folder with no passphase. We see we can connect with the root user to the localhost by using the generated keys. We can then use the same method as above to launch Tetragon and the ps command to capture this ssh connection. Here is what we can see with Tetragon:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
{
  &quot;process_exec&quot;: {
    &quot;process&quot;: {
      &quot;exec_id&quot;: &quot;OjU1ODY3OTQ0NTI0ODY6NDc1MDE=&quot;,
      &quot;pid&quot;: 47501,
      &quot;uid&quot;: 0,
      &quot;cwd&quot;: &quot;/&quot;,
      &quot;binary&quot;: &quot;/usr/sbin/sshd&quot;,
      &quot;arguments&quot;: &quot;-D -R&quot;,
      &quot;flags&quot;: &quot;execve rootcwd clone&quot;,
      &quot;start_time&quot;: &quot;2024-04-23T07:52:52.566318686Z&quot;,
      &quot;auid&quot;: 4294967295,
      &quot;parent_exec_id&quot;: &quot;OjE0MTYwMDAwMDAwOjc0Mg==&quot;,
      &quot;tid&quot;: 47501
    },
    &quot;parent&quot;: {
      &quot;exec_id&quot;: &quot;OjE0MTYwMDAwMDAwOjc0Mg==&quot;,
      &quot;pid&quot;: 742,
      &quot;uid&quot;: 0,
      &quot;cwd&quot;: &quot;/&quot;,
      &quot;binary&quot;: &quot;/usr/sbin/sshd&quot;,
      &quot;flags&quot;: &quot;procFS auid rootcwd&quot;,
      &quot;start_time&quot;: &quot;2024-04-23T06:19:59.931865800Z&quot;,
      &quot;auid&quot;: 4294967295,
      &quot;parent_exec_id&quot;: &quot;OjM4MDAwMDAwMDox&quot;,
      &quot;tid&quot;: 742
    }
  },
  &quot;time&quot;: &quot;2024-04-23T07:52:52.566318386Z&quot;
}

{
  &quot;process_exec&quot;: {
    &quot;process&quot;: {
      &quot;exec_id&quot;: &quot;OjU1ODgxMzk5MjM5NjA6NDc2MDQ=&quot;,
      &quot;pid&quot;: 47604,
      &quot;uid&quot;: 0,
      &quot;cwd&quot;: &quot;/root&quot;,
      &quot;binary&quot;: &quot;/bin/bash&quot;,
      &quot;flags&quot;: &quot;execve clone&quot;,
      &quot;start_time&quot;: &quot;2024-04-23T07:52:53.911790360Z&quot;,
      &quot;auid&quot;: 0,
      &quot;parent_exec_id&quot;: &quot;OjU1ODY3OTQ0NTI0ODY6NDc1MDE=&quot;,
      &quot;tid&quot;: 47604
    },
    &quot;parent&quot;: {
      &quot;exec_id&quot;: &quot;OjU1ODY3OTQ0NTI0ODY6NDc1MDE=&quot;,
      &quot;pid&quot;: 47501,
      &quot;uid&quot;: 0,
      &quot;cwd&quot;: &quot;/&quot;,
      &quot;binary&quot;: &quot;/usr/sbin/sshd&quot;,
      &quot;arguments&quot;: &quot;-D -R&quot;,
      &quot;flags&quot;: &quot;execve rootcwd clone&quot;,
      &quot;start_time&quot;: &quot;2024-04-23T07:52:52.566318686Z&quot;,
      &quot;auid&quot;: 4294967295,
      &quot;parent_exec_id&quot;: &quot;OjE0MTYwMDAwMDAwOjc0Mg==&quot;,
      &quot;tid&quot;: 47501
    }
  },
  &quot;time&quot;: &quot;2024-04-23T07:52:53.911789660Z&quot;
}
</pre></div>


<p class="wp-block-paragraph">And the output of the corresponding ps command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [3,4]; title: ; notranslate">
azureuser@Ubuntu22:~$ ps -ef --forest
root         742       1  0 06:19 ?        00:00:00 sshd: /usr/sbin/sshd -D &#x5B;listener] 0 of 10-100 startups
root       45501     742 10 07:49 ?        00:00:00  \_ sshd: root@pts/1
root       47604   45501  0 07:49 pts/1    00:00:00      \_ -bash
</pre></div>


<p class="wp-block-paragraph">You can see there is a difference but it is not easy to spot! In the normal connection it launches a <strong>bash</strong> under sshd and through the backdoor it is running a command with <strong>sh</strong> instead.</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">We have seen how we can leverage Tetragon to observe anything happening on this machine. Even for unknown threats, you get some information but you have to know first how your system is working in very details. You need to have a baseline for each running process on your machine to be able to detect any deviation. That is what we call the Zero Trust strategy and it is the only way to detect such stealthy backdoor.</p>



<p class="wp-block-paragraph">It may seem tenuous and it is, however that is how Andres Freund discovered it when he noticed ssh was several milliseconds slower than it should. The famous adage says that the devil is in the detail, this backdoor discovery proves that this is especially true when it comes to security.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/detect-xz-utils-cve-2024-3094-with-tetragon/">Detect XZ Utils CVE 2024-3094 with Tetragon</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/detect-xz-utils-cve-2024-3094-with-tetragon/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Investigative look into cloud-native hyper-converged infrastructure with Harvester</title>
		<link>https://www.dbi-services.com/blog/cloud-native-hyper-converged-infrastructure-with-harvester/</link>
					<comments>https://www.dbi-services.com/blog/cloud-native-hyper-converged-infrastructure-with-harvester/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Fri, 19 Apr 2024 06:42:19 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[harvesterhci]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[kubevirt]]></category>
		<category><![CDATA[longhorn]]></category>
		<category><![CDATA[SDN]]></category>
		<category><![CDATA[SuSE]]></category>
		<category><![CDATA[virtualization]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=31651</guid>

					<description><![CDATA[<p>In this first blog, we will have a look on what is Harvester, cloud native hyper-converged infrastructure, it's concepts and the installation.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/cloud-native-hyper-converged-infrastructure-with-harvester/">Investigative look into cloud-native hyper-converged infrastructure with Harvester</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In mid-February, I had the pleasure of attending with <a href="https://www.suse.com/" target="_blank" rel="noreferrer noopener">SUSE</a>, the <a href="https://scsd.ch/de/conference_talks/328" target="_blank" rel="noreferrer noopener">Swiss Cyber Security Days</a>. This two-day event was taking place in Bern, and I gave a 20-minute session on <a href="https://harvesterhci.io/" target="_blank" rel="noreferrer noopener">Harvester</a>. Even if I think this was well received, in 20 minutes, you can&#8217;t go through every single feature of a product. And I planned it more as a global overview than a deep dive.</p>



<p class="wp-block-paragraph">This time, I decided to conduct a deeper exploration of Harvester.</p>



<h2 class="wp-block-heading" id="h-hci-harvester-what-is-this-all-about">HCI, Harvester, what is this all about?</h2>



<p class="wp-block-paragraph">Nowadays, most of our applications run virtualized. From development environments to huge production clusters, virtual machines are everywhere. And to provide better scalability and flexibility, IT infrastructures evolved from traditional legacy datacenters to hyper-converged infrastructures.</p>



<p class="wp-block-paragraph">What is hyper-converged infrastructure, so? An HCI is a software-defined, fully integrated system that combines compute, storage, networking, and virtualization resources into a single platform. Those are big boxes that concentrate everything here in one place. You define your workload, you setup your storage, and you design your network all by yourself.</p>



<p class="wp-block-paragraph">Harvester is an open-source HCI solution that provides cloud-native technologies for managing and orchestrating virtual machines, along with storage and networks. The best is yet to come. Harvester, under the hood, is based on famous and well-known cloud-native technologies. We will discover that while playing with this platform.</p>



<p class="wp-block-paragraph">Nevertheless, let&#8217;s not waste time talking about the theory. Let&#8217;s get to work!</p>



<h2 class="wp-block-heading" id="h-installing-harvester">Installing Harvester</h2>



<p class="wp-block-paragraph">Let&#8217;s start with the installation of Harvester. It&#8217;s, in fact, a pretty straight forward process.</p>



<p class="wp-block-paragraph">ISO is provided and available on GitHub, the <a target="_blank" rel="noreferrer noopener" href="https://github.com/harvester/harvester/releases/tag/v1.3.0">version</a> 1.3.0 is the latest stable version as of this writing. Paying attention to the GitHub release page, there are regularly new versions or updates, like RCs. You can try those, but, well, it is release candidates <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">SUSE and the corresponding <a href="https://docs.harvesterhci.io/v1.3/install/requirements" target="_blank" rel="noreferrer noopener">web page</a> are pretty clear on the hardware requirements.</p>



<p class="wp-block-paragraph">Remember, here we are dealing with a critical piece of software that is going to handle all of your workload. It is obvious, but there&#8217;s no point, except maybe for very basic testing, running Harvester as a VM on your personal computer. And also, don&#8217;t be shy about the specifications.</p>



<p class="wp-block-paragraph">In summary:</p>



<ul class="wp-block-list">
<li>CPU: requires hardware virtualization. All servers have those CPU extensions activated. But in order to cross check, just try to execute and trigger this <a href="https://www.linux-kvm.org/page/FAQ#How_can_I_tell_if_I_have_Intel_VT_or_AMD-V?" target="_blank" rel="noreferrer noopener">command</a> on a Linux shell prompt. In terms of resources, 8 cores are marked as a minimum, with 16 cores recommended.</li>



<li>Memory: 32GB is the minimum. But as always, the more, the better.</li>



<li>Local storage of the node requires a minimum of 250GB. It can be either one single disk or spread across multiple disks</li>
</ul>



<p class="wp-block-paragraph">The network stack? I would treat that, in fact, as separate, as I think it would deserve, regarding the architecture, its own blog post. Only remember that the server would obviously require network connectivity. Please <a href="https://docs.harvesterhci.io/v1.3/install/requirements#port-requirements-for-harvester-nodes" target="_blank" rel="noreferrer noopener">note</a> the set of network ports that you would need to open for incoming traffic.</p>



<h2 class="wp-block-heading" id="h-installation-for-real">Installation for real</h2>



<p class="wp-block-paragraph">As mentioned previously, the installation stack is and ISO file, which is 5.79GB. Once you boot your machine straight from it, you&#8217;ll be welcomed by &#8230; a GRUB, a quite usual welcome page for Linux enthusiasts. Be aware: mouse not required, no graphical interface here (which is nice: the <a target="_blank" rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/KISS_principle">KISS</a> principle).</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="638" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_092210-1024x638.png" alt="" class="wp-image-32699" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_092210-1024x638.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_092210-300x187.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_092210-768x479.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_092210.png 1277w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Once validated, you need to follow the installation process. It will ask you for the node hostname, standard network settings (IP, DNS, Proxy, etc.), VIP, manual token (useful when you add additional Harvester nodes).</p>



<p class="wp-block-paragraph">One word about the VIP. This IP is different from the one you have assigned to the node. The VIP is kind of assigned to the Harvester cluster you are going to create. This is the one you&#8217;ll enter when you want to target the cluster for the Web UI of Harvester.</p>



<p class="wp-block-paragraph">Talking about cluster, based on my own testing, Harvester could <em>potentially</em> work in single-node mode, but more as a cluster. The first node you will install will always be a management node. Starting at the fourth node, the first three ones are management nodes, remaining ones will be worker nodes.</p>



<p class="wp-block-paragraph">I hadn&#8217;t talked until now about the core architecture of Harvester, and it was on purpose: the best is to discover it now <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Once installed, you end up with a welcome screen with a summary of the management cluster URL and status, the current node name, IP, and status as well.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="638" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_094547-1024x638.png" alt="" class="wp-image-32698" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_094547-1024x638.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_094547-300x187.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_094547-768x479.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Screenshot_20240418_094547.png 1277w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Press F12, fill up the password you&#8217;ve entered during the installation process, and you&#8217;ll reach a prompt. Warning: except if I missed a setting, the shell prompt that is presented is using the QWERTY keyboard layout. Tips found in the FAQ, you can SSH using the admin user name (password authentication for a fresh installed node).</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
jpc@dbi-lt-jpc:~&gt; ssh rancher@192.168.20.121
(rancher@192.168.20.121) Password:  
Last login: Thu Apr 18 11:57:11 2024 from 192.168.20.211
rancher@harv-01:~&gt; sudo su -
harv-01:~ #
</pre></div>


<p class="wp-block-paragraph">Enter a very common command for any DevOps &amp; Kubernetes addict:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv-01:~ $ kubectl get nodes -o wide
NAME      STATUS   ROLES                       AGE     VERSION           INTERNAL-IP      EXTERNAL-IP   OS-IMAGE           KERNEL-VERSION                  CONTAINER-RUNTIME
harv-01   Ready    control-plane,etcd,master   4h40m   v1.27.10+rke2r1   192.168.20.121   &lt;none&gt;        Harvester v1.3.0   5.14.21-150400.24.108-default   containerd://1.7.11-k3s2
</pre></div>


<p class="wp-block-paragraph">If you already got some interest into Harvester, you expected that. As said in the introduction, Harvester is based on cloud native components and Kubernetes is at its core.</p>



<h2 class="wp-block-heading" id="h-to-host-and-serve">&#8220;To Host and Serve&#8221;</h2>



<p class="wp-block-paragraph">But Kubernetes is not the only one. Remember: Harvester is a HCI, and it is intended to carry out corporate workloads. And in a cloud-native way <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">As always, on a Kubernetes cluster, looking at namespaces and pods gives a good overview of what is going on here.</p>



<p class="wp-block-paragraph">Let&#8217;s do this!</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv-01:~ $ kubectl get ns
NAME                                     STATUS   AGE
cattle-dashboards                        Active   5h27m
cattle-fleet-clusters-system             Active   5h27m
cattle-fleet-local-system                Active   5h27m
cattle-fleet-system                      Active   5h28m
cattle-logging-system                    Active   5h27m
cattle-monitoring-system                 Active   5h27m
cattle-provisioning-capi-system          Active   5h27m
cattle-system                            Active   5h28m
cluster-fleet-local-local-1a3d67d0a899   Active   5h27m
default                                  Active   5h29m
fleet-local                              Active   5h28m
harvester-public                         Active   5h26m
harvester-system                         Active   5h26m
kube-node-lease                          Active   5h29m
kube-public                              Active   5h29m
kube-system                              Active   5h29m
local                                    Active   5h28m
longhorn-system                          Active   5h26m
</pre></div>


<p class="wp-block-paragraph">Let&#8217;s start with the harvester-system namespace.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv-01:~ $ kubectl get pods -n harvester-system 
NAME                                                    READY   STATUS    RESTARTS   AGE 
harvester-667fb9cbc8-jwmtx                              1/1     Running   0          5h47m 
harvester-load-balancer-6755cb4d67-7xjw8                1/1     Running   0          5h47m 
harvester-load-balancer-webhook-6b5c6b546-bdf66         1/1     Running   0          5h47m 
harvester-network-controller-manager-5ff644ffb6-66s69   1/1     Running   0          5h47m 
harvester-network-controller-v9lhf                      1/1     Running   0          5h47m 
harvester-network-webhook-5c596bdd6c-grctr              1/1     Running   0          5h47m 
harvester-node-disk-manager-gdfzx                       1/1     Running   0          5h47m 
harvester-node-manager-mrqbs                            1/1     Running   0          5h47m 
harvester-node-manager-webhook-9cfccc84c-hxnbm          1/1     Running   0          5h47m 
harvester-webhook-79f5446494-65lvb                      1/1     Running   0          5h47m 
kube-vip-zk62c                                          1/1     Running   0          5h47m 
virt-api-77cbf85485-spnf8                               1/1     Running   0          5h46m 
virt-controller-659ccbfbcd-6xzmb                        1/1     Running   0          5h46m 
virt-controller-659ccbfbcd-tkk2b                        1/1     Running   0          5h46m 
virt-handler-9bwd5                                      1/1     Running   0          5h46m 
virt-operator-6b8b9b7578-66tps                          1/1     Running   0          5h47m
</pre></div>


<p class="wp-block-paragraph">Pods virt-api, virt-controller, virt-operator. For those who know me, they know my addiction to <a href="https://kubevirt.io/" target="_blank" rel="noreferrer noopener">KubeVirt</a>. This wonderful add-on brings the management of virtual machines to Kubernetes and relies on <a href="https://www.linux-kvm.org/page/Main_Page" target="_blank" rel="noreferrer noopener">KVM</a> (Kerned-based Virtual Machine, released in 2007).</p>



<p class="wp-block-paragraph">Add-on to Kubernetes, that also means new objects.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv-01:~ $ kubectl api-resources |grep &quot;kubevirt.io/v1&quot; 
virtualmachineclones                         vmclone,vmclones                                          clone.kubevirt.io/v1alpha1                   true         VirtualMachineClone 
virtualmachineexports                        vmexport,vmexports                                        export.kubevirt.io/v1alpha1                  true         VirtualMachineExport 
virtualmachineclusterinstancetypes           vmclusterinstancetype,vmclusterinstancetypes,vmcf,vmcfs   instancetype.kubevirt.io/v1beta1             false        VirtualMachineClusterInstancetype 
virtualmachineclusterpreferences             vmcp,vmcps                                                instancetype.kubevirt.io/v1beta1             false        VirtualMachineClusterPreference 
virtualmachineinstancetypes                  vminstancetype,vminstancetypes,vmf,vmfs                   instancetype.kubevirt.io/v1beta1             true         VirtualMachineInstancetype 
virtualmachinepreferences                    vmpref,vmprefs,vmp,vmps                                   instancetype.kubevirt.io/v1beta1             true         VirtualMachinePreference 
kubevirts                                    kv,kvs                                                    kubevirt.io/v1                               true         KubeVirt 
virtualmachineinstancemigrations             vmim,vmims                                                kubevirt.io/v1                               true         VirtualMachineInstanceMigration 
virtualmachineinstancepresets                vmipreset,vmipresets                                      kubevirt.io/v1                               true         VirtualMachineInstancePreset 
virtualmachineinstancereplicasets            vmirs,vmirss                                              kubevirt.io/v1                               true         VirtualMachineInstanceReplicaSet 
virtualmachineinstances                      vmi,vmis                                                  kubevirt.io/v1                               true         VirtualMachineInstance 
virtualmachines                              vm,vms                                                    kubevirt.io/v1                               true         VirtualMachine 
migrationpolicies                                                                                      migrations.kubevirt.io/v1alpha1              false        MigrationPolicy 
virtualmachinepools                          vmpool,vmpools                                            pool.kubevirt.io/v1alpha1                    true         VirtualMachinePool 
virtualmachinerestores                       vmrestore,vmrestores                                      snapshot.kubevirt.io/v1alpha1                true         VirtualMachineRestore 
virtualmachinesnapshotcontents               vmsnapshotcontent,vmsnapshotcontents                      snapshot.kubevirt.io/v1alpha1                true         VirtualMachineSnapshotContent 
virtualmachinesnapshots                      vmsnapshot,vmsnapshots                                    snapshot.kubevirt.io/v1alpha1                true         VirtualMachineSnapshot
</pre></div>


<p class="wp-block-paragraph">With KubeVirt, and so Harvester, a virtual machine will be defined as a Kubernetes object, VirtualMachine. VirtualMachineInstances will be a running instance of a VirtualMachine object. Just imagine, being able to apply VirtualMachine definitions and get your VM scheduled, by Kubernetes standard scheduler somewhere on your Harvester cluster <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f970.png" alt="🥰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> . The best of two worlds is brought together. Harvester simplifies all this using, like Rancher is doing by easing the management of standard Kubernetes workloads.</p>



<p class="wp-block-paragraph">Quickly continue to get a taste of what is running also on Harvester. We can see some cattle- namespace. Rancher is running here!</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv-01:~ $ kubectl get pods -n cattle-system
NAME                                         READY   STATUS    RESTARTS        AGE
harvester-cluster-repo-5c75f7d9fd-88g4x      1/1     Running   0               5h31m
rancher-5dbd4cf7dc-995rr                     1/1     Running   0               5h29m
rancher-webhook-5788f655d8-4p8bt             1/1     Running   0               5h31m
system-upgrade-controller-78cfb99bb7-hdslt   1/1     Running   2 (5h14m ago)   5h31m
</pre></div>


<p class="wp-block-paragraph">What else do we have? <a href="https://longhorn.io/">Longhorn</a>, for the storage.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
harv-01:~ $ kubectl get pods -n longhorn-system
NAME                                                READY   STATUS    RESTARTS   AGE
csi-attacher-dc76666dd-jhs8l                        1/1     Running   0          5h32m
csi-attacher-dc76666dd-t96tr                        1/1     Running   0          5h32m
csi-attacher-dc76666dd-w9zwf                        1/1     Running   0          5h32m
csi-provisioner-7fc9d85c66-48n7g                    1/1     Running   0          5h32m
csi-provisioner-7fc9d85c66-89h4d                    1/1     Running   0          5h32m
csi-provisioner-7fc9d85c66-c94hb                    1/1     Running   0          5h32m
csi-resizer-67664c5755-jpl6r                        1/1     Running   0          5h32m
csi-resizer-67664c5755-r4llm                        1/1     Running   0          5h32m
csi-resizer-67664c5755-vcn94                        1/1     Running   0          5h32m
csi-snapshotter-6c9d675d9c-flkf6                    1/1     Running   0          5h32m
csi-snapshotter-6c9d675d9c-hw4mj                    1/1     Running   0          5h32m
csi-snapshotter-6c9d675d9c-sppkx                    1/1     Running   0          5h32m
engine-image-ei-acb7590c-cxtvm                      1/1     Running   0          5h32m
instance-manager-3c8c76df5f2bfa171e62a198a9ade00e   1/1     Running   0          5h32m
longhorn-csi-plugin-t7x2h                           3/3     Running   0          5h32m
longhorn-driver-deployer-67fd98774c-xd7x2           1/1     Running   0          5h32m
longhorn-loop-device-cleaner-vq2nr                  1/1     Running   0          5h32m
longhorn-manager-mn75c                              1/1     Running   0          5h32m
longhorn-ui-7f8cdfcc48-gqcs4                        1/1     Running   0          5h32m
longhorn-ui-7f8cdfcc48-v9nhc                        1/1     Running   0          5h32m
</pre></div>


<p class="wp-block-paragraph">You remember the cattle-monitoring-system namespace? We didn&#8217;t talked also about the based OS, <a href="https://elemental.docs.rancher.com/">Elemental</a>. We will go deeper into all those topics, as they are pretty dense, lots of subjects here. But by using Kubernetes for his HCI, SUSE simplifies the management of workloads for companies and reduces the time required for their delivery.</p>



<p class="wp-block-paragraph">Stay connected for much more!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/cloud-native-hyper-converged-infrastructure-with-harvester/">Investigative look into cloud-native hyper-converged infrastructure with Harvester</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/cloud-native-hyper-converged-infrastructure-with-harvester/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Rancher RKE2: Rancher roles for cluster autoscaler</title>
		<link>https://www.dbi-services.com/blog/rancher-rke2-rancher-roles-for-cluster-autoscaler/</link>
					<comments>https://www.dbi-services.com/blog/rancher-rke2-rancher-roles-for-cluster-autoscaler/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Wed, 17 Apr 2024 08:12:09 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Rancher]]></category>
		<category><![CDATA[SuSE]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=31646</guid>

					<description><![CDATA[<p>The cluster autoscaler brings horizontal scaling into your cluster by deploying it into the cluster to autoscale. This is described in the following blog article https://www.dbi-services.com/blog/rancher-autoscaler-enable-rke2-node-autoscaling/. It didn&#8217;t emphasize much about the user and role configuration. With Rancher, the cluster autoscaler uses a user&#8217;s API key. We will see how to configure minimal permissions by [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/rancher-rke2-rancher-roles-for-cluster-autoscaler/">Rancher RKE2: Rancher roles for cluster autoscaler</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">The cluster autoscaler brings horizontal scaling into your cluster by deploying it into the cluster to autoscale. This is described in the following blog article <a href="https://www.dbi-services.com/blog/rancher-autoscaler-enable-rke2-node-autoscaling/">https://www.dbi-services.com/blog/rancher-autoscaler-enable-rke2-node-autoscaling/</a>. It didn&#8217;t emphasize much about the user and role configuration.</p>



<p class="wp-block-paragraph">With Rancher, the cluster autoscaler uses a user&#8217;s API key. We will see how to configure minimal permissions by creating Rancher roles for cluster autoscaler.</p>



<h2 class="wp-block-heading" id="h-rancher-user">Rancher user</h2>



<p class="wp-block-paragraph">First, let&#8217;s create the user that will communicate with Rancher, and whose token will be used. It will be given minimal access rights which is login access.</p>



<p class="wp-block-paragraph">Go to Rancher &gt; Users &amp; Authentication &gt; Users &gt; Create.</p>



<ul class="wp-block-list">
<li>Set a username, for example, autoscaler</li>



<li>Set the password</li>



<li>Give User-Base permissions</li>



<li>Create</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="509" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1024x509.png" alt="" class="wp-image-31653" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1024x509.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-300x149.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-768x382.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1536x763.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-2048x1018.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The user is now created, let&#8217;s set Rancher roles with minimal permission for the cluster autoscaler.</p>



<h2 class="wp-block-heading" id="h-rancher-roles-authorization">Rancher roles authorization</h2>



<p class="wp-block-paragraph">To make the cluster autoscaler work, the user whose API key is provided needs the following roles:</p>



<ul class="wp-block-list">
<li>Cluster role (for the cluster to autoscale)<br>Get/Update for clusters.provisioning.cattle.io<br>Update of machines.cluster.x-k8s.io</li>



<li>Project role (for the namespace that contains the cluster resource (fleet-default))<br>Get/List of machines.cluster.x-k8s.io</li>
</ul>



<p class="wp-block-paragraph">Go to Rancher &gt; Users &amp; Authentication &gt; Role Templates &gt; Cluster &gt; Create.<br>Create the cluster role. This role will be applied to every cluster that we want to autoscale.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="442" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1-1024x442.png" alt="" class="wp-image-31654" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1-1024x442.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1-300x130.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1-768x332.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1-1536x663.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-1-2048x884.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Then in Rancher &gt; Users &amp; Authentication &gt; Role Templates &gt; Project/Namespaces &gt; Create.<br>Create the project role, it will be applied to the project of our local cluster (Rancher) that contains the namespace fleet-default.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="386" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-2-1024x386.png" alt="" class="wp-image-31655" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-2-1024x386.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-2-300x113.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-2-768x289.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-2-1536x578.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-2-2048x771.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-rancher-roles-assignment">Rancher roles assignment</h2>



<p class="wp-block-paragraph">The user and Rancher roles are created, let&#8217;s assign them.</p>



<h3 class="wp-block-heading" id="h-project-role">Project role</h3>



<p class="wp-block-paragraph">First, we will set the project role, this is to be done once.<br>Go to the local cluster (Rancher), in Cluster &gt; Project/Namespace.<br>Search for the fleet-default namespace, by default it is contained in the project System.<br>Edit the project System and add the user with the project permissions created precedently.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="999" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-3-1024x999.png" alt="" class="wp-image-31656" style="width:637px;height:auto" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-3-1024x999.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-3-300x293.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-3-768x750.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-3.png 1168w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="304" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-4-1024x304.png" alt="" class="wp-image-31657" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-4-1024x304.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-4-300x89.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-4-768x228.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-4-1536x456.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-4-2048x608.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading" id="h-cluster-role">Cluster role</h3>



<p class="wp-block-paragraph">For each cluster where you will deploy the cluster autoscaler, you need to assign the user as a member with the cluster role.<br>In Rancher &gt; Cluster Management, edit the cluster&#8217;s configuration and assign the user.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="923" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-6-1024x923.png" alt="" class="wp-image-31659" style="width:621px;height:auto" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-6-1024x923.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-6-300x270.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-6-768x692.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-6.png 1178w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="610" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-7-1024x610.png" alt="" class="wp-image-31660" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-7-1024x610.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-7-300x179.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-7-768x457.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-7-1536x915.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-7-2048x1220.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The roles assignment is done, let&#8217;s proceed to generate the token that is provided to the cluster autoscaler configuration.</p>



<h2 class="wp-block-heading" id="h-rancher-api-keys">Rancher API keys</h2>



<p class="wp-block-paragraph">Log in with the autoscaler user, and go to its profile &gt; Account &amp; API Keys.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="321" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-8-1024x321.png" alt="" class="wp-image-31661" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-8-1024x321.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-8-300x94.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-8-768x241.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-8-1536x481.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-8-2048x641.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Let&#8217;s create an API Key for the cluster autoscaler configuration. Note that in a recent update of Rancher, the API keys expired by default in 90 days. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="296" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-9-1024x296.png" alt="" class="wp-image-31662" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-9-1024x296.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-9-300x87.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-9-768x222.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-9-1536x444.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-9-2048x591.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">If you see this limitation, you can do the following steps to have no expiration.<br>With the admin account, in Global settings &gt; Settings, search for the setting <strong>auth-token-max-ttl-minutes</strong> and set it to 0.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="153" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-10-1024x153.png" alt="" class="wp-image-31663" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-10-1024x153.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-10-300x45.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-10-768x114.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-10-1536x229.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-10-2048x305.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Go back with the autoscaler user and create the API Key, name it for example, autoscaler, and select &#8220;no scope&#8221;.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="346" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-11-1024x346.png" alt="" class="wp-image-31664" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-11-1024x346.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-11-300x102.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-11-768x260.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-11-1536x520.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-11-2048x693.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="338" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-12-1024x338.png" alt="" class="wp-image-31665" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-12-1024x338.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-12-300x99.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-12-768x254.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-12-1536x507.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-12-2048x676.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">You can copy the Bearer Token, and use it for the cluster autoscaler configuration.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="306" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-14-1024x306.png" alt="" class="wp-image-31667" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-14-1024x306.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-14-300x90.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-14-768x229.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-14-1536x458.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-14-2048x611.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">As seen above, the token never expires.<br>Let&#8217;s reset the parameter <strong>auth-token-max-ttl-minutes</strong> and use the default value button or the precedent value set.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="216" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-13-1024x216.png" alt="" class="wp-image-31666" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-13-1024x216.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-13-300x63.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-13-768x162.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-13-1536x324.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/image-13-2048x432.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">We are now done with the roles configuration.</p>



<h2 class="wp-block-heading" id="h-conclusion">Conclusion</h2>



<p class="wp-block-paragraph">This blog article covers only a part of the setup for the cluster autoscaler for RKE2 provisioning. It explained the configuration of a Rancher user and Rancher&#8217;s roles with minimal permissions to enable the cluster autoscaler. It was made to complete this blog article <a href="https://www.dbi-services.com/blog/rancher-autoscaler-enable-rke2-node-autoscaling/">https://www.dbi-services.com/blog/rancher-autoscaler-enable-rke2-node-autoscaling/</a> which covers the whole setup and deployment of the cluster autoscaler. Therefore if you are still wondering how to deploy and make the cluster autoscaler work, check the other blog.</p>



<h2 class="wp-block-heading" id="h-links">Links</h2>



<p class="wp-block-paragraph">Rancher official documentation: <a href="https://ranchermanager.docs.rancher.com/">Rancher</a><br>RKE2 official documentation: <a href="https://docs.rke2.io/">RKE2</a><br>GitHub cluster autoscaler: <a href="https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler">https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler</a></p>



<p class="wp-block-paragraph">Blog &#8211; Rancher autoscaler &#8211; Enable RKE2 node autoscaling<br><a href="https://www.dbi-services.com/blog/rancher-autoscaler-enable-rke2-node-autoscaling/" target="_blank" rel="noreferrer noopener">https://www.dbi-services.com/blog/rancher-autoscaler-enable-rke2-node-autoscaling</a><br>Blog &#8211; Reestablish administrator role access to Rancher users<br><a href="https://www.dbi-services.com/blog/reestablish-administrator-role-access-to-rancher-users/" target="_blank" rel="noreferrer noopener">https://www.dbi-services.com/blog/reestablish-administrator-role-access-to-rancher-users/</a><br>Blog &#8211; Introduction and RKE2 cluster template for AWS EC2<br><a href="https://www.dbi-services.com/blog/rancher-rke2-cluster-templates-for-aws-ec2" target="_blank" rel="noreferrer noopener">https://www.dbi-services.com/blog/rancher-rke2-cluster-templates-for-aws-ec2</a><br>Blog &#8211; Rancher RKE2 templates &#8211; Assign members to clusters<br><a href="https://www.dbi-services.com/blog/rancher-rke2-templates-assign-members-to-clusters" target="_blank" rel="noreferrer noopener">https://www.dbi-services.com/blog/rancher-rke2-templates-assign-members-to-clusters</a></p>
<p>L’article <a href="https://www.dbi-services.com/blog/rancher-rke2-rancher-roles-for-cluster-autoscaler/">Rancher RKE2: Rancher roles for cluster autoscaler</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/rancher-rke2-rancher-roles-for-cluster-autoscaler/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Learning Azure by having fun with ChatGPT</title>
		<link>https://www.dbi-services.com/blog/learning-azure-by-having-fun-with-chatgpt/</link>
					<comments>https://www.dbi-services.com/blog/learning-azure-by-having-fun-with-chatgpt/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 16 Apr 2024 07:27:16 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=32568</guid>

					<description><![CDATA[<p>Learn Azure with ChatGPT to get a story around all the concepts and components of Azure. It becomes visual and you'll get some fun with it.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/learning-azure-by-having-fun-with-chatgpt/">Learning Azure by having fun with ChatGPT</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Are you studying for an Azure certification? You may feel at some point you need a break from the dry and factual technical information. I&#8217;m in your shoes right now and I have done some experiments with <a href="https://chat.openai.com/auth/login" target="_blank" rel="noreferrer noopener">ChatGPT</a>. I&#8217;m not using it to write my text but to learn by having fun! It is very good at telling stories so why not use that for what interests me right now? Azure architecture!</p>



<p class="wp-block-paragraph">In this blog post I&#8217;m going to show you how I use it, it may give you some ideas to make your learning a little more spicy!</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Azure-cloud-and-OnPrem.jpeg" alt="A visual representation of Azure Cloud and on-premises infrastructure." class="wp-image-32572" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Azure-cloud-and-OnPrem.jpeg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Azure-cloud-and-OnPrem-300x300.jpeg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Azure-cloud-and-OnPrem-150x150.jpeg 150w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/Azure-cloud-and-OnPrem-768x768.jpeg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-prompt-for-preparing-chatgpt-with-azure">Prompt for preparing ChatGPT with Azure</h2>



<p class="wp-block-paragraph">First you&#8217;ll need to prepare ChatGPT by explaining what you want. Set the framework and limit its responses otherwise it is too chatty. As I like science fiction (sci-fi), I&#8217;m interested in a futuristic story but you could choose any style you like. My first prompt and ChatGPT response is shown below:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Act as an Azure architect. You are in charge of educating me, your student, to become an Azure architect too. You will respond to my questions by using story telling to explain each concepts requested.&nbsp;<br>I want you to:<br>&#8211; Always tell a simple and futuristic story<br>&#8211; Limit the reply to 100 words</p>
<cite><br>As an Azure architect, imagine Azure as a vast cosmic city. Each service is a towering skyscraper, and we, architects, design the blueprints. Let&#8217;s start with Virtual Networks. They&#8217;re like the city&#8217;s infrastructure, connecting buildings. Subnets divide areas within each building, like floors. Next, VMs are the inhabitants, residing in these skyscrapers, each serving a unique purpose. Azure Storage, a network of secure vaults, safeguards their belongings. With Azure Load Balancer as traffic controllers, the city thrives, ensuring smooth navigation. As architects of this digital metropolis, we sculpt a future where innovation soars amidst the azure skyline.</cite></blockquote>



<p class="wp-block-paragraph">Not bad! It gives me some key components of an Azure infrastructure and makes some analogies I can easily picture in my head. With this basis, I can now be the hero of this story by asking more questions.</p>



<h2 class="wp-block-heading" id="h-build-up-that-azure-cosmic-city-with-chatgpt">Build up that Azure cosmic city with ChatGPT</h2>



<p class="wp-block-paragraph">You can then ask questions around your area of study (mine is Azure architecture) and stay immersed into that story. For example:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">What are the best practice to govern this Azure cosmic city?</p>
<cite>In our cosmic city, governance is paramount. Azure Policy acts as the city&#8217;s constitution, ensuring compliance with regulations. Role-Based Access Control (RBAC) assigns roles to citizens, granting appropriate permissions. Azure Resource Manager templates are like city blueprints, ensuring consistency in construction. Tags label buildings for easy identification, while Azure Monitor keeps a watchful eye on city activities. With these best practices, our cosmic city thrives, ensuring order, security, and harmony amidst the azure skyline.</cite></blockquote>



<p class="wp-block-paragraph">It gives you the key elements of Azure governance by continuing its story. You can go on like this back and forth by throwing in any chapter of your course. You can focus on a specific use case as well and see how it integrates with this story:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">How can I migrate my SQL Server database on-premises to this city?</p>
<cite>Imagine your SQL Server database as a cozy cottage in the countryside. To migrate to our cosmic city, Azure, we&#8217;ll use Azure Database Migration Service, like a futuristic moving company. It carefully transports your data to Azure SQL Database, a sleek skyscraper in our city. With minimal downtime, your database seamlessly transitions to its new home, ready to thrive amidst the azure skyline. Just sit back, relax, and watch as your data becomes part of the bustling digital metropolis.</cite></blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">How do I ensure my database is highly resilient in this cosmic city?</p>
<cite>In our cosmic city, resilience is key. Azure offers a robust solution: Azure SQL Database with built-in redundancy, akin to a fortress with multiple layers of defense. Automatic backups act as a safety net, ensuring data is never lost. Geo-replication creates duplicates across regions, safeguarding against disasters. With Azure SQL Database&#8217;s high availability and disaster recovery features, your database thrives amidst the azure skyline, resilient against any digital storm.</cite></blockquote>



<p class="wp-block-paragraph">I don&#8217;t know if it works for you but I find it fascinating I can make ChatGPT talk endlessly and respond to any questions I have about Azure in a sci-fi story!</p>



<h2 class="wp-block-heading" id="h-dive-into-an-azure-component">Dive into an Azure component</h2>



<p class="wp-block-paragraph">As usual with ChatGPT you need to drive the discussion to get the most of it. Let&#8217;s see what it has to say about Azure AD (I use the legacy terminology as ChatGPT v3.5 doesn&#8217;t know yet <strong>Microsoft Entra ID</strong>):</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">What and where would be the Azure AD in this city?</p>
<cite>In our bustling city, Azure AD is the central hub, akin to City Hall. It&#8217;s where identities are registered, like citizens in our digital society. Located at the heart of the city, Azure AD ensures secure access to every digital service and resource, much like City Hall grants access to essential services. From authentication to authorization, Azure AD governs the city&#8217;s digital identities, ensuring a seamless and secure experience for all inhabitants amidst the azure skyline.</cite></blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">How would Azure AD conditional access be implemented in this city?</p>
<cite>In our city, Azure AD Conditional Access acts as the city&#8217;s security checkpoints. Picture futuristic gates at key entry points, only granting access to authorized individuals based on specific conditions. Want to enter the financial district skyscraper? You&#8217;ll need more than just a pass; perhaps a biometric scan during business hours. Conditional Access ensures only the right people, with the right permissions, access sensitive areas of our digital city. It&#8217;s our shield against cyber threats amidst the azure skyline, ensuring a safe and secure digital environment for all inhabitants.</cite></blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">How would I connect from my Active Directory in the countryside to this Azure AD in the cloud?</p>
<cite>In the countryside, your Active Directory (AD) is like a quaint village square, bustling with local identities. To connect to Azure AD in our cosmic cloud city, envision a digital bridge spanning the distance between village and skyline. Azure AD Connect is your trusty guide, seamlessly synchronizing identities from countryside AD to Azure AD. With this bridge in place, villagers can access digital services in the cloud using their familiar countryside credentials. Just like that, the countryside becomes an integral part of our digital metropolis, united under the azure skyline.</cite></blockquote>



<p class="wp-block-paragraph">You can then piece by piece for each component create a complete city in the countryside (OnPrem) and in the cloud and illustrate their interaction. We could completely gamify this! SimCity anyone?</p>



<h2 class="wp-block-heading" id="h-limitations">Limitations</h2>



<p class="wp-block-paragraph">Some general concepts are more difficult to put into a visual story as for example the Microsoft Cloud Adoption Framework:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">What would be the Microsoft Cloud Adoption Framework for Azure in this city?</p>
<cite>In our dynamic metropolis, the Microsoft Cloud Adoption Framework for Azure is our roadmap to success. Like a futuristic GPS, it guides us through the twists and turns of digital transformation. Envisioning helps us set our destination, planning ensures we choose the best route, and readiness prepares us for the journey ahead. Migration helps us seamlessly transition, while innovation propels us forward. With governance as our compass and optimization as our fuel, we navigate the ever-changing landscape, building a future where our digital city thrives amidst the azure skyline. Ready to embark on this transformative journey?</cite></blockquote>



<p class="wp-block-paragraph">I don&#8217;t find it fantastic as we recognize the empty blabbering of ChatGPT. We would need to be more specific to get something more interesting.</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">You can see how by relaxing from your studies, you can still continue to learn by having fun in an imaginary world. You could totally convert all this into visual notes that will help you when you renew your certifications. That is something I&#8217;m starting to explore.</p>



<p class="wp-block-paragraph">This is just a glimpse of how you could use ChatGPT in your journey to learn Azure or anything else. Brainstorm any concept, service or component you are learning and see how it integrates into a visual story to get a high-level picture. Let me know if your are using ChatGPT that way for learning and what is the world you are building for it!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/learning-azure-by-having-fun-with-chatgpt/">Learning Azure by having fun with ChatGPT</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/learning-azure-by-having-fun-with-chatgpt/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>DevOps Best Practice &#8211; Backup and Share your work with GitHub</title>
		<link>https://www.dbi-services.com/blog/devops-best-practice-backup-and-share-your-work-with-github/</link>
					<comments>https://www.dbi-services.com/blog/devops-best-practice-backup-and-share-your-work-with-github/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 09 Apr 2024 06:17:19 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[GitHub]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=32303</guid>

					<description><![CDATA[<p>DevOps best practice to backup and share files by using GitHub. Learn to synchronize the files in your machine with a GitHub repository.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/devops-best-practice-backup-and-share-your-work-with-github/">DevOps Best Practice &#8211; Backup and Share your work with GitHub</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">With my mate <strong>Chay Te</strong> (our DevOps champion in all categories and the mastermind of this best practice) we worked on scripts for our new Kubernetes security talk. These scripts where stored in our EC2 instance but this should not be their permanent location. First the EC2 instance could be deleted and we would lose everything. Then we need to version these files and keep track of the changes between us two. It was time to apply DevOps best practice for our scripts and we decided to use GitHub for this purpose.  Read on to learn how to backup and share your work with GitHub in this step-by-step guide!</p>



<h2 class="wp-block-heading" id="h-github">GitHub</h2>



<p class="wp-block-paragraph">The first step is to sign up for a <a href="https://github.com" target="_blank" rel="noreferrer noopener">GitHub account</a> if you don&#8217;t already have one.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="314" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-1-1024x314.png" alt="Sign up for GitHub" class="wp-image-32309" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-1-1024x314.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-1-300x92.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-1-768x235.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-1-1536x470.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-1-2048x627.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Then you can create your first repository (also called repo for short) by giving it a name. You can select a Private repo if the files you share are private (it was in our case). So far so good, nothing complicated here!</p>



<p class="wp-block-paragraph">Now you want to connect from your EC2 instance (in our case but it could be any type of machine) to this repo and push your scripts. Before you can do that, there is some configuration to do in GitHub. You have to create a Personal Access Token (PAT) to allow this connection. Click on your <strong>profile</strong> in the top right corner and select <strong>Settings</strong>. Then choose <strong>Developer Settings</strong> and you will reach the PAT menu. Here there are 2 choices between a fine-grained and a classic token. The first one is in Beta and allow you to choose which access you want to give to each element of your repo. You give it a name and the token will be generated for you. It has an expiration date and you have to keep it somewhere safe like a password as you will not be able to retrieve it later.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="200" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-2-1024x200.png" alt="GitHub personal access token as part of DevOps best practice." class="wp-image-32314" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-2-1024x200.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-2-300x59.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-2-768x150.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-2-1536x301.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-2-2048x401.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">You can now use your GitHub account name and this token to synchronize your scripts or files between EC2 and this repo.</p>



<p class="wp-block-paragraph">The last thing to configure in GitHub is to invite your collaborators to access your repo. Click on <strong>Add people</strong> and enter the email address of your collaborator. She/He will receive an invite to accept to join you in this repo.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="360" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-3-1024x360.png" alt="GitHub add a collaborator" class="wp-image-32316" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-3-1024x360.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-3-300x105.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-3-768x270.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-3-1536x539.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/04/GitHub-3-2048x719.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Creating a repo and collaborating in it is part of DevOps best practice!</p>



<h2 class="wp-block-heading" id="h-git-commands-in-ec2">Git commands in EC2</h2>



<p class="wp-block-paragraph">Your GitHub repo is now ready so let&#8217;s use it and backup your scripts in it. Another DevOps best practice is to use <a href="https://git-scm.com" target="_blank" rel="noreferrer noopener">Git</a> as the CLI tool in our machine.</p>



<p class="wp-block-paragraph">On the EC2 instance, the easiest way to proceed is to clone your GitHub repo (we give it the name MyNewRepo) with Git as follows:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ git clone https://github.com/mygithubaccount/MyNewRepo.git
</pre></div>


<p class="wp-block-paragraph">You will be asked to authenticate with your GitHub account name (here mygithubaccount) and use the PAT you have created above as password. In your EC2 instance you now have a new folder called MyNewRepo. At this stage it is empty. Go into it and set the Git configuration:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ cd MyNewRepo

$ git config --global user.email &quot;benoit.entzmann@dbi-services.com&quot;
$ git config --global user.name &quot;Benoit Entzmann&quot;
$ git branch -M main
$ git remote add origin https://github.com/mygithubaccount/MyNewRepo.git
</pre></div>


<p class="wp-block-paragraph">You set the global email and username you will use with Git. By default there is one Git branch that is called <strong>Master</strong>. Rename it as <strong>main</strong>. Finally set up a connection between your local Git repository and your remote repository.</p>



<p class="wp-block-paragraph">Next copy or move all of your script files into this folder as shown in the example below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ cp -Rp ~/MyScripts/* ./
</pre></div>


<p class="wp-block-paragraph">Now all of your script files are in right folder and you just need to add them to the local Git repo and push them to your repo in GitHub:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ git add .
$ git commit -m &quot;My scripts&quot;
$ git push -u origin main
</pre></div>


<p class="wp-block-paragraph">And this is it! You can just check in GitHub that all of your script files are now in the repo called MyNewRepo.</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">In a few steps we have seen how to backup your script files by using a repository in GitHub. You have not only backup your files, you have also setup the GitHub environment to collaborate in this repo. This is a DevOps best practice!</p>



<p class="wp-block-paragraph">Now in case of a failure or accidental deletion of your EC2 (yes Instance state -&gt; Terminate instance can happen!), you will be able to clone again your repo from GitHub and quickly get back on track with your scripts!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/devops-best-practice-backup-and-share-your-work-with-github/">DevOps Best Practice &#8211; Backup and Share your work with GitHub</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/devops-best-practice-backup-and-share-your-work-with-github/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Enhance Containers Security &#8211; Prevent Encrypted Data Exfiltration with NeuVector</title>
		<link>https://www.dbi-services.com/blog/enhance-containers-security-prevent-encrypted-data-exfiltration-with-neuvector/</link>
					<comments>https://www.dbi-services.com/blog/enhance-containers-security-prevent-encrypted-data-exfiltration-with-neuvector/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 02 Apr 2024 06:07:22 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Containers]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[neuvector]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=32085</guid>

					<description><![CDATA[<p>Containers security by preventing encrypted data exfiltration with NeuVector. Implementing zero trust architecture.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/enhance-containers-security-prevent-encrypted-data-exfiltration-with-neuvector/">Enhance Containers Security &#8211; Prevent Encrypted Data Exfiltration with NeuVector</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In my <a href="https://www.dbi-services.com/blog/containers-security-protect-against-ssn-exfiltration-with-neuvector/" target="_blank" rel="noreferrer noopener">previous blog post</a> we have seen how <a href="https://www.suse.com/neuvector/" target="_blank" rel="noreferrer noopener">NeuVector from SUSE</a> can detect and prevent data exfiltration. We used the DLP (Data Loss Prevention) feature of NeuVector to recognize patterns in our HTTP packet. That was great but what could you do when the traffic is not in clear text but encrypted with HTTPS instead? I ended my previous blog saying that we would then need to apply a different security strategy. Let&#8217;s find out what we can do and how NeuVector can help with that.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="511" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-1-1024x511.png" alt="Encrypted data exfiltration" class="wp-image-32092" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-1-1024x511.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-1-300x150.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-1-768x384.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-1-1536x767.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-1.png 1890w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-application-baseline">Application Baseline</h2>



<p class="wp-block-paragraph">Before deploying a new containerized application in production, you have to assess it first. From the security point of view it means you have to learn what processes are running in this container and what are the network connections to and from it.</p>



<p class="wp-block-paragraph">This observability phase will help you define what is the normal behaviour of your application. That will be your baseline.</p>



<p class="wp-block-paragraph">A good practice is to deploy first your application in a dev or test environment. Here you can do your assessment in a controlled environment. NeuVector can easily help you with this task as we can see in the picture below:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="399" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-2-1024x399.png" alt="Container processes assessment" class="wp-image-32137" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-2-1024x399.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-2-300x117.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-2-768x299.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-2-1536x599.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-2-2048x798.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">We can see all the processes that are currently running in the application&#8217;s container.</p>



<p class="wp-block-paragraph">To exfiltrate data you will also need a connection to an external website or server that is under the control of the attacker. With NeuVector we can see all the connections related to this container as shown below:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="386" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-3-1024x386.png" alt="Network connection assessment" class="wp-image-32138" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-3-1024x386.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-3-300x113.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-3-768x289.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-3-1536x578.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-3-2048x771.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">We can see this container connects to the coredns pod of our cluster and has one external connection with a server outside of our cluster.</p>



<p class="wp-block-paragraph">We can get more information on this external server by looking at the network map and click on that connection:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="278" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-4-1024x278.png" alt="Network connection map and details" class="wp-image-32139" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-4-1024x278.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-4-300x81.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-4-768x208.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-4-1536x417.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-4-2048x555.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">All these information are key to your security strategy again encrypted data exfiltration. There are several ways to exfiltrate data but all involve running a process in that container. If it is not a malware, it could be a simple SSH or a curl command. As a security good practice, these tools shouldn&#8217;t be available in your application&#8217;s container. You have to reduce the possibility of attacks and exploitation to the minimum.</p>



<p class="wp-block-paragraph">Also data exfiltration requires a connection to an external server. As the traffic is encrypted, you will not get an alert and can&#8217;t use DLP. However, you&#8217;ll see an abnormal external connection for your application.</p>



<p class="wp-block-paragraph">It is then paramount to create a baseline of your application and investigate everything that is a drift from it.</p>



<h2 class="wp-block-heading" id="h-zero-trust-architecture-for-encrypted-data-exfiltration">Zero Trust Architecture for encrypted data exfiltration</h2>



<p class="wp-block-paragraph">Basically zero trust means you don&#8217;t trust anything or anybody. In our topic about encrypted data exfiltration, it means we don&#8217;t trust any behaviour that is not part of the normal behaviour of our application (our baseline).</p>



<p class="wp-block-paragraph">NeuVector can help us with that too. Once we are confident, we have learned all the normal behaviour of our application, we are ready to move it to production. Here we can monitor any drift from our baseline as shown below:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="278" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-5-1024x278.png" alt="Monitor drift from baseline in a zero trust strategy" class="wp-image-32145" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-5-1024x278.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-5-300x81.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-5-768x209.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-5-1536x417.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-5-2048x556.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">We switch the mode for this container from Discover to Monitor. By default Zero drift is set which means we will now log any new behaviour that is unknown. We can see this new mode for our container below:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="361" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-6-1024x361.png" alt="container switched to monitor mode" class="wp-image-32146" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-6-1024x361.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-6-300x106.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-6-768x271.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-6-1536x541.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-6-2048x721.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Let&#8217;s now see how we could detect an encrypted data exfiltration by looking at the &#8220;Network Activity&#8221; map:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="263" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-7-1-1024x263.png" alt="Detection of abnormal connection" class="wp-image-32160" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-7-1-1024x263.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-7-1-300x77.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-7-1-768x197.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-7-1-1536x395.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-7-1-2048x526.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">In addition to our normal external connection, we see another one using port 443 (HTTPS). This is a drift from our baseline and you&#8217;ll have to investigate it. We can check the security events to learn more about it:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="265" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-8-1-1024x265.png" alt="Security events logs of our compromised container" class="wp-image-32162" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-8-1-1024x265.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-8-1-300x78.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-8-1-768x199.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-8-1-1536x398.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-8-1-2048x530.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">We can first see an alert about a <strong>curl</strong> process that is not part of the processes we have identified as normal in our baseline. NeuVector logs it as a process profile rule violation. We then see another violation, this one is related to our networking rules. There is an implicit deny rule for any traffic that is not what has been discovered by NeuVector (in our baseline). Setting our container in monitoring mode will not stop that traffic, it will log these drifts as security events and we have then to investigate.</p>



<p class="wp-block-paragraph">With these 2 informations we have a high probability that our container has been compromised. We can&#8217;t say if it is data exfiltration or something else, you can just see a process in your container is connecting to an unknown external server. Note that even if it connects just once, it will be captured by NeuVector. So even stealthy connections will be detected.</p>



<p class="wp-block-paragraph">At this stage, you have to investigate to discard a false positive alert. Maybe somebody did some tests with that container to check connectivity for example. Once you are confident this is abnormal, you can take some actions to stop this abnormal behavior. To do so we switch our container into &#8220;Protect&#8221; mode to block any drift. You can do that directly from the map as shown below:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="637" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-9-1024x637.png" alt="" class="wp-image-32169" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-9-1024x637.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-9-300x187.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-9-768x477.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/NeuVector-SSN-Encrypted-9.png 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">From this point NeuVector will block any network traffic or process that is not part of our baseline.</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">Congratulations! We have detected and protected our container and indirectly our cluster by applying a zero trust security strategy. As the traffic is encrypted we can&#8217;t see what it is and can&#8217;t tell it is precisely data exfiltration. However we have identified its operating pattern and were able to block it. From there you can investigate deeper how this container has been compromised by checking the logs, reviewing the accesses and the roles in your cluster.</p>



<p class="wp-block-paragraph">Note that this zero trust strategy allows you to defeat not only encrypted data exfiltration but any unknown attack as well. It is a very effective strategy and we recommend you to deploy it in your Kubernetes cluster as a best practice. Stay safe!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/enhance-containers-security-prevent-encrypted-data-exfiltration-with-neuvector/">Enhance Containers Security &#8211; Prevent Encrypted Data Exfiltration with NeuVector</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/enhance-containers-security-prevent-encrypted-data-exfiltration-with-neuvector/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cloud Native Storage: Identify your storage</title>
		<link>https://www.dbi-services.com/blog/cloud-native-storage-identify-your-storage/</link>
					<comments>https://www.dbi-services.com/blog/cloud-native-storage-identify-your-storage/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Wed, 27 Mar 2024 14:25:35 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Cloud Native Storage]]></category>
		<category><![CDATA[cncf]]></category>
		<category><![CDATA[CNS]]></category>
		<category><![CDATA[csi]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[kubernetes]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=32106</guid>

					<description><![CDATA[<p>Welcome back in this series of blogs regarding Cloud Native Storage. Check my previous on Cloud Native Storage: Overview for the introduction. In this one, I will discuss about the process involved in choosing a cloud native storage product. If you remember my previous blog, I pasted the exhaustive (big!) list of products. Of course, [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/cloud-native-storage-identify-your-storage/">Cloud Native Storage: Identify your storage</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="635" height="432" src="http://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/cloud_storage.jpg" alt="" class="wp-image-30725" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/cloud_storage.jpg 635w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/cloud_storage-300x204.jpg 300w" sizes="auto, (max-width: 635px) 100vw, 635px" /></figure>
</div>


<p class="wp-block-paragraph">Welcome back in this series of blogs regarding Cloud Native Storage. Check my previous on <a href="https://www.dbi-services.com/blog/cloud-native-storage-overview/">Cloud Native Storage: Overview</a> for the introduction.</p>



<p class="wp-block-paragraph">In this one, I will discuss about the process involved in choosing a cloud native storage product. If you remember my previous blog, I pasted the exhaustive (big!) list of products. Of course, if you are familiar with Kubernetes you’ll probably know that we can create multiple storage classes, and you are right. The point here is more about choosing a product that will fit a specific workload.<br>Workload can be of several kinds.</p>



<ul class="wp-block-list">
<li>Databases</li>



<li>Stateless/stateful application</li>



<li>Monitoring stack</li>



<li>Web applications</li>



<li>Big datatest</li>



<li>Microservices architectures</li>



<li>e-commerce</li>



<li>Healthcare sensitive data</li>



<li>Machine learning</li>
</ul>



<h2 class="wp-block-heading" id="h-first-approach-know-your-constraints">First approach &#8211; Know your constraints</h2>



<p class="wp-block-paragraph">It&#8217;s mandatory to know what are the constraints when thinking about your workload. Let&#8217;s try to list some of them and determine which ones are relevant to your use case</p>



<ul class="wp-block-list">
<li>Reliability and durability</li>



<li>Scalability</li>



<li>Performance</li>



<li>Security</li>



<li>Cloud/On premise</li>



<li>Storage type (S3, nvme, …)</li>



<li>Cost</li>



<li>Lifecycle management</li>



<li>Observability</li>



<li>Ease of use</li>



<li>Vendor support</li>



<li>Popularity</li>
</ul>



<p class="wp-block-paragraph">There is so much to say regarding each constraints, that&#8217;s why I mentioned to do a short list of main constraints and secondly to weight them. This will help you focus on essential expectations. Let&#8217;s take an example with cost. You may remember that products with a white background are open source, it not only means the product is free to use but also that you&#8217;ll be able to compare different products and why not also compare a proprietary product with trials that are often offered.</p>



<p class="wp-block-paragraph">We can also take the performance constraint. This one is essential with relational databases workload. If it&#8217;s your case and you&#8217;re new with the topic, you&#8217;ve probably chosen the local PV storage to maximize latency and throughput, but with more experience you&#8217;ll find that products like</p>



<ul class="wp-block-list">
<li>Portworx that allows you to control IOPS or throughput at the storage layer <a href="https://blog.purestorage.com/products/bringing-proven-enterprise-table-stakes-to-kubernetes-portworx/">here</a>.</li>



<li>Linbit that has impressive IOPS performance <a href="https://linbit.com/blog/iops-world-record-broken-linbit-tops-14-8-million-iops/">here</a></li>
</ul>



<h2 class="wp-block-heading" id="h-adoption">Adoption</h2>



<p class="wp-block-paragraph">Another constraint example I would like to talk about is popularity. Most of the products should be either supported by vendor or adopted by majority of the community so it guarantees you (a certain degree) of confidence to use it. My opinion reflect of course a &#8220;majority adopter&#8221; posture. In case your posture is &#8220;early&#8221;, it means you probably contribute to open source, then I just want to say &#8220;Thank you!&#8221; and keep going. I hope I will also be able to contribute in a near future. In case your posture is &#8220;laggards&#8221;, then continue your analysis with PoC to gain confidence.<br>You&#8217;ll find below the Innovation model lifecycle from Wikipedia.</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/45/DiffusionOfInnovation.png/384px-DiffusionOfInnovation.png" alt="Graphical view of innovation adoption lifecycle with from the left innovators, early adopters, early majority, late majority and Laggards" style="width:562px;height:auto" /></figure>
</div>


<p class="wp-block-paragraph">All kinds of adopters have their pros and cons and contribute to the community by giving feedbacks from their usage.</p>



<p class="wp-block-paragraph">This brings me to the next point I wanted to mention in this blog. How can we discuss with contributors, users and vendor.<br>Let&#8217;s take the easy point with vendor. If you have something to discuss (issue, remarks, usage, feedback) the official vendor communication channels (e-mail, slack, sales, ticket, etc …) will be the best.<br>Now, regarding open-source products, there are severals way to discuss points, you have official vendor communication channels (e-mail, slack, sales, ticket, etc …) and also what you can find from people usage (stackoverflow, reddit, …).<br>Of course, said like that open-source has more possibility to get you answer. But the main difference is SLA with a product you paid for, vendor will have to give you an answer in a defined timeframe regarding the priority given to your ticket.</p>



<h2 class="wp-block-heading" id="h-conclusion">Conclusion</h2>



<p class="wp-block-paragraph">All discussed points brings us to the final words that</p>



<ul class="wp-block-list">
<li>There is no silver bullet solution</li>



<li>You have to know and weight your constraints</li>



<li>You need to know where you stand regarding adoption</li>
</ul>



<p class="wp-block-paragraph">We, at dbi services, can provide support to help you choose and also accompany you on your journey to understand the <a href="https://landscape.cncf.io/guide#runtime--cloud-native-storage">CNCF</a>. Don&#8217;t hesitate to post comments or contact our sales team for support.</p>



<p class="wp-block-paragraph">In the next blog, I&#8217;ll go deeper with a concrete example of a database workload that will leverage on a cloud native storage.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/cloud-native-storage-identify-your-storage/">Cloud Native Storage: Identify your storage</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/cloud-native-storage-identify-your-storage/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)

Served from: www.dbi-services.com @ 2026-08-05 06:46:28 by W3 Total Cache
-->