在很多开发环境,只有NFS存储支持,NFS容易搭建获得。
NFS本身不支持 Storage Classes 的动态申请存储空间
需要一个 nfs-client-provisioner 从而让NFS也具有 Storage Classes 动态分配申请存储空间的能力

安装NFS Server 服务器端

略过,自己搭建,我使用的是群晖提供的NFS服务
10.8.8.2:/volume1/k8s

Rancher(K8S) node节点

所有node安装mount nfs客户端支持
yum install -y nfs-utils

mount -t nfs 10.8.8.2:/volume1/k8s /mnt/
确保node节点可以挂载nfs

启用额外的Rancher Catalogs

Global 》 Catalog 》
Helm Stable(Enable)
Helm Incubator (Enable)
注意启用后需要等10多分钟才能看到Catalogs里面的内容

启用nfs-client-provisioner 从而支持NFS Storage Classes

Global 》 Catalog 》 Launch
搜索 nfs-client-provisioner 》 View Details
add Answer
nfs.server:10.8.8.2
nfs.path:/volume1/k8s

设置

Global 》 Cluster 》 Storage 》Storage Classes 》
nfs-client 》 Set as default

好了现在可以愉快的部署Catalogs 或者 helm 的应用了, 需要持久化的应用能自动的在NFS共享中开辟新的文件夹存储空间了

如何看待,不要更新了学不动了?

(天啦,有人又要来叨逼叨逼了)

计算机简单也复杂,简单在计算机世界由0和1组成。复杂在从硬件到软件,再到不同领域(网络、操作系统、数据库、桌面软件、BS软件、CS软件、APP软件、人工智能、大数据、五花八门的编程语言),最后到IT领域的不同职业。
我们从更新快到岗位焦虑再到可行的解决路线。

1.更新太快

计算机不管是硬件还是软件更新速度太快,太快了。我们现在用到的技术很多都是非常新的,这个和传统行业比起来天差地别。
技术上过时的软硬件技术很多(暴露年纪的时候到了),例如
CRT显示器、软盘、塞班、Delphi、ASP、PowerBuilder

如果从现代的岗位划分来看的话
前端:前端越来越复杂,工程化成了必然,SPA大行其道,JS通过nodejs也具备了后端能力。
后端:CS架构的软件、桌面软件成了“濒危物种”需求量很小了,BS大行其道,现代后端更偏向架构、算法、业务需求拆分。新兴的编程语言golang在Cloud Native时代成为云端编程语言标准。
运维,除了基础的资产管理、部署、调度、监控,有了现代的业务程序容器(Docker为主)化从而解决环境依赖问题,K8S成为容器编排的实施标准,从而解决容器调度编排问题。
APP:Android和IOS原生开发中的问题产生了, Hybrid App、JsBridge技术,现代更有了微信小程序、快应用的基础框架下层,上层暴露给前端的新兴技术。
测试:在基础的人肉测试上,新兴的编程语言如Golang在语言级别的单元测试上是语言级别支持,在语言级别的单侧保证从而能更好的保证业务层面的测试。
最些年还发展了在CI、CD流程上的集成测试,还有电商的全业务链路的压测(如:从登录到下单)。

2. 岗位的焦虑

现代岗位划分的较为细致,因为没有人什么都能精通,岗位发展也是行业必然的结果。
可悲剧的是就算岗位拆分了还是会让人学不动了。
前端:比如我tm才把VUE学会,又来了微信小程序、快应用规范又是自成一套,React还在暗中观察中。ECMAScript下一波更新就快抵达。
后端:只会“拍簧片”这是我人生道路的瓶颈啊,就是只会某单一的编程语言。停留在语言层面。
运维:程序问题我解决不了啊,我不是背锅侠啊。只会安装、配置不会开发貌似工资上不去啊。
APP:刚和前端打组合Hybrid App、JsBridge技术,前端这到好,小程序、快应用会又出来抢我饭碗了。
测试:日复一日的黑盒功能测试,有点无味呀。

焦虑来自未知的恐惧,觉得自己跟不上趟,又不知道怎么跟上趟。
自己在岗位领域深入底层原理还是全面技术发展,不知道怎么搞。

