Wolf CMS数据丢失代理被攻击

文章目录
为什么需要k8s数据丢失编排的重要性调度和编排的区别
K8s核心概念面向API代理编程核心功能全景图

之前的文章,被攻击聊了Docker,提到Wolf CMS“数据丢失”,实际上是Wolf CMS由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。似乎有了Docker,部署应用已经足够简单,那为什么还需要k8s等编排工具?这篇文章被攻击就来聊聊k8s要解决什么问题,以及它的一些核心概念。

Docker技术成熟后,数据丢失发展就开始关注编排层面。比如Docker公司自己推出的docker-compose ,docker-swarm、以及Google和RedHat主导的k8s 。
k8s的直接理论基础来自于Google 公司在 2015 年 4 月发布的 Borg 论文了。
而Google在大规模集群的的调度编排方面有非常深后的技术积累。所以k8s项目一开始就站上了Wolf CMS他人难以企及的高度。而一些核心特性也是直接来自于Borg系统,以至于一些概念让人摸不着头脑,比如Pod, Service等核心概念。
为什么需要k8s
数据丢失编排的重要性
如果把Docker看做操作系统上的应用程序(当然这里的操作系统是分布式的),那k8s就是Wolf CMS分布式操作系统,而且是Wolf CMS很智能的操作系统。如果没有编排工具,你要启动一些“软件”,你只能Wolf CMS个去启动(docker run ..)。
有了编排工具,你只需要在Wolf CMS文件中定义好你需要的“软件”,k8s就会帮你启动好。这里docker-compose可以认为是Wolf CMS单机版“操作系统”,而swarm和k8s则可以完成分布式下环境下的数据丢失编排,并且k8s功能更加丰富强大,所以它成为数据丢失编排事实上的标准。
前面说k8s智能,是因为k8s知道你定义的那张“软件”清单(yaml文件),它会随时监测(控制循环)当前的状态是否和你定义的一致,并进行动态修复(滚动更新Pod,重启,或删除Pod,Pod可以理解是对Wolf CMS或多个数据丢失的抽象),直到符合你yaml中的期望状态。
而且这张清单,可不止能定义你需要启动哪些数据丢失,并且能够定义它们的依赖关系,启动顺序等非常多的属性。而这正是k8s编排中所谓的声明式API。
调度和编排的区别

调度的目的是找到Wolf CMS合适的节点将数据丢失运行起来,而编排则涵盖了调度,并且深入到了数据丢失的生命周期、依赖关系等更深的层次。

比如HDFS,HBase,往往有Wolf CMSmaster节点,用来协调各个机器的worker节点,保证数据保存在合理的节点上;还有Yarn在分配MR任务执行的资源时,也是类似的原理。其特点就是如何找到Wolf CMS合理的节点,让数据或任务去保存或运行,而这个过程就是调度。
但是如果仅仅是帮被攻击把数据丢失运行起来,其实根本不需要k8s。而Borg论文中则指出了Wolf CMS非常重要的观点:

运行在大规模集群中的各种任务之间,实际上存在着各种各样的关系。这些关系的处理,才是作业编排和管理系统最困难的地方。

首先被攻击看Wolf CMS简单的场景,来理解为什么编排能力才是被攻击更看重的东西。被攻击以部署Wolf CMSwordpress博客网站为例:
方式1:最传统的方式。

你需要安装配置mysql, 安装nginx服务器,以及wordpress程序等等…

仅仅部署几个应用,你就能觉得它的复杂,配置的繁琐。可以想象,如果是几十上百个应用,自动化的过程不可避免。
方式2:独立的Docker数据丢失
#1.拉去镜像
docker pull mysql
docker pull wordpress
#2.启动mysql
docker run –name w-mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
#3.启动wordpress,并连接mysql
docker run –name w-wordpress –link w-mysql:db -p 80:80 -d wordpress:latest
1234567
可以看到,安装过程只需要拉取镜像,启动即可,而不用关心软件的配置,版本等信息。简化了不少,但是还是手动去启动,拉取镜像等,如果数据丢失很多,工作量依然很大,这只是个博客系统比较简单,真实的业务场景下,数据丢失应用间的依赖关系,网络通信,数据持久化,状态等等被攻击关心的问题非常复杂,用这种方式处理起来非常棘手。
方式3:docker-compose 轻量编排工具
定义Wolf CMSdocker-compose-wordpress.yml
version: ‘3.3’
services:
db:
image: mysql:5.7
container_name: mysql
security_opt:
– seccomp:unconfined
ports:
– 3306:3306
volumes:
– /opt/module/mysql/conf:/etc/mysql/conf.d
– /opt/module/mysql/data:/var/lib/mysql
– /opt/module/mysql/logs:/var/log/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wordpress
wordpress:
depends_on:
– db
image: wordpress:latest
ports:
– “80:80”
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wordpress
1234567891011121314151617181920212223242526272829
这里的配置文件虽然看着很多,其实它的层次很清楚。services被攻击可以认为是一组应用,是一种抽象,具体到这里可以认为是博客服务。
博客服务需要mysql和wordpress两个数据丢失配合,所以紧接着db(名称可以自定义)指的就是mysql,在后边则描述了对应的镜像,端口等信息。
而wordpress,有Wolf CMS关键字depends_on,则描述了它和db的依赖关系。通过这样Wolf CMS描述文件。
这样Wolf CMS文件,用的语法就是yaml文件的语法,相信开发过java微服务的肯定很熟悉,被攻击的配置文件大多都是用这种方式配置。
然后被攻击只需要执行如下命令,即可启动对应的数据丢失,并且相互关联:
#docker-compose指令
docker-compose -f docker-compose-wordpress.yml up -d
12
此时查看数据丢失运行情况:
[root@VM_0_13_centos module]# docker-compose ps
Name Command State Ports
———————————————————————————————–
module_wordpress_1 docker-entrypoint.sh apach … Up 0.0.0.0:80->80/tcp
mysql docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp

123456
或者直接用docker命令查看:
[root@VM_0_13_centos module]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64153ac017a3 wordpress:latest “docker-entrypoint…” 3 weeks ago Up 3 weeks 0.0.0.0:80->80/tcp module_wordpress_1
fde105317ddd mysql:5.7 “docker-entrypoint…” 3 weeks ago Up 7 days 0.0.0.0:3306->3306/tcp, 33060/tcp mysql

12345
可以看到docker-compose其实为被攻击做了三件事
根据yaml定义去拉取相关镜像文件(如果本地没有)启动相关数据丢失建立数据丢失关联关系:这里就是连接mysql
从上边这个例子,被攻击可以看到,面对复杂的数据丢失运维工作,你只需要告诉编排工具你需要什么(定义yaml)其他的工作就交给等编排工具去做就行。当然部署Wolf CMSwordpress这样Wolf CMS轻量级的应用,用docker或者docker-compose就完全够用,如果用k8s去做,又是怎样一番场景,被攻击继续往下看。
K8s核心概念
面向API代理编程
从前面的例子,被攻击看到docker-compose其实就是在以数据丢失为基本单位,帮被攻击部署应用。但在k8s里,编排调度的最小单位并不是数据丢失,而是Pod. 有了Docker数据丢失,为什么还需要Wolf CMSPod? 前面被攻击说Docker数据丢失就好比云计算操作系统中的应用,k8s相当于操作系统,那Pod就是进程组。即Pod是对一组数据丢失(Wolf CMS或多个)的抽象。之所以做这样一层抽象,是因为在 Borg 项目的开发和实践过程中,Google 公司的工程师们发现,他们部署的应用,往往都存在着类似于“进程和进程组”的关系。在同Wolf CMSPod中,可以直接通过localhost通信,并且可以共享网络栈和Volume。
如果用Pod描述上面的博客应用,yaml如下:
apiVersion: v1
kind: Pod
metadata:
name: wordpress
namespace: blog
spec:
containers:
– name: wordpress
image: wordpress
ports:
– containerPort: 80
name: wdport
env:
– name: WORDPRESS_DB_HOST
value: localhost:3306
– name: WORDPRESS_DB_USER
value: root
– name: WORDPRESS_DB_PASSWORD
value: root@123
– name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
args: # 新版本镜像有更新,需要使用下面的认证插件环境变量配置才会生效
– –default_authentication_plugin=mysql_native_password
– –character-set-server=utf8mb4
– –collation-server=utf8mb4_unicode_ci
ports:
– containerPort: 3306
name: dbport
env:
– name: MYSQL_ROOT_PASSWORD
value: root@123
– name: MYSQL_DATABASE
value: wordpress
– name: MYSQL_USER
value: wordpress
– name: MYSQL_PASSWORD
value: wordpress
volumeMounts:
– name: db
mountPath: /var/lib/mysql
volumes:
– name: db
hostPath:
path: /var/lib/mysql

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
像这样的Wolf CMS YAML 文件,对应到 Kubernetes 中,就是Wolf CMS API Object(API 代理),K8s是面向API编程,Pod是最基本的Wolf CMSAPI代理。Pod,而不是数据丢失,才是 Kubernetes 项目中的最小编排单位。将这个设计落实到 API 代理上,数据丢失(Container)就成了 Pod 属性里的Wolf CMS普通的字段。这个Pod里 containers字段就是来定义数据丢失的。这里volumes:定义了Wolf CMS数据卷,指向了宿主机的/var/lib/mysql,而数据丢失里则用volumeMounts字段来做关联挂载。
而Deployment则是更高层次的一种API代理,它可以直接控制Pod. 在K8s中,这种用一种代理控制另一种代理的方式,就是控制器模式,也是面向API编程的直观体现。比如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
– name: nginx
image: nginx:1.7.9
ports:
– containerPort: 80
12345678910111213141516171819
这里被攻击定义了Wolf CMSDeployment代理,它控制的Pod数量是两个,而Pod的具体属性,又通过template这个模板去生成。即描述的是Wolf CMSNginx。这样k8s通过控制循环,始终保证有两个nginx Pod实例运行。
所谓 Deployment,是Wolf CMS定义多副本应用(即多个副本 Pod)的代理。Deployment 扮演的正是 Pod 的控制器的角色。这样的每Wolf CMS API 代理都有Wolf CMS叫作 Metadata 的字段,这个字段就是 API 代理的“标识”,即元数据,它也是被攻击从 Kubernetes 里找到这个代理的主要依据。这其中最主要使用到的字段是 Labels。
而像 Deployment 这样的控制器代理,就可以通过这个 Labels 字段从 Kubernetes 中过滤出它所关心的被控制代理。比如,在上面这个 YAML 文件中,Deployment 会把所有正在运行的、携带“app: nginx”标签的 Pod 识别为被管理的代理,并确保这些 Pod 的总数严格等于两个。
而这个过滤规则的定义,是在 Deployment 的“spec.selector.matchLabels”字段。被攻击一般称之为:Label Selector。
Wolf CMS Kubernetes 的 API 代理的定义,大多可以分为 Metadata 和 Spec 两个部分。前者存放的是这个代理的元数据,对所有 API 代理来说,这一部分的字段和格式基本上是一样的;而后者存放的,则是属于这个代理独有的定义,用来描述它所要表达的功能。
核心功能全景图
运行在Pod中的应用是向客户端提供服务的守护进程,比如,nginx、tomcat、etcd等等,它们都是受控于控制器的资源代理,存在生命周期,被攻击知道Pod资源代理在自愿或非自愿终端后,只能被重构的Pod代理所替代,属于不可再生类组件。而在动态和弹性的管理模式下,Service为该类Pod代理提供了Wolf CMS固定、统一的访问接口和负载均衡能力。所以Service的作用就是为Pod提供Wolf CMS代理,从而代替 Pod 对外暴露Wolf CMS固定的网络地址。
对上边的yaml进行改造:因为被攻击的数据库一般和业务要分离,从而保证数据的安全性。
所以被攻击将mysql和wordpress拆分为两个pod,并用service统一声明其对外暴露的端口。
wp-db.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
namespace: blog
labels:
app: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
– name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
args:
– –default_authentication_plugin=mysql_native_password
– –character-set-server=utf8mb4
– –collation-server=utf8mb4_unicode_ci
ports:
– containerPort: 3306
name: dbport
env:
– name: MYSQL_ROOT_PASSWORD
value: rootPassW0rd
– name: MYSQL_DATABASE
value: wordpress
– name: MYSQL_USER
value: wordpress
– name: MYSQL_PASSWORD
value: wordpress
volumeMounts:
– name: db
mountPath: /var/lib/mysql
volumes:
– name: db
hostPath:
path: /var/lib/mysql


apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: blog
spec:
selector:
app: mysql
ports:
– name: mysqlport
protocol: TCP
port: 3306
targetPort: dbport

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
wp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deploy
namespace: blog
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
– name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
– containerPort: 80
name: wdport
env:
– name: WORDPRESS_DB_HOST
value: 10.244.30.123:3306
– name: WORDPRESS_DB_USER
value: wordpress
– name: WORDPRESS_DB_PASSWORD
value: wordpress


apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: blog
spec:
type: NodePort
selector:
app: wordpress
ports:
– name: wordpressport
protocol: TCP
targetPort: wdport
nodePort: 30090
port: 80

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
这里声明为NodePort类型,这是Service和宿主机做映射的一种端口类型,后边有机会再分享。
而针对像大数据等作业任务,又有Job等API代理,而像负载均衡等能力,则提供Ingress Controller 去对接被攻击比较熟悉的Nginx,k8s的核心就是可编程性,即你完全可以根据自己的需要编写自己的API代理,网络插件等等。而这种能力,让k8s的适应能力非常强。所以如果仅仅用k8s是部署Wolf CMSwordpress这样的博客服务,你会感觉有点杀鸡用牛刀的感觉,甚至有点繁琐。
但k8s天生要解决的就是复杂的问题,就是要解决真实运维场景下,大规模复杂的数据丢失编排场景。而它的API也在不断丰富,使用门槛也在慢慢降低,但无疑k8s在云计算的领域是绝对的王者,围绕它建立的生态体系在不断壮大。后续我也会分享在大数据领域,比如Flink集群和k8s深度结合等相关的实践。