1 服务器配置
共使用3台服务器,依次配置
hostname
、固定
IP
、
hosts
、防火墙、
selinux
和
Swap
。
节点类型 |
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
1.1 配置HOSTNAME
-
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
1.2 配置固定IP
编辑文件
/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
配置是否成功。
1.3 配置HOSTS
配置每台服务器的
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
验证配置是否成功。
1.4 配置防火墙
k8s
集群需要打开多个端口,由于在内网中部署,暴力一点,关闭服务器防火墙
systemctl stop firewalld
systemctl disable firewalld
1.5 配置selinux
SELinux
,安全增强型
Linux
,是一种采用安全架构的
Linux
系统。因为我们不是专业的
Linux
运维工程师,并且防止在后续部署过程中遇到因为
SELinux
产生的问题,这里直接关闭
SELinux
。
-
查看
SELinux
是否开启:执行命令
/usr/sbin/sestatus -v
,查看
SELinux status
的状态是否为
enabled
-
关闭
SELinux
:编辑文件
vi /etc/selinux/config
,设置
SELINUX
为
disabled
1.6 配置Swap
k8s
想法是将实例紧密包装到尽可能接近100%,所有的部署都应该与
CPU
、内存限制固定在一起。所以,如果调度程序发送一个
Pod
到一台机器,它不应该使用交换。同时,
k8s
的设计者考虑到性能的原因,关闭
swap
。如果在运行容器数量较多时,考虑节省资源的资源,可以添加
kubelet
参数
--fail-swap-on=false
来解决这个问题。
关闭
Swap
的步骤:
-
swapoff -a
-
编辑
/etc/fstab
,注释
swap
所在的行
2 部署容器运行时
这里的
容器运行时
指的是:负责容器运行的软件,可选的有:
containerd
、
docker
和
CRI-O
,我们选择
docker
作为容器运行时。
配置
k8s
集群,需要为每个节点安装一个容器运行时,用来为
Pod
提供运行环境。
2.1 为容器进行时配置Cgroups
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
选项来配置。
2.2 安装Docker
需要在所有的服务器节点中安装
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 <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
-
配置
Docker
开机启动
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl enable docker
3 安装kubeadm、kubelet和kubectl
3.1 查看节点MAC地址和product_uuid的唯一性
-
通过命令
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
时可能会失败。
3.2 允许iptables检查桥接流量
使用命令
lsmod | grep br_netfilter
来查看
br_netfilter
模块是否被加载。如果该模块没有被加载,可执行
sudo modprobe br_netfilter
来加载该模块。
设置服务节点中给的
sysctl
配置中的
net.bridge.bridge-nf-call-iptables
值为1
$ 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
3.3 安装kubeadm、kubelet和kubectl
需要在每台服务器中安装:
-
kubeadm
,用来初始化集群的指令 -
kubelet
,在集群中的每个节点上用来启动
Pod
和容器等 -
kubectl
,用来与集群通信的命令行工具
kubeadmin
、
kubelet
和
kubectl
需要单独安装,因此,需要
确保
他们的版本相匹配。关于版本的偏差可参考:
$ 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
3.4 在控制平面节点(主节点)上配置kublet使用的cgroup管理器
如果使用
Docker
作为
容器进行时
,
kubeadm
会自动为其监测
cgroup
驱动并在运行时对
/var/lib/kubelet/kubeadm-flags.env
文件进行配置。
如果使用
CRI-O
作为
容器进行时
,需要为
kubeadm init
传递
cgroupdriver
值。
这里我们使用
Docker
作为
容器进行时
,跳过这一步即可。
4 配置master节点
-
在
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
5 配置node节点
-
在
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 <none> 88m v1.20.4
k8snode2.geoscene.cd Ready <none> 88m v1.20.4
6 部署Dashboard
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 <none> 443:32730/TCP 92m
这样在公司内网中就可以通过访问
10.10.10.117:32730
来访问
Dashboard
。
7 创建管理员账号
默认访问
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
。