名稱空間是什麼?你為什麼需要它?
kubernetes 名稱空間是什麼?正如 Shakespeare 以前寫過的,我們所謂的名稱空間,或者任何其他名字,就是虛擬叢集。通過虛擬叢集,意味著 kubernetes 可以在單個叢集上提供多個 kubernetes 的叢集,類似一個在其主機抽象出來的虛擬機器。kubernetes 文件 中的解釋:
kubernetes 在一個物理叢集上提供了多個虛擬叢集。這些虛擬叢集被稱為名稱空間。
你為什麼需要名稱空間?一言以蔽之:隔離。
隔離有很多優點,如它提供了安全和乾淨的環境。如果你是基礎設施的所屬者,並且要為開發者提供環境,隔離就相當重要。你最不需要的就是,一個不熟悉你叢集是如何搭建的人去修改系統設定 —— 這可能導致所有人都無法登入。
一個叢集的三個初始名稱空間:default
、kube-system
和 kube-public
。雖然技術上你可以用這三個名稱空間作部署,但我還是推薦你把這三個名稱空間留作系統設定用,而不是你的專案。
Default
用於某些沒有指明名稱空間的部署,這是一種快速建立混亂的做法,如果你在沒有正確資訊的情況下做了很多部署,將很難清理。我不會去動它,因為它只有這一個用途,而且在不止一種情況下誤導過我。Kube-system
是 Kubernetes 系統相關的所有物件組成的名稱空間。任何對此名稱空間的部署都可能是危險的操作,可能對系統本身造成不可挽回的破壞。沒錯,我試過;所以我不推薦。Kube-public
所有人可讀,但是這個名稱空間是為系統保留的。我用了多種方式通過名稱空間來實現隔離。我經常用名稱空間來把多個使用者專案分割到不同的環境。這種方式可以有效防止跨專案的汙染,因為名稱空間提供了獨立的環境。例如,使用者可以安裝不同版本的 Jenkins,如果它們的環境變數是在不同的名稱空間,就不會衝突。
這種隔離對於清理也很有幫助。如果開發小組的多個專案突然被廢棄,你可以用命令 kubectl delete ns <$NAMESPACENAME>
一鍵刪除名稱空間,清理名稱空間內的所有東西。(請確認被刪除的是正確的名稱空間。我曾經在生產環境刪除了錯誤的名稱空間,這很不好。)
如果你是基礎設施所有者,請謹慎操作,因為這可能會引發其他團隊的的故障或引發其他問題。例如,如果你建立了一個特定的名稱空間,裡面有特殊的額外安全的 DNS 功能,但是其他人刪除了它,那麼名稱空間內的所有 pod 和它們執行的應用都會被清空。所有的刪除操作在真正實施之前都應該由同事(通過 GitOps)評審一下。
雖然官方文件不建議 10 人以下團隊 使用多個名稱空間,但出於架構需要,在我自己的叢集上還是用了多個名稱空間。叢集越乾淨越好。
首先,名稱空間不能巢狀。部署只能在一個名稱空間中進行。對於版本化專案,你不一定要用名稱空間,你可以使用標籤來區分有相同名字的版本化應用。名稱空間使用配額來為不同的使用者劃分資源;例如,某個名稱空間最多能有 x 個節點。最後,所有的名稱空間對於該資源型別只能使用一個獨一無二的名字。
你需要安裝 Minikube、Helm 和 kubectl 命令列,才能使用下面的名稱空間命令。我的文章《安全掃描你的 DevOps 流水線》中有它們的安裝教學,你也可以去每個專案的官方主頁去找安裝教學。我使用的是最新的 Minikube。手動安裝很快,第一次就能成功執行。
穫取你的第一組名稱空間:
jess@Athena:~$ kubectl get namespaceNAME STATUS AGEdefault Active 5m23skube-public Active 5m24skube-system Active 5m24s
建立一個名稱空間:
jess@Athena:~$ kubectl create namespace athenanamespace/athena created
現在開發者可以部署到你建立的名稱空間了;例如,這裡是一個簡短的 Helm chart:
jess@Athena:~$ helm install teset-deploy stable/redis --namespace athenaNAME: teset-deployLAST DEPLOYED: Sat Nov 23 13:47:43 2019NAMESPACE: athenaSTATUS: deployedREVISION: 1TEST SUITE: NoneNOTES:` Please be patient while the chart is being deployed `Redis can be accessed via port 6379 on the following DNS names from within your cluster:teset-deploy-redis-master.athena.svc.cluster.local for read/write operationsteset-deploy-redis-slave.athena.svc.cluster.local for read-only operations
穫取你的密碼:
export REDIS_PASSWORD=$(kubectl get secret --namespace athena teset-deploy-redis -o jsonpath="{.data.redis-password}" | base64 --decode)
連線你的 redis 服務:
執行一個你可以作為用戶端用的 Redis pod:
kubectl run --namespace athena teset-deploy-redis-client --rm --tty -i --restart='Never' \ --env REDIS_PASSWORD=$REDIS_PASSWORD \ --image docker.io/bitnami/redis:5.0.7-debian-9-r0 -- bash
使用 Redis CLI 連線:
redis-cli -h teset-deploy-redis-master -a $REDIS_PASSWORDredis-cli -h teset-deploy-redis-slave -a $REDIS_PASSWORD
從叢集外連線你的資料庫:
kubectl port-forward --namespace athena svc/teset-deploy-redis-master 6379:6379 &redis-cli -h 127.0.0.1 -p 6379 -a $REDIS_PASSWORD
現在這一套部署已經完成了,你有一個在名稱空間 test-deploy
中部署的 chart。
檢視你的名稱空間中有哪些 pod:
jess@Athena:~$ kubectl get pods --namespace athenaNAME READY STATUS RESTARTS AGEteset-deploy-redis-master-0 1/1 Running 0 2m38steset-deploy-redis-slave-0 1/1 Running 0 2m38steset-deploy-redis-slave-1 1/1 Running 0 90s
現在,你已經正式把你的應用隔離到了一個名稱空間,建立了一個只在內部通訊的虛擬叢集。
一鍵刪除所有東西:
jess@Athena:~$ kubectl delete namespace athenanamespace "athena" deleted
因為這會刪除應用的所有內部設定,所以這個刪除操作可能會持續一段時間,持續時間取決於你的部署到底有多大。
再次檢查一下所有東西是否被刪除了:
jess@Athena:~$ kubectl get pods --all-namespacesNAMESPACE NAME READY STATUS RESTARTS AGEkube-system coredns-5644d7b6d9-4vxv6 1/1 Running 0 32mkube-system coredns-5644d7b6d9-t5wn7 1/1 Running 0 32mkube-system etcd-minikube 1/1 Running 0 31mkube-system kube-addon-manager-minikube 1/1 Running 0 32mkube-system kube-apiserver-minikube 1/1 Running 0 31mkube-system kube-controller-manager-minikube 1/1 Running 0 31mkube-system kube-proxy-5tdmh 1/1 Running 0 32mkube-system kube-scheduler-minikube 1/1 Running 0 31mkube-system storage-provisioner 1/1 Running 0 27m
這是一個所有 pod 及它們存在於的已知名稱空間的列表。你可以看到,之前建立的應用和名稱空間現在已經不在了。
當前我是出於安全考慮才使用名稱空間,如限制使用者的許可權。你可以限制所有的東西 —— 從哪些角色可以存取名稱空間,到名稱空間可使用的叢集資源(CPU 等)的配額等級。例如,我通過資源配額和基於角色的存取控制(RBAC)設定來確保只有允許的服務賬號可以存取名稱空間。
對於隔離方面的安全,我不希望我的私人 Jenkins 應用可以通過一個信任的本地網路被當做一個有公共 IP 地址的安全映象來存取(我不得不假定,可能會被侵襲)。
如果你很難提前計算出到底要在你的雲平台上部署多少節點(或者,就我而言,是在搞崩我的家庭伺服器之前我能部署多少個),那麼名稱空間在預算方面也很有用。雖然這超出了本文的討論範圍,而且很複雜,但值得你去調研和使用來防止你的叢集過分擴充套件。
名稱空間是一個很好的隔離專案和應用的方法。本文僅是一個關於名稱空間的簡短介紹,所以我建議你更深入地研究下名稱空間,在你的實踐中更多地去使用它們。