Blog.091 K8S 单节点二进制部署 Day 1:Etcd 集群与 Flannel 网络配置

本章目录

 

 

 

 

1. K8S 的部署方式
2. K8S 二进制部署 ①
  2.1 环境准备
  2.2 部署 ectd 集群
  2.3 部署 docker 引擎
  2.4 flannel 网络配置

 

 

 

 

1. K8S 的部署方式

    常见的 K8S 按照部署方式:

  • Minikube:

    Minikube 是一个工具,可以在本地快速运行一个单节点微型 K8S,仅用于学习、预览 K8S 的一些特性使用。
    部署地址:https://kubernetes.io/docs/setup/minikube

  • Kubeadmin:

    Kubeadmin 也是一个工具,提供 kubeadm init 和 kubeadm join,用于快速部署 K8S 集群,新手推荐。
    https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/

  • 二进制安装部署:

    生产首选,特点是稳定可调控,从官方下载发行版的二进制包,手动部署每个组件和自签 TLS 证书,组成 K8S 集群,新手推荐。
    https://github.com/kubernetes/kubernetes/releases

    Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。
    推荐使用二进制包部署 Kubernetes 集群,虽然手动部署麻烦点,但期间可以学习很多工作原理,也利于后期维护。


2. K8S 二进制部署 ①

 

 

  2.1 环境准备

    先准备3台主机,首先搭建Master单节点集群。
    因为 Master 是整个 K8S 集群的大脑,没有 Master 接下来的每一步操作都会变得不可控。

    同时我们需要在节点上同时搭建 etcd 存储集群:
    在生产环境中会使用 etcd 集群做高可用,它的数目必须是3台或3台以上的奇数台。
    etcd 存储单独部署可以节约存储,和 Master 放在一起方便内网通信节约机器。
    只要能保证内网环境稳定和服务器数量充足,一般都会单独部署。

  • K8S 集群 Master01:192.168.80.10:kube-apiserver、kube-controller-manager、kube-scheduler、etcd
  • K8S 集群 Node01:192.168.80.11:kubelet、kube-proxy、docker、flannel、etcd
  • K8S 集群 Node02:192.168.80.12:kubelet、kube-proxy、docker、flannel、etcd

 

    (1)所有主机关闭防火墙

1 systemctl stop firewalld
2 systemctl disable firewalld

 

    (2)所有主机关闭 selinux

1 setenforse 0
2 sed -i ‘s/enforcing/disabled/’ /etc/selinux/config

 

    (3)所有主机关闭 swap

1 swapoff -a
2 sed -ri ‘s/.*swap.*/#&/’ /etc/fstab

 

    (4)根据规划设置主机名

1 hostnamectl set-hostname master01
2 hostnamectl set-hostname node01
3 hostnamectl set-hostname node02

 

    (5)在 master 添加 hosts

1 cat >> /etc/hosts << EOF
2 192.168.80.10 master01
3 192.168.80.11 node01
4 192.168.80.12 node02
5 EOF

 

    (6)所有主机将桥接的 ipv4 流量传递到 iptables 的链

1 cat > /etc/sysctl.d/k8s.conf << EOF
2 net.bridge.bridge-nf-call-ip6tables = 1
3 net.bridge.bridge-nf-call-iptables = 1
4 EOF
5 
6 sysctl  --system

 

    (7)所有主机时间同步

