learn-tech/专栏/Kubernetes入门实战课/15实战演练:玩转Kubernetes(1).md
2024-10-16 06:37:41 +08:00

14 KiB
Raw Blame History

                        因收到Google相关通知网站将会择期关闭。相关通知内容
                        
                        
                        15 实战演练玩转Kubernetes1
                        你好我是Chrono。

经过两个星期的学习,到今天我们的“初级篇”也快要结束了。

和之前的“入门篇”一样在这次课里我也会对前面学过的知识做一个比较全面的回顾毕竟Kubernetes领域里有很多新名词、新术语、新架构知识点多且杂这样的总结复习就更有必要。

接下来我还是先简要列举一下“初级篇”里讲到的Kubernetes要点然后再综合运用这些知识演示一个实战项目——还是搭建WordPress网站不过这次不是在Docker里而是在Kubernetes集群里。

Kubernetes技术要点回顾

容器技术开启了云原生的大潮,但成熟的容器技术,到生产环境的应用部署的时候,却显得“步履维艰”。因为容器只是针对单个进程的隔离和封装,而实际的应用场景却是要求许多的应用进程互相协同工作,其中的各种关系和需求非常复杂,在容器这个技术层次很难掌控。

为了解决这个问题容器编排Container Orchestration就出现了它可以说是以前的运维工作在云原生世界的落地实践本质上还是在集群里调度管理应用程序只不过管理的主体由人变成了计算机管理的目标由原生进程变成了容器和镜像。

而现在容器编排领域的王者就是——Kubernetes。

Kubernetes源自Borg系统它凝聚了Google的内部经验和CNCF的社区智慧所以战胜了竞争对手Apache Mesos和Docker Swarm成为了容器编排领域的事实标准也成为了云原生时代的基础操作系统学习云原生就必须要掌握Kubernetes。

[10讲]Kubernetes的Master/Node架构是它具有自动化运维能力的关键也对我们的学习至关重要这里我再用另一张参考架构图来简略说明一下它的运行机制图片来源

Kubernetes把集群里的计算资源定义为节点Node其中又划分成控制面和数据面两类。

控制面是Master节点负责管理集群和运维监控应用里面的核心组件是apiserver、etcd、scheduler、controller-manager。 数据面是Worker节点受Master节点的管控里面的核心组件是kubelet、kube-proxy、container-runtime。

此外Kubernetes还支持插件机制能够灵活扩展各项功能常用的插件有DNS和Dashboard。

为了更好地管理集群和业务应用Kubernetes从现实世界中抽象出了许多概念称为“API对象”描述这些对象就需要使用YAML语言。

YAML是JSON的超集但语法更简洁表现能力更强更重要的是它以“声明式”来表述对象的状态不涉及具体的操作细节这样Kubernetes就能够依靠存储在etcd里集群的状态信息不断地“调控”对象直至实际状态与期望状态相同这个过程就是Kubernetes的自动化运维管理[11讲])。

Kubernetes里有很多的API对象其中最核心的对象是“Pod”它捆绑了一组存在密切协作关系的容器容器之间共享网络和存储在集群里必须一起调度一起运行。通过Pod这个概念Kubernetes就简化了对容器的管理工作其他的所有任务都是通过对Pod这个最小单位的再包装来实现的[12讲])。

除了核心的Pod对象基于“单一职责”和“对象组合”这两个基本原则我们又学习了4个比较简单的API对象分别是Job/CronJob和ConfigMap/Secret。

Job/CronJob对应的是离线作业它们逐层包装了Pod添加了作业控制和定时规则[13讲])。 ConfigMap/Secret对应的是配置信息需要以环境变量或者存储卷的形式注入进Pod然后进程才能在运行时使用[14讲])。

和Docker类似Kubernetes也提供一个客户端工具名字叫“kubectl”它直接与Master节点的apiserver通信把YAML文件发送给RESTful接口从而触发Kubernetes的对象管理工作流程。

kubectl的命令很多查看自带文档可以用 api-resources、explain ,查看对象状态可以用 get、describe、logs ,操作对象可以用 run、apply、exec、delete 等等([09讲])。

使用YAML描述API对象也有固定的格式必须写的“头字段”是“apiVersion”“kind”“metadata”它们表示对象的版本、种类和名字等元信息。实体对象如Pod、Job、CronJob会再有“spec”字段描述对象的期望状态最基本的就是容器信息非实体对象如ConfigMap、Secret使用的是“data”字段记录一些静态的字符串信息。

