1. 程式人生 > >快速安裝Kubernetes叢集與Django應用示例

快速安裝Kubernetes叢集與Django應用示例

k8s使用例項

以web應用為例

django後端 + postgresql + redis

使用k8s需要搭建私有的映象倉庫,一些基礎的應用映象可以從docker hub上直接拉取,但是自己的包含程式碼的專案映象需要提前打包好上傳到自己的映象倉庫,k8s不能像docker-compose那樣通過Dockerfile直接生成映象

應確保master,node1,node2三個節點都能從你的私有倉庫拉取映象

專案結果

├── build.sh
├── Dockerfile
├── requirements.txt
└── src
    ├── src為django專案根目錄

專案映象打包Dockerfile例項:

FROM python:3.6

# 如果在中國,apt 使用映象
RUN curl -s ifconfig.co/json | grep "China" > /dev/null && \
    curl -s http://mirrors.163.com/.help/sources.list.jessie > /etc/apt/sources.list || true

# 安裝開發所需要的一些工具,同時方便在伺服器上進行除錯
RUN apt-get update;\
    apt-get install -y vim gettext postgresql-client;\
    true

COPY . /opt/demo
WORKDIR /opt/demo/src

# 先判斷是否在中國,如果在中國,使用映象下載
RUN curl -s ifconfig.co/json | grep "China" > /dev/null && \
    pip install -r /opt/demo/requirements.txt -i https://pypi.doubanio.com/simple --trusted-host pypi.doubanio.com || \
    pip install -r /opt/demo/requirements.txt

RUN mkdir /opt/logging
RUN mkdir /opt/running

打包映象 build.sh

docker build -t 127.0.0.1:5000/backend:v1.0 . && docker push 127.0.0.1:5000/backend:v1.0

k8s 配置檔案

backend.yaml

# backend
# dns: backend-service.demo.svc.cluster.local
---
apiVersion: v1
kind: Service
metadata:
  name: backend-service
  namespace: demo
spec:
  ports:
  - port: 80
    targetPort: 8000
  selector:
    app: backend-pod

# ingress 負載均衡
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: backend-ingress
  namespace: demo
spec:
  rules:
      paths:
        - path: /
          backend:
            serviceName: backend-service
            servicePort: 80

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: demo-backend
  namespace: demo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: backend-pod
    spec:
      containers:
        - name: demo-backend
          image: 140.xx.xx.181:5000/backend:v1.0   # 你的後端打包的映象地址(私有)
          imagePullPolicy: Always

          ports:
            - containerPort: 8000
          command: ["/bin/sh"]
          args: ["-c", "python manage.py runserver 0.0.0.0:8000"]
          # python manage.py runserver 0.0.0.0:8000 為測試使用,應使用uwsgi等方式

      initContainers:
        - name: wait-redis
          image: busybox
          command: ['sh', '-c', 'until nslookup redis.demo.svc.cluster.local; do echo waiting for redis service; sleep 2; done;']
        - name: wait-postgresql
          image: busybox
          command: ['sh', '-c', 'until nslookup postgresql.demo.svc.cluster.local; do echo waiting for postgresql service; sleep 2; done;']

---
apiVersion: batch/v1
kind: Job
metadata:
  name: sync-db
spec:
  template:
    metadata:
      name: sync-db
      labels:
        app: backend-sync-db-job
    spec:
      containers:
      - name: backend-db-migrate
        image: 140.xx.xx.181:5000/backend:v1.0
        command:
        - "/bin/sh"
        - "-c"
        - "python manage.py makemigrations && python manage.py migrate"
      restartPolicy: Never

postgres.yaml

# postgresql
# dns: postgresql.demo.svc.cluster.local
---
apiVersion: v1
kind: Service
metadata:
  name: postgresql
  namespace: demo
spec:
  ports:
    - port: 5432
      targetPort: postgresql-port
  selector:
    app: postgresql-pod

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: demo-postgresql
  namespace: demo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: postgresql-pod
    spec:
      nodeName: 140.xx.xx.164   # 為了資料的持久化指定排程節點為node1: 140.xx.xx.164 
      containers:
        - name: demo-postgresql
          image: postgres:9.6.3
          imagePullPolicy: Always

          env:
            - name: POSTGRES_DB
              value: demo
            - name: POSTGRES_USER
              value: root
            - name: POSTGRES_PASSWORD
              value: devpwd

          ports:
            - name: postgresql-port
              containerPort: 5432

          volumeMounts:
            - name: postgresql-storage
              mountPath: /var/lib/postgresql

      volumes:
        - name: postgresql-storage
          hostPath:
            path: /data/postgresql   # 為了資料的持久化,使用主機hostPath方式掛載資料卷

redis.yaml

# redis
# dns: redis.demo.svc.cluster.local
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: demo
spec:
  ports:
    - port: 9200
      targetPort: redis-port
  selector:
    app: redis-pod

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: demo-redis
  namespace: demo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: redis-pod
    spec:
      containers:
        - name: demo-redis
          image: redis:3.0.7
          imagePullPolicy: Always

          ports:
            - name: redis-port
              containerPort: 6379

django後端配置

django的settings.py中關於postgres和redis配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'demo',
        'USER': 'root',
        'PASSWORD': 'devpwd',
        'HOST': 'postgresql.demo.svc.cluster.local',
        'PORT': '',
    }
}

REDIS_HOST = "redis.demo.svc.cluster.local"
# 對於不解析dns的應用配置,可以在配置檔案中手動解析,如
# import socket 
# REDIS_HOST = socket.gethostbyname("redis.demo.svc.cluster.local")

注意: 基於dns的服務發現需要k8s-dns支援(rke預設已安裝)

部署(master)


kubectl create namespace demo  # create namespace

kubectl -n demo apply -f .  # apply backend.yaml postgres.yaml yaml

檢視結果

kubectl -n demo get pods

訪問 140.xx.xx.181/admin/

總結

k8s更適合那種無狀態的微服務型別應用, 浮動的pod,服務的動態伸縮在容器化應用方面有著巨大的優勢 對於以資料為中心且沒有叢集概念的應用比如mysql等資料庫,資料的持久化比較麻煩