harbor鏡像倉庫同步401問題解決過程

       項目中出現同步鏡像時報401錯誤,首先想到的就是確認賬號是否真的沒有權限,然後通過docker login 命令使用該賬號登錄鏡像倉庫,也是報了401錯誤。現象很明確,就是客戶端沒有訪問鏡像倉庫的權限,那麼爲啥會出現這種問題呢?

       猜想要麼就是該賬號確實沒權限,要麼就是獲取到的token在鏡像倉庫服務端校驗的時候失敗了。鏡像同步是通過訪問鏡像倉庫的原生API進行的,在同步時鏡像倉庫服務端一樣需要token認證來檢查客戶端是否有權限上傳鏡像,下面就一一驗證這兩種情況:

       先說明一下,我們項目中,鏡像倉庫服務與鏡像倉庫的token服務器分別部署在不同的機器上。對於第一種情況,驗證很簡單,換一個管理員賬號即可,harbor鏡像倉庫的管理員賬號是有全部鏡像操作的權限的,如果管理員賬號可以,那說明就是之前綁定的賬號確實沒權限,如果管理員賬號也不行,那就說明是第二種情況了。通過docker login命令使用管理員賬號登錄鏡像倉庫,還是報了401錯誤,說明確實是token驗證有問題,而不是賬號的問題。那token驗證爲什麼會出錯呢?

       先來複習一下客戶端訪問鏡像倉庫獲取token的原理。

  1. 客戶端向鏡像倉庫發送請求
  2. 鏡像倉庫發現自己配置了權限認證服務,則返回401狀態,並攜帶獲取認證token的服務地址以及客戶端訪問所需要的權限
  3. 客戶端收到鏡像倉庫的響應後發現要先獲取token才能訪問鏡像倉庫,則攜帶用戶名和密碼訪問獲取token的地址
  4. 權限認證服務器校驗用戶名和密碼後,按照客戶端需要的權限,返回一個JWT標準的token
  5. 客戶端攜帶獲取的token再次訪問鏡像倉庫
  6. 鏡像倉庫驗證客戶端攜帶的token,驗證通過則允許訪問,驗證失敗則同第二步一樣進行返回

上面第四步提到的JWT標準的token,是一個帶有簽名內容、簽名時間、簽名過期時間、簽名可以使用的開始時間、簽名使用的算法等字段的、通過點分爲三部分的一串Base64編碼的字符串。回到這次的問題,其實需要考慮的就是簽名的這些時間是否正確。通過Base64對token的中間部分進行解碼,可以看到簽名相關的時間字段,首先就檢查簽名的過期時間,發現申請的token是一小時後過期,可使用的時間還是很長的,因此排除了簽名過期時間短的問題,那剩下的就只能看簽名可以使用的開始時間了,也就是JWT簽名的nbf字段,查看後發現該字段的秒數轉換爲當前時間後,比鏡像倉庫服務的時間服務器時間快了兩分鐘,即客戶端獲取到token後,攜帶該token請求鏡像倉庫服務時,鏡像倉庫驗證該簽名,發現當前系統時間還沒到簽名的可使用時間,簽名還無法使用,因此就返回了401錯誤。然後去查看鏡像倉庫token服務器的時間,確實比鏡像倉庫服務的服務器時間快了兩分鐘,通過時間同步操作,保證兩臺服務器時間一致後,重新進行鏡像同步,已經可以同步成功了,至此,這個問題完美解決!

總結一下,雖然最終發現還是服務器時間不一致導致的,而且這種問題其實一般在項目部署時都不太容易出現的,畢竟服務器一般都要先做時間同步,保證節點的時間一致,避免很多莫名其妙的問題,但是當出現這種問題時,要知道怎麼排查纔是最重要的,這個需要事先對鏡像倉庫的認證過程有一些瞭解才行,這樣才能判斷大概問題出現在哪個環節。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章