3. 兄弟扶你起来,带你整

有基本盘才不会慌,才不会怕,那用什么立本呢?
我们继续从岗位上去看

前端:什么MVVM、SPA、VUE、React他们的本质是什么?本质是HTML、CSS、JavaScript(ECMAScript)。所以打牢基础就不慌。
更多的时候跟下ECMAScript新版本,而且有babel加持完全不慌。
后端:后端不要局限在单一一门编程语言,这个会把自己限制的死死的,对于PHPER为出发点的开发者,
编程语言PHP+数据存储方面MySQL、Redis为基本盘。 静态现代语言Golang+动态语言[Python、NodeJS]辅助稳固基本盘。
同时MySQL基础的CURD的使用是不够的,起码要会一些基础的OLAP,复杂SQL查询。
运维:业务稳定、快速恢复是基本盘。万变不离怎么资产管理、怎么部署、怎么监控、怎么快速恢复、怎么解放我傻逼的敲命令,做个WEB让开发自己玩去,这就是所谓的运维自动化。
APP:能提供APP原生整体解决方案,全套一条龙就是基本盘。再来和WEB前端的打组合。
测试:什么自动化测试,老夫没有PRD都能测,别整那么没用的,手动斜眼。 手动黑盒测试作为基本盘。

4.建议的职业路线

有了基本盘,再想想怎么💪自己。
说实话,从事互联网行业的人们,没有点兴趣这个行业是做不下去的,有些人只看到工资高,没看到这个行业头发会变少,所以我相信你是喜欢这个行业的。

在技术上的发展
前端: SPA,推荐必学Vue,微信小程序(有美团的mpvue方案)
后端: 语言,只会动态语言的必须要补一个静态语言例如Golang极力推荐,现代的Cloud Native系统几乎都是Golang写的;数据库,尝试更复杂的SQL,可以在数据统计分析方面进步不少,SQL几乎就是数据分析的事实标准。搜索方面Elastcsearch
运维: 语言,Python;数据库,MySQL;容器,Docker;容器编排:Kubernetes(可用Ranher落地)
APP: 语言,Kotlin做一个基础入门,合适的时候可以考虑运用,Swift做一个基础入门,合适的时候可以考虑运用。 JsBridge技术和WEB前端组队。 还有精力就试试后端。
测试: API测试、压力测试,单元测试。还是测试领域更大神了。辅助编程语言Python

在业务管理方面看
不是计算机科学家,就的老老实实用人家的技术去做业务需求,用人单位看中的是你的整体解决能力,就是要给用人单位提供一条龙的输出。
现代社会是分工和合作的,分工是因为大到一个人没法在要的时间完成,合作是因为分工后需要整体协调

在每个岗位的时候一定要有个整体意识,把这个项目推成功了,脑子里不要只想着自己手上这一点事,一起和同事把这个事做成了。
自己要在多人协作中培养自己的团队协作意识,吐槽完了要给解决思路建议,要做发动机,不要做拖后退的人,你当老板自己都嫌弃自己的。

从技术和业务管理协作方面来看,技术是基本盘,综合协同能力是扩展盘,当你都达成了,恭喜你,叫你一声“领导好”。

希望各位同事朋友能在岗位上更上一层楼。

常用参数表

–where ‘id<3000’ 设置操作条件
–limit 10000 每次取1000行数据给pt-archive处理
–txn-size 1000 设置1000行为一个事务提交一次
–progress 5000 每处理5000行输出一次处理信息
–statistics 结束的时候给出统计信息:开始的时间点,结束的时间点,查询的行数,归档的行数,删除的行数,以及各个阶段消耗的总的时间和比例,便于以此进行优化。只要不加上–quiet,默认情况下pt-archive都会输出执行过程的
–charset=UTF8 指定字符集为UTF8
–no-delete 表示不删除原来的数据,注意:如果不指定此参数,所有处理完成后,都会清理原表中的数据
–bulk-delete 批量删除source上的旧数据
–bulk-insert 批量插入数据到dest主机 (看dest的general log发现它是通过在dest主机上LOAD DATA LOCAL INFILE插入数据的)
–purge 删除source数据库的相关匹配记录
–local 不把optimize或analyze操作写入到binlog里面(防止造成主从延迟巨大)
–analyze=ds 操作结束后,优化表空间(d表示dest,s表示source)
默认情况下,pt-archiver操作结束后,不会对source、dest表执行analyze或optimize操作,因为这种操作费时间,并且需要你提前预估有足够的磁盘空间用于拷贝表。一般建议也是pt-archiver操作结束后,在业务低谷手动执行analyze table用以回收表空间