1 yum install ntpdate -y
2 ntpdate time.windows.com

 

  2.2 部署 ectd 集群

    etcd 的目标是构建一个高可用的分布式键值数据库。
    它的内部采用 raft 协议作为一致性算法,etcd 是 go 语言编写的。

    etcd 作为服务发现系统,有以下的特点:

  • 简单:安装配置简单,而且提供了 http api 进行交互,使用也很简单
  • 安全:支持 ssl 证书验证
  • 快速:单实例支持每秒 2k+ 读操作
  • 可靠:采用 raft 算法,实现分布式系统数据的可用性和一致性

    etcd 目前默认使用 2379 端口提供 http api 服务;2380 端口和 peer 通信。
    即 etcd 默认使用 2379 端口对外为客户端提供通讯,使用 2380 进行服务器间内部, etcd 和 etcd 之间通讯。
    由于 etcd 的 leader 选举机制,要求至少为 3 台或以上的奇数台。

 

    (1)准备签发证书环境

    CFSSL 是 CloudFlare 公司开源的一款 PKI/PLS 工具。
    CFSSL 包含一个命令行工具和一个用于签名、验证和捆绑 TLS 证书的 HTTP API 服务。使用 Go 语言编写。
    CFSSL 使用配置文件生成证书,因此自签之前,需要生成它识别的 json 格式的配置文件,CFSSL 提供了方便的命令行生成配置文件。

    CFSSL 用来为 etcd 提供 TLS 证书,它支持签三种类型的证书:

  • client 证书,服务端连接客户端时携带的证书,用于客户端验证服务端身份,如 kube-apiserver 访问 etcd;
  • server 证书,客户端连接服务端时携带的证书,用于服务端验证客户端身份,如 etcd 对外提供服务;
  • peer 证书,相互之间连接时使用的证书,如 etcd 节点之间进行验证和通信。

    这里全部都使用同一套证书认证。


    (2)master01:下载证书制作工具

 1 #在 master01 上下载制作工具
 2 wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
 3 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
 4 wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/local/bin/cfssl-certinfo
 5  6 curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
 7 curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
 8 curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo
 9 
10 #授予执行权限
11 chmod +x /usr/local/bin/cfssl*

 

    或

1 [root@master01 etcd-cert]# cd /usr/local/bin/
2 [root@master01 bin]# rz -E(cfssl  cfssl-certinfo  cfssljson)
3 [root@master01 bin]# chmod +x *
4 [root@master01 bin]# ls
5 cfssl  cfssl-certinfo  cfssljson

 

  • cfss1:证书签发的工具命令
  • cfssljson:将 cfss1 生成的证书(json 格式)变为文件承载式证书
  • cfssl-certinfo:验证证书的信息
  • cfssl-certinfo -cert <证书名称> :看证书的信息

 

 

    (3)创建 K8S 工作目录,生成 CA 证书以及 etcd 证书私钥

 1 #创建k8s工作目录
 2 [root@master01 opt]# mkdir /opt/k8s
 3 [root@master01 opt]# cd /opt/k8s/
 4 
 5 #上传etcd-cert.sh 和 etcd.sh 到/opt/k8s目录
 6 [root@master01 k8s]# ls etcd-cert.sh etcd.sh 
 7 etcd-cert.sh  etcd.sh
 8 
 9 #添加x 权限
10 [root@master01 k8s]# chmod  +x  etcd-cert.sh etcd.sh
11 
12 #创建用于生成CA证书,etcd服务器证书及私钥的目录
13 [root@master01 k8s]# mkdir /opt/k8s/etcd-cert
14 [root@master01 k8s]# mv etcd-cert.sh  etcd-cert
15 [root@master01 k8s]# cd /opt/k8s/etcd-cert/
16 
17 #注意,看一下脚本,把ip改为自己的
18 [root@master01 etcd-cert]# vim etcd-cert.sh
19 
20 #执行脚本,生成CA证书,etcd服务器证书以及私钥
21 [root@master01 etcd-cert]# ./etcd-cert.sh
22 
23 [root@master01 etcd-cert]# ls
24 ca-config.json  ca-csr.json  ca.pem        server.csr       server-key.pem
25 ca.csr          ca-key.pem   etcd-cert.sh  server-csr.json  server.pe

 

 

 

 

    (4)上传 etcd-cert.sh 和 etcd.sh 到 /opt/k8s 目录中

 1 #etcd 二进制包地址: https://github.com/etcd-io/etcd/release
 2 
 3 #上传etcd-v3.3.10 包到/opt/k8s目录中,解压
 4 [root@master01 k8s]# ls etcd-v3.3.10-linux-amd64.tar.gz 
 5 etcd-v3.3.10-linux-amd64.tar.gz
 6 
 7 [root@master01 k8s]# tar xf etcd-v3.3.10-linux-amd64.tar.gz
 8 
 9 [root@master01 k8s]# ls etcd-v3.3.10-linux-amd64
