# Secret 配置
`Secret` 對象類型用來保存敏感信息,例如密碼、OAuth 令牌和 ssh key。將這些信息放在 `secret` 中比放在 `pod` 的定義中或者 docker 鏡像中來說更加安全和靈活。
## Secret 概覽
Secret 是一種包含少量敏感信息例如密碼、token 或 key 的對象。這樣的信息可能會被放在 Pod spec 中或者鏡像中;將其放在一個 secret 對象中可以更好地控制它的用途,并降低意外暴露的風險。
用戶可以創建 secret,同時系統也創建了一些 secret。
要使用 secret,pod 需要引用 secret。Pod 可以用兩種方式使用 secret:作為 [volume](https://kubernetes.io/docs/concepts/storage/volumes) 中的文件被掛載到 pod 中的一個或者多個容器里,或者當 kubelet 為 pod 拉取鏡像時使用。
### 內置 secret
#### Service Account 使用 API 憑證自動創建和附加 secret
Kubernetes 自動創建包含訪問 API 憑據的 secret,并自動修改您的 pod 以使用此類型的 secret。
如果需要,可以禁用或覆蓋自動創建和使用API憑據。但是,如果您需要的只是安全地訪問 apiserver,我們推薦這樣的工作流程。
參閱 [Service Account](https://kubernetes.io/docs/user-guide/service-accounts) 文檔獲取關于 Service Account 如何工作的更多信息。
### 創建您自己的 Secret
#### 使用 kubectl 創建 Secret
假設有些 pod 需要訪問數據庫。這些 pod 需要使用的用戶名和密碼在您本地機器的 `./username.txt` 和 `./password.txt` 文件里。
```bash
# Create files needed for rest of example.
$ echo -n "admin" > ./username.txt
$ echo -n "1f2d1e2e67df" > ./password.txt
```
`kubectl create secret` 命令將這些文件打包到一個 Secret 中并在 API server 中創建了一個對象。
```bash
$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
```
您可以這樣檢查剛創建的 secret:
```bash
$ kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 51s
$ kubectl describe secrets/db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 12 bytes
username.txt: 5 bytes
```
請注意,默認情況下,`get` 和 `describe` 命令都不會顯示文件的內容。這是為了防止將 secret 中的內容被意外暴露給從終端日志記錄中刻意尋找它們的人。
請參閱 [解碼 secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) 了解如何查看它們的內容。
#### 手動創建 Secret
您也可以先以 json 或 yaml 格式在文件中創建一個 secret 對象,然后創建該對象。
每一項必須是 base64 編碼:
```bash
$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "1f2d1e2e67df" | base64
MWYyZDFlMmU2N2Rm
```
現在可以像這樣寫一個 secret 對象:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
```
數據字段是一個映射。它的鍵必須匹配 DNS_SUBDOMAIN,前導點也是可以的。這些值可以是任意數據,使用 base64 進行編碼。
使用 `kubectl create`創建 secret:
```bash
$ kubectl create -f ./secret.yaml
secret "mysecret" created
```
**編碼注意:** secret 數據的序列化 JSON 和 YAML 值使用 base64 編碼成字符串。換行符在這些字符串中無效,必須省略。當在Darwin/OS X上使用 `base64` 實用程序時,用戶應避免使用 `-b` 選項來拆分長行。另外,對于 Linux用戶如果 `-w` 選項不可用的話,應該添加選項 `-w 0` 到 `base64` 命令或管道 `base64 | tr -d '\n'` 。
#### 解碼 Secret
可以使用 `kubectl get secret` 命令獲取 secret。例如,獲取在上一節中創建的 secret:
```bash
$ kubectl get secret mysecret -o yaml
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
```
解碼密碼字段:
```bash
$ echo "MWYyZDFlMmU2N2Rm" | base64 --decode
1f2d1e2e67df
```
### 使用 Secret
Secret 可以作為數據卷被掛載,或作為環境變量暴露出來以供 pod 中的容器使用。它們也可以被系統的其他部分使用,而不直接暴露在 pod 內。例如,它們可以保存憑據,系統的其他部分應該用它來代表您與外部系統進行交互。
#### 在 Pod 中使用 Secret 文件
在 Pod 中的 volume 里使用 Secret:
1. 創建一個 secret 或者使用已有的 secret。多個 pod 可以引用同一個 secret。
2. 修改您的 pod 的定義在 `spec.volumes[]` 下增加一個 volume。可以給這個 volume 隨意命名,它的 `spec.volumes[].secret.secretName` 必須等于 secret 對象的名字。
3. 將 `spec.containers[].volumeMounts[]` 加到需要用到該 secret 的容器中。指定 `spec.containers[].volumeMounts[].readOnly = true` 和 `spec.containers[].volumeMounts[].mountPath` 為您想要該 secret 出現的尚未使用的目錄。
4. 修改您的鏡像并且/或者命令行讓程序從該目錄下尋找文件。Secret 的 `data` 映射中的每一個鍵都成為了 `mountPath` 下的一個文件名。
這是一個在 pod 中使用 volume 掛在 secret 的例子:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
```
您想要用的每個 secret 都需要在 `spec.volumes` 中指明。
如果 pod 中有多個容器,每個容器都需要自己的 `volumeMounts` 配置塊,但是每個 secret 只需要一個 `spec.volumes`。
您可以打包多個文件到一個 secret 中,或者使用的多個 secret,怎樣方便就怎樣來。
**向特性路徑映射 secret 密鑰**
我們還可以控制 Secret key 映射在 volume 中的路徑。您可以使用 `spec.volumes[].secret.items` 字段修改每個 key 的目標路徑:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
```
將會發生什么呢:
- `username` secret 存儲在 `/etc/foo/my-group/my-username` 文件中而不是 `/etc/foo/username` 中。
- `password` secret 沒有被影射
如果使用了 `spec.volumes[].secret.items`,只有在 `items` 中指定的 key 被影射。要使用 secret 中所有的 key,所有這些都必須列在 `items` 字段中。所有列出的密鑰必須存在于相應的 secret 中。否則,不會創建卷。
**Secret 文件權限**
您還可以指定 secret 將擁有的權限模式位文件。如果不指定,默認使用 `0644`。您可以為整個保密卷指定默認模式,如果需要,可以覆蓋每個密鑰。
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
defaultMode: 256
```
然后,secret 將被掛載到 `/etc/foo` 目錄,所有通過該 secret volume 掛載創建的文件的權限都是 `0400`。
請注意,JSON 規范不支持八進制符號,因此使用 256 值作為 0400 權限。如果您使用 yaml 而不是 json 作為 pod,則可以使用八進制符號以更自然的方式指定權限。
您還可以是用映射,如上一個示例,并為不同的文件指定不同的權限,如下所示:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
mode: 511
```
在這種情況下,導致 `/etc/foo/my-group/my-username` 的文件的權限值為 `0777`。由于 JSON 限制,必須以十進制格式指定模式。
請注意,如果稍后閱讀此權限值可能會以十進制格式顯示。
**從 Volume 中消費 secret 值**
在掛載的 secret volume 的容器內,secret key 將作為文件,并且 secret 的值使用 base-64 解碼并存儲在這些文件中。這是在上面的示例容器內執行的命令的結果:
```bash
$ ls /etc/foo/
username
password
$ cat /etc/foo/username
admin
$ cat /etc/foo/password
1f2d1e2e67df
```
容器中的程序負責從文件中讀取 secret。
**掛載的 secret 被自動更新**
當已經在 volume 中消被消費的 secret 被更新時,被映射的 key 也將被更新。
Kubelet 在周期性同步時檢查被掛載的 secret 是不是最新的。但是,它正在使用其基于本地 ttl 的緩存來獲取當前的 secret 值。結果是,當 secret 被更新的時刻到將新的 secret 映射到 pod 的時刻的總延遲可以與 kubelet 中的secret 緩存的 kubelet sync period + ttl 一樣長。
#### Secret 作為環境變量
將 secret 作為 pod 中的環境變量使用:
1. 創建一個 secret 或者使用一個已存在的 secret。多個 pod 可以引用同一個 secret。
2. 在每個容器中修改您想要使用 secret key 的 Pod 定義,為要使用的每個 secret key 添加一個環境變量。消費secret key 的環境變量應填充 secret 的名稱,并鍵入 `env[x].valueFrom.secretKeyRef`。
3. 修改鏡像并/或者命令行,以便程序在指定的環境變量中查找值。
```yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
```
**消費環境變量里的 Secret 值**
在一個消耗環境變量 secret 的容器中,secret key 作為包含 secret 數據的 base-64 解碼值的常規環境變量。這是從上面的示例在容器內執行的命令的結果:
```bash
$ echo $SECRET_USERNAME
admin
$ echo $SECRET_PASSWORD
1f2d1e2e67df
```
#### 使用 imagePullSecret
imagePullSecret 是將包含 Docker(或其他)鏡像注冊表密碼的 secret 傳遞給 Kubelet 的一種方式,因此可以代表您的 pod 拉取私有鏡像。
**手動指定 imagePullSecret**
imagePullSecret 的使用在 [鏡像文檔](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) 中說明。
### 安排 imagePullSecrets 自動附加
您可以手動創建 imagePullSecret,并從 serviceAccount 引用它。使用該 serviceAccount 創建的任何 pod 和默認使用該 serviceAccount 的 pod 將會將其的 imagePullSecret 字段設置為服務帳戶的 imagePullSecret 字段。有關該過程的詳細說明,請參閱 [將 ImagePullSecrets 添加到服務帳戶](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#adding-imagepullsecrets-to-a-service-account)。
#### 自動掛載手動創建的 Secret
手動創建的 secret(例如包含用于訪問 github 帳戶的令牌)可以根據其服務帳戶自動附加到 pod。請參閱 [使用 PodPreset 向 Pod 中注入信息](https://kubernetes.io/docs/tasks/run-application/podpreset) 以獲取該進程的詳細說明。
## 詳細
### 限制
驗證 secret volume 來源確保指定的對象引用實際上指向一個類型為 Secret 的對象。因此,需要在依賴于它的任何 pod 之前創建一個 secret。
Secret API 對象駐留在命名空間中。它們只能由同一命名空間中的 pod 引用。
每個 secret 的大小限制為1MB。這是為了防止創建非常大的 secret 會耗盡 apiserver 和 kubelet 的內存。然而,創建許多較小的 secret 也可能耗盡內存。更全面得限制 secret 對內存使用的更全面的限制是計劃中的功能。
Kubelet 僅支持從 API server 獲取的 Pod 使用 secret。這包括使用 kubectl 創建的任何 pod,或間接通過 replication controller 創建的 pod。它不包括通過 kubelet `--manifest-url` 標志,其 `--config` 標志或其 REST API 創建的pod(這些不是創建 pod 的常用方法)。
必須先創建 secret,除非將它們標記為可選項,否則必須在將其作為環境變量在 pod 中使用之前創建 secret。對不存在的 secret 的引用將阻止其啟動。
通過 `secretKeyRef` 對不存在于命名的 key 中的 key 進行引用將阻止該啟動。
用于通過 `envFrom` 填充環境變量的 secret,這些環境變量具有被認為是無效環境變量名稱的 key 將跳過這些鍵。該 pod 將被允許啟動。將會有一個事件,其原因是 `InvalidVariableNames`,該消息將包含被跳過的無效鍵的列表。該示例顯示一個 pod,它指的是包含2個無效鍵,1badkey 和 2alsobad 的默認/mysecret ConfigMap。
```bash
$ kubectl get events
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names.
```
### Secret 與 Pod 生命周期的聯系
通過 API 創建的 Pod 時,不會檢查應用的 secret 是否存在。一旦 Pod 被調度,kubelet 就會嘗試獲取該 secret 的值。如果獲取不到該 secret,或者暫時無法與 API server 建立連接,kubelet 將會定期重試。Kubelet 將會報告關于 pod 的事件,并解釋它無法啟動的原因。一旦獲取的 secret,kubelet將創建并裝載一個包含它的卷。在安裝所有pod的卷之前,都不會啟動 pod 的容器。
## 使用案例
### 使用案例:包含 ssh 密鑰的 pod
創建一個包含 ssh key 的 secret:
```bash
$ kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub
```
**安全性注意事項**:發送自己的 ssh 密鑰之前要仔細思考:集群的其他用戶可能有權訪問該密鑰。使用您想要共享 Kubernetes 群集的所有用戶可以訪問的服務帳戶,如果它們遭到入侵,可以撤銷。
現在我們可以創建一個使用 ssh 密鑰引用 secret 的pod,并在一個卷中使用它:
```yaml
kind: Pod
apiVersion: v1
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: mySshImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
```
當容器中的命令運行時,密鑰的片段將可在以下目錄:
```
/etc/secret-volume/ssh-publickey
/etc/secret-volume/ssh-privatekey
```
然后容器可以自由使用密鑰數據建立一個 ssh 連接。
### 使用案例:包含 prod/test 憑據的 pod
下面的例子說明一個 pod 消費一個包含 prod 憑據的 secret,另一個 pod 使用測試環境憑據消費 secret。
創建 secret:
```bash
$ kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
secret "prod-db-secret" created
$ kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
secret "test-db-secret" created
```
創建 pod :
```yaml
apiVersion: v1
kind: List
items:
- kind: Pod
apiVersion: v1
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: prod-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
- kind: Pod
apiVersion: v1
metadata:
name: test-db-client-pod
labels:
name: test-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: test-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
```
這兩個容器將在其文件系統上顯示以下文件,其中包含每個容器環境的值:
```
/etc/secret-volume/username
/etc/secret-volume/password
```
請注意,兩個 pod 的 spec 配置中僅有一個字段有所不同;這有助于使用普通的 pod 配置模板創建具有不同功能的 pod。您可以使用兩個 service account 進一步簡化基本 pod spec:一個名為 `prod-user` 擁有 `prod-db-secret` ,另一個稱為 `test-user` 擁有 `test-db-secret` 。然后,pod spec 可以縮短為,例如:
```yaml
kind: Pod
apiVersion: v1
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
serviceAccount: prod-db-client
containers:
- name: db-client-container
image: myClientImage
```
### 使用案例:secret 卷中以點號開頭的文件
為了將數據“隱藏”起來(即文件名以點號開頭的文件),簡單地說讓該鍵以一個點開始。例如,當如下 secret 被掛載到卷中:
```yaml
kind: Secret
apiVersion: v1
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=
---
kind: Pod
apiVersion: v1
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: gcr.io/google_containers/busybox
command:
- ls
- "-l"
- "/etc/secret-volume"
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
```
`Secret-volume` 將包含一個單獨的文件,叫做 `.secret-file`,`dotfile-test-container` 的 `/etc/secret-volume/.secret-file`路徑下將有該文件。
**注意**
以點號開頭的文件在 `ls -l` 的輸出中被隱藏起來了;列出目錄內容時,必須使用 `ls -la` 才能查看它們。
### 使用案例:Secret 僅對 pod 中的一個容器可見
考慮以下一個需要處理 HTTP 請求的程序,執行一些復雜的業務邏輯,然后使用 HMAC 簽署一些消息。因為它具有復雜的應用程序邏輯,所以在服務器中可能會出現一個未被注意的遠程文件讀取漏洞,這可能會將私鑰暴露給攻擊者。
這可以在兩個容器中分為兩個進程:前端容器,用于處理用戶交互和業務邏輯,但無法看到私鑰;以及可以看到私鑰的簽名者容器,并且響應來自前端的簡單簽名請求(例如通過本地主機網絡)。
使用這種分割方法,攻擊者現在必須欺騙應用程序服務器才能進行任意的操作,這可能比使其讀取文件更難。
## 最佳實踐
### 客戶端使用 secret API
當部署與 secret API 交互的應用程序時,應使用諸如 [RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) 之類的 [授權策略](https://kubernetes.io/docs/admin/authorization/) 來限制訪問。
Secret 的重要性通常不盡相同,其中許多可能只對 Kubernetes 集群內(例如 service account 令牌)和對外部系統造成影響。即使一個應用程序可以理解其期望的與之交互的 secret 的權力,但是同一命名空間中的其他應用程序也可以使這些假設無效。
由于這些原因,在命名空間中 `watch` 和 `list` secret 的請求是非常強大的功能,應該避免這樣的行為,因為列出 secret 可以讓客戶端檢查所有 secret 是否在該命名空間中。在群集中`watch` 和 `list` 所有 secret 的能力應該只保留給最有特權的系統級組件。
需要訪問 secrets API 的應用程序應該根據他們需要的 secret 執行 `get` 請求。這允許管理員限制對所有 secret 的訪問,同時設置 [白名單訪問](https://kubernetes.io/docs/admin/authorization/rbac/#referring-to-resources) 應用程序需要的各個實例。
為了提高循環獲取的性能,客戶端可以設計引用 secret 的資源,然后 `watch` 資源,在引用更改時重新請求 secret。
## 安全屬性
### 保護
因為 `secret` 對象可以獨立于使用它們的 `pod` 而創建,所以在創建、查看和編輯 pod 的流程中 secret 被暴露的風險較小。系統還可以對 `secret` 對象采取額外的預防措施,例如避免將其寫入到磁盤中可能的位置。
只有當節點上的 pod 需要用到該 secret 時,該 secret 才會被發送到該節點上。它不會被寫入磁盤,而是存儲在 tmpfs 中。一旦依賴于它的 pod 被刪除,它就被刪除。
在大多數 Kubernetes 項目維護的發行版中,用戶與 API server 之間的通信以及從 API server 到 kubelet 的通信都受到 SSL/TLS 的保護。通過這些通道傳輸時,secret 受到保護。
節點上的 secret 數據存儲在 tmpfs 卷中,因此不會傳到節點上的其他磁盤。
同一節點上的很多個 pod 可能擁有多個 secret。但是,只有 pod 請求的 secret 在其容器中才是可見的。因此,一個 pod 不能訪問另一個 Pod 的 secret。
Pod 中有多個容器。但是,pod 中的每個容器必須請求其掛載卷中的 secret 卷才能在容器內可見。這可以用于 [在 Pod 級別構建安全分區](https://kubernetes.io/docs/concepts/configuration/secret#use-case-secret-visible-to-one-container-in-a-pod)。
### 風險
- API server 的 secret 數據以純文本的方式存儲在 etcd 中;因此:
- 管理員應該限制 admin 用戶訪問 etcd;
- API server 中的 secret 數據位于 etcd 使用的磁盤上;管理員可能希望在不再使用時擦除/粉碎 etcd 使用的磁盤
- 如果您將 secret 數據編碼為 base64 的清單(JSON 或 YAML)文件,共享該文件或將其檢入代碼庫,這樣的話該密碼將會被泄露。 Base64 編碼不是一種加密方式,一樣也是純文本。
- 應用程序在從卷中讀取 secret 后仍然需要保護 secret 的值,例如不會意外記錄或發送給不信任方。
- 可以創建和使用 secret 的 pod 的用戶也可以看到該 secret 的值。即使 API server 策略不允許用戶讀取 secret 對象,用戶也可以運行暴露 secret 的 pod。
- 如果運行了多個副本,那么這些 secret 將在它們之間共享。默認情況下,etcd 不能保證與 SSL/TLS 的對等通信,盡管可以進行配置。
- 目前,任何節點的 root 用戶都可以通過模擬 kubelet 來讀取 API server 中的任何 secret。只有向實際需要它們的節點發送 secret 才能限制單個節點的根漏洞的影響,該功能還在計劃中。
原文地址:https://github.com/rootsongjc/kubernetes.github.io/blob/master/docs/concepts/configuration/secret.md
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能