# 建立 Pod & Kubernetes Dashboard 使用 **`kubectl`** 建立 Kubernetes objects 有兩種方式:**Imperative** & **Declarative**。 ## [Pod](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/) ### Imperative Imperative method 是利用指令描述 Kubernetes resource,例如建立一個 pod,名字為 nginx-pod,裡面跑 nginx。[**kubectl run**](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#run) ```bash kubectl run nginx-pod --image=nginx # pod/nginx-pod created ``` 如果成功,會看到 terminal 顯示 `pod/<pod-name> created`。 利用 **`kubectl get pods`** 可以列出 default namespace 中的 pod: ```bash kubectl get pods # NAME READY STATUS RESTARTS AGE # nginx-pod 1/1 Running 0 2m49s ``` ### Declarative Declarative method 則是指利用檔案來描述資源的設定,一般會用 **YAML** 檔來建立 Kubernetes objects。寫好 yaml 檔後可利用 **`kubectl apply -f <filename>`** 來建立資源。 :::success :notebook: **Note:** 也可使用 **`kubectl create -f <filename>`** ,但利用 **create** 的方式建立資源是一次性的,無法更新 yaml 檔後更新到現有的資源。[Blog](https://blog.miniasp.com/post/2022/10/24/Kubernetes-101-diff-between-kubectl-create-and-kubectl-apply) ::: 在要建立的 Kubernetes objects 的清單(YAML 或 JSON 檔案)中,您需要設定以下欄位的值: + **`apiVersion`**:指定用來創建此物件的 Kubernetes API 版本。 + **`kind`**:指定想要創建的物件類型。 + **`metadata`**:包含有助於唯一識別該物件的數據,包括 **`name`** 字符串、**`labels`**、**`UID`**,以及可選的 **`namespace`**。 + **`spec`**:用於指定您想要為該物件實現的狀態。 建立 Kubernetes objects 的 yaml file 有一定的格式,這邊以 Pod 為例: ```yaml # pod.yaml apiVersion: v1 kind: Pod metadata: name: nginx-pod-yaml spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` + **`apiVersion`**:指定使用的 Kubernetes API 版本。 + **`kind`**:指定資源類型為 Pod。 + **`metadata`**:包含有關 Pod 的元數據,如名稱。 + **`spec`**:定義 Pod 的配置。 + **`containers`**:定義 Pod 中運行的容器。 + **`name`**:容器的名稱為 nginx。 + **`image`**:容器使用的 image 版本為 nginx:1.14.2。 + **`ports`**:容器中的端口設置。 + **`containerPort`**:容器內部的端口為 80。 :::success :notebook: 參考資源: [**API groups & versioning**](https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning) [**Resource URIs**](https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-uris) [**API Overview**](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) :point_left: 有各個資源使用的 API Group & Version 以及 yaml config example [**Workload Resources**](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/):point_left: 各個 Object spec 的規範 ::: 執行結果: ```bash kubectl apply -f pod.yaml # pod/nginx-pod-yaml created kubectl get pods # NAME READY STATUS RESTARTS AGE # nginx-pod-yaml 1/1 Running 0 29s ``` ### kubectl 指令 剛剛使用的指令 **`kubectl get pods`** 或 **`kubectl apply -f pod.yaml`** 即是透過 kubectl 跟 control plane 溝通來操作 k8s cluster objects。 ```bash kubectl [command] [TYPE] [NAME] [flags] ``` + **`command`**:指定要對一個或多個資源執行的操作,例如 **`create`**、**`get`**、**`describe`**、**`delete`**。 + **`TYPE`**:指定[資源類型](https://kubernetes.io/docs/reference/kubectl/#resource-types)。資源類型不會區分大小寫,您可以指定單數、複數或縮寫形式。例如,以下命令會產生相同的輸出: ```bash kubectl get pod pod1 kubectl get pods pod1 kubectl get po pod1 ``` + **`NAME`**:指定資源的名稱。名稱區分大小寫。如果省略名稱,則會顯示所有資源的詳細信息,例如 **`kubectl get pods`**。 對多個資源執行操作時,可以按類型和名稱指定每個資源,也可以指定一個或多個檔案: + 按類型和名稱指定資源: + 如果資源都屬於同一類型,則將它們分組:**`TYPE1 name1 name2 name<#>`**。 範例:**`kubectl get pod example-pod1 example-pod2`** + 各自指定多個資源類型:**`TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>`**。 範例:**`kubectl get pod/example-pod1 replicationcontroller/example-rc1`** + 使用一個或多個檔案指定資源:**`-f file1 -f file2 -f file<#>`** + [使用 YAML 而不是 JSON](https://kubernetes.io/docs/concepts/configuration/overview/#general-configuration-tips),因為 YAML 往往對用戶友善,尤其是對於設定檔。 範例:**`kubectl get -f ./pod.yaml`** + **`flags`**:指定可選標誌。例如,您可以使用 **`-s`** 或 **`--server`** 標誌來指定 Kubernetes API 伺服器的位址和連接埠。 :::success :notebook: 參考資源: [**常用指令**](https://kubernetes.io/docs/reference/kubectl/cheatsheet/) ::: ### Expose Pod 因 Pod 是在 k8s cluster 的內部網路,外部是無法訪問的。如果要讓外面的流量可以到達 Pod 可以利用一些方式,這邊先使用 **`port-forward`** 的方式讓主機能夠訪問 Pod 。但一般的作法會是建立 Service 這個 Kubernetes object,Service 會是將流量導入 Pod 的接口,後續會再介紹。 ```bash kubectl port-forward nginx-pod-yaml 7777:80 # Forwarding from 127.0.0.1:7777 -> 80 # Forwarding from [::1]:7777 -> 80 ``` 使用 **`curl`** 會回傳 Welcome to nginx 的 html。 ```bash curl localhost:7777 # <!DOCTYPE html> # <html> # <head> # <title>Welcome to nginx!</title> # <style> # ... # <p><em>Thank you for using nginx.</em></p> # </body> # </html> ``` 可以使用 **`kubectl logs nginx-pod-yaml`** 來看 log。 ```bash kubectl logs nginx-pod-yaml # 127.0.0.1 - - [19/Dec/2023:14:16:53 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.82.0" "-" ``` ## Kubernetes Dashboard ### 部署 Dashboard UI Dashboard UI 預設是不被部署的。要部署它,請執行以下命令: ```bash kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml ``` ### 存取 Dashboard UI 為了保護您的 cluster 數據,Dashboard 預設使用最小的 RBAC 配置進行部署。目前,Dashboard 僅支援使用 Bearer Token 登入。若要為此示範建立 token,您可以按照我們的 [creating a sample user](https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md) 指南進行操作。 :::danger :no_entry: 嚴重: 本教程中建立的範例使用者將具有管理權限,並且僅用於教育目的。 ::: 對於 **`ServiceAccount`** 和 **`ClusterRoleBinding`** 的以下每個片段,您應該將它們複製到新的清單檔案(例如 **`dashboard-adminuser.yaml`**),並使用 **`kubectl apply -f dashboard-adminuser.yaml`** 來建立它們。 #### Creating a Service Account 我們首先在命名空間 **`kubernetes-dashboard`** 中建立名為 **`admin-user`** 的服務帳號。 ```yaml # dashboard-adminuser.yaml apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard ``` #### Creating a ClusterRoleBinding 在大多數情況下,使用 **`kops`**、**`kubeadm`** 或任何其他流行工具配置 cluster 後,**`ClusterRole`** **`cluster-admin`** 已存在於 cluster 中。我們可以使用它並為我們的 **`ServiceAccount`** 建立 **`ClusterRoleBinding`**。如果不存在,那麼您需要先建立該角色並手動授予所需的權限。 ```yaml # cluster-role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard ``` #### Getting a Bearer Token for ServiceAccount 現在我們需要找到可用於登入的 token。執行以下命令: ```bash kubectl -n kubernetes-dashboard create token admin-user ``` 它應該會列印如下內容: ``` eyJhbGciOiJSUzI1NiIsImtpZCI6Im1Dai1sd2lCMDdhOEFtMlgwODJBRkZ6VzkzYW41d2hvaGE5bmJ6RFJQOVkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI3OTgyYTY1OS00NmNhLTQyMWEtYjE1OS01OTQ2NmM2ODE5ODUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.Ku9h-rpOMSn1D-n0NgapyMWhtnlhHWoqmU0nADw2VqGjTLnBz7eu-iOpoVoJ4fRi5M6JLm4saJD-GLY0elmX1Egp-jv4bYMCj6w7KQ1aFJXVAxIV2gt5sH09q22aA1FGXB4E2kPoQCBcFdsmbLYi2PW1TpCWmi5Ic7a59qessCRt6LjCPuznFH2vKWKcaje7iNQ3LUQWbVtUs7yL_skfAWiMsx6BNP4edhq3RNy0ZFWOSSBEoztgarOR5tLsnnKIcvdxqpIAjpLKLIp1qXCqH2V22Tr6dtZmpg56bn36MW7OUkJqF5T-t1QdC5FDtL184-RCqHfYYldP0lSM9lu2jw ``` #### Getting a long-lived Bearer Token for ServiceAccount 我們也可以使用綁定服務帳戶的 Secret 建立一個 token,該 token 將保存在 Secret 中: ```yaml apiVersion: v1 kind: Secret metadata: name: admin-user namespace: kubernetes-dashboard annotations: kubernetes.io/service-account.name: "admin-user" type: kubernetes.io/service-account-token ``` 創建 Secret 後,我們可以執行以下命令來取得 Secret 中保存的 token: ```bash kubectl get secret admin-user -n kubernetes-dashboard -o jsonpath={".data.token"} | base64 -d ``` #### **`kubectl port-forward`** 執行 **`kubectl port-forward`** 指令並透過簡單的 URL 存取 Dashboard。 首先,我們需要找到啟動 Dashboard 的 Service 名稱。 ```bash kubectl -n kubernetes-dashboard get service # NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE # kubernetes-dashboard ClusterIP 10.43.225.24 <none> 443/TCP 18m # dashboard-metrics-scraper ClusterIP 10.43.139.8 <none> 8000/TCP 18m ``` 接著再把 Service 的 port 映射到 host 的 port 上供外部存取。 ```bash kubectl port-forward -n kubernetes-dashboard svc/kubernetes-dashboard 7788:443 --address 0.0.0.0 ``` 現在可以存取 Dashboard:https://192.168.1.76:7788。 :::success :notebook: **Note:** kubeconfig 驗證方法不支援外部身分提供者或基於 X.509 憑證的驗證。 :::
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up