10 Documentation  etcd  etcdctl  README-etcdctl.md  README.md  READMEv2-etcdctl.md

 

    etcd 就是 etcd 服务的启动命令,后面可以跟各种启动参数;
    etcdctl 主要为 etcd 服务提供了命令行操作。

 

 

    (5)创建用于存放 etcd 配置文件,命令文件,证书的目录

 1 [root@master01 k8s]# mkdir -p /opt/etcd/{cfg,bin,ssl}
 2 [root@master01 k8s]# mv  /opt/k8s/etcd-v3.3.10-linux-amd64/etcd /opt/k8s/etcd-v3.3.10-linux-amd64/etcdctl /opt/etcd/bin/
 3 [root@master01 k8s]# cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/
 4 
 5 [root@master01 k8s]# ls -R /opt/etcd/bin/ /opt/etcd/ssl/
 6 /opt/etcd/bin/:
 7 etcd  etcdctl
 8 
 9 /opt/etcd/ssl/:
10 ca-key.pem  ca.pem  server-key.pem  server.pem

 

 

1 [root@master01 k8s]# pwd
2 /opt/k8s
3 [root@master01 k8s]# ls etcd.sh 
4 etcd.sh
5 
6 [root@master01 k8s]# ./etcd.sh  etcd01 192.168.23.103 etcd02=https://192.168.23.104:2380,etcd03=https://192.168.23.105:2380
7 
8 #新开一个终端查看
9 [root@master01 k8s]# ps -ef | grep etcd

 

 

    (6)另外打开一个窗口查看 etcd 进程是否正常

 

    (7)把 etcd 相关证书文件和命令文件全部拷贝到另外两个 etcd 节点

 1 [root@master01 k8s]# scp -r /opt/etcd/ 192.168.23.104:/opt/
 2 [root@master01 k8s]# scp -r /opt/etcd/ 192.168.23.105:/opt/
 3 
 4 #node1修改etcd文件
 5 [root@node01 cfg]# vim /opt/etcd/cfg/etcd
 6 #[Member]
 7 ETCD_NAME="etcd02
 8 ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
 9 ETCD_LISTEN_PEER_URLS="https://192.168.23.104:2380"
10 ETCD_LISTEN_CLIENT_URLS="https://192.168.23.104:2379"
11 
12 #[Clustering]
13 ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.23.104:2380"
14 ETCD_ADVERTISE_CLIENT_URLS="https://192.168.23.104:2379"
15 ETCD_INITIAL_CLUSTER="etcd01=https://192.168.23.103:2380,etcd02=https://192.168.23.104:2380,etcd03=https://192.168.23.105:2380"
16 ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
17 ETCD_INITIAL_CLUSTER_STATE="new"
18 
19 #node2修改etcd文件
20 [root@node02 ~]# vim /opt/etcd/cfg/etcd
21 #[Member]
22 ETCD_NAME="etcd03"
23 ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
24 ETCD_LISTEN_PEER_URLS="https://192.168.23.105:2380"
25 ETCD_LISTEN_CLIENT_URLS="https://192.168.23.105:2379"
26 
27 #[Clustering]
28 ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.23.105:2380"
29 ETCD_ADVERTISE_CLIENT_URLS="https://192.168.23.105:2379"
30 ETCD_INITIAL_CLUSTER="etcd01=https://192.168.23.103:2380,etcd02=https://192.168.23.104:2380,etcd03=https://192.168.23.105:2380"
31 ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
32 ETCD_INITIAL_CLUSTER_STATE="new"

 

 

 

    (8)把 etcd 服务管理文件拷贝到另外两个 etcd 集群节点

1 [root@master01 k8s]# cd /usr/lib/systemd/system/
2 [root@master01 system]# ls etcd.service 
3 etcd.service
4 [root@master01 system]# pwd
5 /usr/lib/systemd/system
6 [root@master01 system]# scp etcd.service 192.168.23.104:`pwd`
7 [root@master01 system]# scp etcd.service 192.168.23.105:`pwd`

 

 

    (9)在所有 etcd 节点上启动 etcd 服务

 1 [root@master01 k8s]# systemctl  restart etcd
 2 [root@master01 k8s]# systemctl  enable etcd
 3 [root@master01 k8s]# systemctl  status etcd
 4 
 5 [root@node01 cfg]# systemctl  daemon-reload 
 6 [root@node01 cfg]# systemctl  start etcd
 7 [root@node01 cfg]# systemctl  enable etcd
 8 [root@node01 cfg]# systemctl  status etcd
 9 
