参考书籍: [再也不踩坑的Kubernetes实战指南]
本节主要演示使用 kubeadm 安装 Kubernetes 高可用集群,测试环境可以采用 kubeadm 安装,这也是目前官方默认的安装方式,比二进制安装方式更简单,可以让初学者快速上手并测试。目前 GitHub 上也有很多基于 Ansible 的自动化安装方式,但是为了更好地学习 Kubernetes,还是建议体验一下 Kubernetes 的手动安装过程,以熟悉 Kubernetes 的各个组件。
集群安装时
环境设置
本次安装使用 5 台 Linux 服务器,系统版本为 CentOS 7.9,分别为 3 台 Master,2台 Node。Master 节点主要部署的组件有 Keepalived,HAProxy,Etcd,Kubelet,APIServer,Controller,Scheduler;Worker 节点主要部署的为 Kubelet。详情见下表
- 集群规划
主机名 | IP 地址 | 角色 |
---|---|---|
k8s-master-01 | 192.168.200.18 | Master01 |
k8s-master-02 | 192.168.200.19 | Master02 |
k8s-master-03 | 192.168.200.20 | Master03 |
k8s-node-01 | 192.168.200.21 | Node01 |
k8s-node-02 | 192.168.200.22 | Node02 |
k8s-master-lb | 192.168.200.110 | 负载均衡(VIP) |
- 软件版本
配置信息 | 备注 |
---|---|
系统版本 | CentOS 7.9 |
Docker 版本 | 19.03.9 |
Pod 网段 | 172.168.0.0/12 |
Service 网段 | 10.96.0.0/12 |
基础配置
各节点通信采用主机名的方式,这种方式与 IP 地址相比更具有扩展性。所有节点配置 hosts 解析,修改 /etc/hosts 配置文件,如下:
1
2
3
4
5
6
7
8
9
10
11cat > /etc/hosts <<EOF
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.200.18 k8s-master-01
192.168.200.19 k8s-master-02
192.168.200.20 k8s-master-03
192.168.200.21 k8s-node-01
192.168.200.22 k8s-node-02
192.168.200.110 k8s-master-lb
EOF所有节点关闭防火墙,selinux,swap。如果在公有云上部署,可以通过安全组进行安全配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# 关闭 Firewalld
systemctl disable --now firewalld
# 关闭 dnsmasq
systemctl disable --now dnsmasq
# 关闭 NetworkManager,主要是为了 calico 网络
systemctl disable --now NetworkManager
# 关闭 SeLinux
setenforce 0
# 永久关闭 selinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 关闭 Swap 分区
swapoff -a && sysctl -w vm.swappiness=0
# 注释 swap 挂载项
sed -ri 's/.*swap.*/#&/' /etc/fstab所有节点同步时间设置,所有节点同步时间是必须的,并且需要加到开机自启动和计划任务中,如果节点时间不同步,会造成 Etcd 存储 Kubernetes 信息的键-值(Key-Value) 数据库同步数据不正常,也会造成证书出现问题。时间同步配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 安装时间同步软件 ntpdate
yum install -y ntpdate
# 设置时区
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' > /etc/timezone
# 手动同步时间
ntpdate time2.aliyun.com
# 添加定时任务
echo '*/5 * * * * /usr/sbin/ntpdate time2.aliyun.com >/dev/null' >> /var/spool/cron/root
# 添加开机启动执行
echo '/usr/sbin/ntpdate time2.aliyun.com' >> /etc/rc.local所有节点配置 limit
1
2
3
4
5
6
7
8
9
10# 临时设置
ulimit -SHn 65535
# 永久设置
sed -i '/^# End/i\* soft nofile 655350' /etc/security/limits.conf
sed -i '/^# End/i\* hard nofile 131072' /etc/security/limits.conf
sed -i '/^# End/i\* soft nproc 655350' /etc/security/limits.conf
sed -i '/^# End/i\* hard nproc 655350' /etc/security/limits.conf
sed -i '/^# End/i\* soft memlock unlimited' /etc/security/limits.conf
sed -i '/^# End/i\* hard memlock unlimited' /etc/security/limits.conf在 k8s-master-01 节点配置免密登录其他节点,安装过程中生成的配置文件和证书均在 k8s-master-01 上操作,集群管理也在该节点上操作,阿里云或者 AWS 上需要单独一台 kubectl 服务器。秘钥配置如下:
1
2ssh-keygen -t rsa
for i in k8s-master-01 k8s-master-02 k8s-master-03 k8s-node-01 k8s-node-02;do ssh-copy-id -i .ssh/id_rsa.pub root@$i;done配置所有节点使用国内 yum 源
1
2
3
4
5
6
7
8
9# 首先确保服务器上安装了 curl 或者 wget 命令
cd /etc/yum.repos.d && mkdir bak && mv *.repo bak
# 下载阿里云的 CentOS yum 仓库文件
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新版本的 kube-proxy 默认支持的代理模式为 ipvs 模式,性能比 iptables 要强,如果服务器未配置安装 ipvs,将转换为 iptables 模式。
所有节点安装配置 ipvsadm:1
yum install -y ipvsadm ipset sysstat conntrack libseccomp
所有节点配置 ipvs 模块(在内核 4.19版本的 nf_conntrack_ipv4 已经改为 nf_conntrack)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
modprobe -- ip_tables
modprobe -- ip_set
modprobe -- xt_set
modprobe -- ipt_set
modprobe -- ipt_rpfilter
modprobe -- ipt_REJECT
modprobe -- ipip
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules && lsmod |grep -e ip_vs -e nf_conntrack_ipv4调整内核参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26cat > /etc/sysctl.d/kubernetes.conf <<EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory = 1
vm.panic_on_oom = 0
fs.inotify.max_user_watches = 89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max = 2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
net.ipv4.tcp_tw_recycle=0
EOF
sysctl --system所有节点升级系统并重启(可选)(此处没有升级内核)
1
2yum install -y jq psmisc
yum update -y --execlude=kernel* && reboot
安装 Docker-CE
所有节点安装 Docker
1
2
3
4
5
6
7
8
9
10
11
12# 基本工具安装
yum install -y yum-utils device-mapper-persistent-data lvm2
# Docker 源配置
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
# 查看可用 Docker 版本
yum list docker-ce --showduplicates |sort -r
# 安装指定版本 Docker,按需修改
yum install -y docker-ce-19.03.9所有节点配置 Docker 镜像加速
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"],
"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 并配置服务开机启动
1
systemctl enable --now docker.service
检查 Docker 是否正常运行
1
systemctl status docker
安装高可用服务
本例高可用采用的是 HAProxy + Keepalived,HAProxy 和 Keepalived 以守护进程的方式在所有 Master 节点部署。
安装 HAProxy 以及 Keepalived,通过 yum 的方式在所有 Master 节点安装 HAProxy 以及 Keepalived。
1
yum install -y keepalived haproxy
创建 HAProxy 服务的配置文件,所有 Master 节点的 HAProxy 配置相同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70# 备份原始的配置文件
mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy_ori.cfg
# 新建一个配置文件
cat > /etc/haproxy/haproxy.cfg <<EOF
global
log 127.0.0.1 local0 err
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
ulimit-n 16384
user haproxy
group haproxy
stats timeout 30s
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
timeout http-request 15s
timeout queue 1m
timeout connect 5000
timeout client 50000
timeout server 50000
timeout http-keep-alive 15s
timeout check 15s
maxconn 3000
frontend monitor-in
bind *:33305
mode http
option httplog
monitor-uri /monitor
listen stats
bind *:8006
mode http
stats enable
stats hide-version
stats uri /stats
stats refresh 30s
stats realm Haproxy\ Statistics
stats auth admin:admin
frontend k8s-master
bind 0.0.0.0:8443
bind 127.0.0.1:8443
mode tcp
option tcplog
tcp-request inspect-delay 5s
default_backend K8S-master
backend static
balance roundrobin
server static 127.0.0.1:4331 check
backend K8S-master
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server k8s-master-01 192.168.200.11:6443 check
server k8s-master-02 192.168.200.12:6443 check
server k8s-master-03 192.168.200.13:6443 check
EOF创建 Keepalived 服务配置文件,注意修改每个节点配置文件中的 interface(服务器网卡), priority(优先级), mcast_src_ip(本节点IP)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43# 备份原始配置文件
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived_ori.conf
# 声明变量
export INTERFACE=$(ip route show |grep default |cut -d ' ' -f5)
export IPADDR=$(ifconfig |grep -A1 $INTERFACE |grep inet |awk '{print $2}')
# 创建新的配置文件
cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 2
weight -5
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface ${INTERFACE}
mcast_src_ip ${IPADDR}
virtual_router_id 51
priority 100
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
192.168.200.110
}
# track_script {
# chk_apiserver
# }
}
EOF
# 修改其他 master 节点配置文件的 priority 值
# k8s-master-02 节点改为 priority 101
# k8s-master-03 节点改为 priority 102注意,上述的健康检查是关闭的,集群建立完成后再开启。
配置 Keepalived 健康检查脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24cat > /etc/keepalived/check_apiserver.sh <<EOF
#/bin/bash
function check_apiserver() {
for ((i=0;i<5;i++)); do
apiserver_job_id=$(pgrep kube-apiserver)
if [[ ! -z $apiserver_job_id ]]; then
return
else
sleep 2
fi
apiserver_job_id=0
done
}
# 1:running, 0: stopped
check_apiserver
if [[ $apiserver_job_id -q 0 ]];then
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
EOF启动 HAProxy 和 Keepalived
1
2systemctl enable --now haproxy.service
systemctl enable --now keepalived.service
高可用方式不一定非要采用 HAProxy 和 Keepalived,在云上的话可以使用云上的负载均衡,比如在阿里云上可以使用阿里云内部的 SLB,就无须配置 HAProxy 和 Keepalived,只需要将对应的 VIP 地址改成 SLB 的地址即可。在企业内部可以使用 F5 硬件负载均衡,反向代理到每台 Master 节点的 6443 端口即可。
安装基本组件
本节主要安装的是集群中用到的 Kubernetes 各种组件,包括 kubeadm,kubectl,kubelet
所有节点配置 K8S的 yum 源
1
2
3
4
5
6
7
8
9
10cat <<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卸载旧版本
1
yum remove -y kubelet kubeadm kubectl
查看可用的 Kubeadm 组件版本
1
2
3yum list kubeadm --showduplicates |sort -r
yum list kubectl --showduplicates |sort -r
yum list kubelet --showduplicates |sort -r所有节点安装 k8s 组件。这里安装的是 1.19.7
1
yum install -y kubeadm-1.19.7 kubectl-1.19.7 kubelet-1.19.7
启动 kubelet
1
2systemctl daemon-reload
systemctl enable --now kubelet.service如果此时执行 systemctl status kubelet 命令,将得到 kubelet 启动失败的错误提示,请忽略此错误,因为必须完成后续步骤中 kubeadm init 的操作,kubelet 才能正常启动
集群初始化
Master 节点初始化
kubeadm 的安装方式可以配合使用 kubeadm-config 文件来初始化集群,所以需要提前创建各 Master 节点的 kubeadm-config.yaml 文件。由于国内网络的原因,需要将集群镜像的仓库地址改成 imageRepository:registry.cn-hangzhou.aliyuncs.com/google_containers
。
初始化第一个 Master 节点
创建 kubeadm-config.yaml 文件,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21cat > kubeadm-config.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.19.7
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
controlPlaneEndpoint: "k8s-master-lb:8443"
networking:
dnsDomain: cluster.local
podSubnet: 172.168.0.0/16
serviceSubnet: 10.96.0.0/12
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
ipvs:
minSyncPeriod: 1s
scheduler: rr
syncPeriod: 10s
mode: ipvs
EOF该配置文件直接开启了 ipvs 模式的 rr 模式,这样在初始化完成以后不用再次修改了。其中的 podSubnet 为 Pod 的网段。
将 kubeadm-config.yaml 文件拷贝到其他 Master 节点,然后提前下载镜像
1
for i in k8s-master-02 k8s-master-03;do scp kubeadm-config.yaml root@$i:~/;done
各 master 节点提前下载镜像
1
kubeadm config images pull --config /root/kubeadm-config.yaml
Master01 节点初始化,只需要在一个 master 节点执行
kubeadm init
命令,其他 master 节点采用join
的方式加入集群1
kubeadm init --config=kubeadm-config.yaml --upload-certs
初始化时加入 –upload-certs 参数,无须再复制证书到其他节点,之后 join 时添加 –certificate-key 参数即可自动加入该集群。如果初始化失败,可以使用
kubeadm reset
重置后,再次初始化。最后输出的
kubeadm jion
需要记录下来,后面的 master 节点和 node 节点加入集群时需要使用。如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26Your 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/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join k8s-master-lb:8443 --token v0zrdq.iv8jglod8sk0p6pr \
--discovery-token-ca-cert-hash sha256:61cdf9400c7930d5a47e4b0c064c55397dfe2429ad4ebab15a9c54685d8b0733 \
--control-plane --certificate-key b744a7c50ca8ad5b33ad68c07c0e248dba234d8c9faf2c6798c9d80c25bb6407
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join k8s-master-lb:8443 --token v0zrdq.iv8jglod8sk0p6pr \
--discovery-token-ca-cert-hash sha256:61cdf9400c7930d5a47e4b0c064c55397dfe2429ad4ebab15a9c54685d8b0733配置 kubectl
1
2
3rm -rf /root/.kube/
mkdir /root/.kube/
cp -i /etc/kubernetes/admin.conf /root/.kube/config查看节点状态
1
2
3kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-01 NotReady master 10m v1.19.7因为还没有安装网络查件,所以节点状态为 NotReady,可以在此时将其他 Master 节点与 Worker 节点加入集群,加入方法唯一的区别是,worker 节点加入不需要参数 –control-plane 以及 –certificate-key;在 第一个 master 节点初始化时已经提供了相应的加入命令;该命令 2 小时有效,两小时后加入集群,请参考下面的章节。
安装网络查件
1
2
3
4
5
6
7
8
9
10# 下载 Calico 网络查件 yaml
# 参考文档 https://docs.projectcalico.org/v3.9/getting-started/kubernetes/
# wget https://docs.projectcalico.org/v3.8/manifests/calico.yaml
wget https://kuboard.cn/install-script/calico/calico-3.9.2.yaml
# 修改 POD_CIDR 地址为上面配置的 podSubnet 的值
sed -i -e "s?192.168.0.0/16?172.168.0.0/16?g" calico-3.9.2.yaml
# 使用 kubectl 加载配置
kubectl apply -f calico-3.9.2.yaml当网络查件安装完成后,再次查看节点信息,执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态
1
2
3watch kubectl get pod -n kube-system -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master-01 Ready master 108m v1.19.7 192.168.200.11 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9当所有容器处于 Running 时,查看节点信息
1
2
3
4
5
6
7kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready master 45m v1.19.7
k8s-master-02 Ready master 38m v1.19.7
k8s-master-03 Ready master 37m v1.19.7
k8s-node-01 Ready <none> 37m v1.19.7
k8s-node-02 Ready <none> 37m v1.19.7
初始化其他 Master 节点
和第一个 Master 节点同时初始化
初始化第一个 master 节点时的输出内容中,第15、16、17行就是用来初始化第二、三个 master 节点的命令,如下所示:
1
2
3kubeadm join k8s-master-lb:8443 --token xcjgoy.fo0pogwr2ab6lnou \
--discovery-token-ca-cert-hash sha256:fa09e765ecff81f9027ba78714d3cf3ca00400ccf07db7be9940bee76037c507 \
--control-plane --certificate-key 41a741533a038a936759aff43b5680f0e8c41375614a873ea49fde8944614dd6在其他 Master 节点上分别执行
1 | kubeadm join k8s-master-lb:8443 --token xcjgoy.fo0pogwr2ab6lnou \ |
第一个 Master 节点初始化2小时后再初始化其他节点
获得 certificate key,只在第一个 master 节点上执行以下命令
1
2
3
4
5
6
7
8kubeadm init phase upload-certs --upload-certs
# 输出如下
I0119 12:54:52.212869 99481 version.go:252] remote version is much newer: v1.20.2; falling back to: stable-1.19
W0119 12:54:54.884398 99481 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
c03688c2c838b93ede986f5e6d1e9b91bec27ebe0646623de38b7a4b2069161f获取 join 命令,只在第一个 master 节点执行
1
2
3
4
5kubeadm token create --print-join-command
# 输出如下
W0119 12:56:25.987913 101298 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
kubeadm join 192.168.200.110:8443 --token y795lm.5yp84yj4kdwjpfmq --discovery-token-ca-cert-hash sha256:0d3f73918929912063b907f59393fba6313dc91076d685eecba521789b83ca5a其他 Master 节点的初始化命令如下:
1
2
3
4kubeadm join 192.168.200.110:8443 \
--token y795lm.5yp84yj4kdwjpfmq \
--discovery-token-ca-cert-hash sha256:0d3f73918929912063b907f59393fba6313dc91076d685eecba521789b83ca5a \
--control-plane --certificate-key c03688c2c838b93ede986f5e6d1e9b91bec27ebe0646623de38b7a4b2069161f分别在其他 Master 节点执行以上命令,其中 –control-plane 是初始化 Master 节点的时使用的参数,–certificate-key 是上面获取的值。输出信息如下:
1
2
3
4
5
6
7
8... 省略 N 行...
To start administering your cluster from this node, 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
Run 'kubectl get nodes' to see this node join the cluster.按照提示创建 admin.conf 配置文件
1
2
3mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config查看节点信息
1
2
3
4
5
6kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master-01 Ready master 128m v1.19.7 192.168.200.11 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9
k8s-master-02 Ready master 6m14s v1.19.7 192.168.200.12 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9
k8s-master-03 Ready master 6m4s v1.19.7 192.168.200.13 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9
查看集群的最终状态
随便找一个 master 节点,执行以下命令
查看 ipvs 状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.96.0.1:443 rr
-> 192.168.200.11:6443 Masq 1 5 0
-> 192.168.200.12:6443 Masq 1 0 0
-> 192.168.200.13:6443 Masq 1 0 0
TCP 10.96.0.10:53 rr
-> 172.168.151.129:53 Masq 1 0 0
-> 172.168.151.131:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
-> 172.168.151.129:9153 Masq 1 0 0
-> 172.168.151.131:9153 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 172.168.151.129:53 Masq 1 0 0
-> 172.168.151.131:53 Masq 1 0 0查看 节点信息
1
2
3
4
5
6# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready master 142m v1.19.7
k8s-master-02 Ready master 20m v1.19.7
k8s-master-03 Ready master 20m v1.19.7查看 Pod 信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24# kubectl get pods -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-6bcb648b97-5gcgd 1/1 Running 0 74m 172.168.151.130 k8s-master-01 <none> <none>
calico-node-hs2l7 1/1 Running 0 74m 192.168.200.11 k8s-master-01 <none> <none>
calico-node-mkbxh 1/1 Running 0 14m 192.168.200.12 k8s-master-02 <none> <none>
calico-node-vljb9 1/1 Running 0 13m 192.168.200.13 k8s-master-03 <none> <none>
coredns-6c76c8bb89-8sl24 1/1 Running 0 136m 172.168.151.131 k8s-master-01 <none> <none>
coredns-6c76c8bb89-qd5rf 1/1 Running 0 136m 172.168.151.129 k8s-master-01 <none> <none>
etcd-k8s-master-01 1/1 Running 0 136m 192.168.200.11 k8s-master-01 <none> <none>
etcd-k8s-master-02 1/1 Running 0 14m 192.168.200.12 k8s-master-02 <none> <none>
etcd-k8s-master-03 1/1 Running 0 14m 192.168.200.13 k8s-master-03 <none> <none>
kube-apiserver-k8s-master-01 1/1 Running 0 136m 192.168.200.11 k8s-master-01 <none> <none>
kube-apiserver-k8s-master-02 1/1 Running 0 14m 192.168.200.12 k8s-master-02 <none> <none>
kube-apiserver-k8s-master-03 1/1 Running 0 12m 192.168.200.13 k8s-master-03 <none> <none>
kube-controller-manager-k8s-master-01 1/1 Running 1 136m 192.168.200.11 k8s-master-01 <none> <none>
kube-controller-manager-k8s-master-02 1/1 Running 0 14m 192.168.200.12 k8s-master-02 <none> <none>
kube-controller-manager-k8s-master-03 1/1 Running 0 13m 192.168.200.13 k8s-master-03 <none> <none>
kube-proxy-mwjj5 1/1 Running 0 14m 192.168.200.12 k8s-master-02 <none> <none>
kube-proxy-vtz87 1/1 Running 0 13m 192.168.200.13 k8s-master-03 <none> <none>
kube-proxy-z99df 1/1 Running 0 136m 192.168.200.11 k8s-master-01 <none> <none>
kube-scheduler-k8s-master-01 1/1 Running 1 136m 192.168.200.11 k8s-master-01 <none> <none>
kube-scheduler-k8s-master-02 1/1 Running 0 14m 192.168.200.12 k8s-master-02 <none> <none>
kube-scheduler-k8s-master-03 1/1 Running 0 13m 192.168.200.13 k8s-master-03 <none> <none>查看 CSR 信息
1
2
3
4
5# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-87wbs 22m kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:y795lm Approved,Issued
csr-q7g4w 22m kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:y795lm Approved,Issued在所有 Master 节点上允许 HPA 采集数据,修改后自动重启
1
2# 编辑 /etc/kubernetes/manifests/kube-controller-manager.yaml 文件,在 - commands 列表中添加以下内容:
- --horizontal-pod-autoscaler-use-rest-clients=false再次查看 Pod,确认已自动重启
1
2
3
4
5
6
7# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
...
kube-controller-manager-k8s-master-01 1/1 Running 0 3m45s
kube-controller-manager-k8s-master-02 0/1 Running 0 33s
kube-controller-manager-k8s-master-03 0/1 Pending 0 11s
...
Worker 节点初始化
Node 节点与 Master 节点加入集群相比,只是少了 –control-plane 与 –certificate-key 参数,如下:
在所有 worker 节点执行以下命令
1
2
3kubeadm join 192.168.200.110:8443 \
--token y795lm.5yp84yj4kdwjpfmq \
--discovery-token-ca-cert-hash sha256:0d3f73918929912063b907f59393fba6313dc91076d685eecba521789b83ca5a在 Master 节点查看状态
1
2
3
4
5
6
7kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master-01 Ready master 159m v1.19.7 192.168.200.11 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9
k8s-master-02 Ready master 37m v1.19.7 192.168.200.12 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9
k8s-master-03 Ready master 36m v1.19.7 192.168.200.13 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9
k8s-node-01 Ready <none> 60s v1.19.7 192.168.200.14 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9
k8s-node-02 Ready <none> 54s v1.19.7 192.168.200.15 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://19.3.9在 Master 节点查看 Pod 状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-6bcb648b97-5gcgd 1/1 Running 0 98m
calico-node-7ch6f 1/1 Running 0 118s
calico-node-hs2l7 1/1 Running 0 98m
calico-node-mkbxh 1/1 Running 0 38m
calico-node-vljb9 1/1 Running 0 37m
calico-node-xfvb9 1/1 Running 0 2m4s
coredns-6c76c8bb89-8sl24 1/1 Running 0 160m
coredns-6c76c8bb89-qd5rf 1/1 Running 0 160m
etcd-k8s-master-01 1/1 Running 0 160m
etcd-k8s-master-02 1/1 Running 0 38m
etcd-k8s-master-03 1/1 Running 0 37m
kube-apiserver-k8s-master-01 1/1 Running 0 160m
kube-apiserver-k8s-master-02 1/1 Running 0 38m
kube-apiserver-k8s-master-03 1/1 Running 0 36m
kube-controller-manager-k8s-master-01 1/1 Running 0 11m
kube-controller-manager-k8s-master-02 1/1 Running 0 7m49s
kube-controller-manager-k8s-master-03 1/1 Running 0 7m27s
kube-proxy-78hj4 1/1 Running 0 2m4s
kube-proxy-d6dz9 1/1 Running 0 118s
kube-proxy-mwjj5 1/1 Running 0 38m
kube-proxy-vtz87 1/1 Running 0 37m
kube-proxy-z99df 1/1 Running 0 160m
kube-scheduler-k8s-master-01 1/1 Running 1 160m
kube-scheduler-k8s-master-02 1/1 Running 0 38m
kube-scheduler-k8s-master-03 1/1 Running 0 36m
移除 worker 节点
在准备移除的 worker 节点上执行以下命令,比如 k8s-node-01
1
kubeadm reset
在 Master 节点上执行
1
kubectl delete node k8s-node-01
启用 Keepalived 的检查机制
编辑 Keepalived 的配置文件,将文件中以下内容取消注释
1
2
3track_script {
chk_apiserver
}重启 Keepalived 服务
1
systemctl restart keepalived.service
测试集群高可用,将虚拟IP所在的节点,模拟主机关闭,执行以下命令,停止 Keepalived 服务
1
systemctl stop keepalived.service
再次使用以下命令查看 节点信息
1
2
3
4
5
6
7
8# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready master 4h2m v1.19.7
k8s-master-02 Ready master 119m v1.19.7
k8s-master-03 Ready master 119m v1.19.7
k8s-node-01 Ready <none> 83m v1.19.7
k8s-node-02 Ready <none> 83m v1.19.7
安装 Dashboard
安装第三方 Dashboard(kuboard)
随便找一个 worker 节点运行以下容器,比如 k8s-node-02(192.168.200.15)
1
2
3
4
5
6
7
8
9
10
11sudo docker run -d \
--restart=unless-stopped \
--name=kuboard \
-p 10080:80/tcp \
-p 10081:10081/udp \
-p 10081:10081/tcp \
-e KUBOARD_ENDPOINT="http://192.168.200.15:10080" \
-e KUBOARD_AGENT_SERVER_UDP_PORT="10081" \
-e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
-v /root/kuboard-data:/data \
eipwork/kuboard:v3也可以使用镜像 swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard:v3 ,可以更快地完成镜像下载。
请不要使用 127.0.0.1 或者 localhost 作为内网 IP
Kuboard 不需要和 K8S 在同一个网段,Kuboard Agent 甚至可以通过代理访问 Kuboard Server参数解释:
- 建议将此命令保存为一个 shell 脚本,例如 start-kuboard.sh,后续升级 Kuboard 或恢复 Kuboard 时,需要通过此命令了解到最初安装 Kuboard 时所使用的参数;
- 第 4 行,将 Kuboard Web 端口 80 映射到宿主机的 10080 端口(您可以根据自己的情况选择宿主机的其他端口);
- 第 5、6 行,将 Kuboard Agent Server 的端口 10081/udp、10081/tcp 映射到宿主机的 10081 端口(您可以根据自己的情况选择宿主机的其他端口);
- 第 7 行,指定 KUBOARD_ENDPOINT 为
http://内网IP
,如果后续修改此参数,需要将已导入的 Kubernetes 集群从 Kuboard 中删除,再重新导入; - 第 8、9 行,指定 KUBOARD_AGENT_SERVER 的端口为 10081,此参数与第 5、6 行中的宿主机端口应保持一致,修改此参数不会改变容器内监听的端口 10081;
- 第 10 行,将持久化数据 /data 目录映射到宿主机的 /root/kuboard-data 路径,请根据您自己的情况调整宿主机路径;
在浏览器输入
http://192.168.200.15:10080
即可访问 Kuboard v3.0 的界面,登录方式:- 用户名: admin
- 密 码: Kuboard123
安装官方 Dashboard
下载 Dashboard 服务文件
1
curl -O -L http://raw.githubusercontent.com/kubernetes/dashboard/v2.1.0/aio/deploy/recommended.yaml
修改其中 Service 服务,暴露端口,端口范围为 30000~32767;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# vim recommended.yaml
... 省略 N 行 ...
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort # 配置该端口类型为 NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30001 # 添加一个节点端口
selector:
k8s-app: kubernetes-dashboard
---
... 省略 N 行 ...使用 kubelet 加载配置文件
1
kubectl apply -f ./recommended.yaml
使用以下命令查看所有命令空间,确认 kubernetes-dashboard 是否正常运行
1
2
3
4
5
6
7# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-6bcb648b97-5gcgd 1/1 Running 0 5h38m
kube-system calico-node-7ch6f 1/1 Running 0 4h2m
... 省略 N 行 ...
kubernetes-dashboard dashboard-metrics-scraper-79c5968bdc-vj9sr 1/1 Running 0 21m
kubernetes-dashboard kubernetes-dashboard-7448ffc97b-fjhfm 1/1 Running 0 21m访问 Dashboard,随便以集群一个 worker 节点的
ip + Service
的NodePort
就可以进行访问了,这里会有点问题,Dashboard 默认是 https 访问, 浏览器访问要用 https,并且没有证书肯定访问不了,我们要点击高级,接受风险。还有一个解决方案就是使用proxy
在 master 上执行:kubectl proxy --address=0.0.0.0 --disable-filter=true
address表示外界可以使用 192.168.200.11 来访问Dashboard,我们也可以使用0.0.0.0
disable-filter=true
表示禁用请求过滤功能,否则我们的请求会被拒绝,并提示Forbidden (403) Unauthorized
。登录 Dashboard 有两种方式,一种 Token,一种是 kubeconfig。这里我们使用 Token 登录。查看
dashboard-admin token
1
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep kubernetes-dashboard-admin-token | awk '{print $1}')
将得到的 Token 复制到浏览器中的 Token 输入框,就可以登录到 Dashboard 上了。Token 有效时间是 24 小时,超过需要重新使用上面的命令查看。