最近在做服务私有化建设这块,对于物理机能轻量化进行容器资源管理和对服务运维,k3s还是比较合适的。对于新鲜事物,作为非运维的我还是迫切想解并搞个demo出来尝尝鲜。
提示
本文是在没有K8S的基础上去了解和使用K3S,很多点都不会讲到,只是通过自己用到的demo来去理解K3S、K3D及K8S。我会将一些比较好的链接贴在恰当处,方便后续深入了解和使用。
什么是K3S
官网:https://k3s.io/
指南:https://rancher.com/docs/k3s/latest/en/
中文版指南:https://docs.rancher.cn/docs/k3s/_index/
K3s 是一个轻量级的 Kubernetes 发行版,它针对边缘计算、物联网等场景进行了高度优化,易于安装,全部在不到100MB的二进制文件中;非常适合
- Edge
- IoT
- CI
- Development (用的就是这个)
- ARM
- Embedding K8s
- Situations where a PhD in K8s clusterology is infeasible
可以理解为是K8SLite版,单词比K8S一半还少,所以叫K3S
什么是K3D
官网:https://k3d.io/v5.3.0/
指南:https://k3d.io/v5.3.0/usage/configfile/
k3d 是一个轻量级的包装器,用于在 docker 中运行k3s(Rancher Lab 的最小 Kubernetes 发行版)。
k3d 使得在 docker 中创建单节点和多节点k3s集群变得非常容易,例如在 Kubernetes 上进行本地开发。
对于我们研发人员,我们不希望花太多精力和时间去搭建和维护K8S,那么我们使用K3D就能通过类似docker的方式来快速的构建K3S集群,所以两者加起来就相当于一个K8S了。
安装
我的是mac,直接使用brew安装,K3D官网首页有各种系统的安装方式
brew install k3d
附:brew切换国内镜像
如下代表安装成功
NodePort和Ingress的示例
到这里可能还是一脸懵逼的,因为涉及的点太多,也不知道从何下手,那就直接用一个demo来学习:使用集群部署一个可访问的服务,并在宿主机可以访问。
1、首先我们要知道使用k3d创建集群后,宿主机、k3d、k3s是怎样的关系,如下图
就把k3d理解为“docker”
2、使用k3d创建单节点集群架构
为了方便管理,这里使用yaml文件来创建集群,内容如下:
创建一个 server节点为1,agents节点为2的集群,且集群的30080端口映射宿主机的8087端口
附:非常详细的说明
接着我们使用命令k3d cluster create --config cluster.yaml
等待执行完成即可。
我们可以使用k3d cluster list
来查看集群的状态,也可以通过kubectl get all --all-namespaces
来查看k3s集群中已经部署了资源
3、区别
nodeport和ingress分别属于k8s中供外部访问的两种方式,nodeport又是service资源的一种类型,其中service分为以下几种类型:
- ClusterIp:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP
- NodePort:在ClusterlP基础上为Service在每台机器上绑定一个端口,这样就可以通过<NodeIP>:NodePort 来访问该服务
- LoadBalancer:在NodePort的基础上,借助云厂商创建一个外部负载均衡器,并将请求转发到<NodeIP>:NodePort
- ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有kubernetes1.7或更高版本的kube-dns才支持
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
简单的理解就是ingress可以使用域名对容器内的服务进行绑定,并且ingress controller可以动态的加载和更新域名与pod之间的映射关系
附:K8s之NodePort LoadBalancer和Ingress的区别
这里要多翻翻资料理解一下,刚开始还是比较难理解的。
4、NodePod
同样的,我们使用yaml来编写deployment和service
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 256Mi
requests:
cpu: 80m
memory: 128Mi
status: {}
重要的解释一下
- kind:类型,deployment可以理解应用资源,service为访问规则资源,ingress即ingress配置资源
- metadata.name: pod的名称,后续用于service绑定
apiVersion: v1
kind: Service
metadata:
labels:
app: web-service
name: app-service
spec:
ports:
- name:
nodePort: 30080
port: 80
protocol: TCP
targetPort: 80
selector:
app: web
type: NodePort
- spec.selector.app 指定当前service绑定的是哪一个pod
- spec.type 指定当前的service为NodePort类型,默认为ClusterIp
这里有各种port,我画了个图帮助理解一下
接着我们使用kubectl apply -f xxx.yaml
分别创建deployment和service
使用kubectl get pods,service -o wide
查看详细信息
到此我们就可以用宿主机直接访问localhost:8087了
5、Ingress
我们需要创建两组deployment、service和ingress,并且宿主机的hosts需要配置两个域名
我们先使用k3d cluster delete mycluster
删除集群,再重建一个集群k3d cluster create --config cluster.yaml
deployment的声明保持不变,毕竟只是描述应用,改变的是service和新增ingress
apiVersion: v1
kind: Service
metadata:
labels:
app: web-service-a
name: app-service-a
spec:
ports:
- name:
port: 80
protocol: TCP
targetPort: 80
selector:
app: web-a
这里的service没有指定type,因为不需要节点暴露端口,只需要集群内访问ClusterIp
新增ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress-a
spec:
rules:
- host: localhost # b的内容为localhost.k3d.ingress
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service-a # 链接的是上面svc的名字
port:
number: 80
重点说明:
- host: 即使用哪一个域名来访问service
- backend.service.port.number 对应的是service的port
注意: 这里要注意一下, ingress默认端口是80,因为所以在整个k3d里,使用ingress的端口映射如下
所以对应的cluster.yaml里的映射也要改为- port: 9001:80
直接用我给的示例运行就行了
.
├── cluster.yaml
├── nginx-a.yaml
├── nginx-b.yaml
├── nginx-ingress-a.yaml
├── nginx-ingress-b.yaml
├── nginx-service-a.yaml
└── nginx-service-b.yaml
分别执行a和b
因为用的是同一个镜像,我们需要进入a和b的pod中更改nginx默认的html内容来区分
按照同样的方法,在b的实例中更改
接着需要更改我们的hosts文件,我用的是mac,直接在/etc/hosts
更改
127.0.0.1 localhost
127.0.0.1 localhost.k3d.ingress
最后可以访问验证了
最后
想快速了解和学习某一技术,还是得需要拿示例来学习,通过以上我可以使用单机快速的来部署kubernetes集群,并且能编写yaml脚本去部署应用和访问,后续还需要继续了解kubernetes,最终能做到熟练使用吧。
示例代码:https://github.com/vector4wang/spring-boot-quick/tree/master/quick-container/src/main/k3s