从零创建一个 Kubernetes Web 应用
47

前言

从如何创建一个PHP Web应用入手,带大家进入Kubernetes的世界。

基础

环境

  • CentOS 7.5 (Kernel 3.10)
  • Minikube (Kubernetes 1.10.0)

对你的要求

我假设你已经掌握了下面的基础技能:

  • Docker && 会写Dockerfile
  • 如何Google
  • 拥有一个DockerHub账号
  • 手动编译过LNMP或者LAMP

构建基础镜像

alt

上图描述了我们需要创建的Containers,其中Pause ContainerKubernetes自带的所以我们不用关心,但是十分重要,未来将会有一篇文章来描述Pause Container到底干什么的。
其实基础镜像一般用官方现成的就行了,但是在学习过程中建议还是手动编译一下,了解下官方默认配置有哪些坑。Dockerfile代码我会放到GitHub上, 因为在这里展示实在是太长了。

创建Nginx镜像

Nginx: Nginx For K8S GitHub Repo

编译Nginx镜像

    docker build . -t motecshine/nginx1.12-for-k8s:v0.1.0
    docker push motecshine/nginx1.12-for-k8s:v0.1.0

创建PHP-FPM镜像

FPM: FPM For K8S GitHub Repo

编译FPM镜像

    docker build . -t motecshine/php71-for-k8s:v0.1.0
    docker push motecshine/php71-for-k8s:v0.1.0

注意事项: Dockerfile CMD 需要关闭NginxFPMdaemon特性,具体看我REPO的Dockerfile, 这样是为了保证Container生命周期与POD生命周期一致。

构建业务镜像

我们将基于上述镜像来创建我们的业务镜像.

创建Code镜像

我们基于Laravel来创建镜像。

Code: Code For K8S GitHub Repo

编译Code镜像

    docker build . -t motecshine/code-for-k8s:v0.1.1
    docker push motecshine/code-for-k8s:v0.1.1

创建Nginx镜像

laravel-nginx-for-k8s: Laravel For K8S GitHub Repo

编译Nginx镜像

    docker build . -t  motecshine/laravel-nginx-for-k8s:v0.1.1
    docker push  motecshine/laravel-nginx-for-k8s:v0.1.1

创建PHP-FPM镜像

laravel-fpm-for-k8s: Laravel-FPM For K8S GitHub Repo

编译FPM镜像

    docker build . -t  motecshine/laravel-fpm-for-k8s:v0.1.0
    docker push  motecshine/laravel-fpm-for-k8s:v0.1.0

构建Kubernetes应用

整体架构

整体架构如上图所示

构建最小化运行单元(Pod)

alt

创建Deployment

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: laravel
  namespace: default
spec:
  replicas: 1 # 期待副本数量
  template:
    metadata:
      labels:
        app: laravel # app label
        version: testing
    spec:
      containers:
      - name: code
        image: motecshine/code-for-k8s:v0.1.1
        volumeMounts: # 挂载目录
        - mountPath: /data2
          name: code
      - name: fpm
        image: motecshine/laravel-fpm-for-k8s:v0.1.0
        imagePullPolicy: IfNotPresent
        resources: # 资源限制
           limits:
             cpu: 350m
             memory: 350Mi
           requests:
             cpu: 50m
             memory: 50Mi
        ports:
        - name: fpm
          containerPort: 9000
        volumeMounts:
        - mountPath: /data/code # 挂载code
          name: code
        - mountPath: /var/log # 挂载日志
          name: log  
      - name: laravel-nginx
        image: motecshine/laravel-nginx-for-k8s:v0.1.0
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            cpu: 350m
            memory: 350Mi
          requests:
            cpu: 50m
            memory: 50Mi
        ports:
        - name: ivp-nginx
          containerPort: 80 # 暴露Endpoint
        volumeMounts:
        - mountPath: /data/code
          name: code
        - mountPath: /var/log
          name: log  
      volumes:
      - name: code
        emptyDir: {}
      - name: log
        hostPath:
          path: /var/log
          type: Directory

构建Service

apiVersion: v1
kind: Service
metadata:
  name: laravel-service
  namespace: default
  labels:
    app: laravel-service
    version: testing-service
spec:
  type: ClusterIP
  selector:
    app: laravel
    version: testing
  ports:
    - name: http
      port: 80

构建Ingress


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: laravel-ingress
  namespace: default
  labels:
    app: laravel-ingress
spec:
  rules:
  - host: laravel.test
    http:
      paths:
      - path: /
        backend:
          serviceName: laravel-service
          servicePort: 80

安装Minikube

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo cp minikube /usr/local/bin/ && rm minikube

安装Traefik

我们使用开源的Ingress组件安装参考这里

启动Web应用

上面的配置文件在这里

git clone git@github.com:motecshine/laravel-k8s-config.git
cd laravel-k8s-config && kubectl create -f .

效果

效果

结语

简单的介绍了如何创建一个Web应用,这仅仅是个开始,Kubernetes背后是一个庞大的生态环境, CI,CD,ELK(EFK), APM,让我们一点点揭开它神秘的面纱。

下一篇将Kubenetes基于EFK日志收集平台。

本帖由系统于 2个月前 自动加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 13

爱你哦,猪哥 :kissing_heart:

2个月前
motecshine

@郑方方 晚上翻你牌子

2个月前
Destiny

爱你哦,猪哥 :kiss: :kiss: :kiss:

2个月前

太优秀了啊啊啊啊啊啊啊 = 啊=

2个月前
Lwzi

优秀哦 :+1:

2个月前

猪哥太优秀了啊

2个月前

优秀的🐖哥

2个月前

爱你哦,猪哥

2个月前

请问 你用 Traefik,是如何把 80端口 暴漏出来的?

2个月前
motecshine

@klgd Traefik->Service->Pod ContainerPort, Traefik 作为L7层的代理,就想Nginx一样启动默认80 和 443端口

2个月前

@Noober Phper 可能是我没说清楚,集群外访问的话,如果ingress前面没有lb,就需要ingress controller自身暴漏NodePort,默认service NodePort范围是30000-32767,你是如何把80端口暴漏出来的?修改NodePort范围吗?会不会对node节点有影响?

2个月前
motecshine

@klgd

想暴露k8s Service 服务到互联网大概有三种方式:

  1. NodePort(手动映射 Service Endpoint 到 VM Port)
  2. ClusterIP(kube-proxy 通过iptables rules 转发)
  3. Loadbalance(Traefik Nginx-ingress-controller)

你应该说的是第一种,第一种的安全性与可维护性都很差, 服务一多起来,服务器防火墙就成了窟窿,很少会用第一种。第二种也很少见。

2个月前

@Noober Phper Ingress 就是用反向代理负载均衡器将 k8s 集群内的Service暴露到集群外,而Ingress自身部署其实也是一个Service,那么这个Service你是如何暴漏到集群外的?NodePort还是LoadBlancer?

2个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!