Go-Ethereum

使用 docker 執行自定義私有 go-ethereum 節點集群

  • July 24, 2016

這是我一直在研究的設置,但在與對等方創建專用網路的能力方面存在問題。基本設置:使用來自https://github.com/ethereum/ethereum-dockers/tree/master/go-ethereum-base的 dockerfile ,並在鏡像中添加了安裝乙太坊的行。

  1. 創建圖像後,我執行了 2 個圖像實例(請注意,它們都包含基本的自定義 genesis JSON 文件)
docker run -it -p 127.0.0.1:30303:30303 -p 3001:3001 --name e1 

docker run -it -p 127.0.0.1:30304:30304 -p 3002:3002 --name e2 \
 --link e1:e1 
  1. 接下來,我附加到容器 e1 並執行以下命令:
geth --identity "ethnode1" --datadir "/tempdatadir1" --rpc         \
 --port "30303" --rpccorsdomain "*" --rpcport "3001"              \
 --genesis genesis.json --networkid 6161                          \
 --ipcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" \
 --rpcapi "db,eth,net,web3" --nat "any" --maxpeers 2 console

這啟動了一個geth控制台,我可以在其中使用諸如admin.nodeInfo等命令檢查節點資訊。提取用於連接第二個節點的 enode 值:enode://@[::]:30303

使用 Crtl-C 退出控制台

  1. 附加到容器 e2,並執行以下命令:
geth --identity "ethnode2" --datadir "/tempdatadir2" --rpc         \
 --port "30304" --rpccorsdomain "*" --rpcport "3002"              \
 --genesis genesis.json --networkid 6161                          \
 --ipcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" \
 --rpcapi "db,eth,net,web3" --nat "any" --maxpeers 2 console

這啟動了一個geth控制台,我可以在其中使用諸如admin.nodeInfo等命令檢查節點資訊。此時,我嘗試使用以下命令添加第一個節點:admin.addPeer("enode://@127.0.0.1:30303"),它返回 true。但是,當我嘗試使用其中之一列出對等方時admin.Peers,我看到一個空數組並且使用net.peerCount給出 0。

建議,至於如何啟用兩者之間的連接?

  • 是不是使用了錯誤的IP地址?通常,是否可以通過適當地轉發 IP 地址來利用來自主機的特定 IP 地址。
  • 不應該在上面的步驟 2 中退出控制台嗎?
  • 在上述任何一種情況下,我們如何連接到現有geth實例?我嘗試使用geth attach "http://127.0.0.1:3001",但它給了我一個錯誤,說連接被拒絕。關於我們如何附加到現有geth實例的任何建議?

概括

  1. 檢查兩個 Docker 容器之間是否存在網路連接,並在必要時重新配置。檢查是否為每個容器分配了足夠的記憶體。
  2. 在每個 Docker 容器中
  • 安裝 go-ethereumgeth程序
  • 創建兩個帳戶(乙太坊地址)
  • geth使用完全相同的自定義genesis.json文件(相同)執行--networkid--datadir設置為您的首選目錄並使用參數 forgeth開始探勘。
  • geth正在執行的測試
  1. 連接geth實例。

簡短回答您的問題

  • 問:如何啟用兩者之間的連接?

    • A:首先設置Docker容器之間的連接。提供了一些參考資料,但不要使用127.0.0.1,因為這通常僅限於在您的作業系統/Docker 容器中使用。
  • Q:是不是使用了錯誤的IP地址?通常,是否可以通過適當地轉發 IP 地址來利用來自主機的特定 IP 地址。

    • 127.0.0.1答: Docker 容器中應該有一個可用的非IP 地址。以下說明可找到此地址。
  • 問:控制台是否應該在上面的第 2 步中不退出?

    • 答:首先使用geth ... console. 測試時不要退出geth命令提示符。
  • 問:在上述任何一種情況下,我們如何連接到現有的 geth 實例?我嘗試使用 geth attach“ http://127.0.0.1:3001 ”,但它給了我一個錯誤,說連接被拒絕。關於我們如何附加到現有的 geth 實例的任何建議?

    • 答:我在下面列出了一些測試來檢查您的 Docker 容器網路連接。解決連接後,使用您的--rpc*參數,您應該能夠使用geth attach ...127.0.0.1地址和埠進行連接。

編輯 23/04/2016192.*.*.* - OP 使用而不是IP 地址解決了連接問題127.0.0.1,如以下 Docker 命令所示:

docker run -it -p 192.XXX.XXX.XXX:30303:30303 --name e1 <eth image>

docker run -it -p 192.XXX.XXX.XXX:30304:30304 --name e2 --link e1:e1 <eth image>

