<?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>Archives des Docker - dbi Blog</title>
	<atom:link href="https://www.dbi-services.com/blog/category/docker/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.dbi-services.com/blog/category/docker/</link>
	<description></description>
	<lastBuildDate>Thu, 14 Aug 2025 14:52:16 +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>Archives des Docker - dbi Blog</title>
	<link>https://www.dbi-services.com/blog/category/docker/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>SQL Server 2025: Local SQL Server Container – Schema design preview</title>
		<link>https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-design-preview/</link>
					<comments>https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-design-preview/#respond</comments>
		
		<dc:creator><![CDATA[Stéphane Haby]]></dc:creator>
		<pubDate>Wed, 25 Jun 2025 12:52:26 +0000</pubDate>
				<category><![CDATA[Development & Performance]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Technology Survey]]></category>
		<category><![CDATA[Microsoft]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=39320</guid>

					<description><![CDATA[<p>After my blogs about “SQL Server 2025: Local SQL Server Container without Docker Command” and “SQL Server 2025: Local SQL Server Container – Schema compare preview”, I continue to play &#38; test it. One new feature in preview is the “Schema Design compare” in this last MSSQL extension for Visual Studio Code: Let’s start and [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-design-preview/">SQL Server 2025: Local SQL Server Container – Schema design preview</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">After my blogs about “<a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-without-docker-command/"><strong>SQL Server 2025: Local SQL Server Container without Docker Command</strong></a>” and “<a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-compare-preview/"><strong>SQL Server 2025: Local SQL Server Container – Schema compare preview</strong></a>”, I continue to play &amp; test it.</p>



<p class="wp-block-paragraph">One new feature in preview is the “<strong>Schema Design compare</strong>” in this last<a href="https://code.visualstudio.com/download"> MSSQL extension for Visual Studio Code</a>:</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="605" height="873" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-88.png" alt="" class="wp-image-39321" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-88.png 605w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-88-208x300.png 208w" sizes="(max-width: 605px) 100vw, 605px" /></figure>



<p class="wp-block-paragraph">Let’s start and see on a database (db2 in my example):</p>



<figure class="wp-block-image size-full"><img decoding="async" width="938" height="425" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-89.png" alt="" class="wp-image-39322" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-89.png 938w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-89-300x136.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-89-768x348.png 768w" sizes="(max-width: 938px) 100vw, 938px" /></figure>



<p class="wp-block-paragraph">Et voila, I have my 2 tables created during the test on Schema Compare blog here</p>



<figure class="wp-block-image size-full"><img decoding="async" width="939" height="503" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-90.png" alt="" class="wp-image-39323" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-90.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-90-300x161.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-90-768x411.png 768w" sizes="(max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">Now, I create a new table t3 with some columns:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="386" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-91.png" alt="" class="wp-image-39324" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-91.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-91-300x123.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-91-768x316.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">Very easy to create a table without being a SQL Expert.</p>



<p class="wp-block-paragraph">As you can see, you have easily access to the option and add some specific input like the size or a default value.</p>



<p class="wp-block-paragraph">The table t3 is created with a primary key on column c1.</p>



<p class="wp-block-paragraph">Now, I change my table t2 and want to put c1 as primary key.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="940" height="426" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-92.png" alt="" class="wp-image-39325" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-92.png 940w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-92-300x136.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-92-768x348.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></figure>



<p class="wp-block-paragraph">To edit the table t2, just click on the pen:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="633" height="364" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-93.png" alt="" class="wp-image-39326" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-93.png 633w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-93-300x173.png 300w" sizes="auto, (max-width: 633px) 100vw, 633px" /></figure>



<p class="wp-block-paragraph">In the edit table, I just check the column c1 as primary key:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="419" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-94.png" alt="" class="wp-image-39327" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-94.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-94-300x134.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-94-768x343.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">And I have my primary key on table t2:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="938" height="517" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-95.png" alt="" class="wp-image-39328" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-95.png 938w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-95-300x165.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-95-768x423.png 768w" sizes="auto, (max-width: 938px) 100vw, 938px" /></figure>



<p class="wp-block-paragraph">Now, I want do link between my 3 tables (this is named/known as a Foreign Key&#8230;)</p>



<p class="wp-block-paragraph">First between t2 and t3, I go the side of the table t2 and a blue point appears. Take it and go to the table t3</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="670" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-96.png" alt="" class="wp-image-39329" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-96.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-96-300x214.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-96-768x548.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="655" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-97.png" alt="" class="wp-image-39330" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-97.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-97-300x209.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-97-768x536.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">Let’s try between the table t2 and the table t1</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="423" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-98.png" alt="" class="wp-image-39331" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-98.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-98-300x135.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-98-768x346.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">Aie! Error message:</p>



<ul class="wp-block-list">
<li><strong><em>Failed to create a foreign key</em></strong></li>



<li><strong><em>Column ‘c1’ must be a primary key</em></strong></li>
</ul>



<p class="wp-block-paragraph">It’s very good to have this control and information.</p>



<p class="wp-block-paragraph">This will help a lot of developers&#8230;</p>



<p class="wp-block-paragraph">I will not continue more with the design.<br>It’s already and really a good tool to design our schema.</p>



<p class="wp-block-paragraph">One good point is the <strong>export button</strong> to have the schema design as a picture with 3 formats possibilities svg ,png or jpeg.</p>



<p class="wp-block-paragraph">No excuse to not do a documentation! <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>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="508" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-99.png" alt="" class="wp-image-39332" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-99.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-99-300x162.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-99-768x415.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">The <strong>definition button </strong>gives you the design script:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="940" height="732" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-100.png" alt="" class="wp-image-39333" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-100.png 940w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-100-300x234.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-100-768x598.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></figure>



<p class="wp-block-paragraph">The last button to use is the <strong>Publish Changes</strong>:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="938" height="523" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-101.png" alt="" class="wp-image-39334" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-101.png 938w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-101-300x167.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-101-768x428.png 768w" sizes="auto, (max-width: 938px) 100vw, 938px" /></figure>



<p class="wp-block-paragraph">I wait a little bit, and I have the resume of the design change:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="559" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-102.png" alt="" class="wp-image-39335" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-102.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-102-300x179.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-102-768x457.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I like the checkbox “I have read the summary and understand the potential risks” and I publish.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">It’s just a discovery about the Schema design preview.</p>



<p class="wp-block-paragraph">It will be a good help for developers.</p>



<p class="wp-block-paragraph">See you soon for the next episode! <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"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-design-preview/">SQL Server 2025: Local SQL Server Container – Schema design preview</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/sql-server-2025-local-sql-server-container-schema-design-preview/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server 2025: Local SQL Server Container &#8211; Schema compare preview</title>
		<link>https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-compare-preview/</link>
					<comments>https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-compare-preview/#respond</comments>
		
		<dc:creator><![CDATA[Stéphane Haby]]></dc:creator>
		<pubDate>Tue, 24 Jun 2025 15:37:40 +0000</pubDate>
				<category><![CDATA[Development & Performance]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Technology Survey]]></category>
		<category><![CDATA[Microsoft]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=39301</guid>

					<description><![CDATA[<p>After my blog about “SQL Server 2025: Local SQL Server Container without Docker Command”, I continue to play &#38; test it. One new feature in preview is the “schema compare” in this last extension for Visual Code: I like new feature and now let’s go for a test! 😉 I create 2 identically databases db1 [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-compare-preview/">SQL Server 2025: Local SQL Server Container &#8211; Schema compare preview</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">After my blog about “<a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-without-docker-command/">SQL Server 2025: Local SQL Server Container without Docker Command</a>”, I continue to play &amp; test it.</p>



<p class="wp-block-paragraph">One new feature in preview is the “<strong>schema compare</strong>” in this last extension for Visual Code:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="464" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-73.png" alt="" class="wp-image-39302" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-73.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-73-300x148.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-73-768x380.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I like new feature and now let’s go for a test! <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">I create 2 identically databases db1 &amp; db2 with 2 tables and some data inside:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="934" height="1024" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-74-934x1024.png" alt="" class="wp-image-39303" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-74-934x1024.png 934w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-74-273x300.png 273w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-74-768x842.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-74.png 939w" sizes="auto, (max-width: 934px) 100vw, 934px" /></figure>



<p class="wp-block-paragraph">I do a select on both tables on both databases to see if everything is the same:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="636" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-75.png" alt="" class="wp-image-39304" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-75.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-75-300x203.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-75-768x520.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I run the “<strong>schema compare</strong>” to be sure I have everything is aligned:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="495" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-76.png" alt="" class="wp-image-39305" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-76.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-76-300x158.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-76-768x405.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I select the source “db1”, select the target “db2” and click on compare:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="472" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-77.png" alt="" class="wp-image-39306" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-77.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-77-300x151.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-77-768x386.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="363" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-78.png" alt="" class="wp-image-39307" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-78.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-78-300x116.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-78-768x297.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="306" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-79.png" alt="" class="wp-image-39308" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-79.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-79-300x98.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-79-768x250.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">After few seconds (due to my small databases), we have the result:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="241" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-80.png" alt="" class="wp-image-39309" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-80.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-80-300x77.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-80-768x197.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">Good! No schema differences were found! It&#8217;s a good start&#8230;</p>



<p class="wp-block-paragraph">Now, I play and change a little bit the db1:</p>



<ul class="wp-block-list">
<li>On table t1:
<ul class="wp-block-list">
<li>Add a column c4</li>



<li>Drop a column c1</li>



<li>Change the data type of the column c2</li>
</ul>
</li>
</ul>



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



<ul class="wp-block-list">
<li>Create a new schema test2</li>
</ul>



<ul class="wp-block-list">
<li>Transfer the table t2 from schema dbo to scema test2</li>
</ul>



<ul class="wp-block-list">
<li>Create a new table t3</li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="605" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-81.png" alt="" class="wp-image-39310" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-81.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-81-300x193.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-81-768x495.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I run again the schema compare&#8230;</p>



<p class="wp-block-paragraph">This time, we have a result:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="330" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-82.png" alt="" class="wp-image-39311" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-82.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-82-300x105.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-82-768x270.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I have all my change but like other tools it will delete the table dbo.t2 and create a new one test2.t2. This is not really the same as a schema transfer&#8230;</p>



<p class="wp-block-paragraph">Otherwise, we see the missing table dbo.t2</p>



<p class="wp-block-paragraph">I will now run the compare in the other way db2 as source and db1 as target:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="213" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-83.png" alt="" class="wp-image-39312" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-83.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-83-300x68.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-83-768x174.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I see now the delete of what I change on db1, then it’s good and fine except the schema transfer like usual&#8230;</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="448" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-84.png" alt="" class="wp-image-39313" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-84.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-84-300x143.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-84-768x366.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I come back to my precedent comparison and this I use the “<strong>Switch Direction</strong>”:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="416" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-85.png" alt="" class="wp-image-39314" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-85.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-85-300x133.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-85-768x340.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I test now the <strong>script generation</strong>:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="938" height="484" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-86.png" alt="" class="wp-image-39315" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-86.png 938w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-86-300x155.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-86-768x396.png 768w" sizes="auto, (max-width: 938px) 100vw, 938px" /></figure>



<p class="wp-block-paragraph">Et voila, I have my change script:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="581" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-87.png" alt="" class="wp-image-39316" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-87.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-87-300x186.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-87-768x475.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">It will be very nice to use for developers but as you see in my post, you need to be careful with your change (schema change for tables), control and test the script generated before do it on Production databases!</p>



<p class="wp-block-paragraph">See you soon for the next test on my Local SQL Server Container! <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>L’article <a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-schema-compare-preview/">SQL Server 2025: Local SQL Server Container &#8211; Schema compare preview</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/sql-server-2025-local-sql-server-container-schema-compare-preview/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server 2025: Local SQL Server Container without Docker Command</title>
		<link>https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-without-docker-command/</link>
					<comments>https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-without-docker-command/#respond</comments>
		
		<dc:creator><![CDATA[Stéphane Haby]]></dc:creator>
		<pubDate>Mon, 23 Jun 2025 09:37:30 +0000</pubDate>
				<category><![CDATA[Database Administration & Monitoring]]></category>
		<category><![CDATA[Database management]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Technology Survey]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[Microsoft]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=39261</guid>

					<description><![CDATA[<p>The last version of” MSSQL extension for Visual Studio Code” has in Preview &#8220;the Local SqlServer Containers&#8221; based on SQL Server 2025 with the following keys: See all Preview Features here First Step: Download and install Visual Studio Code here Second Step: Download and install MSSQL extension for Visual Studio Code here You can also [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-without-docker-command/">SQL Server 2025: Local SQL Server Container without Docker Command</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 last version of” <strong>MSSQL extension for Visual Studio Code</strong>” has in Preview &#8220;<strong>the Local SqlServer Containers</strong>&#8221; based on SQL Server 2025 with the following keys:</p>



<ul class="wp-block-list">
<li>Create and manage SQL Server containers locally without Docker commands</li>



<li>Use SQL Server 2025 by default with vector and AI-ready features</li>



<li>Auto-connect with a ready-to-use connection profile</li>



<li>Start, stop, restart, or delete containers from the connection panel</li>



<li>Automatic port conflict detection and resolution</li>



<li>Customize container name, hostname, port, and version</li>
</ul>



<p class="wp-block-paragraph">See all Preview Features <a href="https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql">here</a></p>



<p class="wp-block-paragraph"><strong>First Step</strong>: Download and install Visual Studio Code <a href="https://code.visualstudio.com/download">here</a></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="940" height="486" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-46.png" alt="" class="wp-image-39262" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-46.png 940w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-46-300x155.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-46-768x397.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="931" height="727" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-47.png" alt="" class="wp-image-39263" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-47.png 931w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-47-300x234.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-47-768x600.png 768w" sizes="auto, (max-width: 931px) 100vw, 931px" /></figure>



<p class="wp-block-paragraph"><strong>Second Step</strong>: Download and install MSSQL extension for Visual Studio Code <a href="https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql">here</a></p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="939" height="652" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-48.png" alt="" class="wp-image-39264" style="aspect-ratio:1;width:431px;height:auto" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-48.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-48-300x208.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-48-768x533.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">You can also directly from Visual Code, download and install the extension:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="938" height="623" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-49.png" alt="" class="wp-image-39265" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-49.png 938w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-49-300x199.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-49-768x510.png 768w" sizes="auto, (max-width: 938px) 100vw, 938px" /></figure>



<p class="wp-block-paragraph">I choose this easy way&#8230;</p>



<p class="wp-block-paragraph">After few minutes, it’s ready to use:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="631" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-50.png" alt="" class="wp-image-39266" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-50.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-50-300x202.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-50-768x516.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph"><strong>Third</strong> <strong>Step</strong>: create the Local SQL Server Container</p>



<p class="wp-block-paragraph">Go to the “SQL Server” tab, select the “Create Local SQL Container” in the “connections” menu:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="940" height="498" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-51.png" alt="" class="wp-image-39267" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-51.png 940w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-51-300x159.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-51-768x407.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></figure>



<p class="wp-block-paragraph">Oups&#8230; I forget to install Docker:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="940" height="523" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-52.png" alt="" class="wp-image-39268" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-52.png 940w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-52-300x167.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-52-768x427.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></figure>



<p class="wp-block-paragraph"><strong>Second Step BIS</strong>: Download and Install Docker on my desktop <a href="https://docs.docker.com/get-started/introduction/get-docker-desktop/">here</a></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="716" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-53.png" alt="" class="wp-image-39269" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-53.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-53-300x229.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-53-768x586.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="653" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-54.png" alt="" class="wp-image-39270" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-54.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-54-300x209.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-54-768x534.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">Et voila, Docker is installed:</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="939" height="652" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-55.png" alt="" class="wp-image-39271" style="width:585px;height:auto" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-55.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-55-300x208.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-55-768x533.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">After the restart, I go back to my SQL Server connection in Visual Code.</p>



<p class="wp-block-paragraph">I see that I’m ready to start&#8230;</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="386" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-56.png" alt="" class="wp-image-39272" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-56.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-56-300x123.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-56-768x316.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I can choose the SQL Server image until the version of SQL 2017:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="939" height="359" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-57.png" alt="" class="wp-image-39273" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-57.png 939w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-57-300x115.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-57-768x294.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></figure>



<p class="wp-block-paragraph">I choose the SQL server 2025 version, enter a password and a profile name:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="934" height="377" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-58.png" alt="" class="wp-image-39274" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-58.png 934w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-58-300x121.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-58-768x310.png 768w" sizes="auto, (max-width: 934px) 100vw, 934px" /></figure>



<p class="wp-block-paragraph">Check also Accept the Terms &amp; Conditions after reading it of course like every time&#8230;</p>



<p class="wp-block-paragraph">I press the button “Create Container”:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="938" height="408" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-59.png" alt="" class="wp-image-39275" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-59.png 938w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-59-300x130.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-59-768x334.png 768w" sizes="auto, (max-width: 938px) 100vw, 938px" /></figure>



<p class="wp-block-paragraph">The are three steps:</p>



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



<li>Setting up container</li>



<li>Connecting to Container</li>
</ul>



<p class="wp-block-paragraph">After few minutes, my container is online and ready to be use direclty:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="938" height="386" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-60.png" alt="" class="wp-image-39276" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-60.png 938w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-60-300x123.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-60-768x316.png 768w" sizes="auto, (max-width: 938px) 100vw, 938px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="539" height="652" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-61.png" alt="" class="wp-image-39277" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-61.png 539w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-61-248x300.png 248w" sizes="auto, (max-width: 539px) 100vw, 539px" /></figure>



<p class="wp-block-paragraph"><strong>Last</strong> <strong>Step</strong>: Test the connection with a query</p>



<p class="wp-block-paragraph">I open a query and just do a SELECT @@Version and a SELECT @@Servername:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="940" height="444" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-62.png" alt="" class="wp-image-39278" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-62.png 940w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-62-300x142.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/06/image-62-768x363.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></figure>



<p class="wp-block-paragraph">As you can see, we have the SQL server in version 2025 &amp; Edition Developer on Linux Ubuntu installed without any Docker command to deploy it&#8230;</p>



<p class="wp-block-paragraph"><strong>Conclusion</strong></p>



<p class="wp-block-paragraph">Very easy to install and do the first steps with this new feature and without any skills in Docker command&#8230;</p>



<p class="wp-block-paragraph">I know a lot of developers who want to use it asap! <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"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/sql-server-2025-local-sql-server-container-without-docker-command/">SQL Server 2025: Local SQL Server Container without Docker Command</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/sql-server-2025-local-sql-server-container-without-docker-command/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Building multi-architecture images with GitLab CI/CD</title>
		<link>https://www.dbi-services.com/blog/building-multi-architecture-images-with-gitlab-ci-cd/</link>
					<comments>https://www.dbi-services.com/blog/building-multi-architecture-images-with-gitlab-ci-cd/#respond</comments>
		
		<dc:creator><![CDATA[Nicolas Meunier]]></dc:creator>
		<pubDate>Fri, 06 Dec 2024 09:06:15 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[YaK]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[GitlabCI/CD]]></category>
		<category><![CDATA[Image buid]]></category>
		<category><![CDATA[multi-architecture]]></category>
		<category><![CDATA[x86]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=35955</guid>

					<description><![CDATA[<p>Building multi-architecture images become more and more useful. Indeed, many recent computers use ARM processors architecture. Examples include MacBooks using M(x) processors, and Amazon EC2 instances using AWS Graviton processors. However, the diversification of processor architectures adds a new level of complexity to the creation of container images. Indeed, the construction has to cope with [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/building-multi-architecture-images-with-gitlab-ci-cd/">Building multi-architecture images with GitLab CI/CD</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">Building multi-architecture images become more and more useful. Indeed, many recent computers use ARM processors architecture. Examples include MacBooks using M(x) processors, and Amazon EC2 instances using <a href="https://aws.amazon.com/fr/ec2/graviton/">AWS Graviton</a> processors.</p>



<p class="wp-block-paragraph">However, the diversification of processor architectures adds a new level of complexity to the creation of container images. Indeed, the construction has to cope with different instruction sets.</p>



<h2 class="wp-block-heading" id="h-docker-buildx-the-solution-for-building-multi-architecture-images">Docker buildx, the solution for building multi-architecture images</h2>



<p class="wp-block-paragraph">For the <a href="https://gitlab.com/yak4all/yak_core">YaK</a> project, we want to make amd64 (x86) and arm64 images available using GitLab CI/CD.</p>



<p class="wp-block-paragraph">In order to create a build compatible with several architectures, I had to use “docker buildx” in my .gitlab-ci.yml file:</p>



<pre class="wp-block-code"><code>build:
  image: docker:latest
  stage: build
  services:
    - docker:dind
  before_script:
    - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
    - docker buildx create --name yakbuilder --use
  script:
    - docker buildx build --pull --builder=yakbuilder --platform linux/amd64,linux/arm64 -t &#091;IMG]:&#091;TAG] --push .
</code></pre>



<h3 class="wp-block-heading" id="h-how-it-works">How it works:</h3>



<ul class="wp-block-list">
<li>In the <code>"before_script"</code> section , I initialize a QEMU container to emulate ARM architecture and to create a buildx context using the QEMU container</li>



<li>In the <code>"script"</code> section itself, instead of a simple &#8220;docker build&#8221;, I use the <code>"docker <strong>buildx</strong> build"</code> command</li>



<li>I also pass the buildx context created in the <code>"before_script"</code> with the <code>--builder</code> flag</li>



<li>Finally, I add the list of architectures required for the build with the <code>--platform</code> flag</li>
</ul>



<h2 class="wp-block-heading" id="h-build-result">Build Result</h2>



<p class="wp-block-paragraph">With this method, the build is slower. That&#8217;s normal as several images are created (one per architecture) instead of just one.</p>



<p class="wp-block-paragraph">The result can be seen in the GitLab container registry:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="428" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/11/Container-registry-1024x428.png" alt="container registry details" class="wp-image-35958" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/11/Container-registry-1024x428.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/11/Container-registry-300x125.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/11/Container-registry-768x321.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/11/Container-registry.png 1070w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Now, below the image tag, a small “index” label is shown. This refers to the fact that several images are available for this tag. During the image pull, the container engine will choose the image version corresponding to its architecture.</p>



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



<p class="wp-block-paragraph">With <strong>buildx</strong> and QEMU in GitLab CI/CD, building multi-architecture images is easy. You can manage different processor architectures and meet the needs of a wide range of users and ensure the compatibility of your container images.</p>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/building-multi-architecture-images-with-gitlab-ci-cd/">Building multi-architecture images with GitLab CI/CD</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/building-multi-architecture-images-with-gitlab-ci-cd/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>Rancher RKE2 templates &#8211; Assign members to clusters</title>
		<link>https://www.dbi-services.com/blog/rancher-rke2-templates-assign-members-to-clusters/</link>
					<comments>https://www.dbi-services.com/blog/rancher-rke2-templates-assign-members-to-clusters/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 12 Mar 2024 10:23:46 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Docker]]></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=31199</guid>

					<description><![CDATA[<p>When testing RKE2 templates, I faced an issue with member assignments. When creating the cluster, a management cluster name is generated with the format c-m-xxxxxxxx, but the ClusterRoleTemplateBinding requires the cluster name to work. After digging into Rancher source code, I found out how to set the management cluster name. So let&#8217;s start! Force the [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/rancher-rke2-templates-assign-members-to-clusters/">Rancher RKE2 templates &#8211; Assign members to clusters</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">When testing RKE2 templates, I faced an issue with member assignments. When creating the cluster, a management cluster name is generated with the format c-m-xxxxxxxx, but the ClusterRoleTemplateBinding requires the cluster name to work. After digging into Rancher source code, I found out how to set the management cluster name. So let&#8217;s start!</p>



<h2 class="wp-block-heading" id="h-force-the-cluster-name-with-rke2-templates">Force the cluster name with RKE2 templates</h2>



<h3 class="wp-block-heading" id="h-investigation">Investigation</h3>



<p class="wp-block-paragraph">When searching how the cluster name is generated when provisioning, I found the following code in the Rancher GitHub repository.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: go; title: ; notranslate">
func mgmtClusterName() (string, error) {
	rand, err := randomtoken.Generate()
	if err != nil {
		return &quot;&quot;, err
	}
	return name.SafeConcatName(&quot;c&quot;, &quot;m&quot;, rand&#x5B;:8]), nil
}
</pre></div>


<p class="wp-block-paragraph">From the function mgmtClusterName I was able to find the following code.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: go; title: ; notranslate">
if mgmtClusterNameAnnVal, ok := cluster.Annotations&#x5B;mgmtClusterNameAnn]; ok &amp;&amp; mgmtClusterNameAnnVal != &quot;&quot; &amp;&amp; newCluster.Name == &quot;&quot; {
	// If the management cluster name annotation is set to a non-empty value, and the mgmt cluster name has not been set yet, set the cluster name to the mgmt cluster name.
	newCluster.Name = mgmtClusterNameAnnVal
} else if newCluster.Name == &quot;&quot; {
	// If the management cluster name annotation is not set and the cluster name has not yet been generated, generate and set a new mgmt cluster name.
	mgmtName, err := mgmtClusterName()
	if err != nil {
		return nil, status, err
	}
	newCluster.Name = mgmtName
}
</pre></div>


<p class="wp-block-paragraph">Which finally leads to the following annotation.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: go; title: ; notranslate">
mgmtClusterNameAnn    = &quot;provisioning.cattle.io/management-cluster-name&quot;
</pre></div>


<h3 class="wp-block-heading" id="h-forced-the-management-cluster-name">Forced the management cluster name</h3>



<p class="wp-block-paragraph">To avoid using the generated Cluster Name given by mgmtClusterName(), we can add the following annotation &#8220;provisioning.cattle.io/management-cluster-name&#8221; into the cluster.provisioning.cattle.io resources.</p>



<p class="wp-block-paragraph">We can pick the same code from the Rancher template example in ClusterRoleTemplateBinding and do the following.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
apiVersion: provisioning.cattle.io/v1
kind: Cluster
metadata:
  annotations:
    provisioning.cattle.io/management-cluster-name: c-m-{{ trunc 8 (sha256sum (printf &quot;%s/%s&quot; $.Release.Namespace $.Values.cluster.name)) }}
  {{- if .Values.cluster.annotations }}
{{ toYaml .Values.cluster.annotations | indent 4 }}
  {{- end }}
</pre></div>


<p class="wp-block-paragraph">The template code above will ensure that the management cluster name will always be the one we generated ourselves.<br>Now let&#8217;s check the ClusterRoleTemplateBinding resource for automatically assigning users and groups.</p>



<h2 class="wp-block-heading" id="h-rke2-clusterroletemplatebinding">RKE2 ClusterRoleTemplateBinding</h2>



<p class="wp-block-paragraph">To predefined users and groups into the cluster, we can use the template clusterroletemplatebinding.yaml.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
{{ $root := . }}
{{- range $index, $member := .Values.clusterMembers }}
apiVersion: management.cattle.io/v3
clusterName: c-m-{{ trunc 8 (sha256sum (printf &quot;%s/%s&quot; $root.Release.Namespace $root.Values.cluster.name)) }}
kind: ClusterRoleTemplateBinding
metadata:
  name: ctrb-{{ trunc 8 (sha256sum (printf &quot;%s/%s/%s&quot; $root.Release.Namespace $member.principalName $member.roleTemplateName )) }}
  namespace: c-m-{{ trunc 8 (sha256sum (printf &quot;%s/%s&quot; $root.Release.Namespace $root.Values.cluster.name)) }}
roleTemplateName: {{ $member.roleTemplateName }}
userPrincipalName: {{ $member.principalName }}
{{- end }}
</pre></div>


<p class="wp-block-paragraph">For the metadata.name, I added the RoleTemplateName to avoid identical names if you add the same user with different roles.</p>



<p class="wp-block-paragraph">In the values.yaml you will need to provide the following information:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
clusterMembers:
- principalName: &quot;local://u-xxxxx&quot;
   roleTemplateName: &quot;cluster-member&quot;
- principalName: &quot;local://u-xxxxx&quot;
   roleTemplateName: &quot;cluster-owner&quot;
</pre></div>


<p class="wp-block-paragraph">When using only local users, it is easier as you only specify local:// with the ID of the user. But if you use groups, you may not know what value to provide. The same applies to your custom roles. The easiest way is to manually assign your members, and read the YAML files created.</p>



<p class="wp-block-paragraph">For this example, I am adding my GitHub group &#8220;teamA&#8221; as a cluster member, and a local user &#8220;autoscaler&#8221; as a cluster owner.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="340" src="http://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-41-1024x340.png" alt="" class="wp-image-31104" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-41-1024x340.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-41-300x99.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-41-768x255.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-41-1536x509.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-41.png 1912w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Now go to More Resources &gt; RBAC &gt; ClusterRoleBindings and sort by age.<br>You should find the values to specify for principalName and roleTemplateName.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="352" src="http://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-42-1024x352.png" alt="" class="wp-image-31105" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-42-1024x352.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-42-300x103.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-42-768x264.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-42-1536x528.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-42.png 1913w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-new-issues">New issues</h2>



<p class="wp-block-paragraph">When the cluster is created for the first time, Rancher automatically creates the namespace. ClusterRoleTemplateBinding needs to be deployed into this namespace. Therefore it cannot be created at the creation of the cluster. In addition, it needs to wait for the Cluster resources to be provisioned by Rancher.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
helm install --generate-name=true --namespace=fleet-default --timeout=10m0s --values=/home/shell/helm/values-dbiservices-template-ec2-0.0.1.yaml --version=0.0.1 --wait=true /home/shell/helm/dbiservices-template-ec2-0.0.1.tgz
2024-02-28T12:57:21.998195671Z Error: INSTALLATION FAILED: 1 error occurred:
2024-02-28T12:57:21.998226718Z 	* namespaces &quot;c-m-dc91e1f4&quot; not found

or 

2024-03-04T11:48:15.121066673Z 	* admission webhook &quot;rancher.cattle.io.clusterroletemplatebindings.management.cattle.io&quot; denied the request: clusterroletemplatebinding.clusterName: Invalid value: &quot;c-m-dc91e1f4&quot;: specified cluster c-m-dc91e1f4 not found
</pre></div>


<p class="wp-block-paragraph">Therefore, to ensure the assignment of users, the Helm charts must be updated after being deployed the first time.</p>



<p class="wp-block-paragraph">In the local &gt; Apps &gt; Installed Apps, in the fleet-default namespace, edit/update the App, and redeploy it. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="268" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-105-1024x268.png" alt="" class="wp-image-31442" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-105-1024x268.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-105-300x79.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-105-768x201.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-105-1536x402.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-105-2048x536.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">You don&#8217;t need to change any values. It will deploy correctly the ClusterRoleTemplateBinding and assign the users/groups.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
helm upgrade --history-max=5 --install=true --namespace=fleet-default --timeout=10m0s --values=/home/shell/helm/values-dbiservices-template-ec2-0.0.1.yaml --version=0.0.1 --wait=true dbiservices-template-ec2-0-1709125040 /home/shell/helm/dbiservices-template-ec2-0.0.1.tgz
2024-02-28T13:02:07.755854608Z checking 6 resources for changes
2024-02-28T13:02:07.770167607Z Patch Amazonec2Config &quot;dbiservices-template-rke2-ec2-template-controlplane&quot; in namespace fleet-default
2024-02-28T13:02:07.795076109Z Patch Amazonec2Config &quot;dbiservices-template-rke2-ec2-template-workers&quot; in namespace fleet-default
2024-02-28T13:02:07.831247897Z Patch Cluster &quot;dbiservices-template-rke2-ec2&quot; in namespace fleet-default
2024-02-28T13:02:07.931325393Z Created a new ClusterRoleTemplateBinding called &quot;ctrb-d4063a0e&quot; in c-m-dc91e1f4
2024-02-28T13:02:07.931347721Z 
2024-02-28T13:02:07.961962070Z Patch ManagedChart &quot;monitoring-crd-dbiservices-template-rke2-ec2&quot; in namespace fleet-default
2024-02-28T13:02:08.027434827Z Patch ManagedChart &quot;monitoring-dbiservices-template-rke2-ec2&quot; in namespace fleet-default
2024-02-28T13:02:08.065622593Z beginning wait for 6 resources with timeout of 10m0s
2024-02-28T13:02:08.126940145Z Release &quot;dbiservices-template-ec2-0-1709125040&quot; has been upgraded. Happy Helming!
2024-02-28T13:02:08.126959636Z NAME: dbiservices-template-ec2-0-1709125040
2024-02-28T13:02:08.126964700Z LAST DEPLOYED: Wed Feb 28 13:02:06 2024
2024-02-28T13:02:08.126969197Z NAMESPACE: fleet-default
2024-02-28T13:02:08.126973071Z STATUS: deployed
2024-02-28T13:02:08.126977312Z REVISION: 2
2024-02-28T13:02:08.126981410Z TEST SUITE: None
2024-02-28T13:02:08.150360499Z 
2024-02-28T13:02:08.150390675Z ---------------------------------------------------------------------
2024-02-28T13:02:08.156224976Z SUCCESS: helm upgrade --history-max=5 --install=true --namespace=fleet-default --timeout=10m0s --values=/home/shell/helm/values-dbiservices-template-ec2-0.0.1.yaml --version=0.0.1 --wait=true dbiservices-template-ec2-0-17091
/home/shell/helm/dbiservices-template-ec2-0.0.1.tgz
2024-02-28T13:02:08.157013523Z ---------------------------------------------------------------------
</pre></div>


<p class="wp-block-paragraph">The following member roles have been created for the clusters and are showing in the cluster configuration.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
- principalName: &quot;local://u-g9bq8&quot;
  roleTemplateName: &quot;cluster-owner&quot;
- principalName: &quot;github_team://8426662&quot;
  roleTemplateName: &quot;cluster-member&quot;
- principalName: &quot;local://u-g9bq8&quot;
  roleTemplateName: &quot;rt-tz9xs&quot;
</pre></div>


<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="396" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-106-1024x396.png" alt="" class="wp-image-31443" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-106-1024x396.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-106-300x116.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-106-768x297.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-106-1536x595.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-106-2048x793.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-helm-lookup">Helm lookup</h2>



<p class="wp-block-paragraph">Due to that issue with the namespace, setting the management cluster name doesn&#8217;t bring much advantage, as we need to manually redeploy the App (cluster template) to assign the users/groups.</p>



<p class="wp-block-paragraph">Therefore we can use Helm function lookup, which can directly read the cluster name from the Kubernetes local cluster. Same as precedent, we need to redeploy the App (cluster template) the first time as it needs multiple resources to be provisioned by Rancher first.</p>



<p class="wp-block-paragraph">Here is the code for the clusterroletemplatebinding.yaml</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
{{- $root := . }}
{{- $fetchedcluster :=  (lookup &quot;provisioning.cattle.io/v1&quot; &quot;Cluster&quot; &quot;fleet-default&quot; .Values.cluster.name) }}
{{- if ($fetchedcluster.status| default nil).clusterName | default nil }}
  {{- range $index, $member := .Values.clusterMembers }}
---
apiVersion: management.cattle.io/v3
clusterName: {{ $fetchedcluster.status.clusterName }}
kind: ClusterRoleTemplateBinding
metadata:
  name: ctrb-{{ trunc 8 (sha256sum (printf &quot;%s/%s/%s&quot; $root.Release.Namespace $member.principalName $member.roleTemplateName )) }}
  namespace: {{ $fetchedcluster.status.clusterName }}
roleTemplateName: {{ $member.roleTemplateName }}
userPrincipalName: {{ $member.principalName }}
  {{- end }}
{{- end }}
</pre></div>


<p class="wp-block-paragraph">It will look into fleet-default for the cluster.provisionning.catte.io/v1 that is created by the RKE2 templates itself. On the first deployment of the RKE2 templates, it doesn&#8217;t exist yet, therefore an &#8220;if&#8221; condition is added.<br>Once the RKE2 template is deployed, you can like precedently, edit the App to redeploy it, and it will then create the ClusterRoleTemplateBinding.</p>



<p class="wp-block-paragraph">The helm install will show no errors as the ClusterRoleTemplateBinding resources are skipped.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
helm install --generate-name=true --namespace=fleet-default --timeout=10m0s --values=/home/shell/helm/values-dbiservices-template-ec2-0.0.1.yaml --version=0.0.1 --wait=true /home/shell/helm/dbiservices-template-ec2-0.0.1.tgz
2024-02-28T13:18:48.886232477Z creating 5 resource(s)
beginning wait for 5 resources with timeout of 10m0s
2024-02-28T13:18:49.098629894Z NAME: dbiservices-template-ec2-0-1709126327
2024-02-28T13:18:49.098705783Z LAST DEPLOYED: Wed Feb 28 13:18:47 2024
NAMESPACE: fleet-default
STATUS: deployed
2024-02-28T13:18:49.098717154Z REVISION: 1
2024-02-28T13:18:49.098720727Z TEST SUITE: None
2024-02-28T13:18:49.126871035Z 
2024-02-28T13:18:49.126936065Z ---------------------------------------------------------------------
2024-02-28T13:18:49.135118662Z SUCCESS: helm install --generate-name=true --namespace=fleet-default --timeout=10m0s --values=/home/shell/helm/values-dbiservices-template-ec2-0.0.1.yaml --version=0.0.1 --wait=true /home/shell/helm/dbiservices-template-ec2-0.0.1.tgz
---------------------------------------------------------------------
</pre></div>


<p class="wp-block-paragraph">And then, when redeploying the App, it does show the creation of the resources as the cluster name now exists.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
helm upgrade --history-max=5 --install=true --namespace=fleet-default --timeout=10m0s --values=/home/shell/helm/values-dbiservices-template-ec2-0.0.1.yaml --version=0.0.1 --wait=true dbiservices-template-ec2-0-1709126327 /home/shell/helm/dbiservices-template-ec2-0.0.1.tgz
checking 8 resources for changes
Patch Amazonec2Config &quot;kke-test-template-controlplane&quot; in namespace fleet-default
Patch Amazonec2Config &quot;kke-test-template-workers&quot; in namespace fleet-default
Patch Cluster &quot;kke-test&quot; in namespace fleet-default
Created a new ClusterRoleTemplateBinding called &quot;ctrb-96090621&quot; in c-m-58wcfhnl
2024-02-28T13:24:13.652797054Z 
Created a new ClusterRoleTemplateBinding called &quot;ctrb-2c866242&quot; in c-m-58wcfhnl

Created a new ClusterRoleTemplateBinding called &quot;ctrb-d4063a0e&quot; in c-m-58wcfhnl
2024-02-28T13:24:13.689031588Z 
Patch ManagedChart &quot;monitoring-crd-kke-test&quot; in namespace fleet-default
Patch ManagedChart &quot;monitoring-kke-test&quot; in namespace fleet-default
beginning wait for 8 resources with timeout of 10m0s
Release &quot;dbiservices-template-ec2-0-1709126327&quot; has been upgraded. Happy Helming!
2024-02-28T13:24:13.872941208Z NAME: dbiservices-template-ec2-0-1709126327
2024-02-28T13:24:13.872946743Z LAST DEPLOYED: Wed Feb 28 13:24:11 2024
2024-02-28T13:24:13.872951269Z NAMESPACE: fleet-default
2024-02-28T13:24:13.872955002Z STATUS: deployed
2024-02-28T13:24:13.872958850Z REVISION: 4
2024-02-28T13:24:13.872962507Z TEST SUITE: None

---------------------------------------------------------------------
SUCCESS: helm upgrade --history-max=5 --install=true --namespace=fleet-default --timeout=10m0s --values=/home/shell/helm/values-dbiservices-template-ec2-0.0.1.yaml --version=0.0.1 --wait=true dbiservices-template-ec2-0-1709126327 /home/shell/helm/dbiservices-template-ec2-0.0.1.tgz
---------------------------------------------------------------------
</pre></div>


<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="455" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-108-1024x455.png" alt="" class="wp-image-31449" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-108-1024x455.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-108-300x133.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-108-768x341.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-108-1536x683.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-108-2048x910.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="448" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-107-1024x448.png" alt="" class="wp-image-31448" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-107-1024x448.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-107-300x131.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-107-768x336.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-107-1536x673.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/image-107-2048x897.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



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



<p class="wp-block-paragraph">The assignment of users/groups to a cluster through a template is not simple. My approach might be wrong but It was the first solution I thought of when I encountered the problem.<br>The issue of waiting for the creation (first deployment with Helm) is a little bit annoying but is not much of an issue when you are aware of redeploying the RKE2 template. Also if you use Fleet to continuously deploy/update managed clusters, you could add the values for member configuration after the first deployment to avoid managing through the UI like above.<br><br>Below is the link to the GitHub Repository branch for the RKE2 templates using a fixed management cluster name and Helm function lookup.</p>



<h2 class="wp-block-heading" id="h-sources">Sources</h2>



<ul class="wp-block-list">
<li>Official documentation for RKE2 templates<br><a href="https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/manage-clusters/manage-cluster-templates#rke2-cluster-template">https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/manage-clusters/manage-cluster-templates#rke2-cluster-template</a></li>



<li>GitHub Branch for clusterroles<br><a href="https://github.com/kkedbi/cluster-template-examples/tree/clusterroles">https://github.com/kkedbi/cluster-template-examples/tree/clusterroles</a></li>
</ul>



<h2 class="wp-block-heading" id="h-blog">Blog</h2>



<ul class="wp-block-list">
<li>RKE2 Autoscaling<br><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></li>



<li>Reestablish administrator role access to rancher users<br><a href="https://www.dbi-services.com/blog/reestablish-administrator-role-access-to-rancher-users/">https://www.dbi-services.com/blog/reestablish-administrator-role-access-to-rancher-users/</a></li>



<li>Introduction and RKE2 cluster template for AWS EC2<br><a href="https://www.dbi-services.com/blog/?p=30957" target="_blank" rel="noreferrer noopener">https://www.dbi-services.com/blog/rancher-rke2-cluster-templates-for-aws-ec2</a></li>
</ul>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/rancher-rke2-templates-assign-members-to-clusters/">Rancher RKE2 templates &#8211; Assign members to clusters</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-templates-assign-members-to-clusters/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Are You Afraid of the Word DevOps? &#8211; Part 2</title>
		<link>https://www.dbi-services.com/blog/are-you-afraid-of-the-word-devops-part-2/</link>
					<comments>https://www.dbi-services.com/blog/are-you-afraid-of-the-word-devops-part-2/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Mon, 29 Jan 2024 07:24:55 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[containerization]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[microservices]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=30424</guid>

					<description><![CDATA[<p>In my previous blog post, we started to explore how to increase the Time-to-Market (TTM) of your simple application. We improved it and to go further we will now leverage containerization. As in part 1, I intend to explain this simply to be accessible to everyone. The Current Status Your application is running for a [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/are-you-afraid-of-the-word-devops-part-2/">Are You Afraid of the Word DevOps? &#8211; Part 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 my previous <a href="https://www.dbi-services.com/blog/are-you-afraid-of-the-word-devops-part-1/" target="_blank" rel="noreferrer noopener">blog post</a>, we started to explore how to increase the Time-to-Market (TTM) of your simple application. We improved it and to go further we will now leverage containerization. As in part 1, I intend to explain this simply to be accessible to everyone.</p>



<h2 class="wp-block-heading" id="h-the-current-status">The Current Status</h2>



<p class="wp-block-paragraph">Your application is running for a while now but you came to realize of a few limitations. Your application being monolithic, it is not easy to scale because the frontend requirement is different than the backend database. The frontend needs to absorb a changing amount of traffic that will vary during the days for example. On the other end, the database just needs redundancy.</p>



<p class="wp-block-paragraph">Your application is successful and you need to deploy more frontend to cope with the increase of traffic. With your current application design, that means deploying another frontend and backend on another server. Then you may need to repeat that operation again and now your application is clumsy. Each frontend writes into its own database but this is not a good practice. Instead we should have for example two databases (one active, one standby) and several frontend that will all write into the same active database. These data are then regularly replicated in the standby one.</p>



<h2 class="wp-block-heading" id="h-third-acceleration">Third Acceleration</h2>



<p class="wp-block-paragraph">A better way to design our application is to split the frontend and the backend into two separate packages. We can then decorrelate both components and deploy them separately. We can now increase the number of frontend as we need without touching the backend.</p>



<p class="wp-block-paragraph">Another improvement is to install each of these both components in a separate Virtual Machine (VM) instead of a physical server. Having a VM allows the developer to have its own separated environment to deploy your application. He could then pass that VM to the operation team, it should work right away. It is good for the operation to also do some tests, however for the production, it will be better to reconstruct the whole environment cleanly. Also the VMs are not easily scalable so this is only a small improvement. The intent here is to give you a comparison example between a VM and a container we will see in the next section.</p>



<p class="wp-block-paragraph">The speed of your TTM at this stage is as shown below:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="248" height="204" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/TTM-4.png" alt="" class="wp-image-30480" /></figure>
</div>


<h2 class="wp-block-heading" id="h-forth-acceleration">Forth Acceleration</h2>



<p class="wp-block-paragraph">At this stage what can improve our TTM is to leverage containerization. A container is different than a VM because he doesn&#8217;t contain the whole Operating System, it just contains what it needs to operate. So it is smaller in size and start faster than a VM.</p>



<p class="wp-block-paragraph">You have now to convert your application into containers. Basically each component will be a separate container. Depending of the size of your application as well as the number of developers that are working on it, you may have to split the frontend itself into several containers. The good practice is to put one function into one container and keep the whole loosely connected. Each container stays independent and can be upgraded without impacting the others. This process is called containerization and your application can now be called a microservice or cloud-native. In case you meet these words, you will now know what they mean: An application that is now a group of containers working together.</p>



<p class="wp-block-paragraph">To keep it simple, we will just have 2 containers. One for the frontend and one for the backend. The script we used in part 1 to create the environment and install the application is now replaced by a set of instructions used to build what we call an image. This image then contains all the environment and dependencies required by the application. This image is immutable and can be passed on to the operation that can safely use it in production. It is cleaner than a VM and much smaller so that is a preferred choice.</p>



<p class="wp-block-paragraph">A container will use that image and run it to make the component up and running. A container can be killed and re-created very quickly. Also it is very easy to add frontend capacity for example by just launching a new container with the frontend image. However this creation is still manual as the container can&#8217;t scale automatically.</p>



<p class="wp-block-paragraph">The speed of our TTM improved again:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="249" height="205" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/TTM-5-1.png" alt="" class="wp-image-30485" /></figure>
</div>


<h2 class="wp-block-heading" id="h-fifth-acceleration">Fifth Acceleration</h2>



<p class="wp-block-paragraph">When your application has a lot of containers and the need to scale out (add containers) or scale in (remove containers) becomes frequent, doing it manually is cumbersome. This is the time to think about hosting your application into a Kubernetes cluster. Kubernetes is a container orchestrator tool that provides plenty of features to give flexibility and scalability to your application. The container (it is actually called a Pod in Kubernetes that is a wrap around the container but let&#8217;s keep it simple) autoscaling is one of them. If the frontend becomes too loaded, Kubernetes will automatically adds a new one based on criteria you configure. On the opposite if the traffic is very low, one frontend is removed. This is a simple example for you to get an idea of it.</p>



<p class="wp-block-paragraph">Another feature of Kubernetes is to easily deploy replicas of your containers. A replica will be hosted on a separate nodes and thus make your application resilient in case of a hardware failure.</p>



<p class="wp-block-paragraph">Kubernetes provides also the ability to deploy a new release of your application with different strategy and avoid or reduce the downtime of your application.</p>



<p class="wp-block-paragraph">From there, it is now even possible to give the developers access to the Kubernetes cluster where they could deploy their application directly by themselves! They will have a separate environment production-like to do their tests. There is then no separation anymore between developers and operations and this is the spirit of you-know-which-word (I consider you&#8217;ve read the part 1!)!</p>



<p class="wp-block-paragraph">If you want to learn more about Docker containers and Kubernetes, our <a href="https://www.dbi-services.com/courses/docker-and-kubernetes-essential-skills/" target="_blank" rel="noreferrer noopener">Training course</a> can be just what you need! Check it out!</p>



<p class="wp-block-paragraph">Now the speed of our TTM improved a bit more as the deployment of your application will be quicker:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="248" height="201" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/TTM-5.png" alt="" class="wp-image-30483" /></figure>
</div>


<p class="wp-block-paragraph">The Kubernetes flavour of Red Hat is called OpenShit which provides additional feature to vanilla Kubernetes. OpenShift has been optimized to let a developer quickly deploy its application directly from its code. This code will become an image that will be used to deploy some containers in the OpenShift cluster. All of these intermediary steps are taken care of by OpenShift. This is what a pipeline is doing without naming it! That is the automation pushed to its finest and this is the ultimate goal to reach. In this case our TTM is approaching the speed of light:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="248" height="170" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/TTM-7.png" alt="" class="wp-image-30489" /></figure>
</div>


<p class="wp-block-paragraph">Kubernetes is a complex technology and if you don&#8217;t use it yet, you will have some homework to do to decide which flavour and which platform you are going to use:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="572" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/Multi-choices-of-Kubernetes-1024x572.png" alt="" class="wp-image-30490" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/Multi-choices-of-Kubernetes-1024x572.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/Multi-choices-of-Kubernetes-300x168.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/Multi-choices-of-Kubernetes-768x429.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/Multi-choices-of-Kubernetes-1536x859.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/01/Multi-choices-of-Kubernetes-2048x1145.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-some-final-thoughts">Some Final Thoughts</h2>



<p class="wp-block-paragraph">For some small applications, this embedded OpenShift pipeline can be enough, however for bigger applications there is a need for a more complex infrastructure to go from the code to a Kubernetes cluster. This is where you&#8217;ll use more advanced pipeline tools. In a nutshell, a pipeline will build a new image from your code source when it is completed and push it into a registry. Then, a container will be created and deployed in a Kubernetes cluster by using that new image from the registry.</p>



<p class="wp-block-paragraph">When your application is in production, used by end-users, you can collect metrics and feedback from them that will be used to improve your application. With a fast TTM, you can then quickly react to provide a feature in high-demand, innovate with smart add-ons or just fix a bug. This will all flow better, make your application shine and your business will thrive.</p>



<p class="wp-block-paragraph">To keep your TTM on track or give it a nudge, you also need someone that has the view of the whole process from the code development to the production and can help solve the issues during this journey. The Release Manager will perfectly fit in this role. You can check the <a href="https://www.linkedin.com/pulse/release-management-devops-world-emmanuel-wagner-3qwnc/" target="_blank" rel="noreferrer noopener">excellent article</a> of my colleague <strong>Emmanuel Wagner</strong> who shares his experience on this very topic.</p>



<h2 class="wp-block-heading" id="h-summary">Summary</h2>



<p class="wp-block-paragraph">The containerization with the flexibility offered by Kubernetes is a major step for your application to reach the market faster. By using OpenShift from Red Hat with its simple embedded pipeline allows a developer to quickly deploy your application without any knowledge on containers or Kubernetes. He can focus solely on development and quickly see the final result.</p>



<p class="wp-block-paragraph">I hope you&#8217;ve enjoyed this journey and have a clearer idea of what the DevOps process is through this simple example. To be successful with your excellent application, remember to start with small improvements and build up on that!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/are-you-afraid-of-the-word-devops-part-2/">Are You Afraid of the Word DevOps? &#8211; Part 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/are-you-afraid-of-the-word-devops-part-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>All about how Docker containers and data are stored on its host</title>
		<link>https://www.dbi-services.com/blog/all-about-how-docker-containers-and-data-are-stored-on-its-host/</link>
					<comments>https://www.dbi-services.com/blog/all-about-how-docker-containers-and-data-are-stored-on-its-host/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Fri, 30 Jun 2023 13:06:56 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Containers]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=26409</guid>

					<description><![CDATA[<p>You&#8217;ve probably already heard about containers and one of the most popular tool used to create them: Docker. You may wonder how a container stores data on its host, if those data are persistent, if you can find them on the server hosting this container and more broadly how a container is stored on this [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/all-about-how-docker-containers-and-data-are-stored-on-its-host/">All about how Docker containers and data are stored on its host</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">You&#8217;ve probably already heard about containers and one of the most popular tool used to create them: <a href="https://www.docker.com" target="_blank" rel="noreferrer noopener">Docker</a>. You may wonder how a container stores data on its host, if those data are persistent, if you can find them on the server hosting this container and more broadly how a container is stored on this host. Those are very good questions so let&#8217;s dive into this topic by looking at some examples.</p>



<h2 class="wp-block-heading" id="h-data-into-one-docker-container">Data into one Docker container</h2>



<p class="wp-block-paragraph">I&#8217;ve got a Rocky Linux 8 virtual machine and I&#8217;ve installed docker in it. Let&#8217;s just create a container with an Ubuntu image on it to play with and understand its interactions with the host.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ sudo docker container run -it --name myubuntu ubuntu:18.04
...
root@5dd708fd5afb:/# 
</pre></div>


<p class="wp-block-paragraph">We directly connect into our Ubuntu container and the first test we are going to do is to create a file inside this container with a name that will be easy to find on the host:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@5dd708fd5afb:/# touch benoit

root@5dd708fd5afb:/# ls
benoit  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@5dd708fd5afb:/#
</pre></div>


<p class="wp-block-paragraph">I&#8217;ve created a file with my first name that I can now find on my Rocky host:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo find /var/lib/docker/ -name benoit
/var/lib/docker/overlay2/6796ec566b5bbdbcfa99efe742a042b574c17633a504d2d31f87a604e194f0a1/diff/benoit
/var/lib/docker/overlay2/6796ec566b5bbdbcfa99efe742a042b574c17633a504d2d31f87a604e194f0a1/merged/benoit
</pre></div>


<p class="wp-block-paragraph">This file is found in 2 folders. Docker container uses the storage driver overlay2 to store files. You can find all the detailed informations related to it in the <a href="https://docs.docker.com/storage/storagedriver/overlayfs-driver/" target="_blank" rel="noreferrer noopener">Docker documentation</a>. On the Rocky host you can see in the path name to our file the default folder where all the container data are stored: <strong>/var/lib/docker/overlay2/</strong> It is then followed by a directory ID and one of the folder used by overlay2: <strong>diff</strong>,  <strong>link</strong>, <strong>lower</strong>, <strong>merged</strong> and <strong>work</strong>. Without entering into too much details, <strong>diff</strong> is the content of the container layer and <strong>merged</strong> is the unified view of files from the image and container layer.</p>



<p class="wp-block-paragraph">So from the host you have access to the content of a container but it is not recommended to interact directly with it as Docker could get confused (it is one of its tasks to manage that).</p>



<p class="wp-block-paragraph">Then, I exited from this container:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
root@5dd708fd5afb:/# exit
exit
&#x5B;rocky ~]$
</pre></div>


<p class="wp-block-paragraph">Let&#8217;s have a look at what we can see on the host:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo find /var/lib/docker/ -name benoit
/var/lib/docker/overlay2/6796ec566b5bbdbcfa99efe742a042b574c17633a504d2d31f87a604e194f0a1/diff/benoit
</pre></div>


<p class="wp-block-paragraph">The file only appear in the <strong>diff</strong> folder. The container has exited but has not been deleted so let&#8217;s restart it and see if we can still see our file:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo docker ps -a
CONTAINER ID   IMAGE           COMMAND                  CREATED             STATUS                      PORTS     NAMES
5dd708fd5afb   ubuntu:18.04    &quot;/bin/bash&quot;              About an hour ago   Exited (0) 6 minutes ago              myubuntu

&#x5B;rocky ~]$ sudo docker start myubuntu
myubuntu

&#x5B;rocky ~]$ sudo docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED             STATUS         PORTS     NAMES
5dd708fd5afb   ubuntu:18.04   &quot;/bin/bash&quot;   About an hour ago   Up 8 seconds             myubuntu

&#x5B;rocky ~]$ sudo docker exec -it -u 0 myubuntu bash

root@5dd708fd5afb:/# ls
benoit  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
</pre></div>


<p class="wp-block-paragraph">So yes our file is still there! Do we still see it on our Rocky host then?</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo find /var/lib/docker/ -name benoit
/var/lib/docker/overlay2/6796ec566b5bbdbcfa99efe742a042b574c17633a504d2d31f87a604e194f0a1/diff/benoit
/var/lib/docker/overlay2/6796ec566b5bbdbcfa99efe742a042b574c17633a504d2d31f87a604e194f0a1/merged/benoit
</pre></div>


<p class="wp-block-paragraph">Yep, as the container is started we can now see our file again in the <strong>merged</strong> folder. Until the container is deleted, the files created in it are available as they are stored on the host.</p>



<h2 class="wp-block-heading" id="h-data-into-two-docker-containers">Data into two Docker containers</h2>



<p class="wp-block-paragraph">Now let&#8217;s do another test by deleting this container and creating two of them. In each container we&#8217;ll create a file called benoit. In one ssh session:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo docker container run -it --name myubuntu ubuntu:18.04

root@68171839b27d:/# touch benoit

root@68171839b27d:/# ls
benoit  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
</pre></div>


<p class="wp-block-paragraph">Then in another ssh session:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo docker container run -it --name myubuntu2 ubuntu:18.04

root@4ba803c23419:/# touch benoit

root@4ba803c23419:/# ls
benoit  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
</pre></div>


<p class="wp-block-paragraph">Let&#8217;s now find out what we see on the Rocky host:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo find /var/lib/docker/ -name benoit
/var/lib/docker/overlay2/3f074ba37b28f5f2cc533b405ecab3762c092fa406511dc2637264fc0a936200/diff/benoit
/var/lib/docker/overlay2/3f074ba37b28f5f2cc533b405ecab3762c092fa406511dc2637264fc0a936200/merged/benoit
/var/lib/docker/overlay2/710466e337a994b608e0e65bdd55b803d25c5ebbec81db77f17d74eb830c852f/diff/benoit
/var/lib/docker/overlay2/710466e337a994b608e0e65bdd55b803d25c5ebbec81db77f17d74eb830c852f/merged/benoit
</pre></div>


<p class="wp-block-paragraph">As expected we have 2 pairs of our file in 2 separate folders. One for each container. You may wonder if there is a link between this directory ID and the container ID. Let&#8217;s have a look:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS         PORTS     NAMES
4ba803c23419   ubuntu:18.04   &quot;/bin/bash&quot;   7 minutes ago   Up 7 minutes             myubuntu2
68171839b27d   ubuntu:18.04   &quot;/bin/bash&quot;   7 minutes ago   Up 7 minutes             myubuntu
</pre></div>


<p class="wp-block-paragraph">There is no link so how would you know which file belong to which container? I&#8217;m glad you asked! We need to inspect our container in order to link the directory ID to a container ID as shown below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo docker inspect 4ba803c23419 |grep -i upper
                &quot;UpperDir&quot;: &quot;/var/lib/docker/overlay2/710466e337a994b608e0e65bdd55b803d25c5ebbec81db77f17d74eb830c852f/diff&quot;,

&#x5B;rocky ~]$ sudo docker inspect 68171839b27d |grep -i upper
                &quot;UpperDir&quot;: &quot;/var/lib/docker/overlay2/3f074ba37b28f5f2cc533b405ecab3762c092fa406511dc2637264fc0a936200/diff&quot;,
</pre></div>


<p class="wp-block-paragraph">Look at this! By inspecting our container we can see the folder used to store its data on our Rocky host.</p>



<p class="wp-block-paragraph">Finally let&#8217;s delete both containers and see what happens to the data it contained:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo docker ps -a
CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS                       PORTS     NAMES
4ba803c23419   ubuntu:18.04    &quot;/bin/bash&quot;              17 minutes ago   Exited (127) 8 seconds ago             myubuntu2
68171839b27d   ubuntu:18.04    &quot;/bin/bash&quot;              17 minutes ago   Exited (0) 14 seconds ago              myubuntu

&#x5B;rocky ~]$ sudo docker rm 4ba803c23419 68171839b27d
4ba803c23419
68171839b27d

&#x5B;rocky ~]$ sudo find /var/lib/docker/ -name benoit

&#x5B;rocky ~]$ sudo ls /var/lib/docker/overlay2/3f074ba37b28f5f2cc533b405ecab3762c092fa406511dc2637264fc0a936200
ls: cannot access &#039;/var/lib/docker/overlay2/3f074ba37b28f5f2cc533b405ecab3762c092fa406511dc2637264fc0a936200&#039;: No such file or directory

&#x5B;rocky ~]$ sudo ls /var/lib/docker/overlay2/710466e337a994b608e0e65bdd55b803d25c5ebbec81db77f17d74eb830c852f
ls: cannot access &#039;/var/lib/docker/overlay2/710466e337a994b608e0e65bdd55b803d25c5ebbec81db77f17d74eb830c852f&#039;: No such file or directory
</pre></div>


<p class="wp-block-paragraph">Now our files are gone with the container and they have been deleted from the Rocky host as well. In order to keep container data, you&#8217;ll need to create volumes on which data persists even after the container has been deleted.</p>



<h2 class="wp-block-heading" id="h-how-is-a-container-stored-on-its-host">How is a container stored on its host</h2>



<p class="wp-block-paragraph">Now that we have seen where a file created inside a container is stored on the Rocky host, let&#8217;s find out where the container itself is stored on our Rocky host:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
c2032ee57de7   ubuntu:18.04   &quot;/bin/bash&quot;   10 minutes ago   Up 10 minutes             myubuntu

&#x5B;rocky ~]$ sudo docker inspect c2032ee57de7| grep Id
        &quot;Id&quot;: &quot;c2032ee57de7097d6e050bc0b2561c8044baae710f01be570cf65ad7e62c7e24&quot;,

&#x5B;rocky ~]$ sudo ls /var/lib/docker/containers/c2032ee57de7097d6e050bc0b2561c8044baae710f01be570cf65ad7e62c7e24
c2032ee57de7097d6e050bc0b2561c8044baae710f01be570cf65ad7e62c7e24-json.log  checkpoints	config.v2.json	hostconfig.json  hostname  hosts  mounts  resolv.conf  resolv.conf.hash
</pre></div>


<p class="wp-block-paragraph">Easy! With the container ID we can find the associated folder that is stored in the containers folder of <strong>/var/lib/docker</strong></p>



<p class="wp-block-paragraph">After exiting from the container, we can now delete it and see the following:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
&#x5B;rocky ~]$ sudo docker ps -a
CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS                      PORTS     NAMES
c2032ee57de7   ubuntu:18.04    &quot;/bin/bash&quot;              16 minutes ago   Exited (0) 10 seconds ago             myubuntu

&#x5B;rocky ~]$ sudo docker rm c2032ee57de7
c2032ee57de7

&#x5B;rocky ~]$ sudo ls /var/lib/docker/containers/c2032ee57de7097d6e050bc0b2561c8044baae710f01be570cf65ad7e62c7e24
ls: cannot access &#039;/var/lib/docker/containers/c2032ee57de7097d6e050bc0b2561c8044baae710f01be570cf65ad7e62c7e24&#039;: No such file or directory
</pre></div>


<p class="wp-block-paragraph">Our container folder on the Rocky host has been deleted at the same time as the container as we could expect.</p>



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



<p class="wp-block-paragraph">You should now have all the responses to our questioning at the beginning of this blog. I hope you&#8217;ve learned something interesting today. If you want to learn more about Docker and Kubernetes, or if you feel you have some gap in your knowledge, have a look at our dedicated <a href="https://www.dbi-services.com/courses/docker-and-kubernetes-essential-skills/" target="_blank" rel="noreferrer noopener">Workshop</a> on this topic. You&#8217;ll learned everything you need about those technologies with a lot of opportunities to practice with docker container. See you there!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/all-about-how-docker-containers-and-data-are-stored-on-its-host/">All about how Docker containers and data are stored on its host</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/all-about-how-docker-containers-and-data-are-stored-on-its-host/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Windows Server container on an AKS cluster</title>
		<link>https://www.dbi-services.com/blog/windows-server-container-on-an-aks-cluster/</link>
					<comments>https://www.dbi-services.com/blog/windows-server-container-on-an-aks-cluster/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Wed, 22 Mar 2023 09:16:02 +0000</pubDate>
				<category><![CDATA[Cloud]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[AKS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Containers]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[OMrun]]></category>
		<category><![CDATA[Windows Containers]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=23774</guid>

					<description><![CDATA[<p>A few weeks ago I participated at the dbi services bootcamp. All new employees are gathered for a refreshment of dbi services best practices. This is also an opportunity to ask questions directly to our CEO David Hueber as well as provide feedback on our enrolment experience in the company. dbi services is very keen [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/windows-server-container-on-an-aks-cluster/">Windows Server container on an AKS cluster</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">A few weeks ago I participated at the <a href="https://www.dbi-services.com" target="_blank" rel="noreferrer noopener">dbi services</a> bootcamp. All new employees are gathered for a refreshment of dbi services best practices. This is also an opportunity to ask questions directly to our CEO <strong>David Hueber</strong> as well as provide feedback on our enrolment experience in the company. dbi services is very keen on continuously improving his integration process.</p>



<p class="wp-block-paragraph">As part of this 1.5 days, we are grouped in teams and have to face some challenges like building famous monuments with LEGO with some weight limitations in the number of pieces we can pick. It is a good opportunity to be creative, work as a team and have a good laugh in the process!</p>



<p class="wp-block-paragraph">The final part of this bootcamp is to work together on a last minute request from a fictitious client. This request is very challenging and the time is limited. We get the instructions around 5:00pm and have to be ready by the next morning at 9:00am to present our solution. It requires all the brain power of each freshly hired dbi services employee to work together as an emergency task force to tackle this new project. We split the work between us to match our specialty at the best and thus give us all the chances to present a working solution. I took care of building the Kubernetes infrastructure on which we had to create Windows Server 2019 containers.</p>



<h2 class="wp-block-heading">The challenge</h2>



<p class="wp-block-paragraph">Yes you&#8217;ve read correctly: Windows in a container&#8230;really? I&#8217;ve never bothered to try it or even think about it. However the <a href="https://www.dbi-services.com/products/omrun/" target="_blank" rel="noreferrer noopener">OMrun</a> product (from <a href="https://www.omrun.ch/en/" target="_blank" rel="noreferrer noopener">OMIS</a> that has been integrated in dbi services) of our colleagues is working on Windows Server 2019 and so we had the challenge to make it run in a container&#8230; so a Windows one! We also needed to connect it to a MySQL Server instance and provide some redundancy.</p>



<p class="wp-block-paragraph">The time is short, so using a managed Kubernetes solution for orchestrating those Windows containers seemed right. Also as we needed Windows and MySQL Server then Azure AKS (the Microsoft managed Kubernetes solution) sounded like the right choice. Let&#8217;s see how to configure that, it&#8217;s kind of a LEGO but in a digitalised form!</p>



<h2 class="wp-block-heading">AKS cluster creation with Windows workers</h2>



<p class="wp-block-paragraph">A quick research in the Microsoft documentation and you find a useful <a href="https://learn.microsoft.com/en-us/azure/aks/learn/quick-windows-container-deploy-cli" target="_blank" rel="noreferrer noopener">article</a> for this very purpose. This is the configuration I&#8217;ve set for our project, directly from the Bash Azure Cloud Shell:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ az group create --name BootCampOmrun --location westeurope

$ echo &quot;Please enter the username to use as administrator credentials for Windows Server nodes on your cluster: &quot; &amp;&amp; read WINDOWS_USERNAME
</pre></div>


<p class="wp-block-paragraph">The first command creates a resource group which is like a folder in Azure that will contain all the resources you will create in it for this project. The second command asks you for a Windows username that will be stored in the variable WINDOWS_USERNAME. We will use it in the next command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ az aks create \
    --resource-group BootCampOmrun \
    --name AKSBootCamp \
    --node-count 3 \
    --enable-addons monitoring \
    --generate-ssh-keys \
    --windows-admin-username $WINDOWS_USERNAME \
    --vm-set-type VirtualMachineScaleSets \
    --network-plugin azure
</pre></div>


<p class="wp-block-paragraph">This command creates the AKS cluster in our resource group with 3 worker nodes. We are now asked to set the password for the parameter <strong>windows-admin-password</strong>. This username and password parameter set the administrator credentials for any Windows Server nodes on the cluster. Also the parameter <strong>generate-ssh-keys</strong> will create a private and public key used to connect to this AKS cluster.</p>



<p class="wp-block-paragraph">Those workers created with the AKS cluster are Linux workers. Now we need to add a Windows node pool that will create Windows workers on which we can create Windows containers (our goal!):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ az aks nodepool add \
    --resource-group BootCampOmrun \
    --cluster-name AKSBootCamp \
    --os-type Windows \
    --name npwin \
    --node-count 2 \
    --node-vm-size Standard_A4m_v2
</pre></div>


<p class="wp-block-paragraph">So we choose the <strong>os-type</strong> Windows and the <strong>node-vm-size</strong>. Those workers (like the Linux ones) are virtual machines in Azure and you have to select the proper size according to your requirement. OMrun needs 32G of memory so I&#8217;ve checked the Microsoft <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/av2-series" target="_blank" rel="noreferrer noopener">documentation</a> to choose the correct one at a decent price (yes cost budget is also a parameter to take into account for this project!).</p>



<p class="wp-block-paragraph">We can now see all the worker nodes in our AKS cluster:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl get nodes -owide
NAME                                STATUS   ROLES   AGE     VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION     CONTAINER-RUNTIME
aks-nodepool1-25638203-vmss000000   Ready    agent   4h24m   v1.24.9   10.224.0.62    &lt;none&gt;        Ubuntu 18.04.6 LTS               5.4.0-1103-azure   containerd://1.6.15+azure-1
aks-nodepool1-25638203-vmss000001   Ready    agent   4h24m   v1.24.9   10.224.0.33    &lt;none&gt;        Ubuntu 18.04.6 LTS               5.4.0-1103-azure   containerd://1.6.15+azure-1
aks-nodepool1-25638203-vmss000002   Ready    agent   4h24m   v1.24.9   10.224.0.4     &lt;none&gt;        Ubuntu 18.04.6 LTS               5.4.0-1103-azure   containerd://1.6.15+azure-1
aksnpwin000000                      Ready    agent   172m    v1.24.9   10.224.0.91    &lt;none&gt;        Windows Server 2019 Datacenter   10.0.17763.4010    containerd://1.6.14+azure
aksnpwin000001                      Ready    agent   172m    v1.24.9   10.224.0.122   &lt;none&gt;        Windows Server 2019 Datacenter   10.0.17763.4010    containerd://1.6.14+azure
</pre></div>


<p class="wp-block-paragraph">There are 3 Linux worker nodes and 2 Windows ones in our AKS cluster in version 1.24.9.</p>



<h2 class="wp-block-heading">Creation of a Windows container on a Windows worker</h2>



<p class="wp-block-paragraph">That is the last step to do and I&#8217;ve used the information from this <a href="https://kubernetes.io/docs/concepts/windows/user-guide/" target="_blank" rel="noreferrer noopener">website</a> in order to quickly create a Windows pod and container. I&#8217;ve used the following yaml file and saved it as podwin.yaml:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    app: omrun-bc
  name: omrun-bc
spec:
  containers:
  - name: omrun-bc
    image: mcr.microsoft.com/windows/servercore:ltsc2019
    command:
     - powershell.exe
     - -command
     - &quot;&lt;#code used from https://gist.github.com/19WAS85/5424431#&gt; ; $$listener = New-Object System.Net.HttpListener ; $$listener.Prefixes.Add(&#039;http://*:80/&#039;) ; $$listener.Start() ; $$callerCounts = @{} ; Write-Host(&#039;Listening at http://*:80/&#039;) ; while ($$listener.IsListening) { ;$$context = $$listener.GetContext() ;$$requestUrl = $$context.Request.Url ;$$clientIP = $$context.Request.RemoteEndPoint.Address ;$$response = $$context.Response ;Write-Host &#039;&#039; ;Write-Host(&#039;&gt; {0}&#039; -f $$requestUrl) ;  ;$$count = 1 ;$$k=$$callerCounts.Get_Item($$clientIP) ;if ($$k -ne $$null) { $$count += $$k } ;$$callerCounts.Set_Item($$clientIP, $$count) ;$$ip=(Get-NetAdapter | Get-NetIpAddress); $$header=&#039;&lt;html&gt;&lt;body&gt;&lt;H1&gt;Windows Container Web Server&lt;/H1&gt;&#039; ;$$callerCountsString=&#039;&#039; ;$$callerCounts.Keys | % { $$callerCountsString+=&#039;&lt;p&gt;IP {0} callerCount {1} &#039; -f $$ip&#x5B;1].IPAddress,$$callerCounts.Item($$_) } ;$$footer=&#039;&lt;/body&gt;&lt;/html&gt;&#039; ;$$content=&#039;{0}{1}{2}&#039; -f $$header,$$callerCountsString,$$footer ;Write-Output $$content ;$$buffer = &#x5B;System.Text.Encoding]::UTF8.GetBytes($$content) ;$$response.ContentLength64 = $$buffer.Length ;$$response.OutputStream.Write($$buffer, 0, $$buffer.Length) ;$$response.Close() ;$$responseStatus = $$response.StatusCode ;Write-Host(&#039;&lt; {0}&#039; -f $$responseStatus)  } ; &quot;
  nodeSelector:
    kubernetes.io/os: windows
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
</pre></div>


<p class="wp-block-paragraph">Now all is ready and we can apply this yaml file to be scheduled on one of our Windows worker and connect to this Windows container in command line:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl apply -f podwin.yaml 

$ kubectl exec -it omrun-bc -- cmd
</pre></div>


<p class="wp-block-paragraph">And voilà! I couldn&#8217;t believe my eyes to be connected to Windows CLI into a container!</p>



<h2 class="wp-block-heading">How to install OMrun in it?</h2>



<p class="wp-block-paragraph">So this is all good but here comes the tricky part. We have to install OMrun executables in this Windows Server 2019 container and I&#8217;ve tried several options.</p>



<p class="wp-block-paragraph">The first thing is to connect to this AKS cluster from my Mac laptop and install the Azure CLI:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
% brew install azure-cli
</pre></div>


<p class="wp-block-paragraph">It took a while and I could then copy the private and public key generated previously into my .ssh folder and test my connection:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
% az login

% az aks get-credentials --resource-group BootCampOmrun --name AKSBootCamp

% kubectl get nodes
NAME                                STATUS   ROLES   AGE     VERSION
aks-nodepool1-25638203-vmss000000   Ready    agent   4h15m   v1.24.9
aks-nodepool1-25638203-vmss000001   Ready    agent   4h15m   v1.24.9
aks-nodepool1-25638203-vmss000002   Ready    agent   4h15m   v1.24.9
aksnpwin000000                      Ready    agent   163m    v1.24.9
aksnpwin000001                      Ready    agent   163m    v1.24.9
</pre></div>


<p class="wp-block-paragraph">I&#8217;m now connected and can use kubectl (install the package first on your Mac) to interact with the AKS cluster.</p>



<p class="wp-block-paragraph">From there it got messy because AKS is nice but it is meant to manage your cluster so you can&#8217;t easily connect to the workers and containers from your machine as you would with a vanilla Kubernetes. The idea was to upload the OMrun executables to the Windows worker then the container and launch the installation in it. There are ways to connect to the workers through a Linux VM or through RDP in a Windows VM (my colleague <strong>Pierre Thanasack</strong> configured it successfully) in the resource group but that was not the proper way to go. We sticked with the DevOps best practice and created a Docker image we pushed on Docker Hub. Then in the yaml file of our pod we simply referenced that image and voilà&#8230; again!</p>



<p class="wp-block-paragraph">This is my colleague <strong>Ryan Badaï</strong> (one of our rising star in our DevOps Team) that took care of that part and installed all the OMrun executables over a Windows Server 2019 image and built the final docker image. So we had the complete OMrun product as an image that could be made available for our Windows container. Brilliant!</p>



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



<p class="wp-block-paragraph">What a journey! Thanks to this challenge we were able to push our limits, learn something new and present a working solution for such projects. We are now ready to respond to requests of real clients having such requirement. Of course we will need to work out all the details and make this configuration clean. We will also have to try to build Windows Server containers on other Kubernetes platform to have several options to offer for this solution.</p>



<p class="wp-block-paragraph">Real LEGO or containers are both fun and can be used to build great projects!</p>



<p class="wp-block-paragraph">Note for future newcomers, the challenges and project are different at each Bootcamp so be prepared to be amazed by this unique experience! Thank you dbi services for organising such event! #greatplacetowork</p>
<p>L’article <a href="https://www.dbi-services.com/blog/windows-server-container-on-an-aks-cluster/">Windows Server container on an AKS cluster</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/windows-server-container-on-an-aks-cluster/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Apache JMeter Playground</title>
		<link>https://www.dbi-services.com/blog/apache-jmeter-playground/</link>
					<comments>https://www.dbi-services.com/blog/apache-jmeter-playground/#respond</comments>
		
		<dc:creator><![CDATA[Middleware Team]]></dc:creator>
		<pubDate>Fri, 17 Feb 2023 14:55:42 +0000</pubDate>
				<category><![CDATA[Application integration & Middleware]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[JMeter]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[test]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=22710</guid>

					<description><![CDATA[<p>As I am training myself to Apache JMeter, beside testing on my Oracle environment (which include Oracle Internet Directory, Oracle Directory Service Manager, Oracle Identity and Access Management, a Database and a web application protected by SAML), I was looking for a tool to test more feature of it. I found a website called httpbin. [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/apache-jmeter-playground/">Apache JMeter Playground</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">As I am training myself to <a href="https://jmeter.apache.org/" target="_blank" rel="noreferrer noopener">Apache JMeter</a>, beside testing on my Oracle environment (which include Oracle Internet Directory, Oracle Directory Service Manager, Oracle Identity and Access Management, a Database and a web application protected by SAML), I was looking for a tool to test more feature of it.</p>



<p class="wp-block-paragraph">I found a website called <a href="https://httpbin.org" target="_blank" rel="noreferrer noopener">httpbin</a>. You can find plenty of tools to do online testing, but this one can even be self-hosted within a docker image.</p>



<p class="wp-block-paragraph">In this blog, I will explain how to setup httpbin and then use one of this many features to crawl a website to, for example, looking for dead links.</p>



<h2 class="wp-block-heading">httpbin</h2>



<p class="wp-block-paragraph">Starting httpbin is easy as running this command (and it is not the only advantage of it):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
docker run -p 80:80 kennethreitz/httpbin
</pre></div>


<p class="wp-block-paragraph">After pulling the image, the server runs and makes the main web page available:</p>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="1138" height="969" class="wp-image-22716" style="width: 500px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin.png 1138w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-300x255.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-1024x872.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-768x654.png 768w" sizes="auto, (max-width: 1138px) 100vw, 1138px" /></p>



<p class="wp-block-paragraph">It has following features:</p>



<ul class="wp-block-list">
<li>HTTP Methods: Testing different HTTP verbs</li>



<li>Auth: Auth methods</li>



<li>Status codes: Generates responses with given status code</li>



<li>Request inspection: Inspect the request data</li>



<li>Response inspection: Inspect the response data like caching and headers</li>



<li>Response formats: Returns responses in different data formats</li>



<li>Dynamic data: Generates random and dynamic data</li>



<li>Cookies: Creates, reads and deletes Cookies</li>



<li>Images: Returns different image formats</li>



<li>Redirects: Returns different redirect responses</li>



<li>Anything: Returns anything that is passed to request</li>
</ul>



<p class="wp-block-paragraph">When you click on a feature, it will display a list of accessible URLs. You can even try it out directly from within the browser.</p>



<p class="wp-block-paragraph">For example, the most basic one (GET):</p>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="1283" height="798" class="wp-image-22717" style="width: 500px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get.png 1283w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-300x187.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-1024x637.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-768x478.png 768w" sizes="auto, (max-width: 1283px) 100vw, 1283px" /></p>



<p class="wp-block-paragraph">It as no parameter and it will return headers sent by the browser or curl command.</p>



<p class="wp-block-paragraph">This is a bit simple to use JMeter for, so let&#8217;s try another feature.</p>



<h2 class="wp-block-heading">GET Links</h2>



<p class="wp-block-paragraph">The other feature from httpbin I wanted to try is <em>links</em>:</p>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="1370" height="1196" class="wp-image-22718" style="width: 500px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-links.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-links.png 1370w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-links-300x262.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-links-1024x894.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-links-768x670.png 768w" sizes="auto, (max-width: 1370px) 100vw, 1370px" /></p>



<p class="wp-block-paragraph">It will return is a page full of links from 0 to n-1. For example with n equal 20:</p>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="697" height="175" class="wp-image-22719" style="width: 350px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-links-example.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-links-example.png 697w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/httpbin-get-links-example-300x75.png 300w" sizes="auto, (max-width: 697px) 100vw, 697px" /></p>



<h2 class="wp-block-heading">JMeter</h2>



<p class="wp-block-paragraph">Let&#8217;s create a new JMeter Test Plan with the items required to have something to start with:</p>



<ul class="wp-block-list">
<li>A thread group</li>



<li>HTTP Request</li>



<li>Recording Controller</li>



<li>Results Tree</li>
</ul>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="2128" height="720" class="wp-image-22722" style="width: 650px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-httprequest.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-httprequest.png 2128w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-httprequest-300x102.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-httprequest-1024x346.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-httprequest-768x260.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-httprequest-1536x520.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-httprequest-2048x693.png 2048w" sizes="auto, (max-width: 2128px) 100vw, 2128px" /></p>



<p class="wp-block-paragraph">You can see that the path is hard coded, which means that you will need to change it if you want to test with additional links. I can add a <em>User Parameters</em> preprocessor and declare a variable named <code>number_of_links</code>. Path will then be changed to <code>links/${number_of_links}/${number_of_links}</code>.</p>



<p class="wp-block-paragraph">Under this initial HTTP request, I will add <em>Regular Expression Extractor</em> to find all links from the resulting page. It will be set like this:</p>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="1304" height="623" class="wp-image-22724" style="width: 600px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-regexp.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-regexp.png 1304w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-regexp-300x143.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-regexp-1024x489.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-regexp-768x367.png 768w" sizes="auto, (max-width: 1304px) 100vw, 1304px" /></p>



<p class="wp-block-paragraph">All matches (match No. = -1) will be stored in <code>links</code> variable. It will match what is between <code>href='</code> and <code>'&gt;</code>.</p>



<p class="wp-block-paragraph">Next step is too loop on the list of links that were found, so let&#8217;s add a <em>ForEach </em>controller:</p>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="427" height="431" class="wp-image-22725" style="width: 200px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-ForEach.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-ForEach.png 427w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-ForEach-297x300.png 297w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-ForEach-150x150.png 150w" sizes="auto, (max-width: 427px) 100vw, 427px" /></p>



<p class="wp-block-paragraph">Input variable will be the one generated by <em>Regular Expression Extractor</em> and output will be used in further HTTP requests within the loop.</p>



<p class="wp-block-paragraph">Talking about HTTP request, here is how it will look like:</p>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="1298" height="559" class="wp-image-22726" style="width: 500px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-http-link.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-http-link.png 1298w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-http-link-300x129.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-http-link-1024x441.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-http-link-768x331.png 768w" sizes="auto, (max-width: 1298px) 100vw, 1298px" /></p>



<p class="wp-block-paragraph">In this one, I am using <code>link</code> variable in Path parameter as well as the name. This will help to recognize request more easily in the <em>Results Tree</em>.</p>



<p class="wp-block-paragraph">Before running the test plan, here is the tree view of the full plan:</p>



<p class="wp-block-paragraph">l<img loading="lazy" decoding="async" width="574" height="405" class="wp-image-22729" style="width: 340px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-full-TP.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-full-TP.png 574w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMeter-full-TP-300x212.png 300w" sizes="auto, (max-width: 574px) 100vw, 574px" /></p>



<p class="wp-block-paragraph">Once I start the test plan, <em>Results tree</em> will be populated:</p>



<p class="wp-block-paragraph"><img loading="lazy" decoding="async" width="1550" height="842" class="wp-image-22727" style="width: 500px" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-result-tree.png" alt="" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-result-tree.png 1550w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-result-tree-300x163.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-result-tree-1024x556.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-result-tree-768x417.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/02/JMetter-result-tree-1536x834.png 1536w" sizes="auto, (max-width: 1550px) 100vw, 1550px" /></p>



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



<p class="wp-block-paragraph">JMeter is not only a load test tool. With its programming capabilities (ie. logic controller), it can do much more.</p>



<p class="wp-block-paragraph">And you, what are you doing with JMeter?</p>
<p>L’article <a href="https://www.dbi-services.com/blog/apache-jmeter-playground/">Apache JMeter Playground</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/apache-jmeter-playground/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-07-18 15:40:25 by W3 Total Cache
-->