背景

Kubernetes 是时下流行的容器编排引擎,因为字母太多,且掐头去尾后剩下 8 个字母,于是被大家亲切的缩写为 k8s。

Kubernetes https://kubernetes.io/

另外所谓“云原生”概念火爆,各大云厂商也纷纷推出了自己的容器服务,例如阿里云的ACK、腾讯云的TKE、微软云的AKS等,无不是基于 Kubernetes 。

阿里云ACK https://www.aliyun.com/product/kubernetes
腾讯云TKE https://cloud.tencent.com/product/tke
微软云AKS https://azure.microsoft.com/services/kubernetes-service/

由于我个人博客搭建在腾讯云上,大概是去年(2021年)11、12 月的时候萌生的“要不把博客搬到 k8s 上?”的想法。云厂商提供的容器服务一般都支持从原有云服务器转换为 Kubernetes 的 worker 节点;不过当然也有一些限制,例如腾讯云价格相对低廉的轻量应用服务器则不支持转换。不过正巧我的博客使用的是云服务器,那就试试腾讯云的 TKE 吧。

结果懒惰使人省钱,从学习到实战的脚步总是异常的缓慢,在此期间腾讯云发生了 2 件大事:

  1. 负载均衡实例升级调价公告
    https://cloud.tencent.com/document/product/214/59398

  2. 腾讯云容器服务于2022年3月21日10:00(北京时间)对托管集群计费通知
    https://cloud.tencent.com/document/product/457/68706

运行在 k8s 里的程序想要暴露到公网上,在云厂商的环境中最常用的就是通过负载均衡实现,腾讯云这一调价直接从原来的每小时 0.02 元涨到了 0.2 元,个人用户应该很少用这么贵的服务。(相较而言,阿里云则提供廉价版的负载均衡,个人用户的福音。)

另外彻底阻止我使用 TKE 的是,我们知道 k8s 集群需要有 master 和 worker 节点分工合作,云厂商会提供托管 master 节点的服务,用户只需要自己照料好 worker 节点即可。腾讯云也不例外,不过原来托管是免费的,即将要开始收费了!而不使用托管,意味着我必须再准备一台云服务器,又是一笔开销……

虽然上云等于花钱,但是贫穷就能阻止我们上云吗?答案是否定的,我们可以自己搭建 k8s 集群!甚至还能从中收获许多,如:

  • 复习了 k8s 网络相关的知识

  • 加深了对 ingress 的了解,ingress 是从容器外部访问容器内相对而言比较方便的手段

  • 折腾的快感和解决问题的喜悦

话虽如此,但强烈建议没有接触过 Kubernetes 的朋友们,先通过官方文档 和 minikube 在本地学习后,再继续深入。

ingress https://kubernetes.io/docs/concepts/services-networking/ingress/
官方文档 https://kubernetes.io/zh/docs/setup/
minikube https://minikube.sigs.k8s.io/docs/

我计划通过几篇文章来介绍:

  • k8s 集群的搭建(本篇)

  • 配置 ingress 通过域名访问容器内的站点

  • 使用 cert-manager 为站点自动生成和更新 HTTPS 证书

  • 使用 k8s 的本地卷 (local volume)

cert-manager https://cert-manager.io/
本地卷 https://kubernetes.io/docs/concepts/storage/volumes/#local

好了,废话说的太多,现在就开始进行 k8s 集群的搭建吧~

环境介绍

本文下面的操作都是在腾讯云里进行的,使用的是 1 台云服务器 CVM 和 1 台轻量应用服务器 TencentCloud Lighthouse 进行。(一般云厂商都会给新用户很大的优惠力度,特别是第一台云服务器和轻量应用服务器,意味着前 3 年可以以很低的成本体验。)

云服务器 CVM https://cloud.tencent.com/product/cvm
轻量应用服务器 TencentCloud Lighthouse https://cloud.tencent.com/product/lighthouse

我使用的具体配置和规划如下:

  • master 节点 bun-master-01,内网 IP 10.0.16.13/22:4C4G 轻量应用服务器(本来是2核的,前几天腾讯云免费升级…),master 节点是控制节点,管理其它的节点,以及运行 k8s 依赖的 etcd 等

  • worker 节点 bun-worker-01,内网 IP 172.17.0.2/20:4C8G 云服务器,未来应用程序就跑在这个节点上

操作系统都使用的是 Debian 11.1,上述机器都在同一地域。

Debian http://debian.org/

请注意,不应将这样的配置使用在生产环境,因为这不能保证可用性。不过自己玩儿的话,一台机器也可以(建议至少2C2G),将 master 和 worker 部署在同一机器内,但这么做会增加不稳定的因素,另外都上(hua)云(qian)了,新用户购买轻量应用服务器约等于不要钱,当然配置拉满整上。

当然,虽然你使用的可能不是腾讯云或者 Debian,但这并不是你继续阅读的障碍,因为云基础设施、Linux 命令都是类似的,下文在具体的地方会进行标注。

没有具体标明在哪台机器上进行的,则所有机器都需要进行这些步骤,例如内网配置、Debian 配置、安装 docker、kubeadm 等。

集群网络配置

请查看你使用的云厂商没有类似的限制或配置,以免内网不通导致 master 和 worker 节点无法通信。

内网网段配置

要组建集群,首先机器之间得能互相访问。最理想的情况是机器都处在同一个网段,但省钱的方案并不能做到这一点,我的两台主机位于完全不同的两个网段,Lighthouse 甚至不支持修改内网 IP 地址。

好在腾讯云的 CVM 和 Lighthouse 之间虽然默认不能连通,但位于同一地域的机器可以通过内网互联功能,享受 5Gbps 带宽免费互通(不同地域需要收费),可以参考腾讯云文档进行操作,本文不多赘述。

内网互联 https://cloud.tencent.com/document/product/1207/56847

云服务器防火墙配置

另外需要注意的是云厂商提供的防火墙的配置(不是系统里的防火墙),需要在每台主机的入站规则中添加上其它主机的 IP 地址,腾讯云的配置入口位于 实例详情 - 安全组(Lighthouse 为防火墙)。

例如,我直接选择放行整个网段,这样未来如果增加机器就不用再来回改配置了:

因为我是全部放行,可以使用 ping 命令查看机器是否连通了,例如在我的 worker 上 ping master:

> ping 10.0.16.13PING 10.0.16.13 (10.0.16.13) 56(84) bytes of data.
64 bytes from 10.0.16.13: icmp_seq=1 ttl=64 time=0.288 ms
64 bytes from 10.0.16.13: icmp_seq=2 ttl=64 time=0.240 ms
64 bytes from 10.0.16.13: icmp_seq=3 ttl=64 time=0.264 ms

允许访问公网

由于安装 k8s 过程中需要拉取一些镜像或下载一些文件,而这些镜像或文件在腾讯云内网镜像服务中并没有提供,所以至少安装阶段需要访问公网。

Debian 基础配置

如果你使用的是其它 Linux 发行版本,那么通过互联网搜索相关操作,能很快找到对应的命令。

配置机器名称和 hosts

使用统一一致的机器名称利于管理:

hostnamectl set-hostname bun-master-01

配置 hosts 文件让机器名称可以被访问:

cat >> /etc/hosts << EOF
10.0.16.13 bun-master-01
172.17.0.2 bun-worker-01
EOF

关闭防火墙等配置

安装 k8s 前需要将 Linux 的防火墙、安全配置(SELinux)、交换分区(Swap,类似于 Windows 的虚拟内存)关闭。不过这些内容默认情况下都是禁用的,如果你曾经开启过记得关闭。

允许 iptables 检查桥接流量

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

配置时间同步

确保每台机器时间都是正确的,我使用腾讯云内网提供的NTP 服务。

NTP 服务 https://cloud.tencent.com/document/product/213/30392

如果你的云厂商没有提供类似服务,可以采用公网上的 NTP 服务。

安装 ntp:

apt-get install -y ntp

修改 ntp 配置:

vi /etc/ntp.conf

将腾讯云的 NTP 服务器地址替换掉配置文件中默认的:

重启 ntp 并查看效果:

service ntp restart
service ntp status
ntpq -p

最后设置 ntp 开机启动:

systemctl enable ntp

安装 docker

注意:所有节点都需要安装 docker。

我们使用官方脚本安装 docker,在此之前先把一些必要的程序安装一下:

apt-get update
apt-get install -y \ca-certificates \curl \gnupg \lsb-release

接着使用腾讯云内网镜像来进行下载:

http://mirrors.tencentyun.com 只能在腾讯云内网访问,你需要将它们换成你可用的,例如 http://mirrors.tencent.com。本文优先使用腾讯云内网镜像,因为这样高速,且不会产生任何公网流量和费用。