10 [root@node02 ~]# systemctl  daemon-reload 
11 [root@node02 ~]# systemctl restart etcd
12 [root@node02 ~]# systemctl  enable etcd.service 
13 [root@node02 ~]# systemctl  status etcd

 

    (12)切换到 etcd3 版本查看集群节点状态和成员列表

 

1 export ETCDCTL_API=3
2 #v2和v3命令略有不同,etcd2 和etcd3也是不兼容的,默认是v2版本
3 etcdctl --write-out=table endpoint status
4 etcdctl --write-out=table member list
5 export ETCDCTL_API=2
6 #再切回v2版本

 

 

  2.3 部署 docker 引擎

    (1)所有 node 节点都要部署 docker 引擎

1 yum install -y yum-utils device-mapper-persistent-data 1vm2
2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3 yum install -y docker-ce dqsker-ce-cli containerd.io
4  
5 systemctl start docker.service
6 systemctl enable docker.service

 

  2.4 flannel 网络配置

 

    K8S 中 pod 网络通信:

  • pod 内 容器与容器之间的通信

    在同一个 pod 内的容器(pod 内的容器是不会跨宿主机的)共享同一个网络命令空间,相当于它们在同一台机器上一样,可以用 localhost 地址访问彼此的端口。

  • 同一个 node 内 pod 之间的通信

    每个 pod 都有一个真实的全局 IP 地址,同一个 node 内的不同 pod 之间可以直接采用对方 pod 的 IP 地址进行通信,pod1 与 pod2 都是通过 veth 连接到同一个 docker0 网桥、网段,所以它们之间可以直接通信。

  • 不同 node 上 pod 之间的通信

    pod 地址与 docker0 在同一网段,docker0 网段与宿主机网卡是两个不同的网段,且不同 node 之间的同新只能通过宿主机的物理网卡进行。
    要想实现不同 node 上 pod 之间的通信,就必须想办法通过主机的物理网卡 IP 地址进行寻址和通信。
    因此要满足两个条件:pod 的 IP 不能冲突;将 pod 的 IP 和所在的 node 的 IP 关联起来,通过这个关联让不同 node 上 pod 之间直接通过内网 IP 地址通信。

 

 

    Flannel 工作原理:

      数据首先会从源 node 节点的 pod 发出,发出后会经由 docker0 网卡转发到 flannel0网卡,在 flannel0 网卡里有个 flanneld 服务会把这个数据包封装到 udp 报文中,然后根据自己在 tecd 中维护的路由表通过物理网卡转发到目标 node 节点,数据包到达目标 node 节点后会被 flanneld 服务解封装,然后经由 flannel0 网卡和 docker0 网卡转发到目标 pod 的容器。

 

  • Overlay Network:

    叠加网络,在二层或者三层基础网络上叠加的一层虚拟网络技术模式,该网络中的主机通过虚拟链路隧道连接起来(类似于 vpn);

  • VXLAN:

    将源数据包封装到 udp 中,并使用基础网络的 IP/MAC 作为外层报文头进行封装,然后在以太网上传输,到达目的地后由隧道端点解封装并将数据发送给目标地址;

  • Flannel:

    让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。
    Flannel 是 Overlay 网络的一种,也是将 tcp 源数据包封装在另一种网络包里面进行路由转发和通信,目前支持 udp、vxlan、host-gw 三种数据转发方式。

 

    Flannel etcd:
    存储管理 flannel 可分配的 IP 地址段资源;
    监控 etcd 中每个 pod 的实际地址,并在内存中建立维护 pod 节点路由表。

 

    (1)添加 flannel网络配置信息,写入分配的子网段到 etcd 中,供 flannel 使用

1 cd /opt/etcd/ssl
2 /opt/etcd/bin/etcdctl \
3 --ca-file=ca.pem \
4 --cert-file=server.pem \
5 --key-file=server-key.pem \
6 --endpoints="https://192.168.229.90:2379,https://192.168.229.80:2379,https://192.168.229.70:2379" \
7 set /coreos.com/network/config '{"Network": "172.17.0.0/16","Backend": {"Type": "vxlan"}}'

 

  • set /coreos.com/network/config:添加一条网络配置记求,这个配置将用于 flannel 分配给每个 docker 的虛拟 IP 地址段
  • get <ckey>
  • got /coreos.com/octwork/config:获取网络配置记录,后面不用再跟参数了
  • Network:用于指定 flannel 地址池
  • Backend:用于指定数据包以什么方式转发,默认为 udp 模式,Backend 为 vxlan 比起预设的 udp 性能相对好一些。

 

 

1 /opt/etcd/bin/etcdctl \
2 --ca-file=ca.pem \
3 --cert-file=server.pem \
4 --key-file=server-key.pem \
5 --endpoints="https://192.168.229.90:2379,https://192.168.229.80:2379,https://192.168.229.70:2379" \
6 get /coreos.com/network/config 

 

 

    (2)拷贝 flannel 安装包到所有 node 节点

1 cd /opt
2 tar zxvf flannel-v0.10.0-1inux-amd64.tar.gz
3 flanneld
4 #flanneld为主要的执行文件
5 mk-docker-opts.sh
6 #mk-docker-opts . sh脚本用于生成Docker启动参数
7 README.md

 

 

    (3)创建 k8s 工作目录

1 mkdir -p /opt/kubernetes/{cfg,bin,ss1}
2 cd /opt
3 mv mk-docker-opts.sh flanneld /opt/kubernetes/bin/

 

 

    (4)开启 flannel 网络功能

1 cd /opt
2 chmod +x flannel.sh
3 ./flannel.sh https://192.168.229.90:2379,https://192.168.229.80:2379,https://192.168.229.70:2379

 

 

  • flannel 启动后会生成一个 docker 网络相关信息配置文件 /run/flannel/subnet.env,包含了 docker 要使用 flannel 通讯的相关参数。
1 cat /run/flannel/subnet.env
2 DOCKER_OPT_BIP="--bip=172.17.26.1/24"
3 DOCKER_OPT_IPMASQ="--ip-masq= false"
4 DOCKER_OPT_MTU="--mtu=1450"
5 DOCKER_NETWORK_OPTIONS=" --bip=172.17.26.1/24 --ip-masq=false --mtu=1450"  

 

  • --bip:指定 docker 启动时的子网
  • --ip-masq:设置 ipmasq=false 关闭 snat 伪装策略
  • --mtu=1450:mtu 要留出 50 字节给外层的 vxlan 封包的额外开销使用

    Flannel 启动过程解析:

  1. 从 etcd 中获取 network 的配置信息
  2. 划分 subnet, 并在 etcd 中进行注册
  3. 将子网信息记录到 /run/flannel/subnet.env 中

 

 

    (5)配置 docker 连接 flannel

 1 vim /lib/systemd/system/docker.service
 2 [Service]
 3 Type=notify
 4 # the default is not to use systemd for cgroups because the delegate issues stillt
 5 # exists and systemd currently dges not support the cgroup feature set requi red
 6 # for containers run by docker
7 EnvironmentFile=/run/flannel/subnet.env 8 #添加
9 ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS -H fd:// --containerd=/run/containerd/containerd.sock 10 #修改
11 ExecReload=/bin/kill -s HUP $MAINPID 12 TimeoutSec=0 13 RestartSec=2 14 Restart=always

 

 

    (6)重启 docker 服务,ifconfig 查看 docker0 和 flannel.1

1 systemctl daemon-reload
2 systemctl restart docker

 

 

    (7)测试 ping 通对方 docker0 网卡证明 flannel 起到路由作用

1 ping 172.17.91.1
2 docker run -it centos:7 /bin/bash # node1 和 node2 都运行该命令
3 yum install net-tools -y # node1 和 node2 都运行该命令
4 ifconfig //再次测试 ping 通两个 node 中的 centos:7 容器

 

 

 

 

 

 

 

 

 

-

 

posted @ 2021-10-29 16:58  洛洛你好  阅读(369)  评论(0)    收藏  举报