只删除历史数据

pt-archiver \
--source h=127.0.0.1,P=3306,u=wwek,p='你的密码',D=你的库,t=你的表 \
--charset=UTF8 --where '1=1' --progress 10000 --limit=1000 --txn-size 1000 --bulk-delete --statistics --purge

参考

优雅地使用pt-archiver进行数据归档
pt-archiver手册

介绍

使用Kali Linux需要做一些初始化配置才能用的更顺手

修改apt-get的源为阿里云

vim /etc/apt/sources.list

#deb http://http.kali.org/kali kali-rolling main non-free contrib
deb https://mirrors.aliyun.com/kali kali-rolling main non-free contrib

修改时区

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' >/etc/timezone

输入法fcitx拼音,Sogou输入法

apt-get update && apt-get upgrade
apt-get install fcitx
apt install fcitx-libs fcitx-libs-qt
# 去 https://pinyin.sogou.com/linux/?r=pinyin 下载64位的deb包
dpkg -i sogoupinyin_2.2.0.0108_amd64.deb
# apt-get install fcitx fcitx-googlepinyin fcitx-pinyin fcitx-module-cloudpinyin

虚拟专用网络客户端

apt-get install network-manager-pptp
apt-get install network-manager-strongswan
apt-get install network-manager-vpnc
/etc/init.d/network-manager restart

Kali Linux 安装 zerotier的方法

当kali linux安装zerotier的时候使用

curl -s https://install.zerotier.com/ | sudo bash

并不能安装成功,系统会提示未匹配的系统
其实我们知道kali linux是基于debian定制的,那么把kali的标识加入安装脚本后让其识别为debian系统
这样就可以正常安装了
先下载脚本

curl -s https://install.zerotier.com/ > zerotier.sh
vim zerotier.sh

然后在增加

# 约175行左右
elif [ "$dvers" = "10" -o "$dvers" = "11" -o "$dvers" = "sid" -o "$dvers" = "buster" ]; then
# 改为
elif [ "$dvers" = "10" -o "$dvers" = "11" -o "$dvers" = "sid" -o "$dvers" = "buster"  -o "$dvers" = "kali-rolling" ]; then
# 保持后执行
sudo bash zerotier.sh

即可正常安装

Kali Linux 安装VNC+noVNC并设置开机自动启动

vnc server选择使用
noVNC让vnc可以通过web访问

vnc server

sudo apt-get install vnc4server
# 先要运行一遍vncserver 会提示你设置一个密码 (第二轮的密码是vnc的仅查看密码可以输入N不设置)
vncserver
# 设置密码巴拉巴拉
# 关闭vnc
# vncserver -kill :1

修改vnc的配置(kali linux桌面用的xfce)

vim ~/.vnc/xstartup

#!/bin/bash

export XKL_XMODMAP_DISABLE=1
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS

if [ -e "$HOME/.Xresources" ]
then
    xrdb "$HOME/.Xresources"
fi

startxfce4 &

noVNC

noVNC安装

git clone https://github.com/novnc/noVNC.git /usr/local/noVNC
cd /usr/local/noVNC
nohup ./utils/launch.sh --vnc localhost:5901 &

设置VNC和noVNC开机自动启动

由于debian的新版本已经没有 /etc/rc.local 导致我们不能非常简单方便的增加开机自动运行
还好有系统有预留开启”/etc/rc.local”的方法

vim /etc/rc.local
# 加入vncserver 和 noVNC的启动项目
vim /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

#vnc
#/usr/bin/vncserver -depth 24 -geometry 1280x800 :1
/sbin/runuser -l root -c "vncserver :1"
nohup /usr/local/noVNC/utils/launch.sh --vnc localhost:5901 &

exit 0

# 启用 "/etc/rc.local"的支持
systemctl enable rc-local
systemctl start rc-local
systemctl status rc-local

(过期)安装vncserver远程桌面

sudo apt-get install vnc4server

vncserver

#修改配置文件
# vi ~/.vnc/xstartup

#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &

killall Xtightvnc
vncserver

kali linux安装docker

# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/debian/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
vim /etc/apt/sources.list.d/docker.list
deb https://mirrors.aliyun.com/docker-ce/linux/debian wheezy stable
# Step 4: 更新并安装 Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce

Istio能用于生产了么

截止2018年5月6日目前Istio版本号还未达到V1.0,官方也未宣布生产就绪,所以不能用于生产
目前Istio除了不还不完全成熟以外,还有性能问题

当前Feature Status(Road map)

Istio成熟状态 可以在这里查看目前Istio各个组件模块的完善程度

前言

组织的容器支持docker-compose部署
组织的容器支持kubernets部署
以php框架thinkphp为示例,演示php项目的kubernets部署
多容器方式(3容器)分别为:appphp(php代码)、openresty(nginx webserver),php-fpm(php的运行环境)
dockerfile 和 yaml文件
docker iamges仓库

PHP项目在Docker中如何部署运行?

PHP应用的运行方式

PHP应用的运行方式一般有
Apache mod_php 模式、Nginx(FastCgi)+PHP-FPM模式、Swoole常驻内存Daemon模式

Docker单容器

Apache mod_php 模式和Swoole常驻内存Daemon模式本身就是单程序,那么在Docker中入口运行程序直接为应用程序即可

Nginx(FastCgi)+PHP-FPM模式需要nginx和php-fpm 2个程序
这样Docker中就需要运行多个程序,需要有进程守护类软件来运行多个程序,那么可以参考如何在一个Docker中运行多个程序进程
推荐使用s6-overlay

Docker Hub中PHP官方镜像包已经包括Apache mod_php 模式的镜像包,Kubernets官方PHP项目实例GuestBook中就是采用这种模式的镜像包

Docker多容器配合

Docker官方倡导容器单一职责,也就是一个容器只运行一个程序
那么Nginx(FastCgi)+PHP-FPM模式就需要2个容器配合编排工作,再加上如果把PHP代码再独立成一个Docker镜像,那么就是3容器配合编排工作
所以下面就是以PHP项目采用多个Docker镜像的方式再Kubernets平台部署的范例

kubernets(k8s)部署运行

思路说明
容器共有3个,① appphp(wwek/k8s-php-thinkphp-hello:app-v1)php代码容器、② php-fpm(wwek/k8s-php-thinkphp-hello:php-fpm-7.2) 、③ openresty(wwek/k8s-php-thinkphp-hello:openresty)
apphp、php-fpm、openresty三个容器都在一个Pod(8s-php-thinkphp-hello)中
appphp容器作为initContainers初始化容器使用
挂载了一个叫做wwwroot的volume,类型为emptyDir,临时卷
initContainers初始化容器的时候会把php代码复制到wwwroot(volume)中
php-fpm和openresty都挂载wwwroot(volume)
openresty的upstream php 使用域名php-fpm
使用hostAliases把域名php-fpm解析为127.0.0.1(在同一个Pod中网络是共享的,所以用127.0.0.1)

具体的yaml文件

