作为程序员,平时面对太多的包管理系统。比如我在ubuntu下工作,涉及的基本包管理系统就有如下。
- apt: 系统自带软件的包管理系统
- snap: 跟apt类似,不过软件版本更为激进
- pip3: 编程语言python的包管理系统
- cpanm: 编程语言perl的包管理系统
- rbenv: 编程语言ruby的包管理系统
- sdkman: 编程语言scala的包管理系统
其他还有node, go, php等,都有类似的系统,它们无疑增加了使用的复杂度。
不过凡事都有好坏,在熟悉了各自生态的包管理系统后,后续工作的效率更高,也更为规范。
比如,在没使用apt之前,安装一个linux开源程序,都要下载源码,编译,再安装。这不但有一定工作量,还容易出错。每个人装的不一致,还带来不规范。
而有了apt,对于通用的软件,大家都用apt install一键搞定,既快又省事,环境还统一。
类似的,kubernetes也有自己的包管理系统,叫做helm。使用helm在k8s集群上安装软件,也是如此简单,比如安装mysql:
$ helm install repo mysql --generate-name
上述一个命令就搞定了。当然在此之前,要先配置好本地repo:
$ helm repo add bitnami https://charts.bitnami.com/bitnami
安装完后,如何访问mysql?可以启动另一个pod实例,在这个pod里访问mysql:
$ k run mysqlcient --rm -it --restart="Never" --image docker.io/bitnami/mysql:8.0.32-debian-11-r11 -- bash
$ mysql -h 10.244.0.39 -uroot -p
如此一来,使用helm在k8s上安装和使用mysql就变得十分简单。
作为对比,手工在k8s上安装mysql,当然也可以,只是步骤复杂, 要创建YAML文件,还要理解一些概念。安装过程可以参考如下博客。唯一要注意的是本文档使用5.6版本mysql,需要改成5.7,因为docker hub里目前最低就是5.7。
How to Deploy MySQL Statefulset in Kubernetes
除了常用的pod, service, deployment外,还需要理解本文涉及的其他概念,包括:
- Statefulset: 跟deployment类似的概念,不过它是有状态的,比如mysql有本地存储,这就是状态相关的,在restart时不能丢了存储数据。
- Headless service:它也是一个service,不过没有clusterIP(声明时设置为None)。如果有clusterIP,这实际上是一个proxy IP,请求会load balance到后台的pod IP。而mysql是个状态服务,显然不能这样做。
k8s集群里有如下IP:
- pod自身的IP:使用k get pods -o wide可以看到
- cluster IP:一个proxy IP,可以代理到后台多个pod
- external IP:集群的外部通讯IP,从宿主机上可以直接访问
按如上文档手工在k8s上安装mysql后,再登陆和访问mysql:
$ k get pods -l app=custo-mysql
NAME READY STATUS RESTARTS AGE
custo-mysql-0 1/1 Running 0 56m
custo-mysql-1 1/1 Running 0 56m
custo-mysql-2 1/1 Running 0 48m
$ k exec -it custo-mysql-0 -- mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.41 MySQL Community Server (GPL)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
检查下手工安装的mysql,以及通过helm安装的mysql,它们的statefulset状态:
$ k get sts
NAME READY AGE
custo-mysql 3/3 59m
mysql-1677811395 1/1 5h13m
上述helm安装的mysql只有一个pod,可以手工进行扩容:
$ k scale sts/mysql-1677811395 --replicas 2
过一会扩容完再看,现在有两个pod了:
$ k get sts
NAME READY AGE
custo-mysql 3/3 64m
mysql-1677811395 2/2 5h18m
通过手工在k8s上安装软件,以及通过包管理器helm安装软件,两者对比看出:
- 手工安装更复杂,需要理解更多的概念,但有助于加深对k8s的了解。
- helm使用上更为简单,安装过程更为规范,但高度抽象的同时,隐藏了一些细节。
所有的包管理系统都有上述优劣势。先熟悉生态环境,了解执行细节,再深入接触包管理,在提高效率的同时,又知其所以然。这显然是合格的程序员应该遵循的原则。