k8s實踐(5)k8s的命名空間Namespace

1、什麼是Namespace?



你可以認爲namespaces是你kubernetes集羣中的虛擬化集羣。在一個Kubernetes集羣中可以擁有多個命名空間,它們在邏輯上彼此隔離。 他們可以爲您和您的團隊提供組織,安全甚至性能方面的幫助!

“default” Namespace
大多數的Kubernetes中的集羣默認會有一個叫default的namespace。實際上,應該是3個:

default:你的service和app默認被創建於此。
kube-system:kubernetes系統組件使用。
kube-public:公共資源使用。但實際上現在並不常用。
這個默認(default)的namespace並沒什麼特別,但你不能刪除它。這很適合剛剛開始使用kubernetes和一些小的產品系統。但不建議應用於大型生產系統。因爲,這種複雜系統中,團隊會非常容易意外地或者無意識地重寫或者中斷其他服務service。相反,請創建多個命名空間來把你的服務service分割成更容易管理的塊。

2、創建Namespace


 

不要害怕創建namespace。它不會降低服務的性能,反而大多情況下會提升你的工作效率。
創建namespace只需一個很簡單的命令,例如,創建一個名字爲:test的namespace,執行:
kubectl create namespace test
或者使用yaml文件,然後執行kubectl apply -f test.yaml

 #test.yaml:

 kind: Namespace
   apiVersion: v1
   metadata:
      name: test
   labels:
      name: test

查看namespace:kubectl get namespace

會看到test和其他系統默認的命名空間。

3、在namespace中創建資源



如下是一個簡單的 Pod YAML文件:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    name: mypod
spec:
  containers:
  - name: mypod
    image: nginx

你會發現沒有提到namespace。如果你通過命令kubectl apply 來創建pod,它會在當前的命名空間中創建pod。這個命名空間就是defaut,除非你更改過。
有2種方法來指定資源的namespace:

1、kubectl apply -f pod.yaml --namespace=test
2、在yaml中指定:
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: test
  labels:
    name: mypod
spec:
  containers:
  - name: mypod
    image: nginx

如果你用命令$ kubectl get pods來查看你的pod,你會得到:資源未找到的錯誤。
這是因爲命令是在當前(default)命名空間中,如果要查看其他namespace資源,你需要指定namespace:

$ kubectl get pods --namespace=test
NAME      READY     STATUS    RESTARTS   AGE
mypod     1/1       Running   0          10s

但是,這很讓人煩,每次都要指定namespace。下面讓我們看看如何修正這個“煩惱”。

4、管理當前激活的namespace


 

一開始默認的激活的命名空間是default。因此,當你在其他namespace創建了資源,那麼每次使用kubectl命令都要帶上namespace將會很痛苦。幸好,神器 kubens 能夠解決這個問題。
當你運行kubens命令,它會高亮當前的namespace:
要更換到test空間,運行:kubens test
現在你會看到:

這是,你所有的命令會在這個namespace下執行:

$ kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
mypod     1/1       Running   0          10m



5、跨namespace通信


命名空間彼此是透明的。但它們並不是絕對相互隔絕但。一個namespace中service可以和另一個namespace中的service通信。這非常有用,比如你團隊的一個service要和另外一個團隊的service通信,而你們的service都在各自的namespace中。
當你的應用app要訪問Kubernetes的service,你可以使用內置的DNS服務發現並把你的app指到Service的名稱。然而,你可以在多個namespace中創建同名的service。解決這個問題,就用到DNS地址的擴展形式。
在Kubernetes中,Service通過一個DNS模式來暴露endpoint。這個模式類似:
<Service Name>.<Namespace Name>.svc.cluster.local
一般情況下,你只需要service的名稱,DNS會自動解析到它的全地址。然而,如果你要訪問其他namespace中的service,那麼你就需要同時使用service名稱和namespace名稱。例如,你想訪問test中的“database”服務,你可以使用下面的地址:

   database.test
注意⚠️:如果你創建的namespace的名字正好映射到頂級域名,如 “com” 或者 “org”,然後,你創建的service的名稱和一個網站名稱一樣,如 “google” 或者 “baidu”。那麼 Kubernetes會攔截到 “google.com” 或者 “baidu.com”的請求並轉發到你的service中。
當然,這個技術在測試或者代理功能中非常好用。但請慎重!
如果你不想使namespace相互隔離,你可以使用network policy來解決。當然這是另一個話題。

6、Namespace的粒度


通常大家會問:我應該創建多少個namespace?有什麼用?什麼是真正的可控的塊?創建多了吧,礙事;創建少了吧,你還用不上namespace真正的好處。
我認爲,這個答案取決於你的項目或者公司處於什麼階段----從小團隊到大公司,各自都有自己的組織結構。根據不同的情況,你可以採用相對的命名空間的策略。

小團隊

這種場景下,你一般運作5 - 10 個微服務,很容易做到管理這些服務。這種情況下,你將所有的服務創建在default空間中是合理的。當然你可以創建 “production” 和 “development” 兩個空間,但一般情況下,你會在你本地機器上的development環境進行測試,例如使用minikube。

快速增長的團隊

這種場景下,你帶領一個快速增長的團隊運作 10+個微服務。你將團隊分成很多子團隊負責各自的微服務。但可能每個人都知道整個系統是如何運行的,因此每次變更越來越難以和其他每個人進行確認,而且每個人每天會在自己本地機器運行這個複雜的全棧系統。這時,有必要針對生產環境和開發環境使用多個集羣或者命名空間了。每個團隊擁有各自的命名空間,這樣更容易進行管理。

大公司

在大的公司中,並不是每個人都認識其他人。團隊間可能並不清楚各自的機能。微服務間通過service contract(例如gRPC)來通信,並通過service mesh(如istio)來協調通信。
試圖在本地運行整個堆棧是不可能的。 強烈建議使用Kubernetes-aware Continuous Delivery系統(例如,Spinnaker)。
此時,每個團隊肯定需要自己的命名空間。 每個團隊甚至可以選擇多個名稱空間來運行其開發和生產環境。 設置RBAC和ResourceQuotas也是一個好主意。 多個集羣開始顯得很有意義,但可能不一定是必要的。

企業

在這種規模下,有些羣體甚至不知道其他羣體的存在。 某個組也可能是外部公司,服務之間通過標準文檔定義的API來通信。 每個小組都有多個擁有一定數量微服務的團隊。 這時使用我上面提到的所有工具是必要的。 人們不應該手工部署服務,同時應該被鎖定在他們不擁有的命名空間之外。此時,擁有多個集羣以減少配置不當的應用程序導致的爆炸半徑,以及簡化計費和資源管理可能是有意義的。

結論


命名空間可以幫助您組織Kubernetes資源,同時可以提高團隊的開發效率。 請繼續關注未來的Kubernetes最佳實踐劇集,我將向您展示如何鎖定命名空間中的資源併爲您的羣集引入更多安全性和隔離性!

 

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