乐趣区

k8s-高可用集群搭建笔记

该笔记是对摸索安装 k8s 高可用集群的笔记。
选择了比较常见的 kubeadm+keepalived+haproxy 组合方案。

环境:

  • VMware Fusion 11.5
  • Debian 10
  • keepalived:
  • haproxy:
  • kubeadm:v1.16.2
  • kubectl:v1.16.2

步骤:

  • 宿主机环境准备(静态 IP 设置等)
  • 安装配置 haproxy
  • 安装配置 keepalived
  • 安装 docker
  • 安装 kubelet、kubeadm、kubectl
  • k8s 前置设置
  • k8s master 配置和启动
  • k8s worker 配置和启动

参考:

  • 使用 Kubeadm + HAProxy + Keepalived 部署高可用 Kubernetes 集群
  • Debian 安装 Docker CE

1. 虚拟机环境准备

1.1 虚拟机使用静态 IP

配置 VMware Fusion 和 Debian 的静态 IP,这里不展开了,可以参见其他文章。
配置完成后:

NETMASK 172.16.61.0
SUBNET 172.16.61.0
GATEWAY 172.16.61.2

DNS 172.16.61.2

新建三台 master 主机和三台 worker 主机:

debian10master0 172.16.61.100
debian10master1 172.16.61.101
debian10master2 172.16.61.102

debian10worker0 172.16.61.200
debian10worker1 172.16.61.201
debian10worker2 172.16.61.202

1.2 更改 Debian 的 hostname

由于 k8s 集群中的每个 node 的 hostname 不能一样,所以需要确保虚拟机的 hostname 不同。

查看 hostname

$ hostnamectl

更改 hostname

首先通过命令设置新主机名

$ sudo hostnamectl set-hostname example

其次,更改 /etc/hosts 中的主机名

$ sudo vim /etc/hosts

分别更改六台虚拟机的 hostname 为:

  • debian10master0
  • debian10master1
  • debian10master2
  • debian10worker0
  • debian10worker1
  • debian10worker2

2. 安装配置 haproxy

2.1 安装

$ sudo apt-get install -y haproxy

2.2 配置

# cat >> /etc/sysctl.conf <<EOF
net.ipv4.ip_nonlocal_bind = 1
EOF

# sysctl -p
net.ipv4.ip_nonlocal_bind = 1

每台 master 主机都需要执行:

# cat > /etc/haproxy/haproxy.cfg << EOF
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#---------------------------------------------------------------------
frontend kubernetes-apiserver
    mode                 tcp
    bind                 *:16443
    option               tcplog
    default_backend      kubernetes-apiserver

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-apiserver
    mode        tcp
    balance     roundrobin
    server  debian10master0 172.16.61.100:6443 check
    server  debian10master1 172.16.61.101:6443 check
    server  debian10master2 172.16.61.102:6443 check

#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen stats
    bind                 *:1080
    stats auth           admin:awesomePassword
    stats refresh        5s
    stats realm          HAProxy\ Statistics
    stats uri            /admin?stats
EOF

2.3 启动和检查

启动

# systemctl enable haproxy.service
# systemctl start haproxy.service
# systemctl status haproxy.service

检查

# ss -lnt | grep -E "16443|1080"
LISTEN     0      128          *:1080                     *:*                  
LISTEN     0      128          *:16443                    *:*

3. 安装配置 keepalived

在三台 master 主机中安装 keepalived,其中一台配置为 MASTER,另外两台配置为 BACKUP。

3.1 安装

$ sudo apt-get install -y keepalived

3.2 配置

每台 master 主机都需要执行:

# cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward = 1
EOF

# sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.ip_nonlocal_bind = 1

MASTER 配置:

# cat > /etc/keepalived/keepalived.conf << EOF
global_defs {router_id LVS_DEVEL00}

vrrp_script check_haproxy {
    script "/usr/bin/killall -0 haproxy"
    interval 3
    weight -2
    fall 10
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 88
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 35f18af7190d51c9f7f78f37300a0cbd
    }
    virtual_ipaddress {172.16.61.99}
    track_script {check_haproxy}
}
EOF

BACKUP 配置:

# cat > /etc/keepalived/keepalived.conf << EOF
global_defs {router_id LVS_DEVEL01}