好了“初级篇”里的Kubernetes知识要点我们就基本总结完了如果你发现哪部分不太清楚可以课后再多复习一下前面的课程加以巩固。

WordPress网站基本架构

下面我们就在Kubernetes集群里再搭建出一个WordPress网站用的镜像还是“入门篇”里的那三个应用WordPress、MariaDB、Nginx不过当时我们是直接以容器的形式来使用它们现在要改成Pod的形式让它们运行在Kubernetes里。

我还是画了一张简单的架构图,来说明这个系统的内部逻辑关系:

从这张图中你可以看到,网站的大体架构是没有变化的,毕竟应用还是那三个,它们的调用依赖关系也必然没有变化。

那么Kubernetes系统和Docker系统的区别又在哪里呢

关键就在对应用的封装和网络环境这两点上。

现在WordPress、MariaDB这两个应用被封装成了Pod由于它们都是在线业务所以Job/CronJob在这里派不上用场运行所需的环境变量也都被改写成ConfigMap统一用“声明式”来管理比起Shell脚本更容易阅读和版本化管理。

另外Kubernetes集群在内部维护了一个自己的专用网络这个网络和外界隔离要用特殊的“端口转发”方式来传递数据还需要在集群之外用Nginx反向代理这个地址这样才能实现内外沟通对比Docker的直接端口映射这里略微麻烦了一些。

WordPress网站搭建步骤

了解基本架构之后接下来我们就逐步搭建这个网站系统总共需要4步。

第一步当然是要编排MariaDB对象它的具体运行需求可以参考“入门篇”的实战演练课这里我就不再重复了。

MariaDB需要4个环境变量比如数据库名、用户名、密码等在Docker里我们是在命令行里使用参数 --env而在Kubernetes里我们就应该使用ConfigMap为此需要定义一个 maria-cm 对象:

apiVersion: v1 kind: ConfigMap metadata: name: maria-cm

data: DATABASE: 'db' USER: 'wp' PASSWORD: '123' ROOT_PASSWORD: '123'

然后我们定义Pod对象 maria-pod把配置信息注入Pod让MariaDB运行时从环境变量读取这些信息

apiVersion: v1 kind: Pod metadata: name: maria-pod labels: app: wordpress role: database

spec: containers:

  • image: mariadb:10 name: maria imagePullPolicy: IfNotPresent ports:

    • containerPort: 3306

    envFrom:

    • prefix: 'MARIADB_' configMapRef: name: maria-cm

注意这里我们使用了一个新的字段“envFrom”这是因为ConfigMap里的信息比较多如果用 env.valueFrom 一个个地写会非常麻烦,容易出错,而 envFrom 可以一次性地把ConfigMap里的字段全导入进Pod并且能够指定变量名的前缀即这里的 MARIADB_非常方便。

使用 kubectl apply 创建这个对象之后,可以用 kubectl get pod 查看它的状态如果想要获取IP地址需要加上参数 -o wide

kubectl apply -f mariadb-pod.yml kubectl get pod -o wide

现在数据库就成功地在Kubernetes集群里跑起来了IP地址是“172.17.0.2”注意这个地址和Docker的不同是Kubernetes里的私有网段。

接着是第二步编排WordPress对象还是先用ConfigMap定义它的环境变量

apiVersion: v1 kind: ConfigMap metadata: name: wp-cm

data: HOST: '172.17.0.2' USER: 'wp' PASSWORD: '123' NAME: 'db'

在这个ConfigMap里要注意的是“HOST”字段它必须是MariaDB Pod的IP地址如果不写正确WordPress会无法正常连接数据库。

然后我们再编写WordPress的YAML文件为了简化环境变量的设置同样使用了 envFrom

apiVersion: v1 kind: Pod metadata: name: wp-pod labels: app: wordpress role: website

spec: containers:

  • image: wordpress:5 name: wp-pod imagePullPolicy: IfNotPresent ports:

    • containerPort: 80

    envFrom:

    • prefix: 'WORDPRESS_DB_' configMapRef: name: wp-cm

接着还是用 kubectl apply 创建对象kubectl get pod 查看它的状态:

kubectl apply -f wp-pod.yml kubectl get pod -o wide

第三步是为WordPress Pod映射端口号让它在集群外可见。

