目录
2、编写 etcd-cert.sh 和 etcd.sh 脚本
7、把 etcd 相关证书文件和命令文件全部拷贝到另外两个 etcd 集群节点
8、把 etcd 服务管理文件拷贝到了另外两个 etcd 集群节点
7.3 修改 docker0 网卡网段与 flannel 一致
1、编写 apiserver.sh、scheduler.sh、controller-manager.sh
5、复制 CA 证书、apiserver 相关证书和私钥到 kubernetes 工作目录的 ssl 子目录中
6、下载或上传 kubernetes 安装包到 /k8s 目录,并解压
7、复制 master 组件的关键命令文件到 kubernetes 工作目录的 bin 子目录中
9、二进制文件、token、证书都准备好后,开启 apiserver 服务
1、把 kubelet、kube-proxy 拷贝到 node 节点(master01 节点)
3.4 把配置文件 bootstrap.kubeconfig、kube-proxy.kubeconfig 拷贝到 node 节点
4.1 使用 kubelet.sh 脚本启动 kubelet 服务
6.1 已自动生成证书和 kubelet.kubeconfig 文件
一、环境准备
服务器 | 主机名 | IP地址 | 主要组件 |
k8s集群master01 + etcd01 | master01 | 192.168.61.17 | kube-apiserver kube-controller-manager kube-schedular etcd |
k8s集群node01 + etcd02 | node01 | 192.168.61.18 | kubelet kube-proxy docker flannel |
k8s集群node02 + etcd03 | node02 | 192.168.61.22 | kubelet kube-proxy docker flannel |
#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
#修改主机名
hostnamectl set-hostname master01
hostnamectl set-hostname node01
hostnamectl set-hostname node02
#关闭swap(所有节点)
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
#添加 hosts(所有节点)
cat >> /etc/hosts << EOF
192.168.3.11 master01
192.168.3.12 node01
192.168.3.13 node02
EOF
#将桥接的 IPv4 流量传递到 iptables 的链(所有节点)
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
#时间同步(所有节点)
yum install ntpdate -y
ntpdate time.windows.com
二、部署etcd集群
1、下载证书
curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo
chmod +x /usr/local/bin/cfssl*
//cfssl:证书签发的工具命令
//cfssljson:将 cfssl 生成的证书(json 格式)变为文件承载式证书
//cfssl-certinfo:验证证书的信息
//“cfssl-certinfo -cert <证书名称>” 可查看证书的信息
2、编写 etcd-cert.sh 和 etcd.sh 脚本
[root@master1 ~]# mkdir /k8s
[root@master1 ~]# cd /k8s
[root@master k8s]# vim etcd-cert.sh //注意修改称自己的IP
#!/bin/bash
#配置证书生成策略,让 CA 软件知道颁发有什么功能的证书,生成用来签发其他组件证书的根证书
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"www": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
#ca-config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;
#后续在签名证书时会使用某个 profile;此实例只有一个 www 模板。
#expiry:指定了证书的有效期,87600h 为10年,如果用默认值一年的话,证书到期后集群会立即宕掉
#signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;
#key encipherment:表示使用非对称密钥加密,如 RSA 加密;
#server auth:表示client可以用该 CA 对 server 提供的证书进行验证;
#client auth:表示server可以用该 CA 对 client 提供的证书进行验证;
#注意标点符号,最后一个字段一般是没有逗号的。
#-----------------------
#生成CA证书和私钥(根证书和私钥)
#特别说明: cfssl和openssl有一些区别,openssl需要先生成私钥,然后用私钥生成请求文件,最后生成签名的证书和私钥等,但是cfssl可以直接得到请求文件。
cat > ca-csr.json <<EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF
#CN:Common Name,浏览器使用该字段验证网站或机构是否合法,一般写的是域名
#key:指定了加密算法,一般使用rsa(size:2048)
#C:Country,国家
#ST:State,州,省
#L:Locality,地区,城市
#O: Organization Name,组织名称,公司名称
#OU: Organization Unit Name,组织单位名称,公司部门
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
#生成的文件:
#ca-key.pem:根证书私钥
#ca.pem:根证书
#ca.csr:根证书签发请求文件
#cfssl gencert -initca <CSRJSON>:使用 CSRJSON 文件生成生成新的证书和私钥。如果不添加管道符号,会直接把所有证书内容输出到屏幕。
#注意:CSRJSON 文件用的是相对路径,所以 cfssl 的时候需要 csr 文件的路径下执行,也可以指定为绝对路径。
#cfssljson 将 cfssl 生成的证书(json格式)变为文件承载式证书,-bare 用于命名生成的证书文件。
#-----------------------
#生成 etcd 服务器证书和私钥
cat > server-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"192.168.3.11",
"192.168.3.12",
"192.168.3.13"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
#hosts:将所有 etcd 集群节点添加到 host 列表,需要指定所有 etcd 集群的节点 ip 或主机名不能使用网段,新增 etcd 服务器需要重新签发证书。
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
#生成的文件:
#server.csr:服务器的证书请求文件
#server-key.pem:服务器的私钥
#server.pem:服务器的数字签名证书
#-config:引用证书生成策略文件 ca-config.json
#-profile:指定证书生成策略文件中的的使用场景,比如 ca-config.json 中的 www
>>>>wq
----------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------
[root@master k8s]# vim etcd.sh //注意修改称自己的IP
#!/bin/bash
# example: ./etcd.sh etcd01 192.168.3.11 etcd02=https://192.168.3.12:2380,etcd03=https://192.168.3.13:2380
#创建etcd配置文件/opt/etcd/cfg/etcd
ETCD_NAME=$1
ETCD_IP=$2
ETCD_CLUSTER=$3
WORK_DIR=/opt/etcd
cat > $WORK_DIR/cfg/etcd <<EOF
#[Member]
ETCD_NAME="${ETCD_NAME}"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://${ETCD_IP}:2380"
ETCD_LISTEN_CLIENT_URLS="https://${ETCD_IP}:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://${ETCD_IP}:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://${ETCD_IP}:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://${ETCD_IP}:2380,${ETCD_CLUSTER}"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
#Member:成员配置
#ETCD_NAME:节点名称,集群中唯一。成员名字,集群中必须具备唯一性,如etcd01
#ETCD_DATA_DIR:数据目录。指定节点的数据存储目录,这些数据包括节点ID,集群ID,集群初始化配置,Snapshot文件,若未指定-wal-dir,还会存储WAL文件;如果不指定会用缺省目录
#ETCD_LISTEN_PEER_URLS:集群通信监听地址。用于监听其他member发送信息的地址。ip为全0代表监听本机所有接口
#ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址。用于监听etcd客户发送信息的地址。ip为全0代表监听本机所有接口
#Clustering:集群配置
#ETCD_INITIAL_ADVERTISE_PEER_URLS:集群通告地址。其他member使用,其他member通过该地址与本member交互信息。一定要保证从其他member能可访问该地址。静态配置方式下,该参数的value一定要同时在--initial-cluster参数中存在
#ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址。etcd客户端使用,客户端通过该地址与本member交互信息。一定要保证从客户侧能可访问该地址
#ETCD_INITIAL_CLUSTER:集群节点地址。本member使用。描述集群中所有节点的信息,本member根据此信息去联系其他member
#ETCD_INITIAL_CLUSTER_TOKEN:集群Token。用于区分不同集群。本地如有多个集群要设为不同
#ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new是新集群,existing表示加入已有集群。
#创建etcd.service服务管理文件
cat > /usr/lib/systemd/system/etcd.service <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=${WORK_DIR}/cfg/etcd
ExecStart=${WORK_DIR}/bin/etcd \
--name=\${ETCD_NAME} \
--data-dir=\${ETCD_DATA_DIR} \
--listen-peer-urls=\${ETCD_LISTEN_PEER_URLS} \
--listen-client-urls=\${ETCD_LISTEN_CLIENT_URLS},http://127.0.0.1:2379 \
--advertise-client-urls=\${ETCD_ADVERTISE_CLIENT_URLS} \
--initial-advertise-peer-urls=\${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
--initial-cluster=\${ETCD_INITIAL_CLUSTER} \
--initial-cluster-token=\${ETCD_INITIAL_CLUSTER_TOKEN} \
--initial-cluster-state=new \
--cert-file=${WORK_DIR}/ssl/server.pem \
--key-file=${WORK_DIR}/ssl/server-key.pem \
--trusted-ca-file=${WORK_DIR}/ssl/ca.pem \
--peer-cert-file=${WORK_DIR}/ssl/server.pem \
--peer-key-file=${WORK_DIR}/ssl/server-key.pem \
--peer-trusted-ca-file=${WORK_DIR}/ssl/ca.pem
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
#--listen-client-urls:用于指定etcd和客户端的连接端口
#--advertise-client-urls:用于指定etcd服务器之间通讯的端口,etcd有要求,如果--listen-client-urls被设置了,那么就必须同时设置--advertise-client-urls,所以即使设置和默认相同,也必须显式设置
#--peer开头的配置项用于指定集群内部TLS相关证书(peer 证书),这里全部都使用同一套证书认证
#不带--peer开头的的参数是指定 etcd 服务器TLS相关证书(server 证书),这里全部都使用同一套证书认证
systemctl daemon-reload
systemctl enable etcd
systemctl restart etcd
>>>>>wq
[root@master k8s]# chmod +x etcd-cert.sh
[root@master k8s]# chmod +x etcd.sh
3、生成 CA 证书、etcd 服务器证书以及私钥
[root@master k8s]# mkdir /k8s/etcd-cert
[root@master k8s]# mv etcd-cert.sh etcd-cert/
[root@master k8s]# cd etcd-cert/
[root@master etcd-cert]# ./etcd-cert.sh
#生成CA证书、etcd服务器证书以及私钥
[root@master etcd-cert]# ls
ca-config.json ca-csr.json ca.pem server.csr server-key.pem
ca.csr ca-key.pem etcd-cert.sh server-csr.json server.pem
4、安装 etcd 服务
etcd 二进制包地址:https://github.com/etcd-io/etcd/releases
[root@master etcd-cert]# cd /k8s/
[root@master k8s]# rz -E
#传入etcd安装包etcd-v3.3.10-linux-amd64.tar.gz
[root@master k8s]# tar zxvf etcd-v3.3.10-linux-amd64.tar.gz
[root@master01 k8s]# ls etcd-v3.3.10-linux-amd64
Documentation etcd etcdctl README-etcdctl.md README.md READMEv2-etcdctl.md
//etcd 就是 etcd 服务的启动命令,后面可跟各种启动参数
//etcdctl 主要为 etcd 服务提供了命令行操作
5、创建用于存放 etcd 配置文件、命令文件、证书的目录
[root@master01 k8s]# mkdir -p /opt/etcd/{cfg,bin,ssl}
[root@master01 k8s]# mv /k8s/etcd-v3.3.10-linux-amd64/etcd /k8s/etcd-v3.3.10-linux-amd64/etcdctl /opt/etcd/bin/
[root@master01 bin]# cp /k8s/etcd-cert/*.pem /opt/etcd/ssl/
6、启动etcd.sh 脚本
./etcd.sh etcd01 192.168.61.17 etcd02=https://192.168.61.18:2380,etcd03=https://192.168.61.22:2380
//进入卡住状态等待其他节点加入,这里需要三台 etcd 服务同时启动,如果只启动其中一台后,服务会卡在那里,直到集群中所有 etcd 节点都已启动
- 另外打开一个窗口查看 etcd 进程是否正常
[root@master01 ~]# ps -ef | grep etcd
root 2632 2169 0 15:32 pts/1 00:00:00 /bin/bash ./etcd.sh etcd01 192.168.61.17 etcd02=https://192.168.61.18:2380,etcd03=https://192.168.61.22:2380
root 2683 2632 0 15:32 pts/1 00:00:00 systemctl restart etcd
root 2691 1 5 15:32 ? 00:00:03 /opt/etcd/bin/etcd --name=etcd01 --data-dir=/var/lib/etcd/default.etcd --listen-peer-urls=https://192.168.61.17:2380 --listen-client-urls=https://192.168.61.17:2
379,http://127.0.0.1:2379 --advertise-client-urls=https://192.168.61.17:72379 --initial-advertise-peer-urls=https://192.168.61.17:2380 --initial-cluster=etcd01=https://192.168.61.17:2380,etcd02=https://192.168.61.18:2380,etcd03=https://192.168.61.22:2380 --initial-cluster-token=etcd-cluster --initial-cluster-state=new --cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem --trusted-ca-file=/opt/etc/ssl/ca.pem --peer-cert-file=/opt/etcd/ssl/server.pem --peer-key-file=/opt/etcd/ssl/server-key.pem --peer-trusted-ca-file=/opt/etcd/ssl/ca.pemroot 2774 2719 0 15:34 pts/2 00:00:00 grep --color=auto etcd
7、把 etcd 相关证书文件和命令文件全部拷贝到另外两个 etcd 集群节点
scp -r /opt/etcd/ root@192.168.61.18:/opt/etcd/
scp -r /opt/etcd/ root@192.168.61.22:/opt/etcd/
8、把 etcd 服务管理文件拷贝到了另外两个 etcd 集群节点
[root@master01 ~]# scp /usr/lib/systemd/system/etcd.service root@192.168.61.18:/usr/lib/systemd/system/
......
[root@master01 ~]# scp /usr/lib/systemd/system/etcd.service root@192.168.61.22:/usr/lib/systemd/system/
......
9、修改另外两个 etcd 集群节点的配置文件
node1 和 node2 操作相同,注意修改节点名和 IP
[root@node01 ~]# cd /opt/etcd/cfg/
[root@node01 cfg]# ls
etcd
[root@node01 cfg]# vim etcd
#[Member]
ETCD_NAME="etcd01"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.61.18:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.61.18:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.61.18:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.61.17:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.61.17:2380,etcd02=https://192.168.61.18:2380,etcd03
=https://192.168.61.22:2380"ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
>>>>wq
[root@node01 cfg]# systemctl daemon-reload
[root@node01 cfg]# systemctl enable --now etcd.service
[root@node01 cfg]# systemctl status etcd | grep Active
Active: active (running) since 三 2021-12-15 15:41:59 CST; 5min ago
10、 检查集群状态(master01)
v2版本查看(默认版本)
[root@master01 k8s]# ln -s /opt/etcd/bin/etcd* /usr/local/bin
#将etcd执行命令软链接到PATH路径
[root@master01 k8s]# cd /opt/etcd/ssl
[root@master01 ssl]# etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.10.100:2379,https://192.168.10.101:2379,https://192.168.10.102:2379" cluster-health
member 9302ad482744beb is healthy: got healthy result from https://192.168.61.22:2379
member 8f0b2f8f5a943bdf is healthy: got healthy result from https://192.168.61.18:2379
member f330bec74ce6cc42 is healthy: got healthy result from https://192.168.61.17:2379
cluster is healthy
--------------------------
etcdctl \
--ca-file=ca.pem \
--cert-file=server.pem \
--key-file=server-key.pem \
--endpoints="https://192.168.61.17:2379,https://192.168.61.18:2379,https://192.168.61.22:2379" \
cluster-health
v3 版本查看
切换到 etcd3 版本查看集群节点状态和成员列表
v2 和 v3 命令略有不同,etcd2 和 etcd3 也是不兼容的,默认版本是 v2 版本
[root@master01 ssl]# export ETCDCTL_API=3
[root@master01 ssl]# etcdctl --write-out=table endpoint status
+----------------+------------------+---------+---------+-----------+-----------+------------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+----------------+------------------+---------+---------+-----------+-----------+------------+
| 127.0.0.1:2379 | 71f26872cb1756fc | 3.3.10 | 20 kB | false | 377 | 14 |
+----------------+------------------+---------+---------+-----------+-----------+------------+
[root@master01 ssl]# etcdctl --write-out=table member list
+------------------+---------+--------+---------------------------+---------------------------
+| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS
|+------------------+---------+--------+---------------------------+---------------------------
+| 1e3ccef658341896 | started | etcd02 | https://192.168.61.18:2380 | https://192.168.61.18:2379
|| 596e1e583604dc35 | started | etcd03 | https://192.168.61.22:2380 | https://192.168.61.22:2379
|| 71f26872cb1756fc | started | etcd01 | https://192.168.61.17:2380 | https://192.168.61.17:2379
|+------------------+---------+--------+---------------------------+---------------------------
+
#换回 v2 版本
[root@master01 ssl]# export ETCDCTL_API=2
三、部署 docker 引擎(所有 node 节点)
node1 和 node2 操作相同
[root@node01 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@node01 ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@node01 ~]# yum install -y docker-ce docker-ce-cli containerd.io
[root@node01 ~]# systemctl enable --now docker
四、flannel 网络配置
1、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 地址通信。
2、Overlay Network
叠加网络,在二层或者三层网络上叠加的一种虚拟网络技术模式,该网络中的主机通过虚拟链路隧道连接起来(类似于 VPN)。
3、 VXLAN
将源数据包封装到 UDP 中,并使用基础网络的 IP/MAC 作为外层报文头进行封装,然后在以太网上传输,到达目的地后由隧道端点解封装并将数据发送给目标地址。
4、Flannel 简介
Flannel 的功能是让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。Flannel 是 Overlay 网络的一种,将 TCP 源数据包封装在另一种网络包里面进行路由转发和通信,目前支持 UDP、VXLAN、host-GW 三种数据转发方式。
5、Flannel 工作原理
数据从 node01 上 Pod 的源容器中发出后,经由所在主机的 docker0 虚拟网卡转发到 flannel.1 虚拟网卡,flanneld 服务监听在 flanne.1 数据网卡的另外一端。
Flannel 通过 Etcd 服务维护了一张节点间的路由表。源主机 node01 的 flanneld 服务将原本的数据内容封装到 UDP 中后根据自己的路由表通过物理网卡投递给目的节点 node02 的 flanneld 服务,数