Kubernetes 基本教學

Gary Ng
39 min readFeb 6, 2021

--

在使用 kubernetes 的時候, 可以先行安裝 minikube 在本機測試, minikube 會在本機建置一個 single node 的 Kubernetes Clutser。

且記得要使用 minikube 前記得先安裝 virtual box

  1. mac 安裝 kubectl
brew install kubectl

2. mac 安裝 minikube

brew install minikube

3. 啟動 minikube

minikube start --vm=true
安裝過程

在執行 minikube 後會安裝映像檔所以會需要一點時間, 安裝完成後你會在 virtual box 上看到一個 minikube 映像檔。

virtual box minikube

4. 查看 minikube 狀態

minikube status

在 minikube 上執行 hello-minikube-app

kubectl run hello-minikube --image=gcr.io/google_containers/echoserver:1.8 --port=8080

執行 kubectl expose 讓本機可以連線到 hello-minikube

kubectl expose rc hello-minikube --type=NodePort

查看 url

minikube service hello-minikube --url

resource list

You must specify the type of resource to describe. Valid resource types include:    * all
* certificatesigningrequests (aka 'csr')
* clusters (valid only for federation apiservers)
* clusterrolebindings
* clusterroles
* componentstatuses (aka 'cs')
* configmaps (aka 'cm')
* daemonsets (aka 'ds')
* deployments (aka 'deploy')
* endpoints (aka 'ep')
* events (aka 'ev')
* horizontalpodautoscalers (aka 'hpa')
* ingresses (aka 'ing')
* jobs
* limitranges (aka 'limits')
* namespaces (aka 'ns')
* networkpolicies
* nodes (aka 'no')
* persistentvolumeclaims (aka 'pvc')
* persistentvolumes (aka 'pv')
* pods (aka 'po')
* poddisruptionbudgets (aka 'pdb')
* podsecuritypolicies (aka 'psp')
* podtemplates
* replicasets (aka 'rs')
* replicationcontrollers (aka 'rc')
* resourcequotas (aka 'quota')
* rolebindings
* roles
* secrets
* serviceaccounts (aka 'sa')
* services (aka 'svc')
* statefulsets
* storageclasses
* thirdpartyresources

Kubernetes中最小運行單位 Pod

pod 特點:

  1. 一個 pod 可以包含多個 container
  2. 在同一個 pod 裡的 container 可以透過 port 互通

建置一個 pod

my_first_pod.yaml

apiVersion: v1 # 版本
kind: Pod # kubernetes 運行種類
metadata:
name: my-pod # pod 的名稱
labels: # pod 的標籤
app: webserver
spec:
containers:
- name: pod-demo # docker container name
image: zxcvbnius/docker-demo # docker image
ports:
- containerPort: 3000 # 允許 3000 port 可以被外部資源存取

以下對參數稍微做一下說明:

apiVersion:

我們有設定 apiVersion, 那要如何得知有哪些 apiVersion 可以使用呢?可以透過以下指令來得知

kubectl api-versions

輸出內容如下:

kubernetes api version

kind:

運行的類型為 pod, 因為 kubernetes 有 service, deployment 等類型,每個類型做的事情以及代表的意義都不大一樣。

metadata:

metadata 像是對這個 pod 下一些標注資訊,我們這邊的設定了 name 跟 label。

metadata.name : 設定 pod 的名稱

metadata.label: 對 pod 設定標籤,後續可以透過其他參數去指定選取標籤

spec:

指定 pod 要運行哪些 container, 以上面的例子來說只運行一個 container, 且只允許 container 的 3000 port 對外。

設定完 pod yml 黨後可以透過以下指令去創建 pod

kubectl create -f my_first_pod.yml

注意!!

kubernetes container name 等命名規則不能是小駝峰,需用烤肉串的方式命名且不能為大寫,例如: my-pod, 不能命名成 myPod 這是會出錯的!!!

ps: mac 在執行的時候可能會出, 請執行以下指令

  1. rm /usr/local/bin/kubectl
  2. brew link --overwrite kubernetes-cli

目前 pods 狀態

kubectl get pods

假如想要透過 get 去顯示出 pod 的 label 的話可以使用

kubectl get pods --show-labels=true
pods with labels information

查看指定 pods 的詳細資訊

kubectl describe pods {pod name}

kubectl describe pods my-pod

pod 與 container 互動有以下兩種方式

  1. port forwarding 到本機:

直接將 pod 的某個 port forward 到本機的某個 port, 以下範例為將本機的 8000 port 對到 pod 的 3000 port

kubectl port-forward {pod name} {local port}:{container port}

kubectl port-forward my-pod 8000:3000

2. 建置 service

kubectl expose pod <pod name>--port=<port> --name=<service name>

kubectl expose pod my-pod --type=NodePort --name=my-pod-service

新增 pod 的 label

kubectl label pods <pod name> <label-key>=<label value>

查看 pod 有哪些 label

kubectl get pods --show-labels

minikube 查看 url

minikube service my-pod-service --url

也可以透過 alpine 與 kubernetes 中的 pods 進行互動,非常適合用來 debug

kubectl run -i --tty alpine --image=alpine --restart=Never -- sh

假設 alpine 已經存在的話則要先透過以下指令刪除

kubectl delete po/alpine

抑或是可以透過以下指令進入 alpine

kubectl exec -it alpine -- /bin/bash

下完指令後接著安裝 curl

apk add --no-cache curl

查詢 pod 的 cluster id

kubectl describe pods my-pod

發現 ip 為 172.17.0.3 後透過 curl 去存取 container 的 3000 port

curl -X 'GET' http://172.17.0.3:3000

此時會發現輸出了 hello world

參考資料:

Replication Controller

replication controller 是用來管理 pod 數量以及狀態的 controller

特點:

  1. 可以複製多份相同的 pod
  2. 當某一 pod crash 或者 failed 的時候會自動幫你再創建新的 pod, 以達到你預期的個數
apiVersion: v1
kind: ReplicationController
metadata:
name: my-replication-controller
spec:
replicas: 3 # 複製三份
selector: # 選取 label 為 hello-pod-v1 的 pod
app: hello-pod-v1
template: # 定義 pod 的資訊以及 docker image
metadata:
labels:
app: hello-pod-v1
spec: # 描述 container 資訊
containers:
- name: my-pod
image: zxcvbnius/docker-demo
ports:
- containerPort: 3000

參數說明:

replicas:

複製幾個 pod, 預設值為 1

selector:

選取擁有此 label 的 pod

template:

定義 pod 的資訊, 結構跟 pod 雷同

創建 replication controller 物件

kubectl create -f <file name>

查看 replication controller 會發現剛剛創建的 replication controller

kubectl get rc

也可以看到目前 replication controller 目前管理 3 個 pods

kubectl get pods

查看 replication controller 詳細資訊

kubectl describe rc my-replication-controller

接著來試試看刪除一個 pod 看是否會自動幫你建置一個 pod

kubectl delete pod my-replication-controller-9n2nx

接著再執行一次 kubectl get pods 會看到以下畫面, 會發現它自動幫你建了一個 pod

用指令來調整 replicas 的數量

kubectl scale --replicas=4 -f <file name>

接著下 kubectl get pods 會看到以下畫面, 發現自動幫你起了一個 pod

而一般再刪除 replication controller 的時候 pod 也會連帶地停止服務, 倘若只想要刪除 replication controller 而不要刪除 pod 的話需要多設定 cascade 參數

kubectl delete rc <filename> --cascade=false

ReplicaSet

replica set 算是進化版的 replication controller, 主要的差異在於 replica set 擁有更加彈性化的 selector, 在使用 deployment 時會自動幫們建立 replica set

Deployment

  1. 可以做到 zero downtime
  2. application 可以 rollback 到某一版本
  3. application 可以升級到某一版本
  4. 部署 application
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-deployment
template:
metadata:
labels:
app: my-deployment
spec:
containers:
- name: my-pod
image: zxcvbnius/docker-demo:latest
ports:
- containerPort: 3000

創建 deployment 物件

kubectl create -f <filename>

查看 deployment 是否被創建成功

kubectl get deploy

deployment 會自動幫我們建立 replica set

deployment 常用的指令

  1. kubectl get deploy

查看 目前的 deployments

2. kubectl get rs

查看目前的 replica set

3. kubectl describe deploy <deploy name>

取得某一 deploy 的資訊

4. kubectl set image deploy/<deployment name> <podname> = <image path>:<image version>

升級某一 pod 到某一版本

5. kubectl edit deploy <deploymen name>

編輯某一 deploy 文件

6. kubectl rollout status deploy <deployment name>

查看某 deployment 的升級狀況

