一:服务器规划
本次安装使用了 三个控制节点,四个数据节点,和三个etcd节点,服务器 ip操作系统和硬件配置如下:
给k8s roles 打标签
使用kubectl get node 一栏中的ROLES 使用给定的值命名
kubectl label node k8s-node1 kubernetes.io/role=worker1
kubectl label node k8s-node2 kubernetes.io/role=worker2
一:服务器规划
本次安装使用了 三个控制节点,四个数据节点,和三个etcd节点,服务器 ip操作系统和硬件配置如下:

二:初始化k8s 环境
2.1:关闭交换分区(阿里云的机器是默认关闭的,我使用的天翼云的机器,默认没有关闭)
swapoff -a && sysctl -w vm.swappiness=0 && sed -i '\$s/^/#/' /etc/fstab
2.2: 安装必要依赖软件包
yum makecache;yum install ipvsadm ipset sysstat conntrack libseccomp runc -y
2.3:开启时间同步
yum install -y chrony && systemctl start chronyd && systemctl enable chronyd && chronyc sources
2.4:加载内核模块,这些模块会被容器运行时:containerd使用,ip_ 开头的模块被kubelet 用到替代iptables,br_netfilter模块也被内核参数
net.bridge.bridge-nf-call-ip6tables = 1 ,net.bridge.bridge-nf-call-iptables = 1 使用,不先加载br_netfilter 模块,前面两个内核参数修改不成功
centos 中默认 nf_conntrack_ipv4 模块也不会被加载,如果没有加载这个模块所有,nf_conntrack_* 不生效,如:net.netfilter.nf_conntrack_max=10485760
net.netfilter.nf_conntrack_tcp_timeout_established=300 不会生效。状态跟踪功能就不可用。 比如iptables 的状态 跟踪不可用,这是基础模块,必须加载
cat <<EOF | sudo tee /etc/modules-load.d/loadk8s.conf
overlay
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
EOF
2.5 不启动服务器,手动加载内核模块(服务器重启的时候 /etc/modules-load.d/loadk8s.conf 模块会自动加载,这里不重启,手动加载)
modprobe overlay
modprobe br_netfilter
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
# modprobe nf_conntrack_ipv4
内核5以上的nf_conntrack_ipv4 已经被nf_conntrack取代了 执行会报如下错误:
modprobe: FATAL: Module nf_conntrack_ipv4 not found in directory
2.6把服务器名称和对应的名称 添加到/etc/hosts 文件中,每台机器上执行一次。
cat >> /etc/hosts << EOF
192.168.1.160 qm-k8s-prod-master-01
192.168.1.161 qm-k8s-prod-master-02
192.168.1.162 qm-k8s-prod-master-03
192.168.1.163 qm-k8s-prod-node-01
192.168.1.164 qm-k8s-prod-node-02
192.168.1.165 qm-k8s-prod-node-03
192.168.1.167 qm-k8s-prod-node-04
192.168.1.166 k8s-cluster-apiserver-lbs
EOF
2.7 设置机器名称,需要每天机器上执行,注意每台机器的设置对应的名称,不能一样。
hostnamectl set-hostname qm-k8s-prod-master-01
2.8 修改内核参数,net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 需要依赖br_netfilter,不然报错
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
2.9 使修改的内核参数生效
/usr/sbin/sysctl --system
3.0 如果有多台机器,一台一台机器初始化是很麻烦,并且有可能遗漏,我这里已经写好的脚本,在host_ip 中添加上需要初始化的服务器内网ip即可
三:证书规划
3.1 k8s证书描述
二进制安装k8s 证书规划和生成是一个难点,特别是kuber-apiserver 和kube-controller-manager 启动参数中有一堆的证书,理清这些证书用途,对于k8s 功能有更好的认识
认识k8s的证书,可以参考下面链接:https://wenda.zuncuang.com/article/673
3.2 证书规划分类如下:
3.2.1 etcd证书,这个是独立的一套证书体系,有独立私钥,公钥; etcd公钥,私钥;群集节点通讯的公钥和私钥,etcdctl 连接服务端的证书公钥和私钥。
3.2.2 k8s系类证书,独立证书体系,包括k8s ca的公钥和私钥,kuber-apiserver 公钥和私钥,kube-controller-manager 公钥和私钥,kube-scheduler公钥和私钥,kube-proxy公钥和私钥 (kubelet 公钥证书是kube-controller-manger自动颁发的)
3.2.3 service-account证书,这个不属于k8s 证书颁发体系,只是一个密钥对,生成一对公钥/私钥。kube-controller-manager 使用私钥生成token,然后放入secrets 中,用于pod访问kube-apiserver 凭证,kube-apiserver 使用公钥来验证token.
3.2.4 k8s 聚合服务证书,这个也是独立证书体系。聚合服务,主要代理k8s一些扩展api,服务要访问这些k8s扩展api时候,如果不改变k8s 接口调用规则,则需要打开k8s聚合代理功能,服务正常调用k8s 接口,k8s 通过代理方式再访问扩展的api,比如常见的metrics-server 就是一个扩展的api服务。这些证书包括,聚合服务ca证书公钥和私钥,聚合服务的公钥和私钥。
3.3 下载cloudflare公司的证书工具(pki)
3.3.1 下载证书工具 ,到https://github.com/cloudflare/cfssl/releases 下载对应版本cfssl-bundle_1.6.0_linux_amd64,我这里使用当前最新(2021-07-14为止)
wget -O cfssl-certinfo https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl-certinfo_1.6.0_linux_amd64
wget -O cfssl-newkey https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl-newkey_1.6.0_linux_amd64
wget -O cfssl-scan https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl-scan_1.6.0_linux_amd64
wget -O cfssl_1.6.0 https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl_1.6.0_linux_amd64
wget -O cfssljson https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssljson_1.6.0_linux_amd64
说明: cfssl-certinfo 查看证书信息,cfssl-newkey 也可以通过json格式的请求文件生成证书,cfssl-scan 通过扫描一个主机的证书情况,cfssl 和cfssljson 是我们生成证书的
主要程序。其中cfssl 包含上面三种工具的功能
3.4 通过 cfssl 工具生成证书
3.41 生成etcd证书体系
3.4.1.1 生成etcd的根证书
{
"CN": "etcd-ca",
"key": {
"algo": "rsa",
"size": 2048
}
}
cfssl gencert -initca ca-csr.json |cfssljson -bare ca
上面命令生成三个文件,分别是 ca.pem ca-key.pem ca.csr ,其中ca.pem 为etcd根证书公钥文件,ca-key.pem 为根证书私钥。ca.csr 为证书请求,是一个无用的中间状态证书
3.4.1.2 生成etcd服务端证书文件 【etcd-server-peer-csr.json】 这里服务端证书和节点证书使用同一个,不分别生成了,注意把环路地址和节点所有节点ip都加入
{
"CN": "etcd-server",
"hosts": [
"127.0.0.1",
"192.168.188.88",
"192.168.188.89",
"192.168.188.90"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Guangdong",
"L": "Dongguan",
"O": "etc-cluster",
"OU": "system"
}
]
}
*******************************************************************************
{
"signing": {
"default": {
"expiry": "43800h"
},
"profiles": {
"etcd-server": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
},
"etcd-client": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"etcd-peer": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=etcd-ca-config.json -profile=etcd-server etcd-server-peer-csr.json |cfssl -bare etcd-server-peer
其中-profile文件指定参数为 etcd-ca-config.json 配置文件中定义的“profiles” 下的字段
3.4.1.3 生成etcd客户端证书文件 【etcd-client-csr.json】 ,注意把环路地址和节点所有节点ip都加入
{
"CN": "etcd-client",
"hosts": [
"127.0.0.1",
"192.168.188.88",
"192.168.188.89",
"192.168.188.90"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Guangdong",
"L": "Dongguan",
"O": "etc-cluster",
"OU": "system"
}
]
}
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=etcd-ca-config.json -profile=etcd-client etcd-client-csr.json |cfssl -bare etcd-client
上面证书生成工具和 证书请求的配置文件,可以从下面地方下载
四:安装etcd服务,这里三个节点做高可用。
3.1 下载软件,我这里使用当前最新版 V3.5.0,下载的是二进制格式
wget https://github.com/etcd-io/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz
3.2 解压下来的软件里面的 etcd etcdctl etcdutl 三个文件各自放到etcd-1 etcd-2 etcd-3 的/usr/bin目录下面.其中etcd 是服务端程序,etcdctl 是一个连接服务端的命令行工具
etcdutl 是一个 从etcdctl 分离出来的工具,主要用来诊断etcd文件。
3.3 把上述三个文件分别copy到各节点/usr/bin 目录中 然后 chmod +x etcd* 赋予可执行权限
3.4 创建etcd服务运行目录 mkdir -p /var/lib/etcd
3.5 编写systemd风格启动文件【etcd.service】,把文件分别copy到三个节点上,修改--name 为每个节点唯一名字,这个名字是群集节点标志,不能重复。--listen-peer-urls --initial-advertise-peer-urls --listen-client-urls 要修改各自ip地址。
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd
ExecStart=/usr/bin/etcd \
--data-dir=/var/lib/etcd \
--name=etcd-1 \
--cert-file=/opt/kubernetes/etcd/ssl/etcd-server.pem \
--key-file=/opt/kubernetes/etcd/ssl/etcd-server-key.pem \
--trusted-ca-file=/opt/kubernetes/etcd/ssl/ca.pem \
--peer-cert-file=/opt/kubernetes/etcd/ssl/etcd-peer.pem \
--peer-key-file=/opt/kubernetes/etcd/ssl/etcd-peer-key.pem \
--peer-trusted-ca-file=/opt/kubernetes/etcd/ssl/ca.pem \
--listen-peer-urls=https://192.168.188.88:2380 \
--initial-advertise-peer-urls=https://192.168.188.88:2380 \
--listen-client-urls=https://192.168.188.88:2379,http://127.0.0.1:2379 \
--advertise-client-urls=https://192.168.188.88:2379 \
--initial-cluster-token=etcd-cluster-0 \
--initial-cluster=etcd-1=https://192.168.188.88:2380,etcd-2=https://192.168.188.89:2380,etcd-3=https://192.168.188.90:2380 \
--initial-cluster-state=new \
--heartbeat-interval=250 \
--election-timeout=2000
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
注:
ETCD_NAME:节点名称,集群中唯一
ETCD_DATA_DIR:数据目录
ETCD_LISTEN_PEER_URLS:集群通信监听地址
ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址
ETCD_INITIAL_ADVERTISE_PEER_URLS:集群通告地址
ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
ETCD_INITIAL_CLUSTER:集群节点地址
ETCD_INITIAL_CLUSTER_TOKEN:集群Token
ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new是新集群,existing表示加入已有集群
3.6 在各个节点上启动服务,等一分钟左右观察状态
systemctl --now enable etcd.service
3.7 编写一个使用etcdctl 访问服务端的脚本如下:
#!/bin/bash
ETCDCTL_API=3 /usr/bin/etcdctl --cacert=/opt/kubernetes/etcd/ssl/ca.pem --cert=/opt/kubernetes/etcd/ssl/etcd-client.pem --key=/opt/kubernetes/etcd/ssl/etcd-client-key.pem --endpoints=https://192.168.188.88:2379,https://192.168.188.89:2379,https://192.168.188.90:2379 $@
把这个文件保存为 etcdcheck.sh 然后放到/usr/bin 并给与可执行权限。
查看etcd群集情况
etcdcheck endpoint health --write-out=table
查看节点状态
etcdcheck endpoint status --write-out=table
列出member
etcdcheck member list --write-out=table
列出所有key
etcdcheck get / --prefix --keys-only
查看某个key的value
etcdcheck get /registry/statefulsets/sthmei-com/keycloak