先期工作
机器集群实现方案
手头并没有现成的机器群,但好在有一台还算高配的MacBook Pro,如此的话可以在其上借助于虚拟机构建出一个5台机器的集群,在此基础上来搭建Kubernetes集群:
1 | MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports) |
项目 | 选件 | 理由 |
---|---|---|
虚拟机 | VirtualBox | 主要考虑Oracle Virtual Box和VMware Fusion,Vbox提供丰富 的命令工具来操作虚拟机,这使得我们能够方便地基于此来编写 一些控制脚本方便地控制集群机器,所以虚拟机选择VBox |
操作系统 | CentOS 7.9 | 主要考虑的是主流的RHEL、CentOS、Fedora、Ubuntu等等, RHEL/CentOS/Fedora同出一脉,Fedora作为试验先行版自然是不考虑 了,CentOS比较主流,是首选,版本的话也是选择目前的主流版本7 |
Kubernetes集群设计
计划使用6台虚拟机来构建集群,集群机器的IP、Hostname等的设计如下:
Hostname | IP Address | 备注说明 |
---|---|---|
worker-st.xcluster.io | 192.168.99.100 | 不作为K8s集群的一部分,而是安装 jenkins/gitlab….等CICD Devops工具 |
worker-01.xcluster.io | 192.168.99.101 | 作为K8s集群的master节点,负责管理其他节点 |
worker-02.xcluster.io | 192.168.99.102 | 作为K8s集群的1号Node机器,负责跑Pods |
worker-03.xcluster.io | 192.168.99.103 | 作为K8s集群的2号Node机器,负责跑Pods |
worker-04.xcluster.io | 192.168.99.104 | 作为K8s集群的3号Node机器,负责跑Pods |
worker-05.xcluster.io | 192.168.99.105 | 作为K8s集群的4号Node机器,负责跑Pods |
参考文档列表
- 在CentOS集群上部署DNS服务
- https://kubernetes.io/zh/docs/home/
- https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
- https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
创建服务器群
创建CentOS7样机
这一步的目的是创建出一台基础的CentOS7虚拟机并做好基础设置,然后基于该机器再克隆出其他机器,首先是创建第一台(worker-st.xcluster.io)并完成基本配置:
下载CentOS7.9镜像:http://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/
安装好VBox后创建一个虚拟机,配置如下:
名称:Worker-st、类型:Linux、版本:Red Hat (64bit)
内存:4096MB、CPU:双核、显存:64MB、显示器:2个、显示器显示比例:200%
磁盘类型:Normal (VMDK)、磁盘容量:300.00 GB(单个文件、动态增长)
网卡1:NAT、适配器类型:Paravirtualized Network (virtio-net) —— 用以跟MBP共享网络
网卡2:Host-only Adapter — — 用以设置静态IP(192.168.99.XX)
两张网卡的Promiscuous Mode均为默认值:Deny
在虚拟机磁盘中选择下载好的CentOS 7.9的ISO镜像,然后启动虚拟机进行系统安装,安装期间系统设置如下:
- 语言:English (United States)、键盘:English (United States)
- 磁盘分区:自动、Root密码:123456abc、创建管理账户:fury,密码为:123456abc
安装完成后以root登录,然后设置静态IP,这样可以直接从MBP的Terminal远程登录进机器,操作更方便一些(直接从虚拟机的黑框框登录的话,由于显示比例的问题,操作不是很方便):
安装net-tools(包含ifconfig):
$ sudo yum install net-tools
启用SSH登录:添加MBP的公钥到
~/.ssh/authorized_keys
,重启SSHD,修改.ssh
目录权限1
2
3$ sudo service sshd restart
$ sudo chmod 700 ~/.ssh
$ sudo chmod 600 ~/.ssh/authorized_keys设置静态IP
设置DNS
$ sudo vi /etc/resolv.conf
,加入nameserver 114.114.114.114
查看现有网卡:
$ ifconfig -a
配置两张网卡(路径
/etc/sysconfig/network-scripts/
):备份enp0s3配置文件,并拷贝为ifcfg-eth0,内部改name和device为eth0(如果文件内没有HWADDR字段则加上,值为虚拟机网卡设置那里看到的MAC地址
HWADDR=00:0C:29:7C:00:34
),修改ONBOOT=yes
以自启动网卡创建ifcfg-eth1文件,设置内容如下(配置第二张网卡为静态IP):
1
2
3
4
5
6
7DEVICE=eth1
HWADDR=00:0C:29:84:35:09
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.99.100
NETMASK=255.255.255.0
NAME=eth1HWADDR为虚拟机上第二张网卡的MAC地址
然后重启:
$ sudo service network restart
,可能会发现提示错误查看
$ sudo journalctl -xe
或查看错误日志看看是哪个网卡没起来:$ cat /var/log/messages | grep network
,发现说eth0没起来,它的UUID和eth1冲突了,把eth0的UUID删掉(确认HWADDR是第一张网卡的MAC地址),然后重启即可(UUID会自动加上)。
重启系统,这样以后就可以通过MBP的Terminal如下命令开启、登录、关闭虚拟机(XXX为虚拟机名称):
- 开启虚拟机:
$ VBoxManage startvm XXX -type vrdp
- 登录虚拟机:
$ ssh [email protected]
- 关闭虚拟机:
$ VBoxManage controlvm XXX poweroff
其他的基础设置:
安装wget下载工具:
$ sudo yum install wget
修改hostname:
$ sudo vi /etc/hostname
,设置为worker-st.xcluster.io
修改shell显示名:
$ sudo vi ~/.bashrc
添加export PS1='[\[email protected] \W]\$ '
使用阿里云的Repo(备份原
/etc/yum.repos.d/
下的repo文件然后清空该文件夹):1
2
3
4
5$ cd /etc/yum.repos.d/
$ wget http://mirrors.aliyun.com/repo/Centos-7.repo
$ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
$ wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
$ yum clean all && yum makecache安装Vim8.x:
安装所需的基础库:
1
$ yum install -y gcc gcc-c++ ruby ruby-devel lua lua-devel ctags git python python-devel tcl-devel ncurses-devel perl perl-devel perl-ExtUtils-ParseXS perl-ExtUtils-CBuilder perl-ExtUtils-Embed
下载Vim-v8.1:
1
2
3$ wget https://github.com/vim/vim/archive/v8.1.1312.tar.gz
$ tar -zxvf v8.1.1312.tar.gz
$ cd vim-8.1.1312开始安装:
--with-python-config-dir
这项要看自己的实际路径,是python-devel带的目录1
2
3
4
5
6
7
8
9
10
11$ ./configure --with-features=huge \
--enable-multibyte \
--enable-rubyinterp=yes \
--enable-pythoninterp=yes \
--with-python-config-dir=/usr/lib64/python2.7/config \
--enable-perlinterp=yes \
--enable-luainterp=yes \
--enable-cscope \
--prefix=/usr/local
$ make -j4 VIMRUNTIMEDIR=/usr/local/share/vim/vim81 all
$ sudo sudo make -j4 install更改系统默认编辑器并将vi指向vim
1
2
3
4$ sudo update-alternatives --install /usr/bin/editor editor /usr/local/bin/vim 1
$ sudo update-alternatives --set editor /usr/local/bin/vim
$ sudo update-alternatives --install /usr/bin/vi vi /usr/local/bin/vim 1
$ sudo update-alternatives --set vi /usr/local/bin/vim
安装其他基础软件:
1
2$ sudo yum install unzip zip
$ sudo yum install gcc gcc-c++ glibc
至此,我们创建好了一台基础的CentOS7虚拟机,这台机器将作为集群设计里面的第一台worker-st.xcluster.io。
创建Kubernetes样机
这一步在创建好的CentOS7虚拟机样机的基础上安装Kubernetes集群都需要安装的一些组件。从上一步创建好的虚拟机克隆出一台新的虚拟机,克隆时名称改为Worker-01
并选择完全克隆方式。克隆完成后在虚拟机的网卡设置当中刷新两张网卡的MAC地址,然后启动虚拟机,进入虚拟机后做如下修改:
注意:后面基于这台机器克隆其他k8s集群机器时也要做如下这些方面对应的修改
- 修改eth0和eth1的MAC地址和eth1的IP地址(路径
/etc/sysconfig/network-scripts/
)- eth0和eth1的MAC地址(HWADDR)可以从虚拟网卡设置界面获得
- IP地址按照一开始的设计,我们把IP改为
192.168.99.101
- 修改hostname为
worker-01.xcluster.io
- 修改shell显示名:
$ vi ~/.bashrc
添加export PS1='[\[email protected] \W]\$ '
其他为Kubernetes进行的配置:
关闭防火墙:
$ sudo systemctl stop firewalld && systemctl disable firewalld
永久关闭selinux:
$ sudo vim /etc/selinux/config
修改:1
2#SELINUX=enforcing
SELINUX=disabled永久关闭swap:
$ sudo vim /etc/fstab
注释最后一行(swap)配置yum源(自带的kubernetes版本可能比较低):安装方式(生产,kubeadmin)
$ cd /etc/yum.repos.d/
$ vim kubernetes.repo
1
2
3
4
5
6
7[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg$ sudo yum clean all && yum makecache
安装docker
1
2$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
$ sudo yum -y install docker由于内核可能不支持 overlay2所以需要升级内核或者禁用overlay2(选择禁用,安装完docker可以启动docker测试下是否支持,启动docker不报错的可以忽略这一步):
$ sudo vim /etc/sysconfig/docker
修改--selinux-enabled=false
自启动docker服务:
$ sudo systemctl start docker && systemctl enable docker
设置服务器时区:
$ sudo timedatectl set-timezone Asia/Shanghai
设置k8s相关参数:
$ sudo vim /etc/sysctl.d/k8s.conf
1
2net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1让其生效
1
2$ sudo sysctl -p
$ sudo echo "1" > /proc/sys/net/ipv4/ip_forward
安装k8s相关安装包,使用
$ sudo yum list kube*
来查看当前yum源支持的最新版本(这里是1.20.1-0)1
$ sudo yum -y install kubeadm-1.20.1-0 kubelet-1.20.1-0 kubectl-1.20.1-0
自启动服务:
$ sudo systemctl restart kubelet && systemctl enable kubelet
到这里完成了第二台样机设置,这台机器将作为k8s集群的master机器(worker-01.xcluster.io
),其他机器将以这台为样本进行克隆配置。
克隆其他K8s集群机器
基于第二台样机(worker-01.xcluster.io
),克隆出其他的4台机器,注意按上面的提示对应修改MAC地址、IP、hostname、shell显示名等相关信息:
Hostname | IP Address | 备注说明 |
---|---|---|
worker-02.xcluster.io | 192.168.99.102 | 集群1号Node机器 |
worker-03.xcluster.io | 192.168.99.103 | 集群2号Node机器 |
worker-04.xcluster.io | 192.168.99.104 | 集群3号Node机器 |
worker-05.xcluster.io | 192.168.99.105 | 集群号Node机器 |
配置K8s集群
到这里,我们创建好了6台CentoOS服务器,第一台后面作为安装Jenkins/gitlab等工具的机器,不纳入k8s集群,后面5台都安装了k8s相关包和docker,这5台将作为我们的k8s集群机器,这些机器的配置目前是一样的,接下来对第一台机器(worker-01.xcluster.io
)进行设置(初始化k8s集群让其成为master)。
初始化配置Master
在master机器上执行初始化操作,即worker-01.xcluster.io
这台机;注意坑点:
- 如果要用flannel:
- 如果想配合使用dashboard,建议直接放弃,可改用weave,详细可以见这里
- 安装前,使用kubeadm init的时候,参数里记得指定service-cidr.
- 关于flannel和weave:https://www.cnblogs.com/kevingrace/p/6859114.html
- 如果要用weave:
- 安装前,使用kubeadm init的时候,参数里记得不要指定service-cidr参数,但要保留pod-network-cidr. 不然内置的DNS会出问题,这可能是系统的bug。
1 | $ sudo kubeadm init \ |
可以看到初始化已经OK了,通过26行的代码可以在其他node上执行以让master发现(加入k8s集群)。
安装flannel:
下载https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml,然后
$ sudo kubectl apply -f kube-flannel.yml
到这里master就初始化完毕了。
其他节点加入K8s集群
将node节点加入到master集群中,在需要加入k8s集群的node节点上执行该命令(上面的输出)
1
2$ sudo kubeadm join 192.168.99.101:6443 --token 9k35nl.lyfuzdlxzqbwonsr \
--discovery-token-ca-cert-hash sha256:91f6bd754f302b858b02d02f16e164d72b39a9ebcba841931e1e80388fd91910如果忘记kubeadm join后的参数,可用通过下面命令来获取新的:
1
$ sudo kubeadm token create --print-join-command
在Worker-02上的操作结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16[[email protected] ~]$ sudo kubeadm join 192.168.99.101:6443 --token 9k35nl.lyfuzdlxzqbwonsr --discovery-token-ca-cert-hash sha256:91f6bd754f302b858b02d02f16e164d72b39a9ebcba841931e1e80388fd91910
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
[[email protected] ~]$
在其他的Worker上执行相同操作来加入集群,正常的话在master上执行``即可看到其他node的状态:
1 | [[email protected]rker-01 ~]$ sudo kubectl get nodes |
常用的kubernetes命令
$ sudo systemctl start|restart|stop kubelet
:开启、重启、停止kubelet$ sudo systemctl status -l kubelet
:查看集群启动状态$ sudo jornalctl -f -u kubelet
:查看集群日志$ sudo kubectl get <node|nodes>
:列出所有node(及其状态)$ sudo kubectl delete node|nodes> <node name>
:删除集群节点$ sudo kubectl get <pod|pods> [-n <namespace>]
:列出所有的pods$ sudo kubectl get <svc|service|services> [-n <namespace>]
:列出所有的服务$ sudo kubectl apply -f <deployment.yml>
:部署一个服务$ sudo kubectl delete -f <deployment.yml>
:移除一个服务$ sudo kubectl logs -f <pod name> [-n <namespace>]
:查看某个pod日志
安装配置过程中的问题
在master上执行
$ sudo kubectl get nodes
报错:The connection to the server localhost:8080 was refused - did you specify the right host or port?解决:
1
2$ echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
$ sudo source ~/.bash_profile执行完
$ sudo kubeadm join
后在master节点执行$ sudokubectl get nodes
发现Node节点状态为NotReady;在node节点查看日志
$ sudo journalctl -f -u kubelet
找到具体错误原因:summary_sys_containers.go:47] Failed to get system container stats for “/system.slice/kubelet.service”: failed to get cgroup stats for “/system.slice/kubelet.service”: failed to get container info for “/system.slice/kubelet.service”: unknown container “/system.slice/kubelet.service”
解决:是kubernetes和docker版本兼容性问题,启动时添加参数:**–runtime-cgroups=/systemd/system.slice –kubelet-cgroups=/systemd/system.slice**即可:
开机自启动的服务是通过
$ sudo systemctl enable xxx
来配置,该命令执行后会在/etc/systemd/system/multi-user.target.wants/
目录下新建一个/usr/lib/systemd/system/xxx.service
的文件并创建软连接到当前目录在
/usr/lib/systemd/system/xxx.service
同目录下找到kubelet.service.d
文件夹,有个/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
文件,编辑,在KUBELET_CGROUP_ARGS属性添加:1
--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice
如果不存在”KUBELET_CGROUP_ARGS”属性则新增,同时在
ExecStart=/usr/bin/kubelet ....
后新增$KUBELET_CGROUP_ARGS
10-kubeadm.conf的路径网上提到的多为:*/etc/systemd/system/kubelet.service.d/10-kubeadm.conf*,本人的机器路径为:/usr/lib/systemd/system/kubelet.service.d
然后重启
$ sudo systemctl daemon-reload && systemctl restart kubelet
即可解决。
执行
$ sudo journalctl -f -u kubelet
或者$ sudo systemctl status -l kubelet
发现日志中存在错误或警告:Unable to read config path “/etc/kubernetes/manifests”: path does not exist, ignoring
解决:执行
$ sudo mkdir -p /etc/kubernetes/manifests
然后重启kubelet。failed to sync configmap cache: timed out waiting for the condition
解决:新增(编辑)
/var/lib/kubelet/config.yaml
添加1
2featureGates:
CSIMigration: false然后重启所有node。
failed to collect filesystem stats - rootDiskErr: could not stat
解决:不支持overlay2导致的,编辑docker配置
$ sudo vim /etc/sysconfig/docker
修改--selinux-enabled=false
然后重启docker$ sudo systemctl restart docker
MemoryAccounting not enabled for pid: 1215, CPUAccounting not enabled for pid: 1208
查看这两个进程:
$ sudo ps -a 1208
、# ps -a 1215
:1
2
3
4
5
6
7
8[[email protected] ~]$ sudo ps -a 1208
PID TTY STAT TIME COMMAND
1208 ? Ssl 0:12 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=d
8015 pts/0 R+ 0:00 ps -a 1208
[[email protected] ~]$ sudo ps -a 1215
PID TTY STAT TIME COMMAND
1215 ? Ssl 0:32 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/ku
8079 pts/0 R+ 0:00 ps -a 1215查看内存使用情况:
$ free -h
1
2
3
4
5[[email protected] ~]$ free -h
total used free shared buff/cache available
Mem: 3.7G 868M 2.0G 10M 840M 2.6G
Swap: 0B 0B 0B
[[email protected] ~]$并没有存在内存不够的情况。
解决:明确指定DefaultCPUAccounting和DefaultMemoryAccounting即可
1
2
3
4
5
6$ sudo mkdir -p /etc/systemd/system.conf.d
$ sudo vim /etc/systemd/system.conf.d/kubernetes-accounting.conf
[Manager]
DefaultCPUAccounting=yes
DefaultMemoryAccounting=yes
$ sudo systemctl daemon-reload && systemctl restart kubelet
执行
$ sudo kubectl get pods
: No resources found in default namespace解决:不指定命名空间时默认在default这个命名空间;通过**-n**参数指定,系统命名空间为
kube-system
:1
$ sudo kubectl get pods -n kube-system