7 kubectl rolllout history deploy <deployment name>

查看某 deployment 升級歷史紀錄

8. kubectl rollout undo deploy <deployment name>

回到前一版本

9. kubectl rollout undo deploy <deployment name> — to_revision=n

回到指定版本

升級 image version

kubectl set image deploy/hello-deployment my-pod=zxcvbnius/docker-demo:v2.0.08

查看 pods, 刪除了舊的 deployment, 而建立新的

查看歷史紀錄

kubectl rollout history deploy my-deployment

注意 deployment 會自動幫我們建制 replication set

Service

外部服務與 pod 供通的橋樑

my-service.yaml

apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
type: NodePort # 可以是 NodePort 或者 LoadBalancer
ports:
- port: 3000 PORT
nodePort: 30390 # 對外 port, 若是沒有指定則會隨機生成
targetPort: 3000 # pod 的 port, 因為 pod 的 port 有可能會更改因此可以對 pod 的 port 命名
protocol: TCP # TCP or UDP
selector:
app: my-deployment

對以上的參數進行說明:

type:

  1. NodePort: 供 Node 之間使用
  2. LoadBalancer: 需要搭配 cloud provider (aws, gcp) 等雲端服務使用
  3. ClusterIP (default): 供 cluster 之間使用

詳細連結可以查點選這裡

ports:

service port 的資訊

ports.port : 此 service cluster ip 的 port, 用以上的範例來說的話就是開出了一個對外的 port 為 3000 , 所以可以透過 service url 搭配 3000 配來發 request

ports.targetPort: 此為 pod 的 container port, 簡單說就是 servie 的 port 會對應到 pod 的哪個 port, 用以上的範例來說的話就是對外的 3000 port 會對應到 pod 的 3000 port

ports.nodePort: service 對外的 port, 範圍需介於 30000–32767 之間,假如沒有指定的話會隨機分配一個 port

ports.protocol: TCP or UDP, 以上的範例是透過 TCP 3000 port 會對應到 pod 的 3000 container port, 可以透過點擊此連結查看支援的 protocol

selector:

此 service 透過此 selector 去選取擁有此 labels 的 pod

這邊假如 pod 的 container port 有更改的話此 service 的 target port 也會需要更改,此時 pod 的部分可以設置 port name, pod yml file 可以設置如下

first-pod.yml

以上的範例設定了一個 port name 為 first-pod-port 這樣 service 的 targetPort 可以直接設定為 first-pod-port , 這樣 pod 的 container port 有更改的話, service 的 targetPort 就不需要再更改了

first-pod-service.yml

創建 service 物件

kubectl create -f <file name>

service 創建成功後檢查是否有對應到 end point

kubectl describe services {service name}

假如沒有對應的 endpoint 你 request 到 service 是會有問題的,因為 service 找不到對應的 pod

查看目前的 service 清單

kubectl get svc

Labels 以及 Annotation

Labels 為具有識別性的 key-value 標籤

Annotation 不具識別性, 可以記錄 pod 的發人者、日期等

apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: webserver
annotations:
version: latest # 版本
release_date: 2021-02-06 - # 發行日期
spec:
containers:
- name: pod-demo
image: zxcvbnius/docker-demo
ports:
- containerPort: 3000

假如要查看 annotations 的資訊的話需透過 describe 例如:

kubectl describe pods my-pod

假如要查看 label 則透過

kubectl get pods my-pod --show-labels

動態新增標籤

kubectl label pods <pod name> <key>=<value>

Healthy check

  1. 檢查 container是否還正在運行, 倘若失敗則在重啟
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-development
template:
metadata:
labels:
app: my-development
spec:
containers:
- name: webapp
image: zxcvbnius/docker-demo
ports:
- name: webapp-port
containerPort: 3000
livenessProbe:
httpGet:
path: /
port: webapp-port
initialDelaySeconds: 15 # 延遲幾秒才做 healthy check
periodSeconds: 15 # 每個幾秒做 healthy check
timeoutSeconds: 30
successThreshold: 1 # 訪問幾次成功就代表運程正常
failureThreshold: 3 # 訪問幾次失敗就代表運行失敗

上面的範例是每 15 秒都會請發 request 到路徑為 / 的網址, 以檢查服務是否正常,假如服務不正常的話則會重啟 container。

