开发者学堂课程【手把手基于阿里云 ACK 环境创建 Kubernetes 集群及部署应用:【公开课】手把手基于阿里云 ACK 环境创建 Kubernetes 集群及部署应用】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/829/detail/13949
【公开课】手把手基于阿里云 ACK 环境创建 Kubernetes 集群及部署应用
内容介绍:
一、课前导读
二、集群部署的常用方法
三、创建一个集群
四、部署应用
一、课前导读
1.学习如何创建集群及部署应用
这其实是属于基础篇的一部分,在基础篇中主要介绍了五步上手 K8s,这五步大致为:
第一步:创建集群,根据介绍学习如何部署应用
第二步:上到 K8s 生产环境之前,需要注意的事项
第三步:学习集群中监控与日志是如何管理的
第四步:介绍 K8s 中弹性伸缩的问题
第五步:学习 Kubernetes 集群如何进行升级
2.学习目标
通过这五步快速学习上手 K8s,并且能够做到基础的运维相关工作。
3.课前导读
下面先学习第一步,大致分为三个部分:首先介绍集群部署的常用方法的介绍,然后是手把手创建一个集群,最后是学习如何部署应用。
学习之前,需要回顾一些基础知识,点击《CNCF X Alibaba 云原生技术公开课》中的课程:第三讲Kubernetes 核心概念进行一些理论知识的学习,本节知识的理论知识主要就在这节课中,只有学习了之前的理论知识,在本节涉及的实践中才能更加得心应手,在本节,里面涉及的理论知识不会再多加讲解
一、集群部署的常用方法
1.部署集群的三大类型
经过 Kubernetes 这几年的演进,Kubernetes 生态已经非常丰富,部署 Kubernetes 集群也不再像以前那样困难,现在部署 Kubernetes 集群有三大类方法:
(1)minikube:本地开发测试
是最常用的一种方法,最开始的原理是在集群里启用一个虚拟机,然后在虚拟机上部署相应的 k8s 环境,随着 minikube 的演进,里面支持的驱动也越来越多,从最开始只支持 virtuallbox 这种虚拟机,到现在可以支持 Hypervisor 这种裁剪的虚拟机,以及现在可以直接支持 docker 启动。
(2)Kind:K8s 相关的集成测试
近几年才出现的一种方法,原理是 kind 直接围绕 docker创建 k8s 环境,相对第一种方法更为轻量,可以很快启动,它的主打就是速度快,可以达到几秒快速启用的效果。如图:
这里只用了21秒的时间就把集群启动了。
Kind 常用的用途就是在做 k8s 相关的集成测试时,会在集成测试里面将 kind 集中起来,然而在日常用的最多的还是 minikube ,因为它里面会涉及到一些插件,功能也相对较多。
(3)kubeadm : 高可用环境
这种方法的安装在 Kubernetes 官方文档中也有介绍,比如介绍如何部署一个高可用的 Kubernetes 环境,以及一系列组件是如何安装的,相对来说,kubeadm 的安装会更加复杂一些,因为一个高可用的集群其实配置起来是很麻烦的,而且 Kubernete 涉及的组件相对来说是比较多的,最有名的像:ETCD ,以及和 K8S 中的一些外部组件直接交互的 API Server 也是一个比较重要的组件。在 API Server 和其他组件交互时需要部署一个证书,所以还需要配置证书,配置证书之后,还要部署像运行这个实际容器 Kubernete 。
二、创建一个集群( 以 minikube 为例)
1.如何创建一个集群
如果需要部署生产环境的可用集群,可以直接购买一个 ACK 上的一个集群,只需要通过点击按钮,然后选择配置和机型之后即可使用,而且使用也很方便。
如图:
2.演示如何创建集群
(1)如果要启动 minikube ,正常需要先去官方查看 minikube 的相关文档,但是因为官方文档由于镜像在国外,所以访问的时间相对缓慢一些,可以访问由阿里云提供的国内的 minikube 版本,这样使用起来相对较快,而且国内版本在社区版的基础上做了优化,把国外的镜像换成了阿里的镜像源,使用起来是极为方便并且不用付费,安装时只需要把命令按照文档提供的不同版本去执行即可。
(2)在文档的帮助下进行安装和下载,下载之后输入机器密码。
如图:
输入机器密码后,minikube 就下载好了,下载之后的版本可能不是最新版本,但是功能大部分都支持,在本地做调试时也是极其方便的。
(3)启动集群
正常情况下,启用集群只需要输入 minikube start 一步就可以,然后会有 driver 可供选择,通常默认选择 docker driver的使用方式。
如图:
不同的 driver 会有不同的差异。如今,minikube 已经支持很多种 driver,其中,driver 的类型有: Hyperkit 、Hyper-V 、KVM 、Parallels 、 Podman 、VirtualBox 、VMWare 。
①对于 docker driver
docker 这种使用方式比较轻量,背后其实是在一个 docker 这个容器里启用 k8s 的一个集群,但是也有一定问题,在已知 Issues 里也有举例:首先是它不支持 amd64 中类似 arm 的架构;其次是它不稳定,可能会出现问题需要重启;最后是它不支持使用 ingress ,在做实验时候无法使用这种方式,只能换一种 driver 。
②对于 Hyperkit
实际上是对应 Hypervisor 的一个裁剪过的虚拟机,相对来说使用的次数更多,如在开发环境下大部分都是使用 Hyperkit ,对应到 window 上就是 hyperv ,使用时只需把 minikube start 里的 docker driver 改成 Hyperkit 的形式即可,启用方式后面加上一个参数就可以。 然后它的已知 Issues 是 DNS 的问题,如DNS 的位置可能会有冲突,以及消耗CPU 多、机器发热等问题,其中由于前者设定的人数极少因此和其他问题一样可以省略不计,而后者可能会带来占 CPU 过大导致机器发热等,但是在无需使用 minikube 时可以关闭机器,因此也无需担忧这个问题。
③对于 VirtualBox
相对来说没有太多问题,是最古老的一种方式,有相对完整的虚拟机,更加稳定但是太重。
(4)请看以下一部分代码:
Rudrx git : (plugin) minikube status
m
inikube
ty
pe: Control Plane
h
ost: Running
k
ubelet: Running
a
piserver: Running
解析:可以看到,Minikube 是通过 status 来启动的,其中包含几个组件如 type 等,其中最常用的组件是 kubelet 和 apiserver ,意思是说,在使用 kubectl 这些命令时,已经完成 minikube 的配置了,可以直接使用本地的 minikube 。这里介绍一个命令 ADS ,可以直接配置 kubectl ,后面只需要执行 k 就可以,这样可以节省很多时间。
(4)插件系统
正常情况下,minikube 会安装默认的一些插件,这些插件都可通过 minikube addons list 进行查询,如图:
这里默认创建了本地存储的 default-storageclass 以及 storage-provisioner 等很多插件。
如果不明白如何进行打开 minikube addons 命令的指令,可以输入 help ,help 的功能很齐全,如图:
可以看到,有: configure 、disable 、enable 、list 、open 等,其中 enable 的功能就是打开 minikube addons 。
(5)dishboard 的安装以及使用( dashboard 界面)
①如何安装 dishboard
首先,需要明白的是,在 k8s 体系里面,一切(包括 dishboard)都只是 k8s 里的一系列插件。
如图:
可以看到,安装 dishboard 的过程是非常快速的,仅仅只需11秒。
②如何使用 dishboard
在 minikube 执行 dishboard 指令,然后会出现一个页面,如图:
页面会显示有哪些 Namepaces 、Nodes (只有一个节点)等,还会显示有哪些工作量如 Cron Jobs 等(注意:由于是新创建的环境,所以不会有任何内容显示),然后关闭页面,此时集群创建完毕。由于整体在docker 的环境下网络不是互通的,为了本地能访问,会进行调接一直打开进程(在无需进行时候可以关闭,关闭后之前的页面已无法打开)。
三、部署应用
1. golang 和前端
在 Github 里面随便搜一个 golang 和前端的应用,然后挑一个stars 最多的,stars 最多说明使用人数也多
如图:
点击 flipped-aurora/gin-vue-admin 页面,如图:
可以看到,它本身是一个 stars 较多,有一定功能,也有一定用户群体,即可以认为它的使用量较多。拿出一个真实的应用放在 k8s 中,可以看到,它没有显示支持 k8s ,但是它支持 docker compose ,点击 docker compose 会出现一个页面,如图:
可以看到, docker compose 大致分为三个组件,services 、mysql 和 redis ,值得注意的是,在 k8s 同样是分为这三个结构:services 的应用、 mysql 的存储应用和 redis 的缓存应用。于是就满足了创建包含前端、缓存和数据库的应用的条件。如图:
分别点开三个 yaml 文件,可以看到是关于 mysql、redis 和 web-server 的三个 yaml 文件。
2.介绍 mysql
请看以下一段部署 mysql 的代码:
(1)apiVersion: v1
kind: Service
metadata:
labels :
a
pp: mysql
name: mysql
spec:
ports:
- name :
mysql
ports :3306
p
rotocol :TCP
t
argetPort: 3306
selector :
app : mysql
t
ype: ClusterIP
(2)apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels :
a
pp: mysql
spec:
(3)apiVersion: app/v1
kind: Deployment
matadata:
name: mysql
labels:
a
pp: mysql
s
epc:
可以看到,如果需要部署一个 mysql,正常情况下会遇到一些问题如:其他的应用如何访问 mysql 的问题即需要组件之间互相访问,以及 mysql 的存储如何保证持久化的问题,前者的解决方式是需要有 Service 的配置,后者的解决方式是需要有 PersistentVolumeClaim 的配置。
然后还需要用 k8s 里的 Deployment 的模式把整个应用配置起来,配置后不了解的参数可以忽略。需要注意的是,service 是通过 labels 和 k8s 里的 Pod 进行一一对应,来达到其他组件访问 service 是访问 k8s 中 Pod 的目的;然后再把镜像部署上去,其中涉及到的环境变量是通过 k8s 里的 env 传输进去的;对于 imagePullpolicy ,有 always 和 IfNotPresent 两种方式,如果使用 always,代表每次重启都需要进行镜像的拉取,如果使用 IfNotPresent ,代表如果当前本地的 docker 仓库存在镜像,可以直接使用,不需要再拉取镜像。
3.介绍 redis
请看以下一段代码:
(1)apiVersion: v1
kind: Service
metadata:
name: redis
labels :
name: redis
spec:
t
ype: ClusterIP
p
orts:
(2)apiVersion: app/v1
kind: Deployment
matadata:
name: redis
spec:
r
eplicas: 1
selector:
m
atchLabels:
a
pp: redis
可以看到,redis 同样有解决如何被其他组件访问的问题需要解决,即需要有 Service 的配置,且配置的端口是6379。然后同样也是有一个 Deployment 去配置它的镜像,这样可以大大减少对其他无关参数的配置,同样也是通过 labels 进行筛选。
3.介绍 web-server
请看以下一段代码:
apiVersion: v1
kind:Service
metadata:
name: web-server
labels :
name: web-server
spec:
type : LoadBalamcer
ports:
- Name : http
ports :8888
targetPort : 8888
selector :
app :web-server
---
apiVersion: app/v1
kind: Deployment
matadata:
name: web-server
spec:
selector:
matchLables:
app:web-server
template:
metadata:
labels:
app :web-server
可以看到,web-server 服务的启动和上述 mysql 和redis 的操作相似。其中 readinessProbe 和 LivenessProbe 可以判断应用是否正常启动,里面还有一些配置通过 config 的方式写进来了,然后通过 config 绑定到 volumes 上,再把 volumes 绑定,但是也能看出, web-server 的配置有不规范的地方,如 password 的明文现象。
如果为了解决访问问题而配置了 service ,将会有一个 service 的地址,如果是本地的 service 可以直接加上后缀。K8s 的service 机制有一个很大的好处是,假设 service 背后的 Pod 无法运行,会有新的 Pod 代替旧的,可以保证 web-server 服务的正常启动和运行,同时为后续灰度发布等功能做好了铺垫。
4.部署 k8s 文件夹
在部署 k8s 文件夹时将上述三个结构结合起来,同时可以通过 watch 命令看到里面的创建情况。
5.问题解析
(1)组件之间的访问:通过 service。
(2)如何解决应用之间的依赖关系:
一个 go 的 web 应用依赖于 mysql ,只有 mysql 存在,web 应用才存在,在 k8s 中,Pod 是可以不断重启的,即启动失败了还可以重新启动。
(3)如何解决应用的存活问题:使用测活机制即 readiness 和 liveness,它们可以保证应用是存活的,前者代表工作可以正常进行,后者代表进程可以正常运行。
需要注意的是:service 类型有 ClusterIP 、Nodeport 和 LoadBalancer ,其中 ClusterIP 只能在集群范围内使用;Nodeport 的使用方式是在宿主机开一个端口,通过宿主机的 IP 进行访问,使用范围比 ClusterIP 大;而通常在有外界的组件需要访问的情况下,才会使用 LoadBalancer ,它会配置一个集群中的负载均衡器做分配的地址,这个 IP 地址可以正常访问外部。
(4)如何解决集群在 docker 中拉动缓慢的问题
如果因为网络等原因导致集群在 docker 中拉动缓慢,可以采取删除集群,重新部署一个新集群的方式。
如果不行,可以使用另外一个方法:在本地先把页面 pull 起来,如图:
可以看到,本地的 docker pull 的速度会快很多,然后把本地的 docker 镜像保存起来也就是让本地拉取这些镜像,再进行镜像的 sever 之后,创建一个文件夹,并把镜像的 server 放进去,放进去之后,minikube 下达 mod 命令,把这个命令 mod 到 minikube 中,然后开启进程,把本地的 build-image 文件夹 mod 到 minikube 里面的环境中。此时如果无法正常运行,应将窗口关闭后,通过 minikube ssh 再打开一个窗口重新下达命令。
如图:
然后关闭新打开窗口,此时配置已完成。
(5)使用 yaml 文件的好处
①如果本地已经有相对应的镜像,就不需要额外拉取镜像,节省时间。
②如果在开发途中遇到了镜像的问题,可以使用 minikube 去解决。
③如果需要更新,可以将镜像再次打包然后传送,删除 port 进行重启,就可以持续更新。
(6)再次启用 yaml 文件,运行后如图:
可以看到,运行情况良好,没有之前的不良现象,但是需要注意的是,由于它们都在一个 docker 的环境下运行,因此可能会出现一些问题,解决这个问题可以采用换驱动器的方法。如果 CPU 占用过大,可能会出现无法删除的现象。
运行成功后,可以通过 minikube service 进行访问,如图:
可以看到,页面出现了 web-server ,于是我们可以通过它访问应用,访问方式是加 url ,根据情况加上 admin。
打开应用,会有一个登录页面出现,账号的密码默认是123456,如图:
输入验证码后即可进入网站,如图:
可以看到,页面中有许多功能选项,如角色管理等。整体是没有问题的,这也说明应用部署成功。
四、部署成功后可能会遇到的问题
一个元原生应用要真正做到生产可用,还需要解决很多问题,如:隔离、均衡、流水线、负载、高可用、监控、日志、报警、灰度…
其中,最基本的是隔离,如之前部署的都在一个 docker 环境里,是没有太多的隔离性的,需要分配到不同的机器或者配置不同的安全策略。其次是弹性和高可用。同样的,如果是能做到生产可用的应用,监控、日志、报警等功能也是非常重要的环节,还有后期应用更新后需要做的灰度开发,以及金丝雀部署等问题需要注意。