内容简介:Docker 在生产环境的部署方案,目前的最优解显然是 Kubernetes 了,Kubernetes (下称 K8s)提供了非常完备的功能,几乎能覆盖所有能想到的运维场景,这点无需多言。唯独对于流量不大,对于机器资源要求比较严苛的小项目,K8s 就显得不那么友好了: 一套而在实际项目中,往往有一些新想法要试水,或者临时上线一些非常简单的页面,为此单独部署一套 K8s 高可用 5 节点集群显然是浪费的。将其随便塞进一个已经在运行的不相干的集群,也是对运维秩序的扰乱。所以比较折中的做法是牺牲高可用性,基于 1
-
-
基于 minikube 在 VPS 快速部署单节点 Kubernetes*
- 1. 安装 Docker Engine
- 解决 CoreDNS Forwarding loop 问题
- minikube 不使用虚拟机的注意点
- 基于 microk8s 在 VPS 快速部署单节点 Kubernetes
- 使用 kubeadm 部署单节点 Kubernetes
- Kubernetes 单节点部署方式对比
-
基于 minikube 在 VPS 快速部署单节点 Kubernetes*
Docker 在生产环境的部署方案,目前的最优解显然是 Kubernetes 了,Kubernetes (下称 K8s)提供了非常完备的功能,几乎能覆盖所有能想到的运维场景,这点无需多言。
唯独对于流量不大,对于机器资源要求比较严苛的小项目,K8s 就显得不那么友好了: 一套 高可用的 K8s 集群 ,至少需要 3 个 Master 节点,Worker 节点虽然没有明确要求,但至少 2 个 Worker 节点显然是比较恰当的。也就是说哪怕只是一个静态的 html 页面,K8s 也至少需要 4-5 台主机。
而在实际项目中,往往有一些新想法要试水,或者临时上线一些非常简单的页面,为此单独部署一套 K8s 高可用 5 节点集群显然是浪费的。将其随便塞进一个已经在运行的不相干的集群,也是对运维秩序的扰乱。所以比较折中的做法是牺牲高可用性,基于 1 台低配置的 VPS 或虚拟主机,部署一套 K8s 单节点环境。
当然也可以不用 K8s,直接通过命令行或 docker-compose 操作 Docker 也能实现同样目的。这里非要死磕 K8s 主要基于 3 个原因:
- 其一是统一运维的基础设施,如果同一个运维团队里,同时存在 K8s、Docker Swarm、 Shell 脚本等多种运维工具,维护起来难免顾此失彼,容易产生问题,也不利于技术积累。
- 其二是基于 K8s 可以快速水平扩展,特别是一个新想法上线如果短期内获得了不错的反应,流量会有快速的增长,基于 K8s 的配置可以在数分钟内从单机扩展到上百台机器的集群。
- 其三是可以使用成熟的 K8s 部署策略,即便是单节点,仍然可以通过简单配置就实现 滚动更新(RollingUpdate) 、回滚等。同时还可以有 K8s dashboard 这样好用的 UI 界面,而其他方案则要自己实现这些,并不划算。
当然单节点部署 K8s 也需要付出代价,由于单节点既充当了 Master 节点,又是 Worker 节点,会有额外的 CPU 和内存消耗。实测 2 核 4G 的机器,裸 K8s 会额外占用掉 0.2~0.5 核左右的 CPU 资源和 600 MB 左右内存资源,建议单节点机器至少也应该有 2 核 4G 及以上规格。
以下以 Linode 4GB Plan 为例,记录单节点 K8s 的部署过程。
基于 minikube 在 VPS 快速部署单节点 Kubernetes
minikube 原本是用于在开发环境快速安装 K8s 的工具,由于 Docker 需要系统为 Linux 且内核支持 LXC ,因此在 Windows、macOS 下目前都是通过虚拟机来实现 Docker 的安装及运行的。而 Minikube 支持 Windows、macOS、Linux 三种 OS,会根据平台不同,下载对应的虚拟机镜像,并在镜像内安装 k8s。
目前的虚拟机技术都是基于 Hypervisor
来实现的,Hypervisor 规定了统一的虚拟层接口,由此 Minikube 就可以无缝切换不同的虚拟机实现,如 macOS 可以切换 hyperkit
或 VirtualBox, Windows 下可以切换 Hyper-V
或 VirtualBox 等。虚拟机的切换可以通过 --vm-driver
实现,如
minikube start --vm-driver hyperkit minikube start --vm-driver hyperv
如果 Minikube 安装在内核原生就支持 LXC 的 OS 内,如 Ubuntu 等,再安装一次虚拟机显然就是对资源的浪费了,Minikube 提供了直接对接 OS 底层的方式
minikube start --vm-driver=none
因此在 VPS 上,可以借助 Minikube,快速安装 K8s 环境,同时又最大限度的使用 OS 系统资源。
OS 以 Ubuntu 18.04 为例
1. 安装 Docker Engine
由于 minikube 限制 ,必须安装版本不高于 v18.09 的 Docker (截止 2019 年 2 月 19 日)
可以用 apt-cache policy docker-ce
查看可以安装的 Docker 版本, 这里我们选择 18.06.2
apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && \ add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \ apt-get update && apt-get install docker-ce=18.06.2~ce~3-0~ubuntu
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo cp minikube /usr/local/bin/ && rm minikube export MINIKUBE_WANTUPDATENOTIFICATION=false export MINIKUBE_WANTREPORTERRORPROMPT=false export MINIKUBE_HOME=$HOME export CHANGE_MINIKUBE_NONE_USER=true mkdir -p $HOME/.minikube
minikube start --vm-driver=none
如果一切顺利,可以看到 minikube 将下载并安装 kubeadm kubelet 等必要组件,最后按照 minikube 的提示, 安装 kubectl
sudo apt-get update && sudo apt-get install -y apt-transport-https curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubectl
之后就可以通过 kubectl get pods -n kube-system
查看容器的运行情况了
为了方便操作,建议配置 kubectl 的指令补全, 并将命名空间切换至 kube-system, 后文指令都将忽略命名空间 kube-system
。
kubectl completion bash >> ~/.bashrc source ~/.bashrc kubectl config set-context minikube --namespace=kube-system
解决 CoreDNS Forwarding loop 问题
在我的 VPS 上完成上述安装后, 可以看到 CoreDNS 服务并没有完成启动
# kubectl get pods NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-86c58d9df4-jjhwl 0/1 CrashLoopBackOff 5 3m59s kube-system coredns-86c58d9df4-zzj4m 0/1 CrashLoopBackOff 5 3m59s
通过查看日志可以看到 CoreDNS 服务检测到了循环 DNS 查询
# kubectl logs coredns-86c58d9df4-jjhwl [FATAL] plugin/loop: Forwarding loop detected in "." zone. Exiting. See https://coredns.io/plugins/loop#troubleshooting. Probe query: "HINFO 6451342721392587444.9147583119172762210.".
这一问题在 Ubuntu 上非常容易遭遇,是因为 Ubuntu 使用 systemd-resolved 作为 DNS 解析器,当网络状态变化时,systemd-resolved 有可能将 127.0.0.53
作为域名服务器写入 /etc/resolv.conf
,而 CoreDNS 默认又会读取宿主机上 systemd-resolved 所使用的文件,造成死循环。
解决这个问题的一种方法是在启动 minikube 时直接指定 resolv.conf
文件位置, 如
minikube --vm-driver=none start --extra-config=kubelet.resolv-conf=/run/systemd/resolve/resolv.conf
如果启动 minikube 后产生了这个问题,则可以删除 resolv.conf
软链接, 自己生成一个 resolv.conf
,当 systemd-resolved 检测到 /etc/resolv.conf
不是软链接后,就不会再覆盖这个文件。
rm /etc/resolv.conf && echo "nameserver 114.114.114.114" > /etc/resolv.conf kubectl delete pods -n kube-system --selector k8s-app=kube-dns
也可以将 /etc/resolv.conf
指向主机商提供的 DNS 解析文件。
rm /etc/resolv.conf && cp /run/systemd/resolve/resolv.conf /etc/resolv.conf kubectl delete pods -n kube-system --selector k8s-app=kube-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
minikube 虽然是官方出品,但主要还是基于虚拟机做的设计。在 Linux 生产环境下, microk8s 可能是一个更合适的选择。
microk8s 基于 snap 进行安装,ubuntu 16.04 及之后的版本都已经预装了 snap,如果是其他发行版的 Linux 需要先 安装 snap 。 安装前 microk8s 可以通过
snap info microk8s
了解可安装版本和操作指令等信息。
microk8s 的独特之处在于直接包含了 Kubernetes 单节点必须的如 kubectl
, kubelet
等所有工具,甚至直接包含了 docker。因此在一台裸机上运行
snap install microk8s --classic
之后,就可以在进程里看到 /snap/microk8s
为前缀的一系列熟悉的进程, 并且这些进程直接运行在主机,并未使用容器,k8s 也没有使用默认的端口 6443
,而改用 8080
。这样做带来的一个好处是即便系统之前已经安装了 kubectl
, docker
等,也可以进行安装,不会冲突;不过就不能用 kubectl
、 docker
直接进行操作, 而需要使用 microk8s.docker
, microk8s.kubectl
等, 与原来的指令是完全一样的。
安装完成后可以通过 microk8s.status
查看运行状态及插件的开启情况。也可以用 microk8s.inspect
查看已经安装的服务。
通常来说安装了 microk8s 后,我们也不会再次安装 kubectl
, 为了操作方面,可以为 microk8s.kubectl
开启设置 kubectl
为别名, 并开启输入补全。
snap alias microk8s.kubectl kubectl source <(microk8s.kubectl completion bash)
也可以随时取消别名。
snap unalias kubectl
和 minikube 相同,microk8s 默认只安装最核心的功能,可以通过 microk8s.enable dns dashboard
等开启附加的插件。
如果在 microk8s 上部署一些需要高权限的应用时,可能会报 spec.template.spec.containers[0].securityContext.privileged: Forbidden: disallowed by cluster policy
,此时可以
echo "--allow-privileged=true" >> /var/snap/microk8s/current/args/kubelet echo "--allow-privileged=true" >> /var/snap/microk8s/current/args/kube-apiserver systemctl restart snap.microk8s.daemon-kubelet.service systemctl restart snap.microk8s.daemon-apiserver.service
使用 kubeadm 部署单节点 Kubernetes
通过 minikube 或 microk8s 安装 K8s 虽然方便,但是由于很多安装细节被屏蔽,直接用在生产环境也难免让人心存疑虑,那么也可以 使用 kubeadm 部署单节点 kubernetes 。
同样以 Ubuntu18.04 为例, 首先 安装 Docker v18.06.2 后
(K8s 同样对 Docker 版本有要求),参考官方文档, 可以使用 apt-get
直接安装 kubelet
, kubeadm
, kubectl
, 并且限制这些服务不能自动升级。
apt-get update && apt-get install -y apt-transport-https curl curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - cat <<EOF >/etc/apt/sources.list.d/kubernetes.list deb https://apt.kubernetes.io/ kubernetes-xenial main EOF apt-get update apt-get install -y kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl
接下来关闭 swap,这应该是为了 避免 swap 对 CPU 和内存的 limit 造成意外影响 。
swapoff -a
然后运行
kubeadm init --pod-network-cidr=10.244.0.0/16
就会开始 Kubernetes master 节点的安装。安装完成后 CoreDNS 是处于 Pending
状态的,这是由于网络插件尚未安装,Kubernetes 使用 CNI
作为容器网络的接口,因此可以根据主机实际情况选择不同的 CNI 实现,这里以比较流行的 flannel
为例。
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
之后可以看到 CoreDNS 的状态从 Pending
变为 Running
。至此 K8s 的 master 节点所需服务就已经安装完毕。可以参考安装后的提示,配置 kubectl
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
现在尝试部署一个 pod
kubectl run --rm --restart=Never -it --image=hello-world test-pod
发现 pod 状态卡在 Pending
,查看 pod 信息看到如下报错
$ kubectl describe pod test-pod 0/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate.
这是由于 K8s 默认禁止在 master 节点部署 pod,可以使用以下指令取消这一限制。
kubectl taint nodes --all node-role.kubernetes.io/master-
之后可以看到 pod 状态已经变为 Completed
Kubernetes 单节点部署方式对比
至此我们分别用 minikube、microk8s、kubeadm 3 种方式完成了单节点 k8s 的部署。从安装的服务来看,k8s 单节点必要的服务包括:
- 容器运行时: 默认是 Docker
- etcd: key-value 存储服务,用于保存集群的状态
- kube-apiserver: 集群资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制
- kube-controller-manager: 维护集群的状态,比如故障检测、自动扩展、滚动更新等
- kube-scheduler: 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上
- kubelet: 负责维持容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理
- kube-proxy: 负责为 Service 提供 cluster 内部的服务发现和负载均衡
三者差异之处在于:
storage-provisioner
从易用角度来看,microk8s 是安装最简单,门槛最低的;minikube 适合对 minikube 比较熟悉的用户。
无论以何种方式安装 k8s, 都需要注意安全问题, 因为在 k8s 的设计中, Master 节点是不会暴露到外网的,用户服务都会安装到 Worker 节点,但是在单节点的情况下,k8s 所监听的端口都没有设防,容器的权限也有可能过大,这些 安全问题在 minikube 的文档中也有提到 , 需要对网络端口设置 iptables 限制可访问的 IP 等方式来提升安全性,如果是安全性敏感的项目,建议放弃单节点 k8s 的方案。
References:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- VPS 单节点部署 Kubernetes 的方法与对比——让穷人也能用得起 Kubernetes
- 穷人的LoadBalancer
- xml创建节点(根节点、子节点)
- Vultr VPS 节点选择方法 | 各节点延迟一览
- 1.19 JQuery2:节点插入与节点选取
- POC分布式节点算法机制下的超级节点计划
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
开发高质量PHP框架与应用的实际案例解析
Sebastian Bergmann / 刘文瀚、刘海燕 / 清华大学出版社 / 2012-6 / 49.00元
PHP已经成为最受欢迎的编程语言之一,这使得用PHP创建高质量、易维护的应用程序和框架比以往受到更多的青睐。通过使用来自于知名公司的真实案例研究,《开发高质量PHP框架与应用的实际案例解析》为Web软件体系结构的不同层次介绍了规划、执行以及测试自动化方面的内容,并解释了这些公司如何测量和测试软件质量。《开发高质量PHP框架与应用的实际案例解析》作者Sebastian Bergmann、Stefan......一起来看看 《开发高质量PHP框架与应用的实际案例解析》 这本书的介绍吧!