但是有時候我們 application 是會要 load 大筆資料甚至是 configuration 所以暫時無法提供服務,在這種情況下我們不希望 application 被 kill 掉也不希望有 request 近來,那這主情況下的話我們則要使用 readiness。 readiness 的設定跟 livenessProbe 很像只是把 livenessProbe 換成了 readinessProbe。

注意!!! livenessProbe 不會去等待 readinessProbe 是否成功,假如要讓 livenessProbe 有等待的功能的話須設定 initialDelaySeconds 或者是 startUpProbe

readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5

參考資料:

Secret

secret 用於存放敏感資料使用

  1. 使用 secret 存放環境變數
  2. 將 secret mount 到指定的 pod 的某個路徑下
  3. 將敏感的資料存放在 private docker hub

secret 的建立方式有 2 種方式, 1 種是用檔案的方式另外一種則是用 yml 的方式。

首先來介紹第一種方式, 我先來創建 username.txt, password.txt, 且檔案內容隨意輸入即可,輸入完後透過以下指令建立 secret

使用

kubectl create secret generic demo-secret-from-file
- from-file=./username.txt \
- from-file=./password.txt

查看剛建置的 secret 資訊

kubectl describe secrets demo-secret-from-file

取得目前所有的 secret

kubectl get secrets

default-token-shdlr 是 kubernetes 幫我們建置好的物件, 裡面存放著 access token, 可以透過此 access token 來訪問 k8s API

除了 from-file 的方式之外還有 from-literal 也就是直接在 command 輸入 secret 資料

kubectl create secret generic secret-from-literal --from-literal=username=root --from-literal=password=passwd

第二種方式則是透過 secret yaml 建置 secret 物件

ps:注意 data 需為 base64 編碼

apiVersion: v1
kind: Secret
metadata:
name: demo-secret-from-yaml # secret 名稱
type: Opaque
data: # secret 資料
username: cm9vdA==
password: cm9vdHBhc3M=

而在 pod 要使用 secret 也有兩種方式一種是mount, 另外一種則是 引入 secret.yml 裡面的資料到 pod

以下為第二種方式引入 secret.yml 的資料到 pod

apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: webserver
annotations:
version: latest
release_date: 2021-02-06
spec:
containers:
- name: pod-demo
image: zxcvbnius/docker-demo
ports:
- containerPort: 3000
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: demo-secret-from-yaml # secret name
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: demo-secret-from-yaml
key: password

假如忘記 secret name 的話可以特過以下指令列出所有 secret

kubectl get secrets 

以下為第一種方式將 secret 掛載到 pod 特定的目錄下

apiVersion: v1
kind: Pod
metadata:
name: pod-with-secret-mount
labels:
app: webservers
pod: secret-mount
spec:
containers:
- name: demo-pod
image: zxcvbnius/docker-demo
ports:
- containerPort: 3000
name: pod-secret-port
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: /etc/creds # 掛載到指定的資料夾
volumes:
- name: secret-volume
secret:
secretName: demo-secret

參考資料:

ConfigMap

config map 主要用於存放一些非敏感性的資料,例如 mysql 設定、nginx 設定甚至是 redis 設定等資訊

我們可以先隨便新增一個 redis.conf , 然後透過以下指令新增 configmap

kubectl create configmap <configmap name> --from-file=<filename>

在這邊的 configmap name 為 kubernetes 的名稱, filename 為檔案名稱,因此完整的指令如下

kubectl create configmap redis-conf --from-file=redis.conf

接著可以透過以下指令查看我們現有的 configmap

kubectl get configmaps

也可以透過以下指令查看 redis-config 的內容

kubectl describe configmap <name>

kubectl describe configmap redis-config

創建 nginx ingress controller

mac

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/cloud/deploy.yaml

Volumes

假如沒有設定 volume 那當 pod 中的 container 因為某些原因 crash 或者退出後資料會消失,而此時就得利用 volume 將 container 資料保存下來,volume 的好處不只可以把資料把存下來也可以使 pod 中的 container 共用一個檔案或者是資料夾。而底下為 4 種常見的 volume

四種常見的 volume

  1. emptyDir

當 node 被移除 , empty dir 也會被移除

用途:

a. 暫時性資料

b. 共用儲存空間

2. hostPath

Node 的 directory 掛載到某個 pod 的 directory, 簡多說就是 node directory 跟 pod directory 是同步的

3. Cloud Storage

