华为云服务器ubuntu18.04环境下构建k8s多机集群
机器选择使用华为云的两台x86虚拟机,HECS相对来说便宜一点。这回不用实验室的机器了,希望华为云的机子能给点力。
gist,如果只是要安装k8s可以参考这个脚本。可能还是有点问题(我是在root下跑完的),sudo支持上可能有遗漏的地方。
创建用户
useradd -g root wty
usermod -a -G sudo wty
- 创建
/home/wty
更新软件
更新apt
换源,更新apt(可以省略,华为云内网速度应该更快一些)
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
安装并配置zsh
sudo apt-get install zsh
安装zsh- 执行
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
进行配置 - (国内)gitee镜像
安装并配置git
git config --global user.name "wtysos11"
git config --global user.email wtysos11@163.com
ssh-keygen -t rsa -C "wtysos11@163.com"
上传公钥到github
安装docker
- https://yeasy.gitbook.io/docker_practice/install/ubuntu
- https://docs.docker.com/engine/install/ubuntu/
使用脚本安装
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun
usermod -aG docker $USER
参考官方教程配置docker
- root用户执行
service docker start
启动进程 - 普通用户执行
sudo groupadd docker
创建用户组 sudo usermod -aG docker $USER
加入用户组- 重新登陆,或者执行
newgrp docker
- 执行
docker run hello-world
尝试安装是否成功
配置镜像加速:阿里云。由于使用了阿里云,就不进行docker login
了。
安装kubernetes
配置apt仓库
参考,配置apt仓库并安装对应的二进制组件(如果对版本没有要求可以不进行指定)
sudo apt-get update && sudo apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
cat << EOF > /etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
# sudo apt-get install -y kubelet=1.23.4-00 kubeadm=1.23.4-00 kubectl=1.23.4-00
启动kubelet,运行情况检查
systemctl status kubelet
查看情况journalctl -xeu kubelet
输出日志
遇到问题:kubelet shutdown
报错信息"Failed to run kubelet" err="failed to run Kubelet: misconfiguration: kubelet cgroup driver: \"systemd\" is different from docker cgroup driver: \"cgroupfs\""
从报错信息来看,应该是docker的cgroup driver和kubelet的cgroup driver不一致的问题。
参考SO的解决方案,在docker的配置文件(/etc/docker/daemon.json
)中加上了"exec-opts": ["native.cgroupdriver=systemd"]
,然后使用sudo systemctl restart docker
即可(PS:即使是新开启的docker也必须执行)
遇到问题:failed to load kubelet config file
Aug 26 16:17:48 k8s-master systemd[1]: kubelet.service: Service hold-off time over, scheduling restart.
Aug 26 16:17:48 k8s-master systemd[1]: kubelet.service: Scheduled restart job, restart counter is at 87.
-- Subject: Automatic restarting of a unit has been scheduled
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Automatic restarting of the unit kubelet.service has been scheduled, as the result for
-- the configured Restart= setting for the unit.
Aug 26 16:17:48 k8s-master systemd[1]: Stopped kubelet: The Kubernetes Node Agent.
-- Subject: Unit kubelet.service has finished shutting down
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Unit kubelet.service has finished shutting down.
Aug 26 16:17:48 k8s-master systemd[1]: Started kubelet: The Kubernetes Node Agent.
-- Subject: Unit kubelet.service has finished start-up
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Unit kubelet.service has finished starting up.
--
-- The start-up result is RESULT.
Aug 26 16:17:48 k8s-master kubelet[27908]: E0826 16:17:48.885345 27908 server.go:206] "Failed to load kubelet config file" err="failed to load Kubelet config file /var/lib/k
ubelet/config.yaml, error failed to read kubelet config file \"/var/lib/kubelet/config.yaml\", error: open /var/lib/kubelet/config.yaml: no such file or directory" path="/var/
lib/kubelet/config.yaml"
Aug 26 16:17:48 k8s-master systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE
Aug 26 16:17:48 k8s-master systemd[1]: kubelet.service: Failed with result 'exit-code'.
Aug 26 16:17:59 k8s-master systemd[1]: kubelet.service: Service hold-off time over, scheduling restart.
Aug 26 16:17:59 k8s-master systemd[1]: kubelet.service: Scheduled restart job, restart counter is at 88.
-- Subject: Automatic restarting of a unit has been scheduled
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
报错信息主要是failed to load kubelet config file
参考issue/65863的一个回答。不过这个问题可以直接通过kubeadm init
解决(简单来说就是不用管)
其他问题
kubeadm: Configuring a cgroup driver提到v1.22版本中,如果用户没有指定cgroupDriver
的会默认为systemd。目前我用的正是1.22.1版本,应该是这个值没有设置为cgroupfs的问题
# kubeadm-config.yaml
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta3
kubernetesVersion: v1.22.1
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: cgroupfs
通过kubeadm安装k8s集群
- 官网教程,还是比较推荐的,唯一的问题就是没有考虑到国内访问不到谷歌的问题
预先配置
交换与防火墙
top
内查看是否开启交换,开了要关闭- 关闭防火墙
网络
官网“允许iptables检查桥接流量”一节提到lsmod | grep br_netfilter
来检查br_netfilter
模块被加载
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
配置cgroup为systemd
kubelet这边可以不用管,默认是systemd
。需要按照[kubelet shutdown](#遇到问题:kubelet shutdown)内的操作来修改容器运行时的cgroup,不然Kubelet会启动不了。(按照官方的说法,不建议修改kubelet的cgroup为cgroupfs)
正式安装
可以参考我之前配置时的教程。不过当时并没有做可重复性相关的验证。
首先使用kubeadm config images list
列出kubeadm所需要的所有镜像
k8s.gcr.io/kube-apiserver:v1.22.1
k8s.gcr.io/kube-controller-manager:v1.22.1
k8s.gcr.io/kube-scheduler:v1.22.1
k8s.gcr.io/kube-proxy:v1.22.1
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4
执行以下命令进行安装:
sudo kubeadm init --apiserver-advertise-address=10.186.117.4 --pod-network-cidr=10.244.0.0/16 --token-ttl=0 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
命令参考:官方,也可以在命令行下查看。
-
apiserver-advertise-address:这个参数指定了监听的API地址。若没有设置,则使用默认网络接口。我使用的是华为云的服务器,这里填master节点的地址即可(要求能被其他节点访问到)
-
apiserver-bind-port:这个参数指定了API服务器暴露出的端口号,默认是6443。
-
pod-network-cidr:规定了pod能够使用的IP地址段。我之前用的是16位子网掩码,但是现在给的子网就是24位掩码,我也不确定使用其他子网能不能行……先保险起见吧。
-
kubernetes-version:指定kubeadm安装的kubernetes版本。这个是很重要的,因为默认情况下kubeadm会安装与它版本相同的kubernetes版本,而由于国内的网络问题,每次都需要重新下载一遍镜像,非常的麻烦。如果之后版本使用这个脚本,可以加上
--kubernetes-version=v1.19.2
-
image-repository:默认是"k8s.gcr.io"。我觉得如果修改这个可以不用像之前那样从阿里云下载下来后手动tag。可以使用
kubeadm config images pull --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
,参考 -
token-ttl:令牌被删除前的时间,默认是24h。kubeadm初始化完毕后会生成一个令牌,让其他节点能够加入集群,过时之后这个令牌会自动删除。如果设置为0之后令牌就永不过期。
这一步的难点在于如何设置pod-network-cidr,参数的作用。根据官方教程的说法,Pod网络与任何主机网络不得有重叠。但是目前我看到的很多教程都是在主机局域网络下构建的。比如说三台主机都在192.168.1.1/16
子网,而pod网络也在同样的子网下。
这个参数的设置似乎与所使用的CNI有关系:
本文采用flannel,一个很重要的原因是因为服务器的子网与pod的子网部分重叠,可能存在风险,以及flannel似乎更容易部署一些。
值得注意的是,在coredns镜像中,只有x.x.x,而没有vx.x.x,所以需要手动改一下。也可以参考zhangguanzhang的工具来直接同步
如果image-repository不可用可以考虑下面的脚本
#########################################################################
# File Name: pull_master_image.sh
# Description: pull_master_image.sh
# Author: zhangyi
# mail: 450575982@qq.com
# Created Time: 2019-07-31 21:38:14
#########################################################################
#!/bin/bash
kube_version=:v1.22.1
kube_images=(kube-proxy kube-scheduler kube-controller-manager kube-apiserver)
addon_images=(etcd:3.5.0-0 coredns:1.8.4 pause:3.5)
for imageName in ${kube_images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version
docker image tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version k8s.gcr.io/$imageName$kube_version
docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version
done
for imageName in ${addon_images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker image tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done
之后,需要执行这三条命令,其作用是将kubectl所需要的配置文件拉到用户目录下并设置访问权限。(不执行的话kubectl是无法正常工作的)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
有时可能需要显示配置export KUBECONFIG=$HOME/.kube/config
。
如果是使用root用户需要设置export KUBECONFIG=/etc/kubernetes/admin.conf
。
使用kubectl get pods -n=kube-system
可以查看所有的系统容器,这时候coredns
可能没有运行,这个没有关系,等flannel装上之后就好了。
untaint
对于小集群,必须要执行kubectl taint nodes --all node-role.kubernetes.io/master-
,不然调度的时候会少一台机子。
安装flannel
参考flannel官方教程,
curl -fsSL https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml > kube-flannel.yml
下载配置文件kubectl apply -f kube-flannel.yml
日志记录:
➜ ~ kubectl apply -f kube-flannel.yml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
可能出现的问题:
- flannel需要镜像
quay.io/coreos/flannel:v0.14.0
,之前安装的时候没有办法抓下来。不过这次成功搞下来了,可能是阿里云的镜像服务又更进一步了?
此时,k8s的安装就基本完成了,后续就自由发挥了。
istio安装
按照官网指南安装即可,这个版本的istio安装基本不会出现问题
其他问题
- 安装flannel时提示
open /run/systemd/resolve/resolv.conf: no such file or directory
,经过检查发现是节点的systemd-resolved
出现问题,systemctl status systemd-resolved
中状态为Inactive。直接使用systemctl restart systemd-resolved
重启对应的DNS服务即可。 - 端口问题。因为在内网配置了比较严格的安全策略,需要手动打开但偶才能正常工作。其中kubernetes的api-server默认是在6443端口下工作,istio则需要15021端口。而且coreDNS需要UDP53端口……如果可以的话测试环境建议全打开,鬼知道是在哪里被卡的。
- 新节点加入:在之后还有节点要加入的话,可以在主节点执行
kubeadm token create --print-join-command