# Service
apiVersion: v1
kind: Service
metadata:
  name: k8s-php-thinkphp-hello
  labels:
    app: k8s-php-thinkphp-hello
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: k8s-php-thinkphp-hello
---
# deployment
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: k8s-php-thinkphp-hello
  labels:
    app: k8s-php-thinkphp-hello
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8s-php-thinkphp-hello
  template:
    metadata:
      labels:
        app: k8s-php-thinkphp-hello
    spec:
    #做一个emptyDir类型,名为wwwroot的volume 用于多个容器共享同一个挂载
      volumes:
      - name: wwwroot
        emptyDir: {}
      # 私有docker 镜像仓库
      # imagePullSecrets:
      # - name: registrykey-qlcoud-1
      # 自定义设置POD的hosts
      hostAliases:
      - ip: "127.0.0.1"
        hostnames:
        - "php-fpm"
      initContainers:
       #php程序本身
        - name: appphp
          image: "wwek/k8s-php-thinkphp-hello:app-v1"
          imagePullPolicy: Always
          # 复制php程序文件到wwwroot volume
          command: ["sh", "-c", "cp -r /var/www/k8s-php-thinkphp-hello /appdata"]
          volumeMounts:
          - mountPath: /appdata
            name: wwwroot
      containers:
       #php-fpm php运行环境
        - name: php-fpm
          image: "wwek/k8s-php-thinkphp-hello:php-fpm-7.2"
          imagePullPolicy: Always
          volumeMounts:
          - mountPath: /var/www
            name: wwwroot
      #openrsty webserver
        - name: openresty
          image: "wwek/k8s-php-thinkphp-hello:openresty"
          imagePullPolicy: Always
          volumeMounts:
          - mountPath: /var/www
            name: wwwroot
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          # livenessProbe:
          #   httpGet:
          #     path: /
          #     port: http
          # readinessProbe:
          #   httpGet:
          #     path: /
          #     port: http
          resources:
            {}
---
# Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: k8s-php-thinkphp-hello
  labels:
    app: k8s-php-thinkphp-hello
spec:
  rules:
    - host: k8sphpthinkphp.com
      http:
        paths:
          - path: /
            backend:
              serviceName: k8s-php-thinkphp-hello
              servicePort: http
kubectl apply -f k8s-php-thinkphp-hello.yml
kubectl get pods |grep k8s-php-thinkphp-hello
kubectl get service |grep k8s-php-thinkphp-hello
kubectl get ingress |grep k8s-php-thinkphp-hello

把 k8sphpthinkphp.com hosts解析到Ingress 的ip
然后浏览器

访问 http://k8sphpthinkphp.com/ 可以看到thinkphp的欢迎页面

访问 http://k8sphpthinkphp.com/phpinfo.php 可以看到phpinfo信息

如果没有ingress请自行修改service的type为 NodePort 使用节点的ip和端口访问

docker-compose部署运行

一套打包好的业务PHP Docker业务镜像也可以用docker-compose部署,这样方便了本地的开发调试使用

version: '2'

services:

### Applications Code Container #############################

    appphp:
      image: wwek/k8s-php-thinkphp-hello:app-v1
      build:
        context: ./appphp
        dockerfile: "Dockerfile"

### PHP-FPM Container #######################################

    php-fpm:
      image: wwek/k8s-php-thinkphp-hello:php-fpm-7.2
      build:
        context: ./php-fpm
        dockerfile: "Dockerfile"
      volumes_from:
        - appphp
      environment:
        - RUN_MODE=prd
        - MYSQL_HOSTNAME= \
        - MYSQL_USERNAME= \
        - MYSQL_PASSWORD= 
      depends_on:
        - appphp
      expose:
        - "9000"
      networks:
        - backend

### OPENRESTY Server Container ##################################

    openresty:
      image: wwek/k8s-php-thinkphp-hello:openresty
      build:
        context: ./openresty
        dockerfile: "Dockerfile"
      volumes_from:
        - appphp
      ports:
        - "80:80"
        - "443:443"
      depends_on:
        - php-fpm
      networks:
        - frontend
        - backend

### Networks Setup ############################################

networks:
  frontend:
    driver: "bridge"
  backend:
    driver: "bridge"

### Volumes Setup #############################################

volumes:
  redis:
    driver: "local"

直接up方式,直接pull已经build好的docker images

docker-compose up -d

本地build方式

docker-compose up -d --build

浏览器 访问 http://127.0.0.1 访问 http://127.0.0.1/phpinfo.php

代码

所有配置范例代码已经托管到github
k8s-php-thinkphp-hello