支援 AWS EBS, Google Disk, Microsoft Azure Disk

4. NFS (Network File System)

如何保存 container 中的資料

可以使用 volume , 而 volume 又分為很多種

  1. emptyDir
  2. hostPath
  3. Cloud storage
  4. NFS (Network Filesystem )

emptyDir:

建置 emptyDir 後, 所有 container 都可以存取 emptyDir, 而當 pod 從 node 移除時, emptyDir 也隨之被移除

用途:

  1. 暫時性的儲存空間

運行一些無需永久保存的資料

2. 共用的儲存空間:

所有的 pod 中的所有 container 都可以存取, 所以可以當作是共用目錄

apiVersion: v1
kind: Pod
metadata:
name: empty-dir
labels:
app: webservers
spec:
containers:
- name: apiserver
image: zxcvbnius/docker-demo
volumeMounts:
- name: empty-volume
mountPath: /cache
volumes:
- name: empty-volume
emptyDir: {}

hostPath:

檔案會被保存在 Node 上,假如 Node 從 kubernetes cluster 移除的話資料才會消失

apiVersion: v1
kind: Pod
metadata:
name: hostpath-example
spec:
containers:
- name: apiserver
image: zxcvbnius/docker-demo
volumeMounts:
- name: tmp-volume
mountPath: /tmp
volumes:
- name: tmp-volume
hostPath:
path: /tmp
type: Directory

以上的範例是將 node 的 tmp 資料夾跟 container 的 tmp 做 volume, 也就是假如 container 假如在 tmp 資料夾做新增刪除修改的話,也會跟 node tmp 做同步

Persistent Volume Claim

PVC 也是一種持久化儲存的方式,只是他提供的功能更為強大可以指定 volume 大小以將當 pod 掛掉後自動刪除對應的 volume。

創建一個 persistent volume claim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: standard

參數說明

accessModes:

1. ReadWriteOnce: persistent volume claim 所產生出來的 volume 只能掛載到一個 Node 供讀寫

2. ReadOnlyMany: persistent volume claim 所產生出來的 volume 可以掛載到多個 Node 僅供讀取

3. ReadWriteMany: persistent volume claim 所產生出來的 volume 可以掛載到多個 Node 供讀寫

注意!! 有些 volume plugin 只能支援特定的 access mode, 例如 AWS EBS 僅提供 ReadWriteOnce, 可以點選此連結查看官方資訊

resources.requests.storage:

限制儲存空間為 1GB

storageClassName:

指定要選擇使用哪個 Storage Class, 這邊使用 standard, minikube 預設會創建一個 standard 的 storage class

透過以上所學建置簡單的 php + nginx 服務

以下範例將教學如何使用 kubernetes 架設一個 php + nginx, 且 php 顯示 phpinfo 資訊。

首先我們先創建一個叫做 lnmp 的 namespace, 以方便跟 default namespace 做區隔,所以我們新增一個名為 namespace.yml 檔案,內如如下。

apiVersion: v1
kind: Namespace
metadata:
name: lnmp

一樣透過 create 指令去創建

kubectl create -f ./namespace.yml

之後便可以透過以下指令去查看 ns

kubectl get ns

會發現有我們剛剛創建的 namespace。

然後這邊要注意的是 minikube 預設使用的是 default namespace, 所以在日後要從 lnmp namespace 取出 pod , svc(service) 的話指令都需要多加 -n lnmp 去指定要從 lnmp namespace 取資料。

而我們如何得知 minikube 是使否 default namespace 呢?可以透過

kubectl config view

想要切換 namespace 可以參考此連結

創建好 lnmp namespace 好後我們緊接著創建 pods/nginx.yml , 裡面存放 nginx pod。(比較好的方式看是否要建立成 deployment)

apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: lnmp # 指定建置在 lnmp namespace 下
labels:
lnmp: nginx
spec:
containers:
- name: lnmp-nginx
image: nginx:latest
ports:
- containerPort: 80
name: nginx-port

以上會建置一個名為 nginx-pod 的 pod 在 lnmp namespace 下。

一樣都透過 create 創建

kubectl create -f ./pods/nginx.yml

執行完後來查看是否有 nginx pod

kubectl get pods nginx-pod -n lnmp

再重複一次記得後面要加 -n lnmp 指定從 lnmp namespace 取 pod

pod 創建好之後為了讓 pod 可以對外所以要創建 serivce , 此時創建 services/nginx.yml

apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: lnmp # 指定 namespace
labels:
nginx: service
spec:
type: NodePort
selector:
lnmp: nginx
ports:
- protocol: TCP
port: 80
targetPort: nginx-port
nodePort: 32003
name: service-nginx-port

創建 service

kubectl create -f ./services/nginx.yml

查看是否有成功建立 service

kubectl get svc nginx-service -n lnmp

都建置好後可以透過 http://192.168.64.2:32003/ 去存取服務。

而 nginx 建置好之後緊接著建立 php pod, 路徑為 pods/php.yml

apiVersion: v1
kind: Pod
metadata:
name: php-pod
namespace: lnmp
labels:
lnmp: php
spec:
containers:
- name: php
image: php:7.4-fpm
ports:
- containerPort: 9000
name: php-port

創建 php pod

kubectl create -f ./pods/php.yml

一樣 php pod 也需要創建 service, 路徑為 services/php.yml

apiVersion: v1
kind: Service
metadata:
name: php-service
namespace: lnmp
spec:
type: NodePort
selector:
lnmp: php
ports:
- protocol: TCP
port: 9000
targetPort: php-port
name: php-service-port

創建 service

kubectl create -f ./services/php.yml

查看 service

kubectl get svc -n lnmp

都創建好之後,我們知道 nginx 通常會有個 conf 指定到特定的資料夾去解析 php 資訊,因此時我們建立 configMap/nginx.yml

apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
namespace: lnmp
labels:
nginx: conf
data:
config: |
server {
listen 80;
server_name _;

root /app;
index index.php index.html

error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ .php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+.php)(/.+)$;
fastcgi_pass php-service:9000; # 這邊使用 php service 的名稱
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}

創建 config map

kubectl create -f ./configMap/nginx.conf

查看 configmap

kubectl get configmaps -n lnmp

configmap 用好之後接著要設定 pod 引入此 config map, 所以我們繼續編輯 pods/nginx.yml 成如下

apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: lnmp
labels:
lnmp: nginx
spec:
containers:
- name: lnmp-nginx
image: nginx:latest
ports:
- containerPort: 80
name: nginx-port
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d # 要掛載的路徑
volumes:
- name: nginx-conf # volume name
configMap:
name: nginx-conf # config map name
items:
- key: config # config map key
path: my-nginx.conf # filename

以上的範例會將檔案掛載至 /etc/nginx/conf.d 且檔案名稱叫做 my-nginx.conf。

做完此操作後記得刪除 nginx pod 且重新新增 pod

# 刪除 nginx pod 
kubectl delete pods nginx-pod -n lnmp


kubectl create -f ./pods/nginx.yml

pods 成功後我們進入 nginx container 來查看是否有我們掛載進去的 my-nginx.conf

kubectl exec -it nginx-pod -n lnmp -- /bin/bash

cd 進入 /etc/nginx/conf.d 看是否有 my-nginx.conf 指令如下

緊接著我們要創建 php configmap, 裡面存放 index.php 且內容為如下

<?php

phpinfo();

?>

創建 configMap/php-file.yml

apiVersion: v1
kind: ConfigMap
metadata:
name: php-file
namespace: lnmp
labels:
php: file
data:
index: |
<?php

phpinfo();

?>

新增 php-file config

kubectl create -f ./configMap/php-file.yml

查看 configmap

kubectl get configmap -n lnmp

創建好 php-file configmap 後,緊接著也是要修改 php pod 去掛載 php-file config map 近來。

apiVersion: v1
kind: Pod
metadata:
name: php-pod
namespace: lnmp
labels:
lnmp: php
spec:
containers:
- name: php
image: php:7.4-fpm
ports:
- containerPort: 9000
name: php-port
volumeMounts:
- name: php-config-file # volume name
mountPath: /app
volumes:
- name: php-config-file # volume name
configMap:
name: php-file # config map name
items:
- key: index # config map key name
path: index.php

一樣要先刪除 php pod 後再重新創建 php pod

kubectl delete pods php-pod -n lnmp

kubectl create -f ./pods/php.yml

pod 都成功執行起來之後就可以訪問 http://192.168.64.2:32003/

想要得知 ip 為多少可以透過 minikube ip 去查詢!!

可以此考以下 github repo 的程式碼。

--

--

Gary Ng
Gary Ng

軟體工程師、後端工程師

No responses yet