vrrp_script check_haproxy {
    script "/usr/bin/killall -0 haproxy"
    interval 3
    weight -2
    fall 10
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 88
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 35f18af7190d51c9f7f78f37300a0cbd
    }
    virtual_ipaddress {172.16.61.99}
    track_script {check_haproxy}
}
EOF

3.3 启动和检查

启动

# systemctl enable keepalived.service
# systemctl start keepalived.service
# systemctl status keepalived.service

检查

通过 ip address 查看网络情况,应该会发现只有 MASTER 主机上可以看到 172.16.61.99 的绑定。在每台主机上都可以 PING 通 172.16.61.99。

注意

重要,如果 master 和 node 的 hostname 是一样的,会出现 kubectl get nodes 看不到 nodes 的情况。

4. 安装 docker

移除可能的历史遗留安装

$ sudo apt-get remove docker \
               docker-engine \
               docker.io

安装所需程序

$ sudo apt-get update
$ sudo apt-get install -y \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     lsb-release \
     software-properties-common

添加 apt-repository

$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo apt-key add -
$ sudo add-apt-repository \
  "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/debian \
  $(lsb_release -cs) \
  stable"

# 官方源
# $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
# $ sudo add-apt-repository \
#“deb [arch=amd64] https://download.docker.com/linux/debian \
#    $(lsb_release -cs) \
#    stable"

安装 docker

$ sudo apt-get update
$ sudo apt-get install -y docker-ce

启动

$ sudo systemctl enable docker # 相当于设置开机启动,参照:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
$ sudo systemctl start docker

5. 安装 kubelet、kubeadm、kubectl

安装所需软件

$ sudo apt-get update && sudo apt-get install -y apt-transport-https curl

下载并导入相关的 apt-key
注意:这里可能会遇到网络问题无法下载 apt-key.gpg,可以先将文件下载下来然后放到可以访问到的服务器上,然后修改命令中的地址以求执行成功。

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

# cat <<EOF > /etc/apt/sources.list.d/kubernetes.list
deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main
EOF

安装并固定版本

$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl #  标记软件包不被自动更新 

启动

sudo systemctl daemon-reload
sudo systemctl enable --now kubelet

6. k8s 前置设置

6.1 关闭所有虚拟机的 swap

为何要关闭 swap?参考:https://github.com/kubernetes…

临时关闭:

  • 编辑 /etc/fstab 文件,注释掉引用 swap 的行
  • 执行:sudo swapoff -a

永久关闭:

  • 编辑 /etc/fstab 文件,注释掉引用 swap 的行
  • 重启

测试:

执行 top 命令,若 KiB Swap 一行中 total 显示 0 则关闭成功。

6.2 统一 k8s 和 docker 的 cgroup dirver

Docker 使用 cgroup,而 k8s 使用 systemd,两者需要统一。参考:https://www.cnblogs.com/hongd…

修改或创建 /etc/docker/daemon.json,加入下面的内容:

{"exec-opts": ["native.cgroupdriver=systemd"]
}

重启 docker:

$ sudo systemctl restart docker
$ sudo systemctl status docker

6.3 设置 Debian 允许 root 通过 ssh 登录

后续我们会需要在 master 之间传递文件,scp 会需要较高权限。
当然传递文件可以通过别的方式实现,但是这里我们还是说一下记录一下如何让 root 可以通过 ssh 登录。

修改 /etc/ssh/sshd_config

# PermitRootLogin prohibit-password

修改为:

PermitRootLogin yes

然后,重启 sshd 服务

# systemctl restart sshd.service

7. k8s master 配置和启动

7.1 添加 hosts

需要将在每台 master 虚拟机中执行 sudo vim /etc/hosts,添加以下内容:

172.16.61.99    k8svip
172.16.61.100    debian10master0
172.16.61.101    debian10master1
172.16.61.102    debian10master2

7.2 配置第一个 master 节点

注意:务必确保第一台 master 是 keepalived 的 MASTER 主机,否则会执行失败。

7.2.1 编辑 kubeadm 配置文件

$ cd /root/
$ cat > kubeadm-config.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.16.2
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
controlPlaneEndpoint: "k8svip:6443"
networking:
  serviceSubnet: "10.96.0.0/16"
  podSubnet: "192.168.0.0/16"
  dnsDomain: "cluster.local"