編輯 24/04/2016 - OP 在根 ( /) 目錄中創建了數據目錄。這將需要超級使用者 (root) 權限。最好將數據目錄儲存在您的主目錄中。使用$HOME/tempdatadir1而不是/tempdatadir1. 預設情況下,geth將在$HOME/.ethereum.

詳情如下


Docker 容器連接和要求

記憶

geth將需要超過 512 Mb,因此您可能希望使用 1 Gb 進行測試,並在必要時增加它。

碼頭工人網路

目標

您需要設置 Docker 容器,以便geth在 Container #1 中可以連接到gethContainer #2 中,反之亦然。

在您的問題中,您已映射127.0.0.1:30303為通過 port 進行外部訪問30303127.0.0.1IP 地址是一個 localhost地址,通常不允許從作業系統外部進行通信。127.0.0.1請通過在 Docker 容器中使用來檢查非IP 地址,ifconfig -a以確定您的非本地 IP 地址是什麼。嘗試使用這些 IP 地址跨 Docker 容器進行通信。

參考

檢查連接

使用以下命令從 Container #1 中獲取 IP 地址ifconfig -a

ifconfig -a
lo      ...
       inet addr:127.0.0.1 ...
       ...
docker0 ...
       inet addr:192.168.0.1

在 Container #1 中的埠 30303 上執行geth,如下一節所示(或如您在問題中記錄的那樣)。

從 Container #2 或主機,您應該能夠執行以下命令 - 您必須按 Control-C 來終止連接:

user@Kumquat:~$ telnet 192.168.0.1 30303
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is '^]'.

如果您的 IP 地址未設置為接收您的連接嘗試,您的結果應如下所示:

user@Kumquat:~$ telnet 192.168.0.1 30303
Trying 192.168.0.1...
telnet: Unable to connect to remote host: No route to host

如果您的 IP 地址正確,但您的埠未正確映射,您應該會看到:

user@Kumquat:~$ telnet 192.168.0.1 30303
Trying 192.168.0.1...
telnet: Unable to connect to remote host: Connection refused

配置geth

使用基本參數進行配置geth,以便我們可以驗證它是否按預期工作,而 Docker 容器之間沒有 P2P 連接。您首先需要配置兩個帳戶來測試您的挖礦。

新賬戶

在 Container #1 中,執行以下命令兩次以創建兩個新帳戶:

user@Kumquat:~$ geth --datadir "$HOME/tempdatadir1" account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 
Repeat Passphrase: 
Address: {a6847de2447db964ef89644752921c204bf563ab}

與您的帳戶相關的數據(以加密格式)儲存在您--datadir的子目錄下的目錄keystore中。如果您在乙太坊主網路中使用此帳戶,請確保備份這些文件(並記住您的密碼)。

user@Kumquat:~$ ls -al $HOME/tempdatadir1/keystore
total 12
drwx------ 2 user user 4096 Apr 24 16:11 .
drwx------ 3 user user 4096 Apr 24 16:11 ..
-rw------- 1 user user  491 Apr 24 16:11 UTC--2016-04-24T06-11-04.534736154Z--a6847de2447db964ef89644752921c204bf563ab

在 Container #2 中也一樣,使用--datadirfor Container #2。

執行geth礦工

在 Container #1 中執行以下命令,您應該會看到如下所示的消息:

geth --datadir "/tempdatadir1" --port "30303" \
 --genesis genesis.json --networkid 6161     \
 --mine --minerthreads 1 console

容器 #2 相同:

geth --datadir "/tempdatadir2" --port "30304" \
 --genesis genesis.json --networkid 6161     \
 --mine --minerthreads 1 console

您應該看到的消息如下:

I0422 23:24:07.347255    8218 worker.go:348] 🔨  Mined block (#6248 / 11175b1e). Wait 5 blocks for confirmation
I0422 23:24:07.347868    8218 worker.go:569] commit new work on block 6249 with 0 txs & 0 uncles. Took 521.208µs
I0422 23:24:07.348356    8218 worker.go:569] commit new work on block 6249 with 0 txs & 0 uncles. Took 378.62µs
I0422 23:24:18.248751    8218 worker.go:348] 🔨  Mined block (#6249 / 50cdfdeb). Wait 5 blocks for confirmation
I0422 23:24:18.249306    8218 worker.go:569] commit new work on block 6250 with 0 txs & 0 uncles. Took 470.831µs

從賬戶 #1 向賬戶 #2 發送乙太幣

在每個容器中,在控制台中執行sendTransaction命令。geth您的挖礦操作應該將乙太幣添加到 eth.accounts

$$ 0 $$(第一個帳戶,也稱為coinbase)。此命令將從 eth.accounts 發送一個乙太幣$$ 0 $$到 eth.accounts$$ 1 $$:

> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(1, "ether")})
"0xde465790a8ae4ce1aad3179d071ac49ed447c09199de26ce02327e8790e63e4b"

等待交易被探勘。然後執行getTransaction命令檢查交易是否已被探勘到一個塊中:

> eth.getTransaction("0xde465790a8ae4ce1aad3179d071ac49ed447c09199de26ce02327e8790e63e4b")
{
 ...
 blockNumber: 6266,
 ...
}

查看以下賬戶餘額eth.accounts[1]

> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
1

連接geth實例

您將需要找到每個實例的enode資訊。geth我已將長節點公鑰從“d9d93b749257a1d4eaec18ab1c1ad39dc9220e449cfe248aceafc586193ead0ac14a088be5afb8455bd8f14bab7428162b8fbeda399ec748f5df0369789789730d9”縮短為“d9”,以便於閱讀

在 Container #1 中,執行以下命令geth ... console

> admin.nodeInfo
{
 enode: "enode://d9d9...30d9@[::]:30303?discport=0",
 ...
}

geth從Container #2 中獲取相同的資訊。

在下面的 Peer Discovery 部分中,替換**$$ :: $$**在您的 enode 中使用您的 Docker 容器的外部可訪問 IP 地址,然後刪除?discport=0文本。

對等發現

您有 3 種方法可以讓geth您的 Docker 容器相互連接:

  1. 引導節點

在 Container #1 中,將--bootnodes參數添加到geth命令行中,例如,其中“d9d9…30d9”需要替換為gethContainer #2 中的相應公鑰:

geth --bootnodes "enode://1234...5678@192.168.0.2:30304" ...

在 Container #2 中,您可以添加類似的參數:

geth --bootnodes "enode://d9d9...30d9@192.168.0.1:30303" ...

這將連接您的geth節點以進行初始對等發現,它們應該在其中發現彼此並保持 P2P 連接。 2. static-nodes.json

--datadir在您的目錄中的一個名為 的文件中添加以下文本,替換為您的節點資訊static-nodes.json

[
 "enode://1234...5678@192.168.0.2:30304",
 "enode://d9d9...30d9@192.168.0.1:30303"
]
  1. trusted-nodes.json

同上static-nodes.json,但這裡的節點連接不計入--maxpeers參數,如果指定。

嘗試不同的配置風格,直到找到一種至少可以穩定幾天的配置風格。

同行發現參考


如何geth在後台執行

geth作為後台程序執行,console請從命令中刪除參數geth並附加&將在後台啟動程序的符號。由於您可能想要檢查來自 的消息geth,您應該將輸出從管道(發送)geth到日誌文件中。

我就是這樣做的:

  1. logs在 $HOME 目錄中創建一個子目錄:
mkdir $HOME/logs
  1. geth使用命令行選項設置腳本文件。我打電話給我runGeth的並將其保存在$HOME/bin. 完整的文件名是$HOME/bin/runGeth,這個文件包含:
#!/bin/sh

# Kill any running geth instances gracefully
killall -q --signal SIGINT geth

# Wait for 10 seconds
sleep 10

# Make sure that geth is really killed. Try hard killing again
killall -q geth

# Run geth in the background,
#  piping the output messages to a log file
geth --rpc [other parameters] --verbosity 3 2>> $HOME/logs/geth.log &

您必須執行以下命令才能使此腳本可執行:

user@Kumquat:~$ chmod 700 $HOME/bin/runGeth

您現在可以geth從命令行開始執行腳本:

user@Kumquat:~$ runGeth

如果這不起作用,請使用完整路徑名:

user@Kumquat:~$ $HOME/bin/runGeth
  1. 要附加到geth在後台執行的實例,請使用以下命令:
geth attach

這將使用 IPC 協議連接到geth在後台執行的實例。

如果geth要從其他 Docker 容器或從 Docker 容器外部連接到實例,請使用以下命令以及正確的 IP 和埠號:

geth attach rpc:http://192.XXX.XXX.XXX:8545

請注意,該埠8545是可以使用--rpcport {port}命令行參數設置的預設 RPC 埠。

您可以退出這些geth attach程序,而不會影響geth在後台執行的實例。

由於我不喜歡輸入冗長的命令行參數,因此我創建了$HOME/bin/attachGeth包含以下內容的文件:

#!/bin/sh

geth attach rpc:http://192.XXX.XXX.XXX:8545

因此chmod 700 $HOME/bin/attachGeth我可以geth使用命令attachGeth$HOME/bin/attachGeth. 4. geth查看後台執行的實例的日誌文件:

tail -F $HOME/logs/geth.log

按 Control-C 終止此過程。

引用自:https://ethereum.stackexchange.com/questions/3185