curl -fsSL http://mirrors.tencentyun.com/docker-ce/linux/debian/gpg \| sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpgecho \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] http://mirrors.tencentyun.com/docker-ce/linux/debian \$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

接下来开始安装 docker:

apt-get update
apt-get install -y \docker-ce \docker-ce-cli \containerd.io

检查 docker 网络

安装好之后,使用 ip a 命令检查一下 docker 新建的网卡,避免 docker 新建的网卡导致网段冲突,内网机器无法访问。

例如在 bun-master-01 机器上执行 ip a 得到如下返回:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 52:54:00:19:8b:e4 brd ff:ff:ff:ff:ff:ffaltname enp0s5altname ens5inet 10.0.16.13/22 brd 10.0.19.255 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::5054:ff:fe19:8be4/64 scope link valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:c3:bf:8b:a6 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft forever

docker 创建的虚拟网卡 docker0 使用了 172.17.0.1 地址,而我的另一台机器 bun-worker-01 则是 172.17.0.2。这样导致无法从 bun-master-01 访问 bun-worker-01

我们可以修改 docker 的配置文件指定它的虚拟网卡地址,例如我希望 docker 使用 192.168.0.1/16 网段,这样和谁都不冲突:

cat >> /etc/docker/daemon.json << EOF
{"bip": "192.168.0.1/16"
}
EOF

然后重启 docker,并重新运行 ip a 检查配置是否生效,以及重新 ping 一下测试连通性:

service docker restart

配置 docker 镜像加速源

https://mirror.ccs.tencentyun.com 只能在腾讯云内网访问,你需要将它们换成你可用的,例如使用阿里云镜像加速。

阿里云镜像加速 https://help.aliyun.com/document_detail/60750.html

修改 /etc/docker/daemon.json 文件,新增 registry-mirrors 的配置:

{"bip": "192.168.0.1/16","registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}

接下来重启 docker 应用配置:

service docker restart

如果一切正常,让我们跑一下 docker 的 hello-world 试试:

docker run hello-world

如果看到 Hello from Docker! 则说明一切顺利,继续进行下一步吧。

docker 启动失败常见问题

如果在重启 docker 时不幸遇到了这样的提示:

Job for docker.service failed because the control process exited with error code.
See "systemctl status docker.service" and "journalctl -xe" for details.

不要慌,请运行 journalctl -xe 查看具体错误。例如我尝试将 docker 的虚拟网卡 IP 修改为了一个非法的值:

Mar 23 21:44:28 master-01.bun.local dockerd[186689]: time="2022-03-23T21:44:28.584331774+08:00" level=info msg="[graphdriver] using prior storage driver: overlay2"
Mar 23 21:44:28 master-01.bun.local dockerd[186689]: time="2022-03-23T21:44:28.589151624+08:00" level=info msg="Loading containers: start."
Mar 23 21:44:28 master-01.bun.local dockerd[186689]: time="2022-03-23T21:44:28.643081791+08:00" level=info msg="stopping event stream following graceful shutdown" error="<nil>" module=libcontainerd namespace=moby
Mar 23 21:44:28 master-01.bun.local dockerd[186689]: failed to start daemon: Error initializing network controller: Error creating default "bridge" network: failed to allocate gateway (192.168.0.0): Address already in use

docker 要求配置的值是一个真实的 IP 地址,所以不能配置为 192.168.0.0/16,需要配置为 192.168.0.1/16

如果是其它问题,可以在网上进行搜索。

安装 kubeadm, kubelet 以及 kubectl

注意:所有节点都需要安装 kubeadm, kubelet 以及 kubectl。

由于 Google 无法访问,腾讯云的镜像又没有 gpg 文件,只好从阿里云的镜像下载 pgp 文件

自己搭建一个k8s环境相关推荐

  1. Chocolatey 在Window搭建一个开发环境

    2019独角兽企业重金招聘Python工程师标准>>> 在看了(利用 Chocolatey 快速在 Windows 下搭建一个开发环境)后,准备从零开始 一.准备工作 1.用管理员权 ...

  2. 小程序kbone开发---用kbone搭建一个demo环境

    小程序kbone开发-用kbone搭建一个demo环境 微信小程序自诞生以来,渗透到我们生活的方方面面,以其便捷轻量的特点受到了用户的极大欢迎.但是作为开发者的我们,"当 Web 项目完成之 ...

  3. vue + skyline 搭建 一个开发环境

    1.之前用的是ext +  skyline搭建环境 ,正好最近是做前端的事情,有时间用vue + skyline 搭建一个三维场景 2.准备vue 2.x  ,UI 用的是iview 和element ...

  4. Dubbo的基本介绍和搭建一个Dubbo环境

    什么是Dubbo Dubbo是一个分布式服务框架,提供了高性能以及透明化的RPC远程服务调用解决方法,以及SOA服务治理方案. Dubbo的核心部分: 远程通信:提供了高性能以及透明化的RPC远程服务 ...

  5. [kubernetes] 使用 Minikube 快速搭建本地 k8s 环境 (基于 Docker 驱动模式)

    一.实验环境 操作系统:Centos 7 x86_64 Docker:1.12.6 二.部署 k8s 步骤 2.1  安装 kubectl cat <<EOF > /etc/yum. ...

  6. 在开发环境中,自己搭建一个ssl环境(小例子)

    做项目的时候自己总结的一些小例子 public class Test { public static void setSSLProperty() { Security.addProvider(new  ...

  7. 做Amazon、Lazada、Shoppe测评自养号,教你搭建一个完美的环境。

    相信大家都知道,想要做跨境电商测评补单就必须要搭建一个国外环境才能注册,养号,下单等业务.现在不管是做自养号的卖家和测评工作室都有一套自己的环境,但是很多人因为不明白亚马逊的具体风控情况,以为随便建一 ...

  8. python搭建ai_搭建一个新手学习AI/ML的Python环境

    不知不觉消失了好久,公众号也很久没有更新了.因为跑去学习微软AI方向的MPP课程了.MPP是目前微软最先提供关于AI的培训课程,关于MPP的学习体系,我后面会再写一篇简单的介绍. MPP包含了很多的内 ...

  9. Linux下搭建Android交叉编译环境

    前言 为了能够在Android平台上使用一些Linux中的C/C++库,我们需要使用AndroidNDK来编译那些Linux库的源代码,使用NDK开发时,通常使用Android.mk或者Cmake来构 ...

最新文章

  1. 下班后散步雨后湖景一角
  2. 数据蒋堂 | Hadoop中理论与工程的错位
  3. 图神经网络的表达能力,究竟有多强大?
  4. python在日常工作处理中的应用-python在工作中的应用场景介绍
  5. hdu4503 概率
  6. java窗口how2j_HOW2J java文件的创建及常用方法
  7. Problem - 4828 Grids
  8. php mod11 10公式,mod运算规则
  9. springmvc和servlet在上传和下载文件(保持文件夹和存储数据库Blob两种方式)
  10. .NET CORE(C#) WPF简单菜单MVVM绑定
  11. 一步步编写操作系统 6 启动bochs
  12. 笔记:《突破现实的困境:趋势、禀赋与企业家的大战略》
  13. 微軟专为Visual Studio 2019设计出一套容器工具擴充套件
  14. 每周送新书:Android软件安全、深入浅出Istio、软件架构设计
  15. [Delphi]用程序更改 IE 的代理服务器(Proxy)设置及本地连接
  16. tagwriter汉化版_【NFC TagWriter by NXP电脑版下载2020】NFC TagWriter by NXP PC端最新版「含模拟器」...
  17. 服务器拒绝mac访问共享文件,Mac共享文件连接失败怎么办?Mac无法访问打开共享文件解决方法...
  18. 固态硬盘计算机怎么自定义分区,固态硬盘做系统分区教程-固态硬盘如何分区?...
  19. esp分区引导修复失败_UEFI引导修复教程 win10 MBR无损转GPT分区后修复启动
  20. android sdk引入 微信分享_Android分享 ShareSDK微信分享详解

热门文章

  1. 加快Android Studio的编译速度
  2. 一些服务器编程的概念
  3. NotificationManagerService使用详解与原理分析(一)
  4. android之实现各个组件点击事件处理
  5. 第零讲.1 tapestry项目创建与运行
  6. T T[] toArray(T[] a);
  7. Android 中的接口回调
  8. WPF将数据库和GridView绑定并更改GridView模板
  9. sdut2784cf 126b Good Luck!(next数组)
  10. 如何在ashx页面获取Session值(未将对象引用设置到对象的实例) (转)