2024年4月9日 星期二

Elasticsearch 系列 : 建立與使用 Docker 環境下的 Elasticsearch 與 Kibana

Elasticsearch 系列 : 建立與使用 Docker 環境下的 Elasticsearch 與 Kibana

由於最近半年都在從事於 Elasticsearc 方面的專案開發,因為工作上的需要,因此將會把最近用於 Elasticsearc 相關開發技術與方法記錄下來,方便日後查詢,也讓更多人可以認識這個相當優異的工具,以及如何透過 C# 最到相關的應用。

底下為 2023 所撰寫的關於 Elasticsearch 的文章清單

由於之前所寫的文章,都是採用安裝在一台後端伺服器上的 Elasticsearch 服務來進行開發,在這篇文章將會介紹如何透過 Docker 來建立 Elasticsearch 與 Kibana 的環境,讓開發者可以在本機端進行開發,並且可以透過 Kibana 來進行資料庫的管理。

建立 Elasticsearch 要用到的網路

在建立 Elasticsearch 與 Kibana 的 Docker 環境之前,我們需要先建立一個網路,讓 Elasticsearch 與 Kibana 這兩個容器可以透過這個網路來進行溝通。

請在命令提示字元中輸入以下指令

docker network create elastic

執行結果如下

建立 Elasticsearch 要用到的網路

使用底下指令來確認是否有建立成功

docker network ls

確認是否有建立成功

建立與啟動 Elasticsearch Container

接著我們需要建立 Elasticsearch 的 Docker Image,請在命令提示字元中輸入以下指令

docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2

執行結果如下:

建立與啟動 Elasticsearch Image

接著我們需要建立 Elasticsearch 的 Docker Container,請在命令提示字元中輸入以下指令

docker run -it --name elasticsearch --net elastic -p 9200:9200 -e "discovery.type=single-node" -e ELASTIC_PASSWORD=elastic docker.elastic.co/elasticsearch/elasticsearch:8.13.1

上述的指令中,使用了 -e ELASTIC_PASSWORD=elastic 來設定 Elasticsearch 的密碼,這個密碼是用來登入 Elasticsearch 的,請記得保留這個密碼,因為之後會用到。另外,使用了 -e "discovery.type=single-node" 來設定 Elasticsearch 的節點類型為單節點,這樣就可以讓 Elasticsearch 在單節點的環境下運行。

執行結果如下:

建立與啟動 Elasticsearch Container

請在命令題是字元視窗內搜尋 [Enrollment token] 文字,就可以看到底下內容

ℹ️  Configure Kibana to use this cluster:
• Run Kibana and click the configuration link in the terminal when Kibana starts.
• Copy the following enrollment token and paste it into Kibana in your browser (valid for the next 30 minutes):
  eyJ2ZXIiOiI4LjEzLjEiLCJhZHIiOlsiMTcyLjE4LjAuMjo5MjAwIl0sImZnciI6ImUxYjUxZmZlYzkwMmZkYjcwNmM4Y2ZlYTgzMTZiOGUxZmU5NWFlNDAxNTU5MzczMTA1Y2U3Mzg3N2Q2Njc2MTciLCJrZXkiOiJ5aC1Fd0k0QlJDTTYtc3dueUJ3bTpTWlRJeEZBMFJXMmZ6eVBhUzlQOVJBIn0=

請將這段文字 eyJ2ZXIiOiI4LjEzLjEiLCJhZHIiOlsiMTcyLjE4LjAuMjo5MjAwIl0sImZnciI6ImUxYjUxZmZlYzkwMmZkYjcwNmM4Y2ZlYTgzMTZiOGUxZmU5NWFlNDAxNTU5MzczMTA1Y2U3Mzg3N2Q2Njc2MTciLCJrZXkiOiJ5aC1Fd0k0QlJDTTYtc3dueUJ3bTpTWlRJeEZBMFJXMmZ6eVBhUzlQOVJBIn0= 複製起來,因為之後會用到,這段文字稱之為 [Enrollment token]。

從執行結果中可以看到 Elasticsearch 已經成功的建立與啟動,並且可以看到底下內容:

接著我們可以透過瀏覽器來進行測試,請在瀏覽器中輸入以下網址

https://localhost:9200

執行結果如下:

首先,需要先輸入帳號與密碼,帳號為 elastic ,密碼為 elastic

測試 Elasticsearch 是否成功建立

完成後,點選登入按鈕,就會看到底下畫面

測試 Elasticsearch 是否成功建立

{
name: "eee625dddc63",
cluster_name: "docker-cluster",
cluster_uuid: "wKpWcpE8R6q9Ipu_odjzrQ",
version: {
number: "8.13.1",
build_flavor: "default",
build_type: "docker",
build_hash: "9287f29bba5e270bd51d557b8daccb7d118ba247",
build_date: "2024-03-29T10:05:29.787251984Z",
build_snapshot: false,
lucene_version: "9.10.0",
minimum_wire_compatibility_version: "7.17.0",
minimum_index_compatibility_version: "7.0.0"
},
tagline: "You Know, for Search"
}

建立與啟動 Kibana Container

使用底下指令啟動 Kibana 的 Docker Image

docker pull docker.elastic.co/kibana/kibana:8.13.1

執行結果如下:

建立與啟動 Kibana Image

接著我們需要建立 Kibana 的 Docker Container,請在命令提示字元中輸入以下指令

docker run -it --name kibana --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:8.13.1

執行結果如下:

建立與啟動 Kibana Container

從上圖的輸出文字的最後面,可以看到 Kibana has not been configured 的訊息,這表示 Kibana 還沒有設定完成,所以,接著我們可以透過瀏覽器來進行測試,請在瀏覽器中輸入以下網址

http://localhost:5601

執行結果如下:

測試 Kibana 是否成功建立

請在 [Enrollment token] 欄位中貼上剛剛複製下來的 [Enrollment token]

測試 Kibana 是否成功建立

請直接點選 [Configure Elastic] 按鈕,就會看到底下畫面

測試 Kibana 是否成功建立

在這個畫面中,可以看到需要提供驗證碼,所以,現在切換到 Kibana 的命令提示字元視窗,將會看如下圖

Kibana Verification required

