说了半天跨平台,今儿咱就来跨跨!(完结篇)——Kubernetes 上手实践

语言: CN / TW / HK

两句闲言

去年写过两篇这个系列的文章,出于种种原因(当然主要原因是我懒),没有完成。后来也陆续写了一些别的内容,但始终没有再去把这个尾巴给续上,正好最近接触了一下 kubernetes,就以这个为切入点,来完结这个系列吧。

第一篇:point_right:: https://xie.infoq.cn/article/5fdeb09ec3872f86727a94a22

第二篇:point_right:: https://xie.infoq.cn/article/4f735951a021aa02c5c290f09

几片碎语

其实我写这篇 kubernetes 内容的底气也不是很足,目前的知识结构主要是建立在部分官方文档的基础上,因为实践成功,有点大喜过望,记录一下过程,也算是给还没有实际接触过 kubernetes 的老铁们趟趟道,正式开启云原生开发之旅了,哈哈!

再说为什么要聊 kubernetes 呢?现在的软件市场,单体应用以后基本没什么发展前途了,早在很多年以前,单体应用的前景就已经能看到天花板了,只是在一些小微企业和特殊的场景里,单体应用还在发光发热。而放眼整个互联网,不论国内还是国外,云原生,分布式,高并发系统都已经相当普及了。所以这就是所谓的“风口”,我觉得程序员还是要顺势而为,投入到有未来,有发展前景的行业中去,跟上时代,不然知识面太窄,造成就业面也太窄,以后再遇上个裁员潮,就真的芭比 Q 了啊!

准备工作

故事该从哪里说起呢?

如果之前没有接触过 kubernetes,上手的时候是一个模糊,朦胧的状态,虽然现在关于 kubernetes 的文章很多,但有的写的版本比较早,再用新的版本来参照已经不适用,有的写的内容非常大,脱离了入门基础。所以要说起入门级别的指引,还是得看官方的文档!其实上手任何工具,框架,或者开发语言,最好的入门资料,绝大多数时候都是官方的文档。虽然有些时候这些文档并没有中文版本,但翻译软件如此发达的当下,这个并不是太大的问题。我这里依照的入门流程就是几篇官方文档,分别是

:point_right::kubernetes的官方文档

:point_right::docker的官方文档

:point_right::kind的官方文档

:point_right::minikube的官方文档(打了个酱油)

为什么要看这么多文档?答案也很简单,因为不熟!所以在上手的时候,会看到文档里有很多概念,把你指引到相应的地址,其中关联最多的,就是以上四个地方。

注意,我的分享主要是介绍从零开始搭建本地开发环境并实际部署一个集群,其中不会太深入相关概念的解释,建议在上手过程中如果遇到此类困惑,还是去文档中寻求答案。

先试着搭个开发环境吧

这里,我再想多说一句。在选择开发环境,尤其是上手人员还是新手的时候,最好选一个自己熟悉的环境进行操作演练。你平时在 windows 环境下开发,就选 windows 的作为开发环境,是 macOS 就选 macOS,不要贸然选一个自己不熟悉的环境去尝试新的东西。现在的各种软件工具,基本都是跨平台支持,即便 Windows 环境不太适合生产环境,但作为开发环境来练习和入门还是绰绰有余的!

基本情况

先介绍下我本机的相关情况

操作系统 :Windows 11

子系统 :Ubuntu 22.04

基本软件 :docker desktop(V4.11.1,截止到 2022.8.9 号官方发布的最新版本)

准备工作

启用 wsl2

如果还没安装,可以参照官方文档进行安装,系统需要开启 wsl

开启 wsl2

# 在powershell或者命令提示符终端中输入该命令即可wsl.exe –set-default-version 2

复制代码

验证 wsl 版本(我这里因为已经安装好了 docker 环境,所以会列出更多内容)

wsl -l -v

复制代码

安装合适的 Ubuntu 发行版

在 windows store 中找一个合适的发行版即可,我这里用的是 22.04

安装好后,根据指引,进入 ubuntu 子系统,进行更新

# 更新可用软件包的存储库和列表 sudo apt update
# 根据安装的软件包更新系统 > “-y” 将自动批准更改 sudo apt upgrade -y

复制代码

安装 Docker Desktop

Windows 环境下的 Docker Desktop 安装非常简单,参照文档安装即可需要说明的是,在安装之前,请确保系统开启了 hyper-v

启动 wsl 集成

打开,docker desktop,进入设置页面,执行相关配置

配置完成后,进入 ubuntu,验证配置是否生效

sudo apt upgrade -y

复制代码

看到终端打印出相关信息,则证明配置生效!

*一点额外操作

到上面那一步,其实基本的配置就完成了,但由于国内的网络环境限制,为了更好的体验,还要配置一些镜像加速类的操作这里我用的是阿里云的镜像加速,基本操作流程可以参照一下官方文档:point_right:: https://help.aliyun.com/document_detail/60750.html

根据文档进行一系列配置后,会得到一个加速器地址,结构是这样的:

