web项目迁移到k8s

这篇文章应该会很长。php

前言

小说 是我之前写的一个项目,主要是为了练手vue,后端用lumen(php框架)写的。附上码云的连接 vue-novel,先后端代码都很简单。最近把它迁移到了k8s,配合gitlab-runner和rancher-ui实现了CI/CD,在此记录一下。附上迁移后的项目地址:html

最开始这个项目是怎么运行的呢?我在vultr买了个vps,安装 lnmp 集成环境,项目代码用FTP传上去,配置一下nginx就跑起来了。迁移到k8s后,提交和发布代码的大体流程以下:前端

  1. 把代码推送到master分支
  2. gitlab-runner自动打包镜像并推送到docker私有仓库
  3. 进入rancher后台界面,把项目的镜像更新为刚才的镜像

能够看到,咱们要作的仅仅是推送代码,而后去后台更新项目的镜像,项目就上线了。vue

须要准备的

  1. 至少两台vps,而且相互之间能够ping通。
  2. gitlab仓库(本身搭建或直接用官网都行)。
  3. 本身的域名。

须要作的

  • 打包两个docker的基础镜像。全部后端代码用一个基础镜像,前端代码用另外一个。
  • 搭一个k8s集群。我选择用 k3s。这是个精简版的k8s,功可以用,搭建简单,对机器配置要求低。
  • 搭一个rancher-ui。rancher2.0,搭建也很简单,用来可视化地操做k8s集群。
  • 搭一个docker私有仓库。有 官方镜像,能够参考一下,我是搭好集群后直接用rancher搭了个docker私有仓库。
  • 搭一个gitlab或者用 官网,把项目放进去。我是直接用的官网。
  • 配置gitlab-runner
  • 改一下项目的目录结构,给项目编写 .gitlab-ci.yml、Dockerfile、nginx.conf 3个文件
  • 最最重要的一点,把机器(也就是vps)配置好,否则会出现各类问题。

vps配置

每台vps都要配置。node

#!/bin/sh 
# 1. stop firewalld
systemctl stop firewalld && systemctl disable firewalld

# 2. stop SElinux
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

# 3. set timezone
timedatectl set-timezone Asia/Shanghai

# 4
yum install vim htop -y

# 5. increase swap
dd if=/dev/zero of=/home/swap bs=1024 count=5120000
/sbin/mkswap /home/swap
/sbin/swapon /home/swap

# 6. install docker
curl -fsSL get.docker.com | sh
systemctl start docker && systemctl enable docker

复制代码

增长交换内存是由于我机器配置不够,才1G内存;防火墙和SElinux是必定要关闭的,否则集群确定搭建不成功;docker也要安装一下。linux

基础镜像打包

代码上容器确定要用镜像,说一下须要什么镜像。nginx

后端用php,那么须要一个nginx-php镜像,我在github上找了一个,不过有一点小bug,fork过来稍微改了下,附上连接:nginx-php。 这个镜像基于alpine,而后源码安装了php和nginx,咱们本身扩展和更新比较方便。根据这个Dockerfile打包镜像,而后推送到 dockerhub,最终获得一个 nginx-php镜像。若是不想让你的基础镜像公开,能够不推到dockerhub,等私有仓库搭好后放到私有仓库。至于怎么打包和推送镜像,这个比较简单,就不细说了。git

前端的同理,把Dockerfile里安装php相关的部分删掉,打包并推送镜像,最终获得一个 nginx 镜像。github

搭建k8s集群

server搭建

使用k3s搭建集群其实就是几个命令的事,可是国内服务器不行,由于k8s依赖pause镜像,这个镜像你在国内确定下不下来,因此国内搭集群只能手动。redis

自动搭建

运行官方脚本。

curl -sfL https://get.k3s.io | sh -
复制代码

看到systemd: Starting k3s就能够了。修改配置:

vim /etc/systemd/system/multi-user.target.wants/k3s.service
复制代码

把ExecStar的值改成

/usr/local/bin/k3s server --docker --no-deploy traefik --cluster-secret=hjp
复制代码
  • --docker 用docker作底层容器(默认的是containerd)
  • --no-deploy traefik 不安装traefik组件
  • --cluster-secret=hjp 设置密码,待会添加agent(节点)就不须要去查看token了

而后从新加载配置,重启k3s。

systemctl daemon-reload
systemctl restart k3s
复制代码

运行

k3s kubectl get nodes
复制代码

查看一下节点

有一个master节点,这是安装server的时候自带的,这样其实就已经建立了有一个master节点的k8s集群。

