Skip to content

Kubernetes

server api

kubectl cli

key value store, store all the information

Kubernetes 基礎概念教學 小 -> 大:pod -> worker node -> master node -> cluster

Kubernetes 最小的單位,一個 Pod 對應到一個應用服務 (Application),例如一個 Pod 對應到一個 API server。

  • 每個 Pod 都有一個身分證:yaml 檔。
  • 一個 Pod 可以有一個或多個 container,但一般狀況最好只有一個 container。
  • 同個 Pod 中的 containers 共享相同資源跟網路,彼此透過 local port number 溝通。

最小的硬體單位,一個 Worker Node (簡稱 Node) 對應一台機器。 每個 Node 中都有三個組件:kubelet、kube-proxy、Container Runtime。

該 Node 的管理員,負責管理該 Node 上的 Pods 狀態並負責跟 Master 溝通。

該 Node 的傳訊員,負責更新 Node 上的 iptables,讓 k8s 中不在該 Node 的其他物件可以得知該 Node 上所有 Pods 的最新狀態。

該 Node 真正負責容器執行的程式,以 Docker 容器為例,其對應的 container runtime 就是 Docker engine。

運作的指揮中心,一個特化的 Node 負責管理所有其他 Node。 一個 Master Node (簡稱 Master) 中協調出一個最適合放置的 Node 讓該 Pod 跑。

  • 管理整個所需 API 的接口 (Endpoint),例如從 Command Line 下 kubectl 指令就會把指令送到這裡。
  • 負責 Node 之間的溝通橋樑,每個 Node 彼此不能直接溝通,必須要透過 apiserver 轉介。
  • 負責請求的身份認證跟授權。

用來存放 Kubernetes 的資料做為備份,當 Master 因為某些原因而故障的時候,我們可以透過 etcd 幫我們還原狀態。

整個 k8s 的 Pods 調度員,scheduler 會監視新建立但還沒有被指定要跑在哪個 Node 上的 Pod,並根據每個 Node 上面資源規定、硬體限制等條件去協調出一個最適合放置的 Node 讓該 Pod 跑。

  • 負責管理並運行 Kubernetes controller 的組件,簡單來說 controller 就是 k8s 裡一個負責監視 cluster 狀態的 Process,例如:Node Controller、Replication Controller。
  • 這些 Process 會在 Cluster 與預期狀態 (desire state) 不符時嘗試更新現有狀態 (current state)。
  • controller-manager 的監視與嘗試更新也都需要透過訪問 kube-apiserver 達成。

k8s 中多個 Node 跟 Master 的集合。

用於分類以及管理服務,常用的分類方式:「ENV 環境」、「專案名稱」。

Terminal window
# 名字
kubectl get namespaces
# 更多資訊
kubectl describe namespaces

參考文章

Terminal window
kubectl create -f ./hellospace.yaml
kubectl apply -f ./hellospace.yaml

Create vs Apply:

  • kubectl create: 用於創建新資源。如果資源已存在,則會報錯。
  • kubectl apply: 用於創建或更新資源。如果資源已存在,則會根據 YAML 配置進行更新。

kubectl config use-context lm

定義 Pod 要如何被連線跟存取。

service.yaml

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: demoApp
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 3000
nodePort: 30390
- protocol: TCP
port: 8787
targetPort: 8787
Terminal window
kubectl get services

用來管理 Pod 的控制器 (Controller),確保運行指定數量的 Pod。

  1. 管理 ReplicaSet,進而管理 Pod。
  2. 調度 Pod。
  3. 進行 Health Check。
  4. Pod 損壞時自動重啟。
  5. 使用 Rolling Update 進行不停機更新。
  6. 根據資源使用量自動擴充/縮減。
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: my-app
name: my-app-deploy
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: registry.example.com/projects/my-app:latest
Terminal window
kubectl get deploy
kubectl get pods -n my-app
volumes:
- name: test-volume
hostPath:
path: /data
type: Directory

NFS 範例:

spec:
containers:
volumeMounts:
- mountPath: /home/app/public/uploads
name: upload-data
volumes:
- name: upload-data
nfs:
server: xxx.xxx.xxx.xxx
path: /data/uploads

透過 HTTP/HTTPS 在 Service 前搭建 reverse-proxy,統一對外入口。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: my-app
name: my-app-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 3000
tls:
- hosts:
- app.example.com
secretName: my-app-tls
Terminal window
kubectl create secret tls my-app-tls --cert=path/to/cert.crt --key=path/to/cert.key -n my-app

編輯 /etc/hosts 進行本地映射:

Terminal window
10.6.5.201 app.example.com

刪除 Namespace 會同時刪除該 Namespace 下的所有資源。

Terminal window
kubectl delete namespace <namespace-name>
Terminal window
kubectl exec -it <pod-name> -n <namespace> -- /bin/bash

確保敏感資訊不以明文暴露。

Terminal window
kubectl create secret generic empty-secret

Docker Registry Secret 範例:

Terminal window
kubectl create secret -n my-app docker-registry docker-auth \
--docker-server=registry.example.com \
--docker-username=deployer \
--docker-password=xxxxxxxxxxxxx

在 deployment.yaml 中引用:

imagePullSecrets:
- name: docker-auth