[系统分配前缀].mirror.aliyuncs.com

然后把这个添加到 docker 的配置文件里就好

 "registry-mirrors": [    "https://{系统分配的前缀}.mirror.aliyuncs.com"  ]

复制代码

好了,终于可以正式去创建集群了!

创建集群

kind 还是 minikube?

两种方式其实都可以,在 kubernetes1.24 之前,minikube 的方式应该是更容易,现在网上的很多资料也都是基于 minikube 的。但环境来到 wsl 中后,情况可能会发生变化。这里我把我踩过的坑简单介绍一下,怕折腾的同学可以简单参考一下

  • 安装,这个没什么可说的,在 wsl 中安装 minikube 还是很流畅的,执行着几段命令就可以

# 下载curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64# 使二进制可执行文件chmod +x ./minikube# 将二进制文件移动到可执行路径sudo mv ./minikube /usr/local/bin/

复制代码

  • 启动

minikube start

复制代码

到这里,会出现一个大概这样“System has not been booted with systemd…”的错误然后到这里,我折腾了一番,为了让 wsl 中启用 systemd,找了很多方法,结果,成功的让我的虚拟机起不来了。。然后为了继续“探索”,我也不得不把子系统删掉,再重新安装了一次。这也是上边这一段为啥没截图的原因,因为不想再折腾一次了~~

但后来翻看文档内容,我的尝试应该是方向错了,因为 minikube 本身提供了基于 windows 系统的启动方式,并不需要在 wsl 中使用,所以,如果大家想在 Windows 上尝试 minikube,建议先看一下文档的介绍吧~~

对了,我还确实找到了一个可以在 wsl 中使用 systemd 的脚本。看评论应该是好使,但我没再继续尝试了,因为它这个脚本也已经实在 2019 年写的了,而且毕竟也不是官方出的方案,有兴趣的同学可以研究一下,传送门:point_right:: https://forum.snapcraft.io/t/running-snaps-on-wsl2-insiders-only-for-now/13033

用 kind 来创建一个集群

安装 kind

打开 windows 终端,进入到 wsl 子系统,按顺序输入如下命令,安装 kind

# 下载curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.14.0/kind-linux-amd64# 使二进制可执行文件chmod +x ./kind# 将二进制文件移动到可执行路径sudo mv ./kind /usr/local/bin/kind

复制代码

可以看到,安装流程和 minikube 的安装流程基本一致

创建一个单节点集群

安装好 kind 后,可以简单做一些验证性的操作,然后就可以创建集群了

# 创建一个单节点集群,名字叫wslkindkind create cluster --name wslkind

复制代码

到这里,就已经创建了一个基本的集群节点了。

因为 kind 本身就是一个适合学习和测试的工具,启动快,资源占用低,但目前不适合生产环境,所以这里更多的内容,就不过多啰嗦了,大家感兴趣可以到官方文档去了解一下。

利用 Docker Desktop 创建集群(推荐)

事实上,在 Windows 环境下创建基于 docker 的 k8s 集群,已经变得非常简单,通过 docker desktop 提供的 kubernetes 能力就可以完成,关于这一点,docker 的官网有更为详细的介绍,大家可以去看一下。

在 Windows 环境下,用 Docker Desktop 来部署 k8s 集群有一个非常大的优势,就是 docker 提供了可视化的界面,多数情况下,不需要输入命令就可以完成操作,这对新手来说还是非常友好的。

开启 kubernetes

打开 Docker Desktop 的设置界面,到 kubernetes 栏目,勾选“Enable Kubernetes”选项,然后应用并重启。

执行上述操作后,会自动下载一些镜像到本地,这里我们可以先不用去管。

打包应用镜像

开启 kubernetes 环境后,既可以去打包我们自己的应用镜像了,这里我之前已经打包好并上传到dockerhub了,具体流程,在文章开头的两个链接里有具体介绍,也单独写过一篇相关的文章,可以简单参考一下。打包后,登录 dockerhub,可以看到自己上传的镜像

编写 k8s 启动文件

为什么要编写一个配置文件?关于这一点,其实内容有 亿 点抽象,我贴一段 docker 官网上的话(翻译过的,原文地址)

“使用 Kubernetes YAML 描述应用程序 Kubernetes 中的所有容器都被调度为 pod,它们是共享一些资源的同地容器组。此外,在实际应用中,我们几乎从不创建单独的 pod;相反,我们的大部分工作负载都被安排为部署,它们是由 Kubernetes 自动维护的可扩展的 Pod 组。最后,所有 Kubernetes 对象都可以并且应该在称为 Kubernetes YAML 文件的清单中进行描述。这些 YAML 文件描述了 Kubernetes 应用程序的所有组件和配置,可用于在任何 Kubernetes 环境中轻松创建和销毁您的应用程序。”

总之,现阶段,我们要知道,需要编写一个 yaml 格式的文件,来描述应用程序的一些基本内容,通过这个文件,才能让 kubernetes 来启动集群

