一个Python服务Dokcer化并k8s布署实例

这篇文章记录了我试验将一个基于python的服务docker化并k8s布署的过程。

  1. 服务介绍
  2. Docker化
    1. 设计
    2. 业务代码改造
    3. 创建docker镜像
  3. K8S布署
    1. 设计
    2. yaml文件
    3. 运行

服务介绍

这是一个用 python 实现的程序,tornado 作为 web 服务器,mongodb 作为存储,redis 作为缓存。

Docker化

设计

  1. 为了方便,使用docker hub作为镜像仓库,而不是自己搭建私有库。
  2. 业务代码直接打包进docker image,如果修改业务代码,需要重新生成docker image。

业务代码改造

将配置文件中之前涉及到的 mongo 和 redis 的配置改为服务名称。

改造前:

{
	"mongodb": {
		"host":"127.0.0.1",
		"port":"27017"
	},
	"redis": {
		"host":"127.0.0.1",
		"port":"6379"
	}
}

改造后:

{
	"mongodb": {
		"host":"nebulae-redis-mongo",  # 服务名称
		"port":"27017"
	},
	"redis": {
		"host":"nebulae-redis-mongo",
		"port":"6379"
	}
}
  1. nebulae-redis-mongo 为一个服务的名称,下面讲 k8s 设计时会说到。

创建docker镜像

一、目录结构
nebulae
     |
     --- Dockerfile
     |
     --- code  # 业务逻辑代码
            |
            --- nebulae 
二、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程序
创建镜像命令
  1. 在 nebulae 目录下运行下面命令,创建镜像
docker build -t test/nebulae:tag
  1. 将镜像推至 docker hub
docker push test/nebulae:tag

K8S布署

设计

  1. 本例中,mongo 和 redis 放入一个 pod 里,并在创建服务时命名为nebulae-redis-mongo,也是上面代码改造中替换的名字。
  2. nebulae-redis-mongo 只有一个Pod
  3. python 应用程序启动三个Pod,将服务命名为 nebulae-python
  4. 使用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

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 的标签

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上的目录地址

nebulae-pyton 的服务定义

apiVersion: v1
kind: Service
metadata:
  name: nebulae-python
spec:
  type: NodePort
  ports:
  - port: 10001
    nodePort: 30013
  selector:
    app: nebulae-python

运行:

最终的 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

最后布署到k8s,一行命令解决:

$kubectl create -f nebulae.yaml
.....
replicationcontroller "nebulae-redis-mongo" created
service "nebulae-redis-mongo" created
replicationcontroller "nebulae-python" created
service "nebulae-python" created

查看服务

$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

查看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

猜你喜欢

转载自blog.csdn.net/qq_24095941/article/details/85761609