Kubernetes入门实践(搭建Wordpress网站)
容器只是对单个进程的隔离和封装,实际的应用场景要求许多的应用进程互相协同工作,因此出现了容器编排,Kubernetes将集群中的计算资源定义为节点(Node),其中又划分成控制面和数据面两类,控制面是Master节点,负责管理集群和运维监控,里面的核心组件是apiserver、etcd、scheduler、controller-manager,数据面是Worker节点,受Master节点的管控,其中的核心组件是kubelet、kube-proxy、container-runtime
Kubernetes还支持了插件,能够灵活扩展各项功能,常用的插件有DNS和Dashboard,同时为了更好地管理集群和业务应用,抽象除了API对象,使用YAML语言描述这些对象,最核心的对象是Pod,捆绑了一组存在密切协作关系的容器,容器之间共享网络和存储,在集群里必须一起调度一起运行。通过Pod概念,Kubernetes简化了对容器的管理工作,其他的所有任务都是通过对Pod这个最小单位的再包装实现的
除了核心的Pod对象,基于单一职责和对象组合这两个基本原则,另外还有4个简单的API对象: Job/CronJob和ConfigMap/Secret,Job/CronJob对应的是离线作业,逐层包装了Pod,添加了作业控制和定时规则,ConfigMap/Secret对应的是配置信息,要以环境变量或者存储卷的形式注入进Pod,然后进程才能在运行时使用
Kubernetes提供了一个客户端工具,名叫kubectl,直接与Master节点的apiserver通信,将YAML文件发送给RESTful接口,从而触发Kubernetes的对象管理工作流程,其命令有很多,可以用api-resources
和explain
命令查看,查看API对象状态可以用get
、describe
、logs
,操作对象可以用run
、apply
、exec
、delete
YAML具有固定的格式,开头必须写的字段是apiVersion
、kind
和metadata
,表示对象的版本、种类和名字等元信息,实体对象如Pod、Job和CronJob会再有spec字段描述对象的期望状态,最基本的就是容器信息,非实体对象如ConfigMap、Secret使用的是data字段,记录了一些静态的字符串信息
网站基本构建
与Docker搭建Wordpress网站不同的是,Kubernetes多了对应用的封装以及网络环境,Wordpress和MariaDB这两个应用被封装了Pod (由于都是在线业务,所以不使用Job/CronJob),运行所需的环境变量被改写为ConfigMap,统一用声明式来管理,与此同时,Kubernetes集群在内部维护了一个自己的专用网络,这个网络和外界隔离,要用特殊的端口转发方式来传递数据,还要在集群之外用Nginx反向代理该地址,才能实现与外部沟通
编排MariaDB
首先编排MariaDB对象,要求一些环境变量: 数据库名称、用户名和密码,使用YAML定义:
apiVersion: v1
data:
DATABASE: 'db'
USER: 'wp'
PASSWORD: '123'
ROOT_PASSWORD: '123'
kind: ConfigMap
metadata:
creationTimestamp: null
name: maria-cm
这里定义了数据库名称为db,用户名为wp,密码为123,ROOT用户密码为123,编辑Pod对象的YAML文件,将配置信息注入到Pod,让MariaDB运行时从环境变量读取这些信息:
apiVersion: v1
kind: Pod
metadata:
labels:
app: wordpress
role: database
name: maria-pod
spec:
containers:
- image: mariadb:10
name: maria
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
envFrom:
- prefix: 'MARIADB_'
configMapRef:
name: maria-cm
envFrom这个字段可以一次性将ConfigMap里的字段全部导入进Pod,并且能够制定变量名的前缀
使用apply运行这个容器:
$ minikube kubectl -- apply -f maria-cm.yml
pod/maria-cm created
$ minikube kubectl -- apply -f maria-pod.yml
pod/maria-pod created
查看运行状态,加-o wide查看IP地址:
$ minikube kubectl -- get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
maria-pod 1/1 Running 0 3m55s 172.17.0.2 minikube <none> <none>
数据库现在正常运行了,IP地址是172.17.0.2
编排Wordpress
先用ConfigMap定义其环境变量:
apiVersion: v1
data:
HOST: '172.17.0.2'
USER: 'wp'
PASSWORD: '123'
NAME: 'db'
kind: ConfigMap
metadata:
name: wp-cm
在这个ConfigMap里要注意的是HOST字段,必须是MariaDB Pod的IP地址
之后编写Pod对象文件,为了简化环境变量同样使用了envFrom:
apiVersion: v1
kind: Pod
metadata:
labels:
app: wordpress
role: website
name: wp-pod
spec:
containers:
- image: wordpress:5
name: wp-pod
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
envFrom:
- prefix: 'WORDPRESS_DB_'
configMapRef:
name: wp-cm
接着使用kubectl apply创建对象:
$ minikube kubectl -- apply -f wp-cm.yml
configmap/wp-cm created
$ minikube kubectl -- apply -f wp-pod.yml
pod/wp-pod created
随后查看状态:
$ minikube kubectl -- get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
maria-pod 1/1 Running 0 5m50s 172.17.0.2 minikube <none> <none>
wp-pod 1/1 Running 0 55s 172.17.0.3 minikube <none> <none>
因为Pod都是运行在Kubernetes内部的私有网段里的,为了Wordpress映射端口号,让集群可见外可见,要使用kubectl port-forward
命令,专门负责把本机的端口映射到目标对象的端口号,类似Docker的参数-p,经常用于Kubernetes的临时调试和测试
将本地的8080映射到Wordpress Pod的80,kubectl会把这个端口的所有数据都转发给集群内部的Pod:
$ minikube kubectl -- port-forward wp-pod 8080:80 &
[1] 21501
$ Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
末尾使用&是将进程挂到后台运行,使用命令fg可以将任务带回前台
创建Nginx
在Kubernetes之外启动Nginx反向代理
这里使用Docker即可,编辑Nginx配置文件:
server {
listen 80;
default_type text/html;
location / {
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080
}
}
使用docekr启动:
$ sudo docker run -d --rm --net=host -v /tmp/proxy.conf:/etc/nginx/conf.d/default.conf nginx:alpine
2b7332de74939d668067ba0b8181d12cacaaa664458de541ba34686abcefd495
查看进程列表:
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b7332de7493 nginx:alpine "/docker-entrypoint.…" 33 seconds ago Up 32 seconds eloquent_panini
Nginx已经启动
使用浏览器访问 http://127.0.0.1:8080,即可看到wordpress页面