NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

轻量级 Kubernetes k3s 初探

  • 2020-04-12
  • 本文字数:6428 字

    阅读完需:约 21 分钟

轻量级Kubernetes k3s初探

1 k3s 简介–5 less than K8s

k3s[1] 是 rancher®开源的一个 Kubernetes 发行版,从名字上就可以看出 k3s 相对 k8s 做了很多裁剪和优化,二进制程序不足 50MB,占用资源更少,只需要 512MB 内存即可运行。


而之所以称为 k3s 是因为相对 k8s 裁剪了如下 5 个部分:


  • 过时的功能和非默认功能

  • Alpha 功能

  • 内置的云提供商插件

  • 内置的存储驱动

  • Docker


官方称 k3s 是:


★ k3s 是史上最轻量级 Kubernetes.”


相对 k8s 最主要的优化如下:


  • 使用内嵌轻量级数据库 SQLite 作为默认数据存储替代 etcd,当然 etcd 仍然是支持的。

  • 内置了 local storage provider、service load balancer、helm controller、Traefik ingress controller,开箱即用。

  • 所有 Kubernetes 控制平面组件如 api-server、scheduler 等封装成为一个精简二进制程序,控制平面只需要一个进程即可运行。

  • 删除内置插件(比如 cloudprovider 插件和存储插件)。

  • 减少外部依赖,操作系统只需要安装较新的内核以及支持 cgroup 即可,k3s 安装包已经包含了 containerd、Flannel、CoreDNS,非常方便地一键式安装,不需要额外安装 Docker、Flannel 等组件。


k3s 的四大使用场景为:


  • Edge

  • IoT

  • CI

  • ARM


当然如果想学习 k8s,而又不想折腾 k8s 的繁琐安装部署,完全可以使用 k3s 代替 k8s,k3s 包含了 k8s 的所有基础功能,而 k8s 附加功能其实大多数情况也用不到。

2 一键式安装 k3s

k3s 安装确实非常简单,只需要一个命令即可完成:


curl -sfL https://get.k3s.io | sh -
复制代码


通过如上只执行了一个命令即部署了一套 all in one k3s 单节点环境,相对 k8s 无需额外安装如下组件:


  • kubelet

  • kube-proxy

  • Docker

  • etcd

  • ingress,如 ngnix


当然可以使用 k3s agent 添加更多的 worker node,只需要添加K3S_URLK3S_TOKEN参数即可,其中K3S_URL为 api-server URL,而k3S_TOKEN为 node 注册 token,保存在 master 节点的/var/lib/rancher/k3s/server/node-token路径。

3 和使用 k8s 一样使用 k3s

3.1 和使用 k8s 一样使用 k3s 命令工具

k3s 内置了一个 kubectl 命令行工具,通过k3s kubectl调用,为了与 k8s 的 kubectl 命令一致,可以设置 alias 别名:



# 该步骤可以省略,在/usr/local/bin中已经添加了一个kubectl软链接到k3salias kubectl='k3s kubectl`
# 配置kubectl命令补全source <(kubectl completion bash)
复制代码


配置完后,我们就可以通过kubectl查看 kube-system 运行的 pod 列表如下:



# kubectl get pod -n kube-systemNAME READY STATUS RESTARTS AGEmetrics-server-6d684c7b5-4qppl 1/1 Running 0 70mlocal-path-provisioner-58fb86bdfd-8l4hn 1/1 Running 0 70mhelm-install-traefik-pltbs 0/1 Completed 0 70mcoredns-6c6bb68b64-b9qcl 1/1 Running 0 70msvclb-traefik-2ttg2 2/2 Running 0 70mtraefik-7b8b884c8-xkm77 1/1 Running 0 70m
复制代码


我们发现并没有运行 apiserver、controller-manager、scheduler、kube-proxy 以及 flannel 等组件,因为这些都内嵌到了 k3s 进程。另外 k3s 已经给我们默认部署运行了 traefik ingress、metrics-server 等,不需要再额外安装了。


k3s 默认没有使用 Docker 作为容器运行环境,而是使用了内置的 contained,可以使用crictl子命令与 CRI 交互。


当然如果习惯使用 docker 命令行可以设置如下别名:


alias docker='k3s crictl'
# 配置docker命令补全source <(docker completion)complete -F _cli_bash_autocomplete docker
复制代码


通过docker ps查看运行的容器:



# docker psCONTAINER IMAGE CREATED STATE NAME ATTEMPT POD IDdeedde06105b5 8fafd8af70e9a 6 minutes ago Running kubernetes-bootcamp-v1 0 b59bdf9ed7b2a5464873f8064a 8fafd8af70e9a 6 minutes ago Running kubernetes-bootcamp-v1 0 51d2058a38262d8ae5df73ee95 aa764f7db3051 About an hour ago Running traefik 0 a7990965f71c31ecdf0ce98ebf 897ce3c5fc8ff About an hour ago Running lb-port-443 0 4057796b8eddd021a4d7bcc391 897ce3c5fc8ff About an hour ago Running lb-port-80 0 4057796b8eddd089ee47dd3de0 c4d3d16fe508b About an hour ago Running coredns 0 5e54975c3ae1e3c97b40b9beed 9d12f9848b99f About an hour ago Running local-path-provisioner 0 5a4e666f9c8f7ac020ab1621c0 9dd718864ce61 About an hour ago Running metrics-server 0 f69f6812b7a66
复制代码


当然我们只是使用crictl模拟了docker命令,相对真正的docker我们发现多了ATTEMPT以及POD ID,这是 CRI 所特有的。

3.2 和使用 k8s 一样创建 k3s 资源

我们使用 k8s 最喜欢拿来入门的bootcamp作为例子,Deployment 声明如下:


apiVersion: apps/v1kind: Deploymentmetadata:  labels:    app: kubernetes-bootcamp-v1  name: kubernetes-bootcamp-v1spec:  replicas: 2  selector:    matchLabels:      app: kubernetes-bootcamp-v1  template:    metadata:      labels:        app: kubernetes-bootcamp-v1    spec:      containers:      - image: jocatalin/kubernetes-bootcamp:v1        name: kubernetes-bootcamp-v1
复制代码


使用kubectl apply创建 Deployment 资源:


# kubectl  apply -f kubernetes-bootcamp-v1.yamldeployment.apps/kubernetes-bootcamp-v1 created# kubectl  get podNAME                                     READY   STATUS        RESTARTS   AGEkubernetes-bootcamp-v1-c5ccf9784-m79vt   1/1     Running       0          3skubernetes-bootcamp-v1-c5ccf9784-5blct   1/1     Running       0          3s
复制代码


创建 Service:


# kubectl apply -f -apiVersion: v1kind: Servicemetadata:  labels:    app: kubernetes-bootcamp-v1  name: kubernetes-bootcamp-v1spec:  ports:  - port: 8080    protocol: TCP    targetPort: 8080  selector:    app: kubernetes-bootcamp-v1  type: ClusterIP# kubectl  get serviceNAME                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGEkubernetes               ClusterIP   10.43.0.1      <none>        443/TCP    29mkubernetes-bootcamp-v1   ClusterIP   10.43.132.97   <none>        8080/TCP   8m14s# curl 10.43.132.97:8080Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-v1-c5ccf9784-5blct | v=1
复制代码


我们不需要再单独安装其他 ingress controller,因为 k3s 已经内置了 Traefik,直接创建 Ingress:


# kubectl apply -f -apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: "int32bit-test-ingress"  labels:    app: int32bit-test-ingressspec:  rules:    - host: test.int32bit.me      http:        paths:        - path: /v1          backend:            serviceName: "kubernetes-bootcamp-v1"            servicePort: 8080# kubectl  get ingress int32bit-test-ingressNAME                    HOSTS              ADDRESS           PORTS   AGEint32bit-test-ingress   test.int32bit.me   192.168.193.197   80      5m54s
复制代码


其中192.168.193.197为 master 节点的 IP,由于我们没有 DNS 解析,因此可以通过配置/etc/hosts文件进行静态配置:


192.168.193.197 test.int32bit.me
复制代码


此时我们就可以直接通过 ingress 地址 test.int32bit.me 访问我们的服务了,ingress 直接通过ClusterIP转发,不需要NodePort


# curl http://test.int32bit.me/v1Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-v1-c5ccf9784-5blct | v=1
复制代码


我们发现 k3s 和 k8s 的 Resource 声明完全兼容,没有任何区别。

4 k3s 网络

4.1 CNI 网络

k3s 内置了 Flannel 网络插件,默认使用 VXLAN 后端,默认 IP 段为10.42.0.0/16


# ip -o -d link show flannel.114: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8951 \    qdisc noqueue state UNKNOWN mode DEFAULT group default \    link/ether 46:61:15:1f:1e:3f brd ff:ff:ff:ff:ff:ff promiscuity 0 \    vxlan id 1 local 192.168.193.197 dev ens5 \    srcport 0 0 dstport 8472 nolearning ttl inherit ageing 300 \    udpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 \    numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
复制代码


内置的 Flannel 除了 VXLAN 还支持 ipsec、host-gw 以及 wireguard。


当然除了默认的 Flannel,k3s 还支持其他 CNI,如 Canal、Calico 等。

4.2 其他网络组件

k3s 除了内置 Flannel 网络插件以外,还内置了 CoreDNS、Traefik Ingress Controller、Service Load Balancer,如果不使用默认的组件,用户也可以自己部署其他组件,比如使用 MetalLB 替代内置的 load balancer。