apiVersion: apps/v1kind: Deploymentmetadata:     name: k8s-cipapi    namespace: default    labels:        name: k8s-cipapispec:     replicas: 1    selector:        matchLabels:             name: k8s-cipapi    template:        metadata:          labels:            name: k8s-cipapi        spec:          containers:          - name: k8s-cipapi            image: tonydf/cipapi:v220804 # 镜像标识,如果本地不存在就会到dockerhub拉取,当然这个拉去规则是可以设置的。            ports:               - containerPort: 8002
---
apiVersion: v1kind: Servicemetadata: name: k8s-cipapi namespace: defaultspec: type: NodePort selector: name: k8s-cipapi ports: - port: 8002 targetPort: 80

复制代码

注意,这里涉及到很多属性,我就简单挑几个说明一下

  • apiVersion,创建该对象所使用的 Kubernetes API 的版本

  • kind,想要创建的对象的类别

  • metadata,帮助唯一标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace

  • spec,你所期望的该对象的状态

  • ---,这三个线表示同级别内容的分割

以上只是外层属性的含义,其中每个属性内部还有各自专属的子属性,的确有些复杂,但好在层次分明,条例清晰,yaml 的格式也比 json 更加简洁,实际理解起来并不是很困难。更具体的大家可以去看kubernetes的官方文档

启动集群

在 windows 终端中,通过命令,启动我们自己的 k8s

kubectl apply -f .\cipapi.yaml

复制代码

启动之后可以命令,查看启动状态

kubectl get deployments

复制代码

可以看到,启动集群之后,集群状态并没有马上变成“ready”状态,这是因为我再启动这个集群的时候,并没有在本地打包容器镜像,因此 k8s 会自动根据我设定的镜像标签去 dockerhub 拉取镜像。几分钟后,再来看集群状态

就已经是启动状态了。还可以通过如下命令,来查看服务状态

 kubectl get services

复制代码

k8s-cipapi 就是我们自己的服务项目了。同样的,可以执行 docker ps 命令,来对照一下容器的状态

可以看到,k8s 自动帮我们创建了一个容器,并根据我们在 yaml 中配置的相关内容设置了容器的 name。

数据验证

确定集群正常启动后,就可以来验证一下服务是否正常启动了通过命令

kubectl get svc

复制代码

可以看到 k8s 给我们部署好的服务的外部端口

可以看到,容器内部,使用的是 8002 端口,暴露给外网访问的端口变成了 31494 在浏览器访问一下

这里呢,是因为 swagger 的默认配置不支持跨域,而 k8s 通过类似 nginx 反向代理的形式把对外的端口改成了 31494,所以访问 swagger 默认文档的时候会提示这个错误,所以这个是系统配置的问题,并不是集群造成的问题。接下来在通过 postman 来实际访问一下接口,看看效果

可以看到,接口成功返回了数据!

另外,这里的 31494 其实是 k8s 帮我们暴露给外部访问的一个 node 端口,因为我这里主要定位是“跑通”,所以更多关于概念性的东西大家还是务必要到官方文档去看一下。

通过 kubernetes-dashboard 来检测集群状态

通过上面的实践,可以看到,部署好集群之后,还要监控集群的状态,而在实际的开发应用中,如果每次都通过命令行的形式来查看,效率就太低了,因此我们可以部署一个 dashboard 应用,来可视化的管理我们的集群。

先上 github 地址:point_right:: https://github.com/kubernetes/dashboard

其实具体安装和配置流程,这个文档里也介绍的很清楚了,我这里就简单过一下流程

安装

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.0/aio/deploy/recommended.yaml

复制代码

访问

# 要从本地工作站访问 Dashboard,必须为 Kubernetes 集群创建一个代理访问通道kubectl proxy

复制代码

代理启动后,在浏览器访问这个地址 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/,就可以看到登陆界面了

创建 rbac 配置文件

要想快速访问这个管理面板,需要创建一个基于 rbac 的 token,为了快速完成这个操作,首先需要创建一个 yaml 文件

apiVersion: v1kind: ServiceAccountmetadata:  name: admin-user  namespace: kubernetes-dashboard  ---
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: admin-userroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminsubjects:- kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard

复制代码

然后通过创建集群的指令,完成服务的部署

kubectl apply -f dashboard-adminuser.yaml

复制代码

之后,就可以获取 token 了

kubectl -n kubernetes-dashboard create token admin-user

复制代码

复制这个 token 值,到登陆界面,就可以看到管理面板了

到此,在开发环境部署 k8s 集群的旅程就基本结束了,接下来就是更加深入的了解,和调整优化了!

结束语

基本就是这些啦,关于 k8s 和微服务的探索,这仅仅是冰山一角,还有更多的内容等待去挖掘,我也会继续狂奔,顺势而为,希望参与评选的大家,都有好成绩啊,哈哈。

*注:本文也同步发布于阿里云开发者社区:point_right:: https://developer.aliyun.com/article/994445