注意这里有个坑。 按照官方文档的说法,其实能够直接运行命令的时候指定配置

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--docker --no-deploy traefik --cluster-secret=hjp" sh -
复制代码

这样就不用再修改配置。可是这样启动k3s后,后面搭建docker私有仓库、docker-registry配置ingress会一直显示initializing,因此仍是安装后手动修改配置吧。

手动搭建

我是国外的服务器,因此直接用脚本搭建的,k3s的 官方文档 最下面写了怎么手动搭建。其实就是去github上把 k3s 下载,而后上传到服务器运行。然而国内服务器要多作一步,即在这以前先把pause镜像手动下载,从新打个tag。dockerhub上有个镜像谷歌仓库,附上连接 pause镜像

docker pull mirrorgooglecontainers/pause:3.1
docker tag mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1
复制代码

把下载的k3s文件复制到/usr/local/bin/k3s

cp ./k3s /usr/local/bin/k3s
chmod 777 /usr/local/bin/k3s
复制代码

启动k3s

k3s server &
复制代码

以后的操做步骤应该跟自动搭建是同样的。

k3s命令目录

k3s命令目录在/usr/local/bin/

要卸载的话,先运行k3s-killall.sh,再运行k3s-uninstall.sh。

搭建rancher-ui

ui搭建

接下来要搭个 rancher 界面来操做集群,其实也是一个命令的事。进入另外一台vps,执行

docker run -d -v /var/lib/rancher/:/var/lib/rancher/ --restart=unless-stopped --name rancher-server -p 80:80 -p 443:443 rancher/rancher:stable
复制代码

注意rancher和k3s不能装在同一台机器上,否则这个容器启动会报错。k3s V0.8.1版本的时候仍是能够的,不知道最近更新了什么,附上 github该问题的连接。把域名(rancher.hjply.com)指向这台vps的ip,而后浏览器访问rancher.hjply.com。因为rancher是自签名证书,会弹出安全警告,直接无视便可。

设置密码后进入。

搭建完成,右下角能够切换语言。

集群导入

把集群导入rancher后,才能可视化地操做集群。

在刚才的页面点击 "添加集群",选择 “导入现有的Kubernetes集群”, 名字随便写个,点建立

进入这个页面

复制最后一条命令,在k3s server那台机器上执行

过一会自动跳转到这个页面

状态会从waiting变成active,表示导入完成。

若是这个状态一直没变化,或者页面没有自动跳转,估计就是防火墙、SElinux没关,或者k3s和rancher两台机器互相ping不通。

导入成功后查看一下集群。

能够看到有一个节点,就是k3s server自带的master节点,若是有须要能够继续添加节点。

集群添加节点

再开一台机器,vps配置同上,而后配置一个host

vi /etc/hosts
复制代码

加一条

127.0.0.1 vultr3
复制代码

运行命令

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--docker --node-name=vultr3" K3S_URL=https://217.69.8.236:6443 K3S_CLUSTER_SECRET=hjp sh -
复制代码
  • --node-name必定要设置,还要把节点名称(随便填写,如:vultr3)指向本机ip,而且node-name不能和已有的节点名称重复。若是不设置node-name就会默认使用机器的hostname,可能会重复致使加入集群失败。
  • K3S_URL就是k3s server就填k3s server这台机器的ip
  • K3S_CLUSTER_SECRET就是建立k3s server时候设置的密码

再查看一下集群。

看到有2个节点,表示成功。

Docker私有仓库搭建

直接用rancher搭建私有仓库比较方便。

先进入集群页面,建立一个项目。点击添加项目,项目名称随便写,系统的这2个项目(Default和System)不要动。

进入这个项目,而后进到应用商店。

点“启动”,选择docker-registry,点“查看详情”进入部署页面。

部署的时候须要注意2点。

  1. 须要一个ssl证书
  2. 须要手动生成账号密码

为何须要启用https?由于咱们要使用账号密码控制私有仓库的访问权限,不能谁均可以往里面push镜像,而启用账号密码就必须用https(官方文档要求,如图)。

直接在阿里云申请个免费证书,下载到电脑

在这里插入图片描述

接下来就是生成账号密码。进入k3s server那台机器(必定要用这台机器,由于不一样机器生成的密码不同),依次执行:

mkdir -p /home/registry/auth

docker run --entrypoint htpasswd registry -Bbn hjp hjp >>/home/registry/auth/htpasswd

cat /home/registry/auth/htpasswd
复制代码

(账号hjp,密码hjp)_

复制一下生成的密码,填入部署页面