5 k3s 存储

5.1 内置本地存储插件

k3s 删除了 k8s 内置 cloud provider 以及 storage 插件(当然这不会影响使用通过手动安装的外部插件),内置了 Local Path Provider。


比如我们创建一个 2G 的 PVC:


# kubectl apply -f -apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: local-path-pvc  namespace: defaultspec:  accessModes:    - ReadWriteOnce  storageClassName: local-path  resources:    requests:      storage: 2Gi
复制代码


创建一个 Pod 使用新创建的 PVC:


# kubectl apply -f -apiVersion: v1kind: Podmetadata:  name: volume-testspec:  containers:  - name: volume-test    image: jocatalin/kubernetes-bootcamp:v1    volumeMounts:    - name: volv      mountPath: /data  volumes:  - name: volv    persistentVolumeClaim:      claimName: local-path-pvc
复制代码


查看创建的 Pod 以及 PVC:


# kubectl get pod volume-testNAME          READY   STATUS    RESTARTS   AGEvolume-test   1/1     Running   0          116s# kubectl get pvcNAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGElocal-path-pvc   Bound    pvc-6bd15859-540f-4ade-94dc-821e29cacdba   2Gi        RWO            local-path     4m8s# kubectl get pvNAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGEpvc-6bd15859-540f-4ade-94dc-821e29cacdba   2Gi        RWO            Delete           Bound    default/local-path-pvc   local-path              106s
复制代码


查看 PV:


# kubectl describe  pvName:              pvc-6bd15859-540f-4ade-94dc-821e29cacdbaLabels:            <none>Annotations:       pv.kubernetes.io/provisioned-by: rancher.io/local-pathFinalizers:        [kubernetes.io/pv-protection]StorageClass:      local-pathStatus:            BoundClaim:             default/local-path-pvcReclaim Policy:    DeleteAccess Modes:      RWOVolumeMode:        FilesystemCapacity:          2GiNode Affinity:  Required Terms:    Term 0:        kubernetes.io/hostname in [ip-192-168-193-197]Message:Source:    Type:          HostPath (bare host directory volume)    Path:          /var/lib/rancher/k3s/storage/pvc-6bd15859-540f-4ade-94dc-821e29cacdba    HostPathType:  DirectoryOrCreateEvents:            <none>
复制代码


可见其实就类似 k8s 的 HostPath 存储卷类型。

5.2 使用外部存储 Longhorn

前面提到的内置 local path 存储,只能单机使用,不支持跨主机使用,也不支持存储的高可用。


可以通过使用外部的存储插件解决 k3s 存储问题,比如 Longhorn[2]


Longhorn 是专门针对 Kubernetes 设计开发的云原生分布式块存储系统,可以直接使用kubectl apply或者helm安装:


kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml
复制代码


为了能够访问 Longhorn Dashboard,我创建如下 ingress:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: "longhorn-ui"  namespace: longhorn-system  labels:    app: longhorn-uispec:  rules:    - host: longhorn-frontend.int32bit.me      http:        paths:        - path: /          backend:            serviceName: "longhorn-frontend"            servicePort: 80    - host: longhorn-backend.int32bit.me      http:        paths:        - path: /          backend:            serviceName: "longhorn-backend"            servicePort: 9500
复制代码


通过http://longhorn-frontend.int32bit.me/dashboard即可访问 Dashboard:



longhorn


安装 Longhorn storageclass:


kubectl create -f \https://raw.githubusercontent.com/longhorn/longhorn/master/examples/storageclass.yaml
复制代码


创建 PVC:


# kubectl apply -f -apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: longhorn-volv-pvcspec:  accessModes:    - ReadWriteOnce  storageClassName: longhorn  resources:    requests:      storage: 2Gi
复制代码


创建 Pod 使用新创建的 PVC:


# kubectl apply -f -apiVersion: v1kind: Podmetadata:  name: test-volume-longhornspec:  containers:  - name: test-volume-longhorn    image: jocatalin/kubernetes-bootcamp:v1    volumeMounts:    - name: volv      mountPath: /data  volumes:  - name: volv    persistentVolumeClaim:      claimName: longhorn-volv-pvc
复制代码


通过 Longhorn Dashboard 查看 volume:



longhorn-pvc


可见 PV 已经挂载到 Pod test-volume-longhorn中。

6 加上 k9s,全了

最后,附上 k9s,这样 k3s、k8s、k9s 全了 : )


https://github.com/derailed/k9s/releases/download/v0.19.0/k9s_Linux_x86_64.tar.gztar xvzf k9s_Linux_x86_64.tar.gzmv k9s /usr/local/bin/kubectl-k9s
复制代码



k9s

写在最后

