On this page
一、环境架构
在VMware上准备了三台虚拟机,用于搭建k8s集群,其结构如下:
- k8s-master:
2核4GB;IP: 10.0.0.100; 部署:etcd, kube-apiserver, kube-controller-manager, kubectl, kubeadm, kubelet, kube-proxy, flannel - k8s-slave1:
2核2GB;IP: 10.0.0.101; 部署:kubectl, kubelet, kube-proxy, flannel,docker - k8s-slave2:
2核2GB;IP: 10.0.0.102; 部署:kubectl, kubelet, kube-proxy, flannel,docker
二、环境初始化
为所有机器配置hosts解析
10.0.0.100 k8s-master
10.0.0.101 k8s-slave1
10.0.0.102 k8s-slave2
关闭swap
POD的内存管理策略中通常给每个POD分配一个固定的内存量,如果POD的使用内存超过可用内存,则该POD会被强制终止;开启swap后,当可用内存不足时,一部分硬盘空间会被临时用来当成内存使用,但硬盘的性能毕竟和内存差了不止一点,这样会导致性能大幅度下降,同时也可能会引起当POD超过可用内存后转而使用Sawp空间,但由于性能太底下而导致程序夯住,因此一般关掉,这也是官方的建议
swapoff -a
要永久关闭,还要编辑 /etc/fstab 文件,将有swap的那一行注释掉。
关闭SELinux,Firewalld并清空iptables规则
关闭SELinux:
编辑 /etc/selinux/config ,设置SELINUX=disabled
关闭防火墙服务:
systemctl stop firewalld && systemctl disable firewalld
清空iptables规则
iptables -F && iptables -X && iptables -Z
使用chronyd确保时间同步正确
hwclock -w
修改内核参数,开启数据包转发功能
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
vm.max_map_count=262144
EOF
modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf
安装docker
配置docker软件源
curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装
yum install docker-ce-19.03.15 docker-ce-cli-19.03.15 -y
配置cgroup驱动
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<'EOF'
{
"exec-opts":["native.cgroupdriver=systemd"]
}
EOF
验证:
docker info |grep -i cgroup
结果应该是: Cgroup Driver: systemd
三、安装kubeadm工具(master和slave节点都安装)
启用kubernetes软件源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
重新生成缓存
yum clean all && yum makecache
查看并安装指定软件版本
yum list kubeadm –showduplicates
yum install kubelet-1.19.3 kubeadm-1.19.3 kubectl-1.19.3 ipvsadm -y
启动并设置问开机自启
systemctl start kubelet && systemctl enable kubelet
四、初始化Master主节点
初始化集群
kubeadm init \
–apiserver-advertise-address=10.0.0.100 \
–image-repository registry.aliyuncs.com/google_containers \
–kubernetes-version v1.19.3 \
–service-cidr=10.1.0.0/16 \
–pod-network-cidr=10.2.0.0/16 \
–service-dns-domain=cluster.local \
–ignore-preflight-errors=Swap \
–ignore-preflight-errors=NumCPU
参数解释:
- –apiserver-advertise-address=10.0.0.100 \ API-Server地址,一般也就是master主机的地址
- –image-repository registry.aliyuncs.com/google_containers \ 镜像仓库地址,在国内可以用这个,在国外没必要
- –kubernetes-version v1.19.3 \ k8s版本
- –service-cidr=10.1.0.0/16 \ clusterIP k8s服务发现网段,也就是service网段
- –pod-network-cidr=10.2.0.0/16 \ podIP网段(pod创建后的运行网段)
- –service-dns-domain=cluster.local \ 集群内dns后缀
- –ignore-preflight-errors=Swap \ 忽略swap报错
- –ignore-preflight-errors=NumCPU 忽略CPU报错
上面的初始化完成后会产生大段的结果日志,主要关注最后提示的kubeadm join命令,Kubernetes Node节点需要使用这行命令来加入集群。
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run “kubectl apply -f [podnetwork].yaml” with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.0.0.100:6443 –token 04ysh6.s4h4wnzbov9eq1z4 \
–discovery-token-ca-cert-hash
sha256:f7263afe295687ad5ea02ad328a8eeee76c7b8625b4861ba2476ba0997fc432b
创建k8s集群配置文件
根据上面的提示,我们可以创建k8s集群配置文件(指定了默认的SSL证书存储位置,api-server的地址等)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
接下来,看看端口都被那些k8s的那些组件占领了
到此为止k8s就算是大概装好了,可以使用以下命令查看k8s集群状态
kubectl get nodes -owide
结果应该是Master Status NotReady,这是因为还没部署网络插件
五、部署Flannel网络插件(master)
部署flannel使master机器和slave机器互联,允许获取状态并将容器远程部署到slave主机上。
下载flannel
git clone –depth 1 https://github.com/coreos/flannel.git
修改网络插件信息
编辑flannel/Documentation/kube-flannel.yml文件,修改下面的部分:
net-conf.json: |
{
“Network”: “10.2.0.0/16”,
“Backend”: {
“Type”: “vxlan”
}
}
Network,即Master初始化时–pod-network-cidr
参数对应的值。
containers:
– name: kube-flannel
image: docker.io/flannel/flannel:v0.22.1
command:
– /opt/bin/flanneld
args:
– –ip-masq
– –kube-subnet-mgr
– –iface=网卡名
指定对外访问的网卡,如果有多块网卡但没有指定,则会自动使用第一个网卡
基于kubectl命令,应用这个yml文件,读取并创建这个POD资源
kubectl create -f ./kube-flannel.yml
成功创建flannel POD后,可以发现所有的Node机器上都有flannel的容器
因为kubectl create是像api-server发起创建POD的请求,之后flannel的配置信息被写入到etcd数据库中;由于slave节点上的kubelet进程一直在监听etcd,因此当etcd有更新时,两个slave立即进行了同步。
六、将k8s-slave节点加入集群
在k8s-slave节点上输入下面的命令
kubeadm join 10.0.0.100:6443 –token 04ysh6.s4h4wnzbov9eq1z4 \
–discovery-token-ca-cert-hash sha256:f7263afe295687ad5ea02ad328a8eeee76c7b8625b4861ba2476ba0997fc432b
之后master和slave节点就进入了ready状态
七、测试:运行一个Nginx POD
创建:
kubectl run test-nginx –image=nginx:1.20.1
查看:
kubectl get pods -owide
最后可以发现,这个容器被部署在了k8s-slave2机器上;使用docker ps可以发现kubenetes为这个容器创建了一个POD根容器和一个nginx容器
目前因为没有端口映射等配置,所以只能使用curl命令去访问
修改index文件:
kubectl exec test-nginx — sh -c “echo ‘Hello World’ > /usr/share/nginx/html/index.html”
到这里kubernetes就正式完成安装和初始化工作了
八、中间出现的问题和解决方法
kubelet服务无法启动
kubelet服务一直是auto-restart状态,原因在于没有关闭交换内存,输入 swapoff -a 后成功启动。
Master初始化失败
因为kubelet没有启动,所以导致失败;成功启动kubelet后仍然失败,这是因为在先前失败的初始化操作时已经为Kubernetes创建了一些配置文件,因为已经有存在的配置文件,所有无法初始化。
解决方法:
使用kubeadm reset命令重置kubeadm配置文件。
九、Kubernetes命令自动补全
yum install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc