Tuesday, August 29, 2023

[Golang] 在VSCode中管理多個Go專案 Go 1.18+

在進行多個Go專案開發時,我們經常會遇到一些困擾,尤其是當我們嘗試在VSCode中同時打開一個包含多個Go專案的目錄時。這時候,你可能會遇到以下錯誤訊息:

錯誤

gopls requires a module at the root of your workspace.
You can work with multiple modules by opening each one as a workspace folder.
Improvements to this workflow will be coming soon (https://github.com/golang/go/issues/32394),
and you can learn more here: https://github.com/golang/go/issues/36899.

從Go 1.18版本開始,原生支持多模塊工作區,這是通過在父目錄中具有一個go.work文件來實現的。
假設我們有這樣的目錄結構:

/parent
├── proj1
│ ├── go.mod
│ ├── hello-world.go
└── proj2
├── go.mod ├── slices.go

我們可以通過執行以下命令來創建並填充go.work文件:

cd parent
go work init
go work use proj1
go work use proj
2

這將在您的父目錄中添加一個go.work文件,其中包含您標記為使用的目錄列表:

go 1.18

use (
    ./proj1
./proj2
)

通過這種方式,我們就能夠在VSCode中輕鬆地管理和切換不同的Go專案,而無需擔心模塊相關的問題。

Monday, August 21, 2023

[Golang] 實現跨平台編譯的CGO交叉編譯:解鎖Go語言開發的更多可能

實現跨平台編譯的CGO交叉編譯:解鎖Go語言開發的更多可能

在現代軟體開發中,跨平台支援已經成為一個重要的議題。不同的平台可能需要不同的二進位檔案格式或庫,這導致了開發者需要在多個平台上進行編譯。如果你使用的是Go語言,你有幸可以利用CGO交叉編譯來實現這一點。

CGO交叉編譯的基本概念

在沒有使用CGO的情況下,Go語言的交叉編譯非常簡單,只需使用少量的參數即可完成。以下是一個例子:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build

在這個命令中,我們使用了CGO_ENABLED=0來關閉CGO,然後通過GOOS和GOARCH來指定目標平台為Linux,架構為amd64。這樣我們就可以在不使用CGO的情況下進行編譯。

另外,我們還可以使用-ldflags選項來添加一些編譯選項,例如去除調試信息、靜態編譯等。以下是一個帶有這些選項的例子:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags '-s -w --extldflags "-static -fpic"' main.go

CGO的挑戰與解決辦法

然而,當我們需要使用CGO進行交叉編譯時,情況就變得複雜了。CGO(C Go調用)允許Go語言調用C函數,但這對於交叉編譯來說可能是一個障礙,因為不同的平台可能有不同的C庫。

在這種情況下,我們需要關閉CGO,並使用專門的編譯器和選項。以下是一個示例,展示了如何使用CGO進行交叉編譯:

CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CGO_LDFLAGS="-static" go build -a -v

在這個命令中,我們將CGO_ENABLED設置為1,以啟用CGO。然後,我們通過CC環境變數指定GCC編譯器,並使用CGO_LDFLAGS來指定CGO部分的編譯為靜態編譯。這樣我們就可以實現帶有CGO的交叉編譯。

跨平台編譯工具的應用

如果你是在macOS平台上進行開發,你可以通過一個名為musl-cross的工具來簡化交叉編譯的過程。以下是如何使用這個工具的步驟:

  1. 通過Homebrew安裝musl-cross工具:
brew install FiloSottile/musl-cross/musl-cross
  1. 安裝成功後,你可以使用musl-cross工具來實現交叉編譯。只需在編譯命令中指定編譯器和參數即可:
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CGO_LDFLAGS="-static" go build -a -v

結語

CGO交叉編譯是一個強大的工具,使得Go語言開發者能夠在不同的平台上進行開發和部署。無論是對於沒有CGO的純Go項目,還是帶有CGO的項目,我們都可以透過適當的參數和工具,輕鬆實現跨平台編譯的目標。這種靈活性為我們的開發帶來了更多可能性,使得我們能夠更方便地在不同的環境中進行測試和部署。

參考資料:

[Go語言涉及CGO的交叉編譯(跨平台編譯)解決辦法]
[FiloSottile/musl-cross - GitHub Repository] (https://github.com/FiloSottile/musl-cross)

在 Docker 中使用 Koko 工具創建網絡連接的示例

在 Docker 中使用 Koko 工具創建網絡連接的示例

在 Docker 環境中,經常需要創建不同容器之間的網絡連接以及配置網絡參數。Koko 是一個工具,可以幫助我們在 Docker 容器中設置網絡連接。本文將介紹如何使用 Koko 工具在 Docker 容器中創建網絡連接,並顯示一些示例命令。

1.創建獨立的網絡連接

首先,我們可以使用以下命令在兩個 Ubuntu 容器之間創建獨立的網絡連接:

sudo docker run --network none -dt --name ubuntu1 ubuntu:bionic /bin/bash
sudo docker run --network none -dt --name ubuntu2 ubuntu:bionic /bin/bash

這將在兩個容器之間創建一個隔離的網絡環境,使它們能夠相互通信。

2.在容器中創建veth對

接下來,我們可以使用以下命令容器在主機和主機之間創建 veth 對:

sudo ./koko -c net1 -d k8s_helloworld-python_helloworld-python_default_409cdca7-6c2a-45bf-a885-a5e6794f34c1_22,net1,10.200.0.2/24
sudo ./koko -c net2 -d k8s_helloworld-python-access-pod_helloworld-python-access-pod_default_36bf5089-8791-44dc-aa0c-40d1bd09a8c4_22,net1,10.200.0.3/24

接下來的命令將在容器和主機之間創建兩個 veth 對 net1 和 net2,並為它們分配 IP 地址。

3.創建橋接網絡

我們可以通過以下步驟創建一個橋接網絡放置veth對連接到橋接接口:

sudo ip l a br0 type bridge
sudo ip l s br0 up
sudo ip l s net1 master br0
sudo ip l s net2 master br0

這將創建一個名為 br0 的橋接接口,把 net1 和 net2 連接到這個橋接接口上。

4. 在命名空間中顯示IP地址

要顯示容器中的IP地址,我們可以使用以下命令:

sudo docker exec -it k8s_micro-apm_micro-apm-qj76q_kube-system_5bd48be1-5530-4811-a546-1d4a688343a2_3 ip addr | grep -P "^\d|inet "
sudo docker exec -it k8s_helloworld-python_helloworld-python_default_409cdca7-6c2a-45bf-a885-a5e6794f34c1_22 ip addr | grep -P "^\d|inet "
sudo docker exec -it k8s_helloworld-python-access-pod_helloworld-python-access-pod_default_36bf5089-8791-44dc-aa0c-40d1bd09a8c4_22 ip addr | grep -P "^\d|inet "
sudo docker exec -it k8s_micro-apm_micro-apm-qj76q_kube-system_5bd48be1-5530-4811-a546-1d4a688343a2_3 ping -c5 10.200.0.2

這些命令將顯示容器中的 IP 地址,並且最後一條命令還會在容器之間執行 Ping 測試。

5.清理網絡連接

最後,我們可以使用以下命令來清理網絡連接:

sudo ./koko -D k8s_micro-apm_micro-apm-qj76q_kube-system_5bd48be1-5530-4811-a546-1d4a688343a2_3,net1
sudo ./koko -D k8s_helloworld-python_helloworld-python_default_409cdca7-6c2a-45bf-a885-a5e6794f34c1_22,net1
sudo ./koko -D k8s_helloworld-python-access-pod_helloworld-python-access-pod_default_36bf5089-8791-44dc-aa0c-40d1bd09a8c4_22,net1
sudo ip l d br0

在創建網絡連接和橋接接口之前將清理命令。

結論

通過這些示例命令,我們可以在 Docker 容器中使用 Koko 工具來創建、管理和清理網絡連接,滿足不同的網絡配置需求。希望本文能夠幫助您更好地理解如何在 Docker 環境中進行網絡設置。