VPS 单节点部署 Kubernetes 的方法与对比
徐贝 分布式实验室
Docker 在生产环境的部署方案,目前的最优解显然是 Kubernetes 了,Kubernetes 提供了非常完备的功能,几乎能覆盖所有能想到的运维场景,这点无需多言。
唯独对于流量不大,对于机器资源要求比较严苛的小项目,Kubernetes 就显得不那么友好了:一套高可用的 Kubernetes 集群,至少需要 3 个 Master 节点,Worker 节点虽然没有明确要求,但至少 2 个 Worker 节点显然是比较恰当的。也就是说哪怕只是一个静态的 html 页面,Kubernetes 也至少需要 4-5 台主机。
而在实际项目中,往往有一些新想法要试水,或者临时上线一些非常简单的页面,为此单独部署一套 Kubernetes 高可用 5 节点集群显然是浪费的。将其随便塞进一个已经在运行的不相干的集群,也是对运维秩序的扰乱。所以比较折中的做法是牺牲高可用性,基于 1 台低配置的 VPS 或虚拟主机,部署一套 Kubernetes 单节点环境。
当然也可以不用 Kubernetes,直接通过命令行或 docker-compose 操作 Docker 也能实现同样目的。这里非要死磕 Kubernetes 主要基于 3 个原因:
其一是统一运维的基础设施,如果同一个运维团队里,同时存在 Kubernetes、Docker Swarm、Shell 脚本等多种运维工具,维护起来难免顾此失彼,容易产生问题,也不利于技术积累。
其二是基于 Kubernetes 可以快速水平扩展,特别是一个新想法上线如果短期内获得了不错的反应,流量会有快速的增长,基于 Kubernetes 的配置可以在数分钟内从单机扩展到上百台机器的集群。
其三是可以使用成熟的 Kubernetes 部署策略,即便是单节点,仍然可以通过简单配置就实现滚动更新(RollingUpdate)、回滚等。同时还可以有 Kubernetes Dashboard 这样好用的 UI 界面,而其他方案则要自己实现这些,并不划算。
以下以 Linode 4GB Plan 为例,记录单节点 Kubernetes 的部署过程。
基于 Minikube 在 VPS 快速部署单节点 Kubernetes
目前的虚拟机技术都是基于 Hypervisor来实现的,Hypervisor 规定了统一的虚拟层接口,由此 Minikube 就可以无缝切换不同的虚拟机实现,如 macOS 可以切换 Hyperkit 或 VirtualBox, Windows 下可以切换 Hyper-V 或 VirtualBox 等。虚拟机的切换可以通过 --vm-driver 实现,如:
minikube start --vm-driver hyperkitminikube start --vm-driver hyperv
如果 Minikube 安装在内核原生就支持 LXC 的 OS 内,如 Ubuntu 等,再安装一次虚拟机显然就是对资源的浪费了,Minikube 提供了直接对接 OS 底层的方式:
因此在 VPS 上,可以借助 Minikube,快速安装 Kubernetes 环境,同时又最大限度的使用 OS 系统资源。
OS 以 Ubuntu 18.04 为例。
1、安装 Docker Engine
由于 Minikube 限制,必须安装版本不高于 v18.09 的 Docker (截止 2019 年 2 月 19 日)。
可以用 apt-cache policy docker-ce 查看可以安装的 Docker 版本, 这里我们选择 18.06.2。
2、安装 Minikube
3、启动 Minikube
如果一切顺利,可以看到 Minikube 将下载并安装 kubeadm kubelet 等必要组件,最后按照 Minikube 的提示,安装 kubectl:
之后就可以通过 kubectlgetpods-n kube-system 查看容器的运行情况了。
为了方便操作,建议配置 kubectl 的指令补全, 并将命名空间切换至 kube-system, 后文指令都将忽略命名空间 kube-system。
解决 CoreDNS Forwarding loop 问题
在我的 VPS 上完成上述安装后, 可以看到 CoreDNS 服务并没有完成启动:
通过查看日志可以看到 CoreDNS 服务检测到了循环 DNS 查询
这一问题在 Ubuntu 上非常容易遭遇,是因为 Ubuntu 使用 systemd-resolved 作为 DNS 解析器,当网络状态变化时,systemd-resolved 有可能将 127.0.0.53 作为域名服务器写入 /etc/resolv.conf,而 CoreDNS 默认又会读取宿主机上 systemd-resolved 所使用的文件,造成死循环。
解决这个问题的一种方法是在启动 Minikube 时直接指定 resolv.conf 文件位置, 如:
如果启动 Minikube 后产生了这个问题,则可以删除resolv.conf软链接, 自己生成一个resolv.conf,当 systemd-resolved 检测到 /etc/resolv.conf 不是软链接后,就不会再覆盖这个文件。
也可以将 /etc/resolv.conf 指向主机商提供的 DNS 解析文件。
Minikube 不使用虚拟机的注意点
由于 Minikube 主要设计是基于虚拟机安装的,vm-driver=none 也会带来一些影响,主要包括:
Minikube 在安装时将覆盖主机原有的 /usr/local/bin/kubeadm,/usr/local/bin/kubectl,/etc/kubernetes 等目录
无法在一台主机上使用 vm-driver=none 安装 2 个 minikube
minikube dashboard,minikube mount,minikube ssh 等基于虚拟机的指令均无法使用
minikube delete 将删除 /etc/kubernetes 目录
基于 MicroK8s 在 VPS 快速部署单节点 Kubernetes
MicroK8s 基于 Snap 进行安装,Ubuntu 16.04 及之后的版本都已经预装了 Snap,如果是其他发行版的 Linux 需要先安装 Snap。 安装前 MicroK8s 可以通过:
snap info microk8s
了解可安装版本和操作指令等信息。
MicroK8s 的独特之处在于直接包含了 Kubernetes 单节点必须的如 kubectl,kubelet 等所有工具,甚至直接包含了 Docker。因此在一台裸机上运行:
之后,就可以在进程里看到 /snap/microk8s 为前缀的一系列熟悉的进程, 并且这些进程直接运行在主机,并未使用容器,Kubernetes 也没有使用默认的端口 6443,而改用 8080。这样做带来的一个好处是即便系统之前已经安装了kubectl,Docker 等,也可以进行安装,不会冲突;不过就不能用 kubectl、 Docker直接进行操作, 而需要使用 microk8s.docker,microk8s.kubectl 等, 与原来的指令是完全一样的。
安装完成后可以通过 microk8s.status 查看运行状态及插件的开启情况。也可以用 microk8s.inspect 查看已经安装的服务。
通常来说安装了 MicroK8s 后,我们也不会再次安装 kubectl, 为了操作方面,可以为 microk8s.kubectl 开启设置 kubectl 为别名, 并开启输入补全。
也可以随时取消别名。
和 Minikube 相同,MicroK8s 默认只安装最核心的功能,可以通过 microk8s.enable dns dashboard 等开启附加的插件。
使用 Kubeadm 部署单节点 Kubernetes
同样以 Ubuntu18.04 为例, 首先安装 Docker v18.06.2 后 (Kubernetes 同样对 Docker 版本有要求),参考官方文档, 可以使用 apt-get 直接安装 kubelet,kubeadm,kubectl,并且限制这些服务不能自动升级。
apt-get update && apt-get install -y apt-transport-https curlcurl -s https:///apt/doc/apt-key.gpg | apt-key add -cat <<EOF >/etc/apt/sources.list.d/kubernetes.listdeb https://apt.kubernetes.io/ kubernetes-xenial mainEOFapt-get updateapt-get install -y kubelet kubeadm kubectlapt-mark hold kubelet kubeadm kubectl
接下来关闭 Swap,这应该是为了避免 Swap 对 CPU 和内存的Llimit 造成意外影响。
然后运行:
就会开始 Kubernetes Master 节点的安装。安装完成后 CoreDNS 是处于 Pending 状态的,这是由于网络插件尚未安装,Kubernetes 使用 CNI 作为容器网络的接口,因此可以根据主机实际情况选择不同的 CNI 实现,这里以比较流行的 Flannel 为例。
之后可以看到 CoreDNS 的状态从 Pending 变为 Running。至此 Kubernetes 的 Master 节点所需服务就已经安装完毕。可以参考安装后的提示,配置 kubectl:
现在尝试部署一个 Pod:
发现 Pod 状态卡在 Pending,查看 Pod 信息看到如下报错:
这是由于 Kubernetes 默认禁止在 Master 节点部署 Pod,可以使用以下指令取消这一限制。
之后可以看到 Pod 状态已经变为 Completed。
Kubernetes 单节点部署方式对比
容器运行时:默认是 Docker
etcd:key-value 存储服务,用于保存集群的状态
kube-apiserver:集群资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制
kube-controller-manager:维护集群的状态,比如故障检测、自动扩展、滚动更新等
kube-scheduler:负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上
kubelet:负责维持容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理
kube-proxy:负责为 Service 提供 Cluster 内部的服务发现和负载均衡
MicroK8s 部署 Kubernetes 是直接安装到主机而不是以容器方式安装
MicroK8s 虽然默认没有安装 DNS 服务,但通常情况下为了使用服务发现,还是需要安装的,MicroK8s 默认的 DNS 服务是 Kube-Dns,而不是目前官方推荐的 CoreDNS 。
网络插件 Kubeadm 需要自己选择, MicroK8s 和 Minikube 都会自己安装
Minikube 默认额外安装了 storage-provisioner 用于虚拟机挂载磁盘 从易用角度来看,MicroK8s 是安装最简单,门槛最低的;Minikube 适合对 Minikube 比较熟悉的用户。
无论以何种方式安装 Kubernetes, 都需要注意安全问题, 因为在 Kubernetes 的设计中, Master 节点是不会暴露到外网的,用户服务都会安装到 Worker 节点,但是在单节点的情况下,Kubernetes 所监听的端口都没有设防,容器的权限也有可能过大,这些安全问题在 Minikube 的文档中也有提到, 需要对网络端口设置 iptables 限制可访问的 IP 等方式来提升安全性,如果是安全性敏感的项目,建议放弃单节点 Kubernetes 的方案。
原文链接:https:///pages/kubernetes-for-single-vps
如何在Windows 10上运行Docker和Kubernetes?kubernetes和docker区别
如何有效访问Kubernetes中的Pod | Kubernetes Pod管理与调试指南
使用 Kubernetes 在 Windows 10 上创建本地集群搭建kubernetes集群
Kubernetes管理windows和linux服务器 kubernetes windows应用
Kubernetes1.91(K8s)安装部署过程(二)--证书kubeconfig文件创建k8s 安装部署
深入了解 kubeblocks:管理与部署 Kubernetes 容器化应用的智能助理
全面解析kubelet-client-current.pem在Kubernetes中的重要性与管理
Kubeapps:简化Kubernetes应用管理的强大工具
解决Kubernetes中的 couldn't get resource list for metrics.k8s.io/v1beta1 错误的全面指南