k3s 在去年的 2 月就已经推出并开源,现在不算是新东西,周末正好没啥事于是安装体验下,主要还是想使用下 mdnice[3] 体验下公众号文章排版效果。


使用后一次后发现,mdnice 真的是特别适合技术类公众号文章编辑:


  • Markdown 语法,支持在线编辑,写完后即排版成功,复制即可粘贴到微信公众号;

  • 支持零配置图床、脚注、代码、公式;

  • 内置 18 种风格主题,支持自定义 CSS 样式;

  • 内容在浏览器中实时保存;

  • 支持 chrome 插件,可直接在微信公众平台上编辑。


尤其是代码块,代码高亮和滚屏是刚需。目前很多公众号编辑器支持得都不是很好,比如秀米就对代码块的支持效果非常不好。而 midnice 直接使用 Markdown 语法嵌入代码块,并且支持 Atom、Monokai、github、vs2015、xcode 等多种代码风格。

参考资料

[1] k3s: https://rancher.com/docs/k3s/latest/en/


[2] Longhorn: https://github.com/longhorn/longhorn


[3] mdnice: https://docs.mdnice.com/#/


本文转载自公众号 int32bit(ID:int32bit)。


原文链接


https://mp.weixin.qq.com/s/gtw6k-jmtatlk8LSkMzGiA


2020-04-12 14:1314137

评论

发布
暂无评论
发现更多内容

【JVM故障问题排查心得】「内存诊断系列」JVM内存与Kubernetes中pod的内存、容器的内存不一致所引发的OOMKilled问题总结(上)

洛神灬殇

Docker Kubernetes 容器 JVM 12月日更

Java递归实现评论多级回复

Jeremy Lai

递归 解决方案

Centos7安装Nginx教程,一步安装http和https

Jeremy Lai

nginx Linux安装

meta force原力元宇宙魔豹联盟矩阵公排dapp系统开发源代码

开发微hkkf5566

云原生大数据平台零信任网络安全实践技术稿

星环科技

【JVM故障问题排查心得】「内存诊断系列」JVM内存与Kubernetes中pod的内存、容器的内存不一致所引发的OOMKilled问题总结(下)

洛神灬殇

JVM 12月日更 堆外内存 内存干扰

Zebec节点Zepoch销量接近800个,生态发展信心十足

EOSdreamer111

React 之 createElement 源码解读

冴羽

JavaScript 前端 前端框架 React react源码

模拟HashMap冲突

Jeremy Lai

hashmap 哈希冲突

SpringBoot快速整合通用Mapper

Jeremy Lai

通用Mapper spring-boot

将 Vue.js 项目部署至静态网站托管,并开启 Gzip 压缩

华为云开发者联盟

开发 华为云 12 月 PK 榜

阿里云ECS后台CPU占用100%,top却找不到

Jeremy Lai

cpu 100% 阿里云;

手把手教你用Java获取IP归属地

Jeremy Lai

IP地址

详解HashMap源码解析(上)

Jeremy Lai

HashMap底层原理

深入理解Redis 数据结构—字典

Jeremy Lai

字典 redis 底层原理

刷新AI作图速度,最快开源Stable Diffusion出炉

OneFlow

人工智能 深度学习 前沿技术

瓴羊Quick BI带给企业新发展,企业数字营销和运营变得格外简单

对不起该用户已成仙‖

详解ConCurrentHashMap源码(jdk1.8)

Jeremy Lai

ConcurrentHashMap 源码阅读

MySQL更新锁表超时 Lock wait timeout exceeded

Jeremy Lai

事务隔离 Mysql死锁

【0.1mm钻孔】揭秘激光钻孔加工常见的4种方法

华秋PCB

工艺 PCB PCB设计 钻孔

详解HashMap源码解析(下)

Jeremy Lai

HashMap底层原理

Java通过反射注解赋值

Jeremy Lai

解决问题 java注解

SpringBoot整合RabbitMQ实现六种工作模式

Jeremy Lai

spring-boot Rabbit MQ

字节一面:说说TCP的三次握手

Jeremy Lai

三次握手 TCP协议

小程序正式版报错600002 url not in domain list

Jeremy Lai

小程序

【JUC】循环屏障CyclicBarrier详解

JAVA旭阳

Java 并发 JUC

SAP MM 使用两个STO实现免关税跨国公司间转储(II)

SAP虾客

SAP MM PO输出 NACE

零售品牌如何挑选达人KOL?火山引擎VeDI有妙招!

字节跳动数据平台

大数据 营销 营销数字化 12 月 PK 榜

Zebec节点Zepoch销量接近800个,生态发展信心十足

股市老人

五种方式实现 Java 单例模式

Jeremy Lai

设计模式 单例模式

详解MySQL隔离级别

Jeremy Lai

隔离级别

轻量级Kubernetes k3s初探_开源_付广平_InfoQ精选文章