Python服務Dokcer化並k8s部署實例
這篇文章記錄了我試驗將一個基於python的服務docker化並k8s部署的過程。
服務介紹
Docker化
設計
業務代碼改造
創建docker鏡像
K8S部署
設計
yaml文件
運行
服務介紹
這是一個用 python 實現的程序,tornado 作為 web 服務器,mongodb 作為存儲,redis 作為緩存。
Docker化
設計
為了方便,使用docker hub作為鏡像倉庫,而不是自己搭建私有庫。
業務代碼直接打包進docker image,如果修改業務代碼,需要重新生成docker image。
業務代碼改造
將配置文件中之前涉及到的 mongo 和 redis 的配置改為服務名稱。
改造前:
{
"host":"127.0.0.1",
"port":"27017"
},
"redis": {
"host":"127.0.0.1",
"port":"6379"
}
}
1
2
3
4
5
6
7
8
9
10
改造後:
{
"mongodb": {
"host":"nebulae-redis-mongo", # 服務名稱
"port":"27017"
},
"redis": {
"host":"nebulae-redis-mongo",
"port":"6379"
}
}
1
2
3
4
5
6
7
8
9
10
nebulae-redis-mongo 為一個服務的名稱,下面講 k8s 設計時會說到。
創建docker鏡像
nebulae
|
--- Dockerfile
|
--- code # 業務邏輯代碼
|
--- nebulae
1
2
3
4
5
6
7
二、Dockerfile
FROM python:3.6 # 基礎鏡像
COPY ./code/nebulae /code/nebulae # 將代碼copy進容器
WORKDIR /code/nebulae/services
RUN pip install -r requirements.txt # 安裝程序依賴
EXPOSE 10001 # 容器對外暴露的端口
CMD ["python","nebulae_server.py"] # 容器執行的命令,起動python程序
2
3
4
5
6
7
8
9
10
11
創建鏡像命令
在 nebulae 目錄下運行下面命令,創建鏡像
docker build -t test/nebulae:tag
1
將鏡像推至 docker hub
docker push test/nebulae:tag
1
K8S部署
設計
本例中,mongo 和 redis 放入一個 pod 裏,並在創建服務時命名為nebulae-redis-mongo,也是上面代碼改造中替換的名字。
nebulae-redis-mongo 只有一個Pod
python 應用程序啟動三個Pod,將服務命名為 nebulae-python
使用volume的hostPath 將 python 應用程序的日誌掛截到 Node 上
k8s yaml 文件
nebulae-redis-mongo的Pod的定義:
piVersion: v1
kind: ReplicationController # 聲名資源類型,為k8s的類型
metadata:
name: nebulae-redis-mongo
labels:
name: nebulae-redis-mongo
spec:
replicas: 1 # 維持的Pod個數
selector:
app: nebulae-redis-mongo # 對應下方template裏的labels
template: # 具體的 Pod 定義
metadata:
labels:
app: nebulae-redis-mongo
spec:
containers: # 這個Pod裏包含了mongo和redis裏
- name: nebulae-redis
image: redis # redis官方鏡像
ports:
- containerPort: 6379
- name: nebulae-mongo
image: mongo # mongo官方鏡像
ports:
- containerPort: 27017
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
nebulae-redis-mongo服務的定義
apiVersion: v1
kind: Service # k8s 服務資源
metadata:
name: nebulae-redis-mongo
labels:
name: nebulae-redis-mongo
spec:
type: NodePort
ports:
- port: 6379
name: nebulae-redis
nodePort: 30011 # 在Node上監聽此端口
- port: 27017
name: nebulae-mongo
nodePort: 30012 # 在Node上監聽此端口
selector:
app: nebulae-redis-mongo # 對應 Pod 的標簽
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
nebulae-pyton 的Pod定義
apiVersion: v1
kind: ReplicationController
metadata:
name: nebulae-python
spec:
replicas: 3 # Pod副本數
selector:
app: nebulae-python
template:
metadata:
labels:
app: nebulae-python
spec:
containers:
- name: nebulae-python
image: test/nebulae:0.0.3 # 在docker hub中的鏡像地址
volumeMounts:
- mountPath: /code/nebulae/services/log # 容器中的日誌目錄
name: nebulae-python-log # 卷名
ports:
- containerPort: 10001
volumes:
- name: nebulae-python-log # 卷名
hostPath:
path: "/tmp/logs/nebulae" # node上的目錄地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
nebulae-pyton 的服務定義
apiVersion: v1
kind: Service
metadata:
name: nebulae-python
spec:
type: NodePort
ports:
- port: 10001
nodePort: 30013
selector:
app: nebulae-python
1
2
3
4
5
6
7
8
9
10
11
運行:
最終的 nebulae 的創建文件,名為 nebulae.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nebulae-redis-mongo
labels:
name: nebulae-redis-mongo
spec:
replicas: 1
selector:
app: nebulae-redis-mongo
template:
metadata:
labels:
app: nebulae-redis-mongo
spec:
containers:
- name: nebulae-redis
image: redis
ports:
- containerPort: 6379
- name: nebulae-mongo
image: mongo
ports:
- containerPort: 27017
---
apiVersion: v1
kind: Service
metadata:
name: nebulae-redis-mongo
labels:
name: nebulae-redis-mongo
spec:
type: NodePort
ports:
- port: 6379
name: nebulae-redis
nodePort: 30011
- port: 27017
name: nebulae-mongo
nodePort: 30012
selector:
app: nebulae-redis-mongo
---
apiVersion: v1
kind: ReplicationController
metadata:
name: nebulae-python
spec:
replicas: 3
selector:
app: nebulae-python
template:
metadata:
labels:
app: nebulae-python
spec:
containers:
- name: nebulae-python
image: yf8155674/nebulae:0.0.3
volumeMounts:
- mountPath: /code/nebulae/services/log
name: nebulae-python-log
ports:
- containerPort: 10001
volumes:
- name: nebulae-python-log
hostPath:
path: "/tmp/logs/nebulae"
---
apiVersion: v1
kind: Service
metadata:
name: nebulae-python
spec:
type: NodePort
ports:
- port: 10001
nodePort: 30013
selector:
app: nebulae-python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
最後布署到k8s,一行命令解決:
$kubectl create -f nebulae.yaml
.....
replicationcontroller "nebulae-redis-mongo" created
service "nebulae-redis-mongo" created
replicationcontroller "nebulae-python" created
service "nebulae-python" created
1
2
3
4
5
6
查看服務
$kubectl get svc # 查看當前的服務
.....
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nebulae-python NodePort 10.8.255.117 <none> 10001:30013/TCP 1m
nebulae-redis-mongo NodePort 10.8.255.202 <none> 6379:30011/TCP,27017:30012/TCP 1m
1
2
3
4
5
查看Pod狀態
$kubectl get pods
....
NAME READY STATUS RESTARTS AGE
nebulae-python-9phxq 1/1 Running 0 3m
nebulae-python-nqkq4 1/1 Running 0 3m
nebulae-python-p9zvs 1/1 Running 0 3m
nebulae-redis-mongo-p7625 2/2 Running 0 3m
Python服務Dokcer化並k8s部署實例