配置一下负载均衡,使用自定义域名(registry.hjply.com指向k3s server这台机器)

点击启动,就建立了docker仓库。这里我没有作持久化配置,因此容器删掉后里面的镜像也会被删除。最后还差一步配置ssl和账号密码。

进入证书页面

添加证书,把从阿里云下载的证书导入,点击保存便可。

而后升级一下仓库的ingress,点击“升级”,把SSL证书勾选上,保存。

这样仓库的https就配置好了,咱们测试一下,打开网页 registry.hjply.com/v2/_catalog

输入帐号密码

看到仓库是空的,里面没有镜像,到此docker私有仓库就搭建完了。最后还要把仓库的帐号密码保存在集群,由于待会拉取镜像须要权限认证。

点击镜像库凭证

把账号密码填写一下,保存便可。

gitlab-runner配置

gitlab-runner有3种,即

  • Specific Runners
  • Shared Runners
  • Group Runners

其中Specific Runners是针对项目的,每一个项目能够分别配置本身的runner;

Shared Runners是gitlab上别人共享出来的runner,咱们不用,把它禁用掉;

Group Runners是针对项目组的,只要给项目组配置一个runner,组内的全部项目均可以使用这个runner。

新建一个group,把项目都放进去

进入group_hjp的CI/CD配置页面

能够看到如今尚未安装runner。找一下 文档,里面有写怎么安装gitlab-runner,咱们直接在vps上安装,依次运行

curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash

sudo yum install gitlab-runner
复制代码

便可。安装以后须要注册,运行

gitlab-runner register
复制代码

  • URL填gitlab的地址,若是没有本身搭建的话,就是https://gitlab.com/
  • token去刚才CI/CD的页面复制一下
  • description随便写
  • tags随便写,多个用逗号分隔
  • executor看你的gitlab-runner用来作什么,我是用来执行shell,因此选shell

这样就注册完成了。刷新网页验证一下

进入到项目的CI/CD页面,验证Groups Runners是否可用。

最后,由于待会要用这个runner打包和推送镜像到docker私有仓库,因此还须要配置一下docker。

先把私有仓库地址加入docker配置文件(新版docker没有这个文件,直接vim建立便可)

vim /etc/docker/daemon.json
复制代码

把私有仓库地址写入文件,保存退出。

从新加载docker配置

systemctl reload docker
复制代码

同理,在k3s server上也要把私有仓库地址加到/etc/docker/daemon.json配置文件里,由于拉取镜像须要用。

而后切换到gitlab-runner用户,登陆registry.hjply.com并保存帐号密码

若是报 /var/run/docker.sock 没有权限的错误,须要把gitlab-runner这个用户添加到docker用户组

usermod -G docker gitlab-runner
复制代码

到这里gitlab-runner和docker配置就完成了。

项目改造

之后端代码为例,先把目录层级改一下。

咱们加个src目录,把代码全放进去,而后开始编写 .gitlab-ci.yml、Dockerfile、nginx.conf文件

nginx.conf

server {
    listen 80 default_server;

    client_max_body_size 5m;
    client_body_buffer_size 256k;
    client_header_buffer_size 256k;
    large_client_header_buffers 4 8k;

    set     $rootPath       '/data/src/public';
    root    $rootPath;

    index index.php index.html index.htm;

    server_name localhost;

    if (!-e $request_filename) {
        rewrite ^/(.*)$ /index.php/$1 last;
    }

   location ~ ^(.+\.php)(.*)$ {
        fastcgi_pass            unix:/usr/local/php/var/run/php-fpm.sock;
        fastcgi_index           index.php;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_param           PATH_INFO $fastcgi_path_info;
        fastcgi_param           SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_buffer_size     128k;
        fastcgi_buffers         256 16k;
        client_body_buffer_size 1024k;
        include                 fastcgi_params;
    }

}
复制代码

这就是个很普通的php项目nginx配置,就很少说了。

Dockerfile

FROM hongjiapei/nginx-php

COPY nginx.conf /usr/local/nginx/conf.d/nginx.conf

COPY src /data/src

RUN chown -R www-data.www-data /data/src/ && chmod -R 755 /data/src \
    && rm -rf /usr/local/php/etc/php-fpm.d/www.conf

WORKDIR /data/src

EXPOSE 80

CMD sh -c 'nginx && php-fpm -D && tail -f /usr/local/nginx/logs/error.log'

复制代码

继承了咱们以前打包的nginx-php镜像,而后用本身的nginx.conf覆盖掉默认的配置,最后前台启动nginx和php-fpm、打印nginx错误日志。注意这里不能后台启动nginx和php-fpm,否则等你命令执行完了容器就自动退出了。