最後一行的文字,將會是 Your verification code is: \u001b[30m\u001b[106m 106 918 \u001b[49m\u001b[39m,請將這段文字 106 918 複製起來,因為之後會用到,這段文字稱之為 [Verification code]。

將 [Verification code] 貼到瀏覽器上

Kibana Verification required

完成後,點選 [Verify] 按鈕,就會看到底下畫面

等候 kibana 完成初始化設定之後,就會看到底下畫面

現在可以正常連上 kibana

Kibana Verification required

請在 [Username] 欄位中輸入 elastic,在 [Password] 欄位中輸入 elastic,然後點選 [Log in] 按鈕,就可以看到底下畫面

第一次使用 Kibana

在這個畫面中,點選 [Explore on my own] 按鈕,就可以看到底下畫面

第一次使用 Kibana

其他說明

docker exec -it elasticsearch /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana

上述的指令表示了透過 elasticsearch-create-enrollment-token 來建立一個 enrollment token,這個 enrollment token 是用來讓 Kibana 與 Elasticsearch 之間進行溝通的,而 -s kibana 表示了這個 enrollment token 是用來給 Kibana 使用的。 





2024年2月26日 星期一

.NET8 Blazor / MudBlazor - 動態切換不同客製化版面配置 Layouts

.NET8 Blazor / MudBlazor - 動態切換不同客製化版面配置 Layouts

想要練習這篇文章的開發過程,開發電腦上必須要能夠先安裝 MudBlazor 專屬的專案範本,透過這個專案範本便可以建立一個 Blazor 開發專案,進行接下來的練習;若開發電腦上還沒有安裝這個專案範本套件,可以參考 .NET8 Blazor - 使用 MudBlazor 專案範本來建立Blazor專案 這篇文章。

建立練習專案

  • 打開 Visual Studio 2022 IDE 應用程式

  • 從 [Visual Studio 2022] 對話窗中,點選右下方的 [建立新的專案] 按鈕

  • 在 [建立新專案] 對話窗右半部

    • 切換 [所有語言 (L)] 下拉選單控制項為 [C#]
    • 切換 [所有專案類型 (T)] 下拉選單控制項為 [Blazor]
  • 在中間的專案範本清單中,找到並且點選 [MudBlazor Web App (MudBlazor)] 專案範本選項

    A project template for creating a MudBlazor web app that supports both server-side rendering and client interactivity. This template can be used for web apps with rich dynamic user interfaces (UIs)

  • 點選右下角的 [下一步] 按鈕

  • 在 [設定新的專案] 對話窗

    • 找到 [專案名稱] 欄位,輸入 csMudBlazorLayout 作為專案名稱
    • 在剛剛輸入的 [專案名稱] 欄位下方,確認沒有勾選 [將解決方案與專案至於相同目錄中] 這個檢查盒控制項
  • 點選右下角的 [下一步] 按鈕

  • 現在將會看到 [其他資訊] 對話窗

    • 在 [架構] 欄位中,請選擇最新的開發框架,這裡選擇的 [架構] 是 : .NET 8.0 (長期支援)
    • [驗證類型] 請選擇預設值 [無]
    • 在 [Interactive render mode] 欄位中,請選擇預設值 [Server]
    • 在 [Interactivity location] 欄位中,請選擇預設值 [Per page/component]
    • 若想要看到範例頁面,可以依照自己的需求,勾選 [Include sample pages] 這個檢查盒控制項
  • 請點選右下角的 [建立] 按鈕

稍微等候一下,這個主控台專案將會建立完成

底下為建立完成的專案結構

最左邊 側邊欄 Sidebar 版面配置

  • 滑鼠右擊專案節點下的 [Components] > [Layout] 資料夾
  • 從彈出的功能表中,選擇 [加入] > [Razor 元件] 選項
  • 看到 [加入新檔案] 對話窗
  • 在 [名稱] 欄位中,輸入 DrawerLeftTopAppbar.razor
  • 點選右下角的 [新增] 按鈕
  • 使用底下的程式碼取代原有檔案中的程式碼
@inherits LayoutComponentBase

<MudThemeProvider />

<MudLayout>
    <MudAppBar Elevation="1">
        <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
        <MudSpacer />
        <MudIconButton Icon="@Icons.Material.Filled.MoreVert" Color="Color.Inherit" Edge="Edge.End" />
    </MudAppBar>
    <MudDrawer @bind-Open="_drawerOpen" Elevation="2">
        <MudDrawerHeader>
            <MudText Typo="Typo.h5" Class="mt-1">Application</MudText>
        </MudDrawerHeader>
        <NavMenu />
    </MudDrawer>
    <MudMainContent>
        @Body
    </MudMainContent>
</MudLayout>

@code {
    bool _drawerOpen = true;

    void DrawerToggle()
    {
        _drawerOpen = !_drawerOpen;
    }
}

想要客製化一個版面配置元件,需要使用 @inherits LayoutComponentBase 這個指示詞,這個指示詞可以讓這個 Razor 元件可以繼承使用 Blazor 的 [LayoutComponentBase] 類別的功能,如此,這個元件便可以用於版面配置之用。

這個 Razor 元件中,使用了 [MudBlazor] 的 [MudThemeProvider] 元件,這個元件可以使用 [MudBlazor] 的主題設定。[MudThemeProvider] 是 [MudBlazor] 框架中的一個組件,它允許開發者定義和管理應用程序的主題,包括顏色、字型和其他設計相關的設定,它為開發者提供了一種高效且靈活的方式來管理和定制應用程序的主題,從而提升了開發效率和用戶體驗。

[MudLayout] 元件扮演著建立頁面版面配置 Layout 的基礎角色。它是用來定義應用程式的整體版面配置結構,如頭部、側邊欄、內容區域和部等。透過使用,開發者可以輕鬆實現反應方式和整潔的介面版面配置,以適應不同的螢幕尺寸和設備。

[MudAppBar] 元件中用於建立應用程式的頂部導覽列。它是UI中一個關鍵的視覺元素,通常用於展示品牌、導航連結、搜尋列或其他重要的介面元素;這裡 [Elevation="1"] 設定了一個相對較淺的陰影效果,適合於需要強調層次感而不過分突出的頂部導覽列設計。較低的陰影值使得在視覺上更加貼合背景,而不至於瞳距過度分離或突兀。

對於 [MudDrawer] 元件是一個用於側邊導航的面板,它可以滑出展示連結或其他內容,是實現響應式佈局和提升使用者介面互動性的重要元件。

在 [MudDrawer] 元件內,使用到 [MudDrawerHeader] ,是 [MudBlazor] 元件庫中的一個元件,設計用於在 MudDrawer 元件內部提供一個標準化的頭部區域,這個頭部區域常用於顯示標題、圖示或提供一些上下文信息,以增強使用者介面的可識別性和美觀度。接著這個 [MudDrawerHeader] 下方才會是側邊欄功能表清單。

側邊欄的頂部會有一個標題,並且在標題下方會有一個導覽列,用來顯示導覽連結;應用程式列將不會在螢幕最上方且占據所有的螢幕寬度。

在 Razor 元件的程式碼區段中,定義了一個 _drawerOpen 布林變數(預設為 true),用來控制側邊欄的開啟與關閉。在 [MudIconButton] 元件中,透過 OnClick="@((e) => DrawerToggle())" 宣告,當點擊這個元件之後,將會觸發 [DrawerToggle] 方法,而在 [DrawerToggle] 方法中,透過 _drawerOpen 變數的值,來控制側邊欄的開啟與關閉。

下圖為顯示側邊欄面板的效果

下圖為關閉側邊欄面板的效果

最上方 應用程式列 AppBar 與 左邊 側邊欄 版面配置

  • 滑鼠右擊專案節點下的 [Components] > [Layout] 資料夾
  • 從彈出的功能表中,選擇 [加入] > [Razor 元件] 選項
  • 看到 [加入新檔案] 對話窗
  • 在 [名稱] 欄位中,輸入 TopAppbarWithClippedDrawer.razor
  • 點選右下角的 [新增] 按鈕
  • 使用底下的程式碼取代原有檔案中的程式碼
@inherits LayoutComponentBase

<MudThemeProvider />

<MudLayout>
    <MudAppBar Elevation="1">
        <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
        <MudText Typo="Typo.h5" Class="ml-3">Application</MudText>
        <MudSpacer />
        <MudIconButton Icon="@Icons.Material.Filled.MoreVert" Color="Color.Inherit" Edge="Edge.End" />
    </MudAppBar>
    <MudDrawer @bind-Open="_drawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2">
        <NavMenu />
    </MudDrawer>
    <MudMainContent>
        @Body
    </MudMainContent>
</MudLayout>

@code {
    bool _drawerOpen = true;

    void DrawerToggle()
    {
        _drawerOpen = !_drawerOpen;
    }
}

這個版面配置與前一個很類似,差別在於在 [MudAppBar] 元件中,增加了一個 [MudText] 元件 (<MudText Typo="Typo.h5" Class="ml-3">Application</MudText>),用來顯示應用程式的標題。

對於在 [MudLayout] 內的 [MudDrawer] 元件是一個用於側邊導航的面板,它可以滑出展示連結或其他內容,是實現響應式佈局和提升使用者介面互動性的重要元件。

[ClipMode="DrawerClipMode.Always"] 這意味著無論側邊導航的面板的狀態(打開或關閉),最上方 應用程式列將會永遠顯示在最上方,不會被側邊導航面板覆蓋掉。

[MudMainContent] 元件用於包裝應用程式的主要內容區域,這裡將會使用 @Body 前置詞來標示這裡將會是一個預留位置,用來檢視所路由到的 Razor 元件內容。

下圖為顯示側邊欄面板的效果

下圖為關閉側邊欄面板的效果

僅上方 應用程式列 AppBar 版面配置

  • 滑鼠右擊專案節點下的 [Components] > [Layout] 資料夾
  • 從彈出的功能表中,選擇 [加入] > [Razor 元件] 選項
  • 看到 [加入新檔案] 對話窗
  • 在 [名稱] 欄位中,輸入 AppbarOnly.razor
  • 點選右下角的 [新增] 按鈕
  • 使用底下的程式碼取代原有檔案中的程式碼
@inherits LayoutComponentBase

<MudThemeProvider />

<MudLayout>
    <MudAppBar Elevation="1">
        <MudText Typo="Typo.h5" Class="ml-3">Application</MudText>
        <MudSpacer />
        <MudIconButton Icon="@Icons.Material.Filled.MoreVert" Color="Color.Inherit" Edge="Edge.End" />
    </MudAppBar>
    <MudMainContent>
        @Body
    </MudMainContent>
</MudLayout>

在這個版面配置下,將不會有側邊欄面版。 下圖為顯示結果

指定不同路由頁面使用不同的版面配置

  • 建立路由頁面來套用 [最左邊 側邊欄 Sidebar 版面配置]
  • 滑鼠右擊專案節點下的 [Components] > [Pages] 資料夾
  • 從彈出的功能表中,選擇 [加入] > [Razor 元件] 選項
  • 看到 [加入新檔案] 對話窗
  • 在 [名稱] 欄位中,輸入 CustomLayout1.razor
  • 點選右下角的 [新增] 按鈕
  • 使用底下的程式碼取代原有檔案中的程式碼
@page "/CustomLayout1"
@using MB01.Components.Layout
@layout DrawerLeftTopAppbar

<PageTitle>客製化版面配置 : Drawer left + top appbar</PageTitle>

<MudText Typo="Typo.h3" GutterBottom="true">Hello, world!</MudText>
<MudText Typo="Typo.h4" Class="mb-8 mud-secondary-text">
    客製化版面配置 : Drawer left + top appbar !
</MudText>
<MudText Class="mb-8">Welcome to your new app, powered by MudBlazor and the .NET 8 Template!</MudText>

在這個 Razor 元件中,使用了 @layout DrawerLeftTopAppbar 這個指示詞,這個指示詞可以指定這個 Razor 元件使用 DrawerLeftTopAppbar 這個版面配置元件。

  • 建立路由頁面來套用 [最上方 應用程式列 AppBar 與 左邊 側邊欄 版面配置]
  • 滑鼠右擊專案節點下的 [Components] > [Pages] 資料夾
  • 從彈出的功能表中,選擇 [加入] > [Razor 元件] 選項
  • 看到 [加入新檔案] 對話窗
  • 在 [名稱] 欄位中,輸入 CustomLayout2.razor
  • 點選右下角的 [新增] 按鈕
  • 使用底下的程式碼取代原有檔案中的程式碼
@page "/CustomLayout2"
@using MB01.Components.Layout
@layout TopAppbarWithClippedDrawer

<PageTitle>客製化版面配置 : Top appbar with clipped drawer</PageTitle>

<MudText Typo="Typo.h3" GutterBottom="true">Hello, world!</MudText>
<MudText Class="mb-8">客製化版面配置 : Top appbar with clipped drawer !</MudText>
<MudText Class="mb-8">Welcome to your new app, powered by MudBlazor and the .NET 8 Template!</MudText>

在這個 Razor 元件中,使用了 @layout TopAppbarWithClippedDrawer 這個指示詞,這個指示詞可以指定這個 Razor 元件使用 TopAppbarWithClippedDrawer 這個版面配置元件。

  • 建立路由頁面來套用 [僅上方 應用程式列 AppBar 版面配置]
  • 滑鼠右擊專案節點下的 [Components] > [Pages] 資料夾
  • 從彈出的功能表中,選擇 [加入] > [Razor 元件] 選項
  • 看到 [加入新檔案] 對話窗
  • 在 [名稱] 欄位中,輸入 CustomLayout3.razor
  • 點選右下角的 [新增] 按鈕
  • 使用底下的程式碼取代原有檔案中的程式碼
@page "/CustomLayout3"
@using MB01.Components.Layout
@layout AppbarOnly

<PageTitle>客製化版面配置 : Appbar Only</PageTitle>

<MudText Typo="Typo.h4" Class="mb-8 mud-secondary-text">
    Hello, world!
</MudText>
<MudText Class="mb-8">客製化版面配置 : Appbar Only !</MudText>
<MudText Class="mb-8">Welcome to your new app, powered by MudBlazor and the .NET 8 Template!</MudText>

在這個 Razor 元件中,使用了 @layout AppbarOnly 這個指示詞,這個指示詞可以指定這個 Razor 元件使用 AppbarOnly 這個版面配置元件。

修正渲染模式

因為在版面配置 Layout 將會有使用到 C# 程式碼,也就是會有使用者互動需求,因此,需要開啟這個專案預設採用 互動式伺服器 模式,也就是 使用 Blazor Server的互動式伺服器端轉譯(互動式SSR)。

  • 在專案節點下找到並打開 [App.razor 檔案]
  • 找到 <Routes /> 標籤
  • 將這個標籤替換為 <Routes @rendermode="RenderMode.InteractiveServer" />