共使用3台服务器,依次配置hostname
、固定IP
、hosts
、防火墙、selinux
和Swap
。
节点类型 | IP |
HOSTNAME |
---|---|---|
master |
10.10.10.117 |
k8smaster.geoscene.cd |
node-1 |
10.10.10.115 |
k8snode1.geoscene.cd |
node-2 |
10.10.10.116 |
k8snode2.geoscene.cd |
master
服务器:hostnamectl --static set-hostname k8smaster.geoscene.cd
node-1
服务器:hostnamectl --static set-hostname k8snode1.geoscene.cd
node-2
服务器:hostnamectl --static set-hostname k8snode2.geoscene.cd
编辑文件/etc/sysconfig/network-scripts/ifcfg-ens192
,修改BOOTPROTO
的值为static
,并在文件追加:
IPADDR="10.10.10.117"
GATEWAY="10.10.10.1"
NETMASK="255.255.255.0"
DNS1="114.114.114.114"
为3台服务器配置对应固定IP
,配置完成后,重启服务器。
使用命令ip addr
和ping www.baidu.com
验证固定IP
配置是否成功。
配置每台服务器的host
,让每台服务器可以使用域名互相访问。在每台服务器中执行:
cat << EOF >> /etc/hosts
10.10.10.117 k8smaster.geoscene.cd
10.10.10.115 k8snode1.geoscene.cd
10.10.10.116 k8snode2.geoscene.cd
EOF
配置完成后,使用命令ping k8smaster.geoscene.cd
验证配置是否成功。
k8s
集群需要打开多个端口,由于在内网中部署,暴力一点,关闭服务器防火墙
systemctl stop firewalld
systemctl disable firewalld
SELinux
,安全增强型Linux
,是一种采用安全架构的Linux
系统。因为我们不是专业的Linux
运维工程师,并且防止在后续部署过程中遇到因为SELinux
产生的问题,这里直接关闭SELinux
。
SELinux
是否开启:执行命令/usr/sbin/sestatus -v
,查看SELinux status
的状态是否为enabled
SELinux
:编辑文件vi /etc/selinux/config
,设置SELINUX
为disabled
k8s
想法是将实例紧密包装到尽可能接近100%,所有的部署都应该与CPU
、内存限制固定在一起。所以,如果调度程序发送一个Pod
到一台机器,它不应该使用交换。同时,k8s
的设计者考虑到性能的原因,关闭swap
。如果在运行容器数量较多时,考虑节省资源的资源,可以添加kubelet
参数--fail-swap-on=false
来解决这个问题。
关闭Swap
的步骤:
swapoff -a
/etc/fstab
,注释swap
所在的行这里的容器运行时指的是:负责容器运行的软件,可选的有:containerd
、docker
和CRI-O
,我们选择docker
作为容器运行时。
配置k8s
集群,需要为每个节点安装一个容器运行时,用来为Pod
提供运行环境。
Cgroups
是Linux
内核提供的一种可以限制单个进程或者多个进程所使用的资源的机制,可以对CPU
、内存等资源实现精细化的控制。Docker
就使用Cgroups
来对CPU
、内存等部分资源进行控制。
如果Linux
系统发行版使用systemd
来初始化系统时,初始化进程会生成并使用一个root
控制组,充当cgroup
管理器。这时systemd
和Cgroups
紧密集成,并将为每个systemd
单位分配一个Cgroup
。更多Cgroup
的内容可查看这里。
在安装容器运行时和kubelet
时,可以为其指定一个Cgroups
管理器,但k8s
官网并不推荐这种配置,在资源压力下会变得不稳定。
容器运行时和kubelet
以及systemd
使用同一个Cgroups
管理器,单个管理器会简化分配资源的视图,并且默认情况下对可用资源和使用的资源具有更一直的管理。
对于Docker
容器运行时,可以设置native.cgroupdriver=system
选项来配置。
需要在所有的服务器节点中安装Docker
。
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
Docker
仓库sudo yum-config-manager --add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
Docker CE
sudo yum update -y && sudo yum install -y \
containerd.io-1.2.13 \
docker-ce-19.03.11 \
docker-ce-cli-19.03.11
Docker Daemon
## 创建/etc/docker目录
sudo mkdir /etc/docker
## 设置Docker Daemon
cat <
Docker
开机启动sudo mkdir -p /etc/systemd/system/docker.service.d
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl enable docker
ifconfig -a
查看网络的MAC
地址,其中ether
后面的为网卡的MAC
地址$ ifconfig -a
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:b1:ea:dc:9b txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.10.10.117 netmask 255.255.255.0 broadcast 10.10.10.255
inet6 fe80::a3b1:f5:ed45:867d prefixlen 64 scopeid 0x20<link>
inet6 fe80::91b6:36c5:d7ee:7ae9 prefixlen 64 scopeid 0x20<link>
inet6 fe80::60d1:71b4:d966:e79d prefixlen 64 scopeid 0x20<link>
ether 00:50:56:8c:00:10 txqueuelen 1000 (Ethernet)
RX packets 193219 bytes 376026738 (358.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 179064 bytes 15122260 (14.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 64 bytes 5568 (5.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 64 bytes 5568 (5.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
cat /sys/class/dmi/id/product_uuid
对product_uuid
校验正常情况,硬件设备的网络MAC
地址和product_uuid
都会有唯一值,但是虚拟机中可能会存在重复值。如果这两个配置不唯一,在安装kubeadm
时可能会失败。
使用命令lsmod | grep br_netfilter
来查看br_netfilter
模块是否被加载。如果该模块没有被加载,可执行sudo modprobe br_netfilter
来加载该模块。
设置服务节点中给的sysctl
配置中的net.bridge.bridge-nf-call-iptables
值为1
$ cat <
需要在每台服务器中安装:
kubeadm
,用来初始化集群的指令kubelet
,在集群中的每个节点上用来启动Pod
和容器等kubectl
,用来与集群通信的命令行工具kubeadmin
、kubelet
和kubectl
需要单独安装,因此,需要确保他们的版本相匹配。关于版本的偏差可参考:
Kubernetes
版本与版本键的偏差策略Kubeadm
特定的版本偏差策略$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
$ setenforce 0
$ sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
$ yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
$ systemctl enable --now kubelet
如果使用Docker
作为容器进行时,kubeadm
会自动为其监测cgroup
驱动并在运行时对/var/lib/kubelet/kubeadm-flags.env
文件进行配置。
如果使用CRI-O
作为容器进行时,需要为kubeadm init
传递cgroupdriver
值。
这里我们使用Docker
作为容器进行时,跳过这一步即可。
k8smaster.geoscene.cd
服务器中执行:$ kubeadm init \
--apiserver-advertise-address=10.10.10.117 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
其中,
--apiserver-advertise-address
,API
服务器所公布的其正在监听的IP
地址,如果没有设置,将会使用默认网络接口--image-repository
,拉取镜像的容器仓库--service-cidr
,为服务的虚拟IP
地址另外指定的IP
地址段,默认值为"10.96.0.0/12"--pod-network-cidr
, 指明 pod 网络可以使用的 IP 地址段。如果设置了这个参数,控制平面将会为每一个节点自动分配 CIDRs
命令运行成功后需要记录返回信息的最后一行,即:kubeadm join 10.10.10.117:6443 --token **** --discovery-token-ca-cert-hash sha256:dd74bd1b52313dd8664b8147cb6d18a6f8b25c6c5aa4debc3
,这条命令用来在工作节点中使用,将其添加到master
节点中。
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
Pod
网络插件$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
node
节点中执行命令,将node
节点添加到master
节点中$ kubeadm join 10.10.10.117:6443 --token **** --discovery-token-ca-cert-hash sha256:dd74bd1b52313dd8664b8147cb6d18a6f8b25c6c5aa4debc3
master
节点中使用命令kubectl get nodes
查看节点加载情况,刚刚加入的node
节点的status
为NOT Ready
,需要等待7~8分钟左右才能变成Ready
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8smaster.geoscene.cd Ready control-plane,master 93m v1.20.4
k8snode1.geoscene.cd Ready 88m v1.20.4
k8snode2.geoscene.cd Ready 88m v1.20.4
Dashboard
是基于网页的K8S
用户界面,展示了K8S
集群中的资源状态信息和所有报错信息。部署K8S
集群时,不会默认安装Dashboard
,需要单独安装。
安装Dashboard
也很简单,命令如下:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
Dashboard
默认使用API Server
的方式访问,访问起来很麻烦,访问URL
一大串。可以把访问的方式改成NodePort
,这样可以通过IP:PORT
的方式来访问。
使用命令kubectl --namespace=kubernetes-dashboard edit service kubernetes-dashboard
编辑Dashboard
配置文件,将里面的type: ClusterIP
改为type: NodePort
。
使用命令kubectl --namespace=kubernetes-dashboard get service kubernetes-dashboard
查看Dashboard
对外映射接口。
$ kubectl --namespace=kubernetes-dashboard get service kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard NodePort 10.104.86.86 443:32730/TCP 92m
这样在公司内网中就可以通过访问10.10.10.117:32730
来访问Dashboard
。
默认访问Dashboard
,会提示输入Token
或者提供Kubeconfig
文件来登录。需要为集群创建一个管理员账号,并生成Token
来登录Dashboard
。
$ kubectl create serviceaccount dashboard-admin -n kube-system
$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
$ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
可记录输出结果中的token
信息,或者每次登录前执行最后一条命令来获取token
。