因为Pod都是运行在Kubernetes内部的私有网段里的外界无法直接访问想要对外暴露服务需要使用一个专门的 kubectl port-forward 命令它专门负责把本机的端口映射到在目标对象的端口号有点类似Docker的参数 -p经常用于Kubernetes的临时调试和测试。

下面我就把本地的“8080”映射到WordPress Pod的“80”kubectl会把这个端口的所有数据都转发给集群内部的Pod

kubectl port-forward wp-pod 8080:80 &

注意在命令的末尾我使用了一个 & 符号,让端口转发工作在后台进行,这样就不会阻碍我们后续的操作。

如果想关闭端口转发,需要敲命令 fg 它会把后台的任务带回到前台然后就可以简单地用“Ctrl + C”来停止转发了。

第四步是创建反向代理的Nginx让我们的网站对外提供服务。

这是因为WordPress网站使用了URL重定向直接使用“8080”会导致跳转故障所以为了让网站正常工作我们还应该在Kubernetes之外启动Nginx反向代理保证外界看到的仍然是“80”端口号。这里的细节和我们的课程关系不大感兴趣的同学可以留言提问讨论

Nginx的配置文件和[第7讲]基本一样只是目标地址变成了“127.0.0.1:8080”它就是我们在第三步里用 kubectl port-forward 命令创建的本地地址:

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; } }

然后我们用 docker run -v 命令加载这个配置文件以容器的方式启动这个Nginx代理

docker run -d --rm
--net=host
-v /tmp/proxy.conf:/etc/nginx/conf.d/default.conf
nginx:alpine

有了Nginx的反向代理之后我们就可以打开浏览器输入本机的“127.0.0.1”或者是虚拟机的IP地址我这里仍然是“http://192.168.10.208”看到WordPress的界面

你也可以在Kubernetes里使用命令 kubectl logs 查看WordPress、MariaDB等Pod的运行日志来验证它们是否已经正确地响应了请求

使用Dashboard管理Kubernetes

到这里WordPress网站就搭建成功了我们的主要任务也算是完成了不过我还想再带你看看Kubernetes的图形管理界面也就是Dashboard看看不用命令行该怎么管理Kubernetes。

启动Dashboard的命令你还记得吗在第10节课里讲插件的时候曾经说过需要用minikube命令是

minikube dashboard

它会自动打开浏览器界面显示出当前Kubernetes集群里的工作负载

点击任意一个Pod的名字就会进入管理界面可以看到Pod的详细信息而右上角有4个很重要的功能分别可以查看日志、进入Pod内部、编辑Pod和删除Pod相当于执行 logs、exec、edit、delete 命令,但要比命令行要直观友好的多:

比如说我点击了第二个按钮就会在浏览器里开启一个Shell窗口直接就是Pod的内部Linux环境在里面可以输入任意的命令无论是查看状态还是调试都很方便

ConfigMap/Secret等对象也可以在这里任意查看或编辑

Dashboard里的可操作的地方还有很多这里我只是一个非常简单的介绍。虽然你也许已经习惯了使用键盘和命令行但偶尔换一换口味改用鼠标和图形界面来管理Kubernetes也是件挺有意思的事情有机会不妨尝试一下。

小结

好了作为“初级篇”的最后一节课今天我们回顾了一下Kubernetes的知识要点我还是画一份详细的思维导图帮助你课后随时复习总结。

这节课里我们使用Kubernetes搭建了WordPress网站和第7讲里的Docker比较起来我们应用了容器编排技术以“声明式”的YAML来描述应用的状态和它们之间的关系而不会列出详细的操作步骤这就降低了我们的心智负担——调度、创建、监控等杂事都交给Kubernetes处理我们只需“坐享其成”。

虽然我们朝着云原生的方向迈出了一大步不过现在我们的容器编排还不够完善Pod的IP地址还必须手工查找填写缺少自动的服务发现机制另外对外暴露服务的方式还很原始必须要依赖集群外部力量的帮助。

所以我们的学习之旅还将继续在接下来的“中级篇”里会开始研究更多的API对象来解决这里遇到的问题。

课下作业

最后是课下作业时间,给你留两个动手题:

MariaDB、WordPress现在用的是ConfigMap能否改用Secret来实现呢 你能否把Nginx代理转换成Pod的形式让它在Kubernetes里运行呢

期待能看到你动手体验后的想法,如果觉得有帮助,欢迎分享给自己身边的朋友一起学习。

下节课就是视频演示的操作课了,我们下节课再见。