kubernetes实践录 - 在ubuntu上搭建k8s集群
kubernetes
应该怎么读?
在装kubernetes
之前,有必要了解下这个东西的发音。
断句: koob-er-net-ees
音标:[kubə’netis]
音译: 库伯耐提斯
github上相关的讨论: https://github.com/kubernetes/kubernetes/issues/44308
这部分内容参考了: kubernetes 如何发音?
系统准备
准备3台ubuntu系统(版本都是20.04及以上), 配置好代理, 网络(互相之间可以ping通). 我这边是有一台装了ubuntu的物理主机和另外两个在这个宿主上的通过vmware跑的ubuntu server虚拟机, 两个虚拟机的网络模式选择桥接模式; 三台ubuntu都连到同一个路由器.
三台机子的ip地址:
# 主节点/控制节点 主机名: laplus
192.168.124.66
# 从节点1 主机名: laplus-1
192.168.124.9
# 从节点2 主机名: laplus-2
192.168.124.10
然后分别配置下三台机子的主机名, 方便辨认
打开/etc/hosts
文件, 分别加上
# ip为 192.168.124.66 ubuntu加上下面的内容
127.0.0.1 laplus
# ip为 192.168.124.9 ubuntu加上下面的内容
127.0.0.1 laplus-sub1
# ip为 192.168.124.10 ubuntu加上下面的内容
127.0.0.1 laplus-sub2
完成后就有三台主机名分别为laplus
, laplus-sub1
,laplus-sub2
的ubuntu, 其中laplus
这台会作为k8s主节点, laplus-sub1
和laplus-sub2
作为从节点. laplus
是我给这个集群起的一个名字😉.
kubernetes对配置要求:
- 每台机器2GB及以上内容
- 每台机器至少2核cpu
关于代理
没有代理的话会可能会导致整个过程异常艰难, 所以一定要先配置好代理!
ubuntu
上要注意, 用sudo
执行命令时, 要加-E
参数才能使代理相关的环境变量生效, 也就是把sudo
改成sudo -E
.
容器运行时(container runtime) - Docker
kubernetes支持多种容器运行时(container runtime), 我当然用docker啦, 其他的暂时还没怎么了解过.
官方安装指南: https://docs.docker.com/engine/install/ubuntu/.
# 卸载旧版本(如果之前安装过), 如果apt报错 Unable to locate package 那也不碍事, 说明机器上没有相关残留
sudo apt remove docker docker-engine docker.io containerd runc
# 设置docker仓库
sudo apt update -y && \
sudo apt install -y \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加docker官方的GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版docker仓库源
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装docker
sudo apt update -y && sudo apt install docker-ce docker-ce-cli containerd.io -y
# 验证安装是否成功
docker -v
docker配置http代理
这一步一定不能跳过! 否则后面使用kubeadm init
命令初始化集群时会失败!
首先, 使用systemctl status docker
命令查询docker.service
文件的路径, 在我的环境中它的文件路径是/lib/systemd/system/docker.service
; 然后编辑这个文件, 添加如下内容:
[Unit]
...
[Service]
...
Environment="HTTP_PROXY=http://127.0.0.1:10809"
Environment="HTTPS_PROXY=http://127.0.0.1:10809"
Environment="NO_PROXY=localhost,127.0.0.0/8,192.168.0.0/16,10.0.0.0/8"
[Install]
WantedBy=multi-user.target
三台机器上每台都要进行安装和配置.
禁用swap
划重点, 根据kubenertes的文档, 安装前必须要禁用swap
分区.
每台ubuntu都要进行禁用操作:
vim /etf/fstab
# 注释掉文件中包含swap的那一行
# # /etc/fstab: static file system information.
# #
# # Use 'blkid' to print the universally unique # identifier for a
# # device; this may be used with UUID= as a more # robust way to name devices
# # that works even if disks are added and # removed. See fstab(5).
# #
# # <file system> <mount point> <type> # <options> <dump> <pass>
# # / was on /dev/sda2 during installation
# UUID=aa665d86-d779-4b3e-9893-743ae3ac0074 # / ext4 errors=remount-ro # 0 1
# # /boot/efi was on /dev/sda1 during installation
# UUID=13FE-4A60 /boot/efi vfat # umask=0077 0 1
# # /swapfile # none swap sw 0 0
# 然后重启下
sudo shutdown -r now
防火墙
laplus-sub1
和laplus-sub2
不会暴露在公网, 所以直接关掉其上的防火墙, ubuntu上关防火墙命令是:
sudo systemctl disable ufw.service && sudo systemctl stop ufw.service
laplus
上按照我个人的习惯还是要开个防火墙的, 我习惯了用firewalld
, 所以先禁用ubuntu的ufw
, 然后安装并启用firewalld
, 相关命令如下:
# 禁用并关闭 ufw 这个服务
sudo systemctl disable ufw.service && \
sudo systemctl stop ufw.service
# 卸载 ufw
sudo apt remove ufw -y
# 启动firewalld并将其设为开机后自动启动, 同时开放 22 端口
sudo systemctl start firewalld && \
sudo firewall-cmd --zone=public --add-port=22/tcp --permanent && \
sudo firewall-cmd --zone=public --add-port=22/udp --permanent && \
sudo firewall-cmd --reload
划重点, 根据kubernetes的官方文档, kubernetes的主节点需要开放6443
、2379-2380
、10250
、10259
、10257
这些端口
放行端口的指令:
# 6443 端口
sudo firewall-cmd --zone=public --add-port=6443/tcp --permanent && \
sudo firewall-cmd --zone=public --add-port=6443/udp --permanent
# 2379-2380 端口
sudo firewall-cmd --permanent --zone=public --add-port=2379-2380/tcp && \
sudo firewall-cmd --permanent --zone=public --add-port=2379-2380/udp
# 10250 端口
sudo firewall-cmd --zone=public --add-port=10250/tcp --permanent && \
sudo firewall-cmd --zone=public --add-port=10250/udp --permanent
# 10259 端口
sudo firewall-cmd --zone=public --add-port=10259/tcp --permanent && \
sudo firewall-cmd --zone=public --add-port=10259/udp --permanent
# 10257 端口
sudo firewall-cmd --zone=public --add-port=10257/tcp --permanent && \
sudo firewall-cmd --zone=public --add-port=10257/udp --permanent
# 之后使用ingress的话, 下面的端口也需要开放
sudo firewall-cmd --zone=public --add-port=10251-10255/tcp --permanent && \
sudo firewall-cmd --zone=public --add-port=10251-10255/udp --permanent && \
sudo firewall-cmd --zone=public --add-port=8472/tcp --permanent && \
sudo firewall-cmd --zone=public --add-port=8472/udp --permanent && \
sudo firewall-cmd --add-masquerade --permanent
# 如果之后想在控制节点访问NodePort端口的话, 需要放行 30000-32767
sudo firewall-cmd --permanent --add-port=30000-32767/tcp
# 使配置生效
sudo firewall-cmd --reload
确保内核参数开启net.bridge.bridge-nf-call-iptables
使用sysctl -a
查看全部内核参数值, 确保``的值为1
如果发现其值不是1, 使用 sysctl -w net.bridge.bridge-nf-call-iptables=1
命令, 将bridge-nf-call-iptables
的值设为1.
安装kubeadm
kubelet
和kubectl
首先照例更新下apt
的包索引, 并安装之后会用到的必要的工具
sudo -E apt-get update -y && \
sudo -E apt-get install -y apt-transport-https ca-certificates curl
下载Google云公钥:
sudo -E curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
添加kubernetes仓库源:
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
安装kubelet
kubeadm
kubectl
:
sudo -E apt-get update -y && \
sudo -E apt-get install -y kubelet kubeadm kubectl && \
sudo -E apt-mark hold kubelet kubeadm kubectl
每台机器上都要执行上面的操作安装好kubelet
kubeadm
kubectl
安装完成后, kubelet
会一直处在重启状态.
主节点使用systemctl status kubelet
查看kubelet
运行状态:
从节点使用systemctl status kubelet
查看kubelet
运行状态:
配置cgroup
详见文档: Container runtimes
可以直接执行下面的命令
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload & \
sudo systemctl restart docker
这一步也不能跳过, 否则下面执行kubeadm init
命令时会失败. 什么? 你问我怎么知道, 因为我一开始图省事就跳过了啊😂, 然后我是怎么知道是这一步的问题的呢? 用journalctl -u kubelet.service | tail -n 20
看了下kubelet
的日志就知道了
通过kubeadm
初始化集群
主节点初始化:
sudo -E kubeadm init --control-plane-endpoint=192.168.124.66 \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.124.66
执行成功后, 控制台会打印出相关信息, 告诉你如何把从节点加进来, 注意保存下相关内容.
主节点初始化完成后还需要安装网络插件, 我选择的flannel.
安装flannel
# 先执行
sudo bash -c "echo '199.232.96.133 raw.githubusercontent.com' >> /etc/hosts"
# 这会往hosts文件中加一条解析, 否则即使你配置了代理也无法下载 raw.githubusercontent.com 的内容! 真坑!
sudo -E curl -fsSlo ./kube-flannel.yml https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml & \
sudo -E kubectl apply -f kube-flannel.yml
从节点加入主节点:
sudo kubeadm join 192.168.124.66:6443 --token bp40hq.1snqrahs3ixraeh4 \
--discovery-token-ca-cert-hash sha256:b3169e035bcae40203afe63a0208d7df32d788c8b69b52bd9e8053606e32bc0b
完事后, 主节点执行下sudo kubectl get nodes
查看另外两个节点有没有成功加进来, 成功的话输出应该像下面这样:
非root
用户不加sudo
的情况下使用kubectl
提示没有权限怎么办?
执行chmod 666 /etc/kubernetes/admin.conf
修改文件权限即可
执行后admin.conf
文件的权限就变成了rw-rw-rw
, 即所有用户都有权对其进行读写, 生产环境最好不要这样.
kubectl配置自动补全
官网文档:Enable shell autocompletion
安装配置bash-completion
运行type _init_completion
, 检查系统中是否已经安装了bash-completion
; 如果已经有了的话, 跳过此步即可; 如果没有的话, 先安装下bash-completion
(这个东西正常情况下应该是已经装好了的)
运行下面的命令安装bash-completion
sudo -E apt install bash-completion
然后在~/.bashrc
文件中添加:
source /usr/share/bash-completion/bash_completion
然后执行source ~/.bashrc
.
生成kubectl
自动完成脚本
~/.bashrc
中添加source <(kubectl completion bash)
echo 'source <(kubectl completion bash)' >>~/.bashrc
然后生成kubectl
自动完成脚本
kubectl completion bash >/etc/bash_completion.d/kubectl
最后执行source ~/.bashrc
命令即可享受自动补全的快乐了😉.
下集预告
- kubernetes实践录 - 跑一个私有nuget仓库
Baget