EOF

CNI 使用 Calico,设置 podSubnet 为 192.168.0.0/16

7.2.2 初始化第一个 master 节点

# kubeadm init --config kubeadm-config.yaml

这行命令执行完以后,命令行会输出成功提示和后续操作步骤。我这里的是:

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/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join k8svip:6443 --token bbz7m3.llwlpune2566m8zg \
    --discovery-token-ca-cert-hash sha256:495f19148fbddcb1de8af8a4b4b3aae883dd2eee3eb48abf8fe20eb95fc43ad9 \
    --control-plane

Then you can join any number of worker nodes by running the following on each as root:

  kubeadm join k8svip:6443 --token bbz7m3.llwlpune2566m8zg \
    --discovery-token-ca-cert-hash sha256:495f19148fbddcb1de8af8a4b4b3aae883dd2eee3eb48abf8fe20eb95fc43ad9

通过 kubectl get nods 查看 nodes 状态,这个时候 master 还处于 NotReady 状态,因为还没有安装网络插件 Calico。

7.2.3 安装 Calico

# curl https://docs.projectcalico.org/v3.9/manifests/calico.yaml -O
# kubectl apply -f calico.yaml

网络插件 Calico 安装完之后稍等一会,再次查看 nodes 状态,应该已经变成 Ready。

7.2.4 复制相关文件到其他 master 节点

部署其他 master 节点之前,将第一个节点的相关文件复制到其他节点上。
这里需要注意的是,Debian 默认不允许 root 账号通过 ssh 登录,需要做一些配置,在前面的章节已经讲过。

# ssh root@debian10master1 mkdir -p /etc/kubernetes/pki/etcd
# scp /etc/kubernetes/admin.conf root@debian10master1:/etc/kubernetes
# scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@debian10master1:/etc/kubernetes/pki
# scp /etc/kubernetes/pki/etcd/ca.* root@debian10master1:/etc/kubernetes/pki/etcd

# ssh root@debian10master2 mkdir -p /etc/kubernetes/pki/etcd
# scp /etc/kubernetes/admin.conf root@debian10master2:/etc/kubernetes
# scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@debian10master2:/etc/kubernetes/pki
# scp /etc/kubernetes/pki/etcd/ca.* root@debian10master2:/etc/kubernetes/pki/etcd

7.3 配置其他 master 节点

只需要执行第一台 master 初始化完成后输出的新添加 master 的命令即可,在这里是:

kubeadm join k8svip:6443 --token bbz7m3.llwlpune2566m8zg \
  --discovery-token-ca-cert-hash sha256:495f19148fbddcb1de8af8a4b4b3aae883dd2eee3eb48abf8fe20eb95fc43ad9 \
  --control-plane

7.4 检查测试

查看集群状态:

# kubectl get nodes

查看 pods

# kubectl get pods --all-namespaces

8. k8s worker 配置和启动

只要执行第一台 master 初始化完成后输出的新添加 worker 的命令即可,在这里是:

kubeadm join k8svip:6443 --token bbz7m3.llwlpune2566m8zg \
  --discovery-token-ca-cert-hash sha256:495f19148fbddcb1de8af8a4b4b3aae883dd2eee3eb48abf8fe20eb95fc43ad9

参考:

  • kubernetes 安装(国内环境)– 知乎
  • Debian 9 使用 kubeadm 创建 k8s 集群(上)| Debian 社区
  • Debian 9 使用 kubeadm 创建 k8s 集群(下)| Debian 社区
  • 安装 kubeadm – Kubernetes
  • Kubernetes 的几种主流部署方式 02-kubeadm 部署高可用集群 – Kubernetes,Istio 点滴 – SegmentFault 思否
  • https://kuboard.cn/install/in…
  • https://blog.csdn.net/chenlei…
  • http://lioncruise.github.io/2…
  • https://juejin.im/entry/5a03f…
  • https://yeasy.gitbooks.io/doc…
  • 在生产环境使用 K8s 一年后,我们总结了这些经验和教训 – 知乎
  • k8s 中的问题排查解决 (一)/)
  • 使用 kubeadm 创建高可用集群 | Kubernetes
  • 安装 Kubernetes 高可用_K8S 安装部署
退出移动版