.gitlab-ci.yml

stages:
  - build
  - push

build_image:
  stage: build
  script:
    - ls -la
    - CI_COMMIT_TAG=`git log | grep -e "^commit.*" | wc -l` && docker build --pull -t registry.hjply.com/group_hjp/xsbe:"$CI_COMMIT_TAG" .
  only:
    - master
  tags:
    - abc

push_image:
  stage: push
  script:
    - CI_COMMIT_TAG=`git log | grep -e "^commit.*" | wc -l` && docker push registry.hjply.com/group_hjp/xsbe:"$CI_COMMIT_TAG" && docker rmi registry.hjply.com/group_hjp/xsbe:"$CI_COMMIT_TAG"
  only:
    - master
  tags:
    - abc

复制代码

这里分为两步,第一步打包镜像,第二步推送镜像。only:master表示只有master推送的时候才启动流水线,tags:abc表示使用tag包含abc的runner,因此刚才注册gitlab-runner写的tag是什么这里就写什么,git log | grep -e "^commit.*" | wc -l 表示git日志里带有commit关键字的条数,通常提交一次就多一条,咱们用这个数字做为镜像的tag,推送完镜像后把本机的镜像删掉。

到这里配置就所有完成了,接下来提交代码测试一下。

提交和发布代码

提交代码

在master提交代码,进入项目页面查看

能够看到项目正在执行流水线,点进去看下

等两个阶段都成功就表示执行完成,查看一下镜像

刚才提交的代码镜像是registry.hjply.com/group_hjp/xsbe:4

发布代码

初次部署

进入rancher后台,第一次须要部署服务,之后只须要更新。

点击“部署服务”,使用刚才的镜像启动,把80端口暴露出来,部署服务以前要确保两件事

  1. k3s server这台机器 /etc/docker/daemon.json已经配置了insecure-registry
  2. 已经在集群保存了镜像库凭证

若是没配置好,镜像拉取会失败的。

等状态变成active就表示部署完成

而后配置ingress,这样就能够经过域名把请求转发到容器。

进入“负载均衡”,点击“添加ingress规则”

把域名指向容器的80端口,保存。

初次部署基本完成,打开网页验证一下(要提早把这个域名指向k3s server这台机器)。

项目配置

刚才只用了一个pod启动项目,若是性能不够,能够多加几个pod,点击那个“+”号便可。

到这里项目尚未彻底部署完成,还差最后一步,即配置文件。lumen的配置文件为.env文件,通常数据库、redis配置都写在里面,这个文件确定不会放在git里,下面说一下怎么给项目添加配置文件。

点击“配置映射”

键就用配置文件的文件名.env,值就是文件内容,能够填多行,保存,而后升级项目。

给项目添加一个ConfiMap卷,保存。

等项目自动更新pod。

更新完成,随便进入一个pod,查看一下是否有.env文件。

有.env文件,打开看一下是否正确

跟刚才配置的同样,到这里初次部署就完成了。

项目更新

项目更新就比较简单了,新增一个接口xsbe.hjply.com/test,在master提交代码,等流水线执行完,而后去看看镜像的tag是什么

去rancher后台更新一下项目

把tag改成刚才镜像的tag,保存便可。

等pod更新完后,打开网页验证一下

说明代码更新成功。

流水线失败的处理

流水线失败不可怕,根据报错信息去解决便可。之前端项目为例,提交代码后发现流水线失败了

点进去看看报错信息

发现是npm命令找不到,原来是gitlab-runner这台机器忘了装nodejs,安装一下

yum install nodejs -y
复制代码

点击最右边的刷新按钮从新执行流水线

成功后去看看镜像的tag

去rancher后台部署一下

配置ingress

部署完成,打开网页测试一下

到这里就完成了。

最后咱们看一下私有仓库里的镜像

就是咱们刚才推送的2个镜像。

最后

  • 数据库并无打算用k8s来部署,由于数据库是有状态应用,要考虑数据的存储、可用性、扩展性、事务、灾备等等,太复杂了。
  • docker-registry应该把数据存在机器上,否则重启就没了,固然最好仍是不要用k8s来部署。
  • 每次master提交都会生成一个镜像,这样发布和回滚代码都比较方便。
  • 机器不够了能够随时添加,项目挂了会自动重启,重试若干次仍是没有成功才会启动失败。
  • rancher还有不少功能,能够看 官方文档
相关文章
相关标签/搜索