网站首页 > 博客文章 正文
带证书的二进制方式安装部署k8s
1.配置固定IP
cd /etc/sysconfig/network-scripts/
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
#BOOTPROTO=dhcp
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR0=192.168.10.6
PREFIXO0=24
GATEWAY0=192.168.10.2
DNS1=192.168.10.2
2.主机信息配置
/etc/hosts
192.168.10.10 k8s1 192.168.10.11 k8s2 192.168.10.12 k8s3
echo -e "192.168.10.10 k8s1\n192.168.10.11 k8s2\n192.168.10.12 k8s3" >> /etc/hosts
主机名称
/etc/hostname
echo "k8s1" >/etc/hostname
hostname k8s1
su -
关闭selinux
关闭 SELinux,否则后续 K8S 挂载目录时可能报错 Permission denied
cat /etc/selinux/config
SELINUX=disabled
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
关闭防火墙
systemctl stop firewalld systemctl disable firewalld
关闭swap内存
如果开启了 swap 分区,kubelet 会启动失败(可以通过将参数 --fail-swap-on 设置为 false 来忽略 swap on),故需要在每台机器上关闭 swap 分区:
swapoff -a
sed -i '/swap/d' /etc/fstab
# swapon -va //启用Swap分区
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
关闭 dnsmasq
linux 系统开启了 dnsmasq 后(如 GUI 环境),将系统 DNS Server 设置为 127.0.0.1,这 会导致 docker 容器无法解析域名,需要关闭它:
service dnsmasq stop
systemctl disable dnsmasq
调整内核参数
cat < /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
EOF
sysctl --system
添加 k8s 和 docker 账户
useradd -m k8s
passwd k8s
visudo
%wheel ALL=(ALL) NOPASSWD: ALL
cat /etc/group|grep wheel
gpasswd -a k8s wheel
useradd -m docker
gpasswd -a k8s docker
mkdir -p /etc/docker/
/etc/docker/daemon.json
{ "registry-mirrors": ["https://hub-mirror.c.163.com", "https://doc ker.mirrors.ustc.edu.cn"], "max-concurrent-downloads": 20 }
无密码 ssh 登录其它节点
设置 k8s1 可以无密码登录所有节点的 k8s 和 root 账户:
以k8s账号登录
ssh-keygen -t rsa
ssh-copy-id root@k8s1
ssh-copy-id root@k8s2
ssh-copy-id root@k8s3
将可执行文件路径 /opt/k8s/bin 添加到 PATH 变量中
echo 'PATH=/opt/k8s/bin:$PATH:$HOME/bin:$JAVA_HOME/bin' >>/root/.bashrc
echo 'PATH=/opt/k8s/bin:$PATH:$HOME/bin:$JAVA_HOME/bin' >>~/.bashrc
在每台机器上安装依赖包:
yum install -y epel-release
yum install -y conntrack ipvsadm ipset jq sysstat curl iptables
加载内核模块
modprobe br_netfilter
modprobe ip_vs
设置系统时区
查看当前时区
timedatectl
timedatectl set-timezone Asia/Shanghai
timedatectl set-local-rtc 0
ystemctl restart rsyslog
systemctl restart crond
目录配置
mkdir -p /opt/k8s/bin
chown -R k8s /opt/k8s
mkdir -p /etc/kubernetes/cert
chown -R k8s /etc/kubernetes
mkdir -p /etc/etcd/cert
chown -R k8s /etc/etcd/cert
mkdir -p /var/lib/etcd && chown -R k8s /etc/etcd/cert
检测docker环境脚本
curl https://raw.githubusercontent.com/docker/docker/master/contrib /check-config.sh > check-config.sh
集群环境变量
/opt/k8s/bin/environment.sh
#!/usr/bin/bash
# 生成 EncryptionConfig 所需的加密 key
ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
# 最好使用 当前未用的网段 来定义服务网段和 Pod 网段
# 服务网段,部署前路由不可达,部署后集群内路由可达(kube-proxy 和 ipvs 保证)
SERVICE_CIDR="10.254.0.0/16"
# Pod 网段,建议 /16 段地址,部署前路由不可达,部署后集群内路由可达(flanneld保证)
CLUSTER_CIDR="172.30.0.0/16"
# 服务端口范围 (NodePort Range)
export NODE_PORT_RANGE="8400-9000"
# 集群各机器 IP 数组
export NODE_IPS=(192.168.10.10 192.168.10.11 192.168.10.12)
# 集群各 IP 对应的 主机名数组
export NODE_NAMES=(k8s1 k8s2 k8s3)
# kube-apiserver 节点 IP
export MASTER_IP=192.168.10.10
# kube-apiserver https 地址
export KUBE_APISERVER="https://${MASTER_IP}:6443"
# etcd 集群服务地址列表
export ETCD_ENDPOINTS="https://192.168.10.10:2379,https://192.168.10.11:2379,https://192.168.10.12:2379"
# etcd 集群间通信的 IP 和端口
export ETCD_NODES="k8s1=https://192.168.10.10:2380,k8s2=https://192.168.10.11:2380,k8s3=https://192.168.10.12:2380"
# flanneld 网络配置前缀
export FLANNEL_ETCD_PREFIX="/kubernetes/network"
# kubernetes 服务 IP (一般是 SERVICE_CIDR 中第一个IP)
export CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"
# 集群 DNS 服务 IP (从 SERVICE_CIDR 中预分配)
export CLUSTER_DNS_SVC_IP="10.254.0.2"
# 集群 DNS 域名
export CLUSTER_DNS_DOMAIN="cluster.local."
# 将二进制目录 /opt/k8s/bin 加到 PATH 中
export PATH=/opt/k8s/bin:$PATH
分发集群环境变量定义脚本
切换到k8s用户
source environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp environment.sh k8s@${node_ip}:/opt/k8s/bin/
ssh k8s@${node_ip} "chmod +x /opt/k8s/bin/*"
done
安装 cfssl 工具集
mkdir -p /opt/k8s/cert
chown -R k8s /opt/k8s
cd /opt/ k8s
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
mv cfssl_linux-amd64 /opt/k8s/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
mv cfssljson_linux-amd64 /opt/k8s/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /opt/k8s/bin/cfssl-certinfo
chmod +x /opt/k8s/bin/*
export PATH=/opt/k8s/bin:$PATH
创建根证书 (CA)
CA 证书是集群所有节点共享的,只需要创建一个 CA 证书,后续创建的所有证书都由 它签名
创建配置文件
CA 配置文件用于配置根证书的使用场景 (profile) 和具体参数 (usage,过期时间、服务 端认证、客户端认证、加密等),后续在签名其它证书时需要指定特定场景
k8s1
cd /opt
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
signing :表示该证书可用于签名其它证书,生成的 ca.pem 证书中 CA=TRUE ;
server auth :表示 client 可以用该该证书对 server 提供的证书进行验证;
client auth :表示 server 可以用该该证书对 client 提供的证书进行验证;
创建证书签名请求文件
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "4Paradigm"
}
]
}
CN: Common Name ,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法;
O: Organization ,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);
kube-apiserver 将提取的 User、Group 作为 RBAC 授权的用户标识;
生成 CA 证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
ls ca*
分发证书文件
将生成的 CA 证书、秘钥文件、配置文件拷贝到所有节点的 /etc/kubernetes/cert 目录下:
source /opt/k8s/bin/environment.sh # 导入 NODE_IPS 环境变量
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp ca*.pem ca-config.json k8s@${node_ip}:/etc/kubernetes/cert
done
部署 kubectl 命令行工具
kubectl 是 kubernetes 集群的命令行管理工具,本文档介绍安装和配置它的步骤。 kubectl 默认从 ~/.kube/config 文件读取 kube-apiserver 地址、证书、用户名等信 息,如果没有配置,执行 kubectl 命令时可能会出错:
$ kubectl get pods
The connection to the server localhost:8080 was refused - did you spe cify the right host or port?
本文档只需要部署一次,生成的 kubeconfig 文件与机器无关。
下载和分发 kubectl 二进制文件
下载和解压:
kubernetes-client-linux-amd64.tar.gz
tar zxvf kubernetes-client-linux-amd64.tar.gz
分发到所有使用 kubectl 的节点:
# 导入 NODE_IPS 环境变量
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp kubernetes/client/bin/kubectl k8s@${node_ip}:/opt/k8s/bin/
ssh k8s@${node_ip} "chmod +x /opt/k8s/bin/*"
done
chown -R k8s.k8s /opt*
创建 admin 证书和私钥
kubectl 与 apiserver https 安全端口通信,apiserver 对提供的证书进行认证和授权。 kubectl 作为集群的管理工具,需要被授予最高权限。这里创建具有最高权限的 admin 证书。
创建证书签名请求:
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "4Paradigm"
}
]
}
O 为 system:masters ,kube-apiserver 收到该证书后将请求的 Group 设置为 system:masters;
预定义的 ClusterRoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予所有 API的权限;
该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;
生成证书和私钥:
cfssl gencert -ca=/etc/kubernetes/cert/ca.pem \
-ca-key=/etc/kubernetes/cert/ca-key.pem \
-config=/etc/kubernetes/cert/ca-config.json \
-profile=kubernetes admin-csr.json | cfssljson -bare admin
ls admin*
创建 kubectl.kubeconfig 文件
kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地 址、CA 证书和自身使用的证书;
source /opt/k8s/bin/environment.sh
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/cert/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kubectl.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials admin \
--client-certificate=admin.pem \
--client-key=admin-key.pem \
--embed-certs=true \
--kubeconfig=kubectl.kubeconfig
# 设置上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin \
--kubeconfig=kubectl.kubeconfig
# 设置默认上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig
--certificate-authority :验证 kube-apiserver 证书的根证书;
--client-certificate 、 --client-key :刚生成的 admin 证书和私钥,连 接 kube-apiserver 时使用;
--embed-certs=true :将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl.kubeconfig 文件中(不加时,写入的是证书文件路径);
分发 kubectl.kubeconfig 文件 分
发到所有使用 kubelet 命令的节点:
导入 NODE_IPS 环境变量
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh k8s@${node_ip} "mkdir -p ~/.kube"
scp kubectl.kubeconfig k8s@${node_ip}:~/.kube/config
ssh root@${node_ip} "mkdir -p ~/.kube"
scp kubectl.kubeconfig root@${node_ip}:~/.kube/config
done
保存到用户的 ~/.kube/config 文件;
部署 etcd 集群
etcd 是基于 Raft 的分布式 key-value 存储系统,由 CoreOS 开发,常用于服务发现、 共享配置以及并发控制(如 leader 选举、分布式锁等)。kubernetes 使用 etcd 存储所 有运行数据。
本文档介绍部署一个三节点高可用 etcd 集群的步骤:
下载和分发 etcd 二进制文件;
创建 etcd 集群各节点的 x509 证书,用于加密客户端(如 etcdctl) 与 etcd 集群、 etcd 集群之间的数据流;
创建 etcd 的 systemd unit 文件,配置服务参数;
检查集群工作状态;
下载和分发 etcd 二进制文件
到 https://github.com/coreos/etcd/releases 页面下载最新版本的发布包:
https://github.com/coreos/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz
分发二进制文件到集群所有节点:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp etcd-v3.3.9-linux-amd64/etcd* k8s@${node_ip}:/opt/k8s/bin
ssh k8s@${node_ip} "chmod +x /opt/k8s/bin/*"
done
创建 etcd 证书和私钥
创建证书签名请求:
cat > etcd-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"192.168.10.10",
"192.168.10.11",
"192.168.10.12"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "4Paradigm"
}
]
}
EOF
hosts 字段指定授权使用该证书的 etcd 节点 IP 或域名列表,这里将 etcd 集群的三 个节点 IP 都列在其中;
生成证书和私钥:
cfssl gencert -ca=/etc/kubernetes/cert/ca.pem \
-ca-key=/etc/kubernetes/cert/ca-key.pem \
-config=/etc/kubernetes/cert/ca-config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
分发生成的证书和私钥到各 etcd 节点:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/etcd/cert && chown -R k8s /etc/etcd/cert"
scp etcd*.pem k8s@${node_ip}:/etc/etcd/cert/
done
创建 etcd 的 systemd unit 模板文件
source /opt/k8s/bin/environment.sh
cat > etcd.service.template <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
User=k8s
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/opt/k8s/bin/etcd \\
--data-dir=/var/lib/etcd \\
--name=##NODE_NAME## \\
--cert-file=/etc/etcd/cert/etcd.pem \\
--key-file=/etc/etcd/cert/etcd-key.pem \\
--trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
--peer-cert-file=/etc/etcd/cert/etcd.pem \\
--peer-key-file=/etc/etcd/cert/etcd-key.pem \\
--peer-trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
--peer-client-cert-auth \\
--client-cert-auth \\
--listen-peer-urls=https://##NODE_IP##:2380 \\
--initial-advertise-peer-urls=https://##NODE_IP##:2380 \\
--listen-client-urls=https://##NODE_IP##:2379,http://127.0.0.1:2379 \\
--advertise-client-urls=https://##NODE_IP##:2379 \\
--initial-cluster-token=etcd-cluster-0 \\
--initial-cluster=${ETCD_NODES} \\
--initial-cluster-state=new
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
User :指定以 k8s 账户运行;
WorkingDirectory 、 --data-dir :指定工作目录和数据目录为 /var/lib/etcd ,需在启动服务前创建这个目录;
--name :指定节点名称,当 --initial-cluster-state 值为 new 时, -- 04.部署etcd集群 26 name 的参数值必须位于 --initial-cluster 列表中;
--cert-file 、 --key-file :etcd server 与 client 通信时使用的证书和私钥;
--trusted-ca-file :签名 client 证书的 CA 证书,用于验证 client 证书;
--peer-cert-file 、 --peer-key-file :etcd 与 peer 通信使用的证书和私 钥;
--peer-trusted-ca-file :签名 peer 证书的 CA 证书,用于验证 peer 证书;
为各节点创建和分发 etcd systemd unit 文件
替换模板文件中的变量,为各节点创建 systemd unit 文件:
source /opt/k8s/bin/environment.sh
for (( i=0; i < 3; i++ ));
do
sed -e "s/##NODE_NAME##/${NODE_NAMES[i]}/" -e "s/##NODE_IP##/${NODE_IPS[i]}/" etcd.service.template > etcd-${NODE_IPS[i]}.service;
done
ls *.service
NODE_NAMES 和 NODE_IPS 为相同长度的 bash 数组,分别为节点名称和对应 的 IP;
分发生成的 systemd unit 文件:
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /var/lib/etcd && chown -R k8s /var/lib/etcd"
scp etcd-${node_ip}.service root@${node_ip}:/etc/systemd/system/etcd.service
done
必须先创建 etcd 数据目录和工作目录;
文件重命名为 etcd.service;
启动 etcd 服务
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd &"
done
etcd 进程首次启动时会等待其它节点的 etcd 加入集群,命令 systemctl start etcd 会卡住一段时间,为正常现象。
检查启动结果
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}" ssh k8s@${node_ip} "systemctl status etcd|grep Active"
done
确保状态为 active (running) ,否则查看日志,确认原因:
journalctl -u etcd
验证服务状态
部署完 etcd 集群后,在任一 etc 节点上执行如下命令:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
--endpoints=https://${node_ip}:2379 \
--cacert=/etc/kubernetes/cert/ca.pem \
--cert=/etc/etcd/cert/etcd.pem \
--key=/etc/etcd/cert/etcd-key.pem endpoint health
done
输出均为 healthy 时表示集群服务正常。
如果有异常,需要删除 /var/lib/etcd/* 重新启动etcd服务
部署 flannel 网络
kubernetes 要求集群内各节点(包括 master 节点)能通过 Pod 网段互联互通。flannel 使 用 vxlan 技术为各节点创建一个可以互通的 Pod 网络
flaneel 第一次启动时,从 etcd 获取 Pod 网段信息,为本节点分配一个未使用的 /24 段地址,然后创建 flannedl.1 (也可能是其它名称,如 flannel1 等) 接口。
flannel 将分配的 Pod 网段信息写入 /run/flannel/docker 文件,docker 后续使用这 个文件中的环境变量设置 docker0 网桥。
下载和分发 flanneld 二进制文件
到 https://github.com/coreos/flannel/releases 页面下载最新版本的发布包:
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
分发 flanneld 二进制文件到集群所有节点:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp flannel/{flanneld,mk-docker-opts.sh} k8s@${node_ip}:/opt/k8s/bin/
ssh k8s@${node_ip} "chmod +x /opt/k8s/bin/*"
done
创建 flannel 证书和私钥
flannel 从 etcd 集群存取网段分配信息,而 etcd 集群启用了双向 x509 证书认证,所以 需要为 flanneld 生成证书和私钥。 创建证书签名请求:
cat > flanneld-csr.json <<EOF
{
"CN": "flanneld",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "4Paradigm"
}
]
}
EOF
该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;
生成证书和私钥:
cfssl gencert -ca=/etc/kubernetes/cert/ca.pem \
-ca-key=/etc/kubernetes/cert/ca-key.pem \
-config=/etc/kubernetes/cert/ca-config.json \
-profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld
ls flanneld*pem
将生成的证书和私钥分发到所有节点(master 和 worker):
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/flanneld/cert && chown -R k8s /etc/flanneld"
scp flanneld*.pem k8s@${node_ip}:/etc/flanneld/cert
done
向 etcd 写入集群 Pod 网段信息
注意:本步骤只需执行一次
source /opt/k8s/bin/environment.sh
etcdctl --endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
set ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 24,"Backend": {"Type": "vxlan"}}'
{"Network":"172.30.0.0/16", "SubnetLen": 24,"Backend": {"Type": "vxlan"}}
flanneld 当前版本 (v0.10.0) 不支持 etcd v3,故使用 etcd v2 API 写入配置 key 和 网段数据;
写入的 Pod 网段 ${CLUSTER_CIDR} 必须是 /16 段地址,必须与 kube-controllermanager 的 --cluster-cidr 参数值一致;
创建 flanneld 的 systemd unit 文件
source /opt/k8s/bin/environment.sh
export IFACE=ens33
cat > flanneld.service << EOF
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service
[Service]
Type=notify
ExecStart=/opt/k8s/bin/flanneld \\
-etcd-cafile=/etc/kubernetes/cert/ca.pem \\
-etcd-certfile=/etc/flanneld/cert/flanneld.pem \\
-etcd-keyfile=/etc/flanneld/cert/flanneld-key.pem \\
-etcd-endpoints=${ETCD_ENDPOINTS} \\
-etcd-prefix=${FLANNEL_ETCD_PREFIX} \\
-iface=${IFACE}
ExecStartPost=/opt/k8s/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTION S -d /run/flannel/docker
Restart=on-failure
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF
mk-docker-opts.sh 脚本将分配给 flanneld 的 Pod 子网网段信息写入 /run/flannel/docker 文件,后续 docker 启动时使用这个文件中的环境变量配 置 docker0 网桥
flanneld 使用系统缺省路由所在的接口与其它节点通信,对于有多个网络接口(如 内网和公网)的节点,可以用 -iface 参数指定通信接口,如上面的 eth0 接口;
flanneld 运行时需要 root 权限;
分发 flanneld systemd unit 文件到所有节点
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp flanneld.service root@${node_ip}:/etc/systemd/system/
done
启动 flanneld 服务
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
done
检查启动结果
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh k8s@${node_ip} "systemctl status flanneld|grep Active"
done
确保状态为 active (running) ,否则查看日志,确认原因:
journalctl -u flanneld
检查分配给各 flanneld 的 Pod 网段信息
查看集群 Pod 网段(/16):
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
get ${FLANNEL_ETCD_PREFIX}/config
{"Network":"172.30.0.0/16", "SubnetLen": 24,"Backend": {"Type": "vxlan"}}
查看已分配的 Pod 子网段列表(/24):
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
ls ${FLANNEL_ETCD_PREFIX}/subnets
/kubernetes/network/subnets/172.30.100.0-24
/kubernetes/network/subnets/172.30.48.0-24
/kubernetes/network/subnets/172.30.4.0-2
查看某一 Pod 网段对应的节点 IP 和 flannel 接口地址:
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.48.0-24
{"PublicIP":"192.168.10.10","BackendType":"vxlan","BackendData":{"VtepMAC":"92:a3:f6:f2:9f:e1"}}
验证各节点能通过 Pod 网段互通
在各节点上部署 flannel 后,检查是否创建了 flannel 接口(名称可能为 flannel0、 flannel.0、flannel.1 等):
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "/usr/sbin/ip addr show flannel.1|grep -w inet"
done
在各节点上 ping 所有 flannel 接口 IP,确保能通:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "ping -c 1 172.30.100.0"
ssh ${node_ip} "ping -c 1 172.30.48.0"
ssh ${node_ip} "ping -c 1 172.30.4.0"
done
部署 master 节点
kubernetes master 节点运行如下组件:
kube-apiserver
kube-scheduler
kube-controller-manager
这 3 个组件均可以以集群模式运行,通过 leader 选举产生一个工作进程,其它进程处于 阻塞模式
下载最新版本的二进制文件
tar -xzvf kubernetes-server-linux-amd64.tar.gz
cd kubernetes
tar -xzvf kubernetes-src.tar.gz
将二进制文件拷贝到所有 master 节点:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp server/bin/* k8s@${node_ip}:/opt/k8s/bin/
ssh k8s@${node_ip} "chmod +x /opt/k8s/bin/*"
done
部署 kube-apiserver 组件
本文档讲解部署一个单 master 的部署,对应的节点 IP 为环境变量 ${MASTER_IP}。
创建 kubernetes 证书和私钥
创建证书签名请求:
source /opt/k8s/bin/environment.sh
cat > kubernetes-csr.json <
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"${MASTER_IP}",
"${CLUSTER_KUBERNETES_SVC_IP}",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "4Paradigm"
}
]
}
EOF
hosts 字段指定授权使用该证书的 IP 或域名列表,这里列出了 apiserver 节点 IP、 kubernetes 服务 IP 和域名;
域名最后字符不能是 . (如不能为 kubernetes.default.svc.cluster.local. ),否则解析时失败,提示: x509: cannot parse dnsName "kubernetes.default.svc.cluster.local." ;
如果使用非 cluster.local 域名,如 opsnull.com ,则需要修改域名列表中 的最后两个域名 为: kubernetes.default.svc.opsnull 、 kubernetes.default.svc.opsnull .com
kubernetes 服务 IP 是 apiserver 自动创建的,一般是 --service-cluster-iprange 参数指定的网段的第一个IP,后续可以通过如下命令获取:
kubectl get svc kubernetes
生成证书和私钥:
cfssl gencert -ca=/etc/kubernetes/cert/ca.pem \
-ca-key=/etc/kubernetes/cert/ca-key.pem \
-config=/etc/kubernetes/cert/ca-config.json \
-profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
ls kubernetes*
将生成的证书和私钥文件拷贝到 master 节点:
source /opt/k8s/bin/environment.sh
ssh root@${MASTER_IP} "mkdir -p /etc/kubernetes/cert/ && sudo chown - R k8s /etc/kubernetes/cert/"
scp kubernetes*.pem k8s@${MASTER_IP}:/etc/kubernetes/cert/
k8s 账户可以读写 /etc/kubernetes/cert/ 目录;
创建加密配置文件
source /opt/k8s/bin/environment.sh
cat > encryption-config.yaml <
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: ${ENCRYPTION_KEY}
- identity: {}
EOF
将加密配置文件拷贝到 master 节点的 /etc/kubernetes 目录下:
source /opt/k8s/bin/environment.sh
scp encryption-config.yaml root@${MASTER_IP}:/etc/kubernetes/
创建和分发 kube-apiserver systemd unit 文件
source /opt/k8s/bin/environment.sh
cat > kube-apiserver.service <<EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
ExecStart=/opt/k8s/bin/kube-apiserver \\
--enable-admission-plugins=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
--anonymous-auth=false \\
--experimental-encryption-provider-config=/etc/kubernetes/encryption-config.yaml \\
--advertise-address=${MASTER_IP} \\
--bind-address=${MASTER_IP} \\
--insecure-port=0 \\
--authorization-mode=Node,RBAC \\
--runtime-config=api/all \\
--enable-bootstrap-token-auth \\
--service-cluster-ip-range=${SERVICE_CIDR} \\
--service-node-port-range=${NODE_PORT_RANGE} \\
--tls-cert-file=/etc/kubernetes/cert/kubernetes.pem \\
--tls-private-key-file=/etc/kubernetes/cert/kubernetes-key.pem \\
--client-ca-file=/etc/kubernetes/cert/ca.pem \\
--kubelet-client-certificate=/etc/kubernetes/cert/kubernetes.pem \\
--kubelet-client-key=/etc/kubernetes/cert/kubernetes-key.pem \\
--service-account-key-file=/etc/kubernetes/cert/ca-key.pem \\
--etcd-cafile=/etc/kubernetes/cert/ca.pem \\
--etcd-certfile=/etc/kubernetes/cert/kubernetes.pem \\
--etcd-keyfile=/etc/kubernetes/cert/kubernetes-key.pem \\
--etcd-servers=${ETCD_ENDPOINTS} \\
--enable-swagger-ui=true \\
--allow-privileged=true \\
--apiserver-count=3 \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/kube-apiserver-audit.log \\
--event-ttl=1h \\
--alsologtostderr=true \\
--logtostderr=false \\
--log-dir=/var/log/kubernetes \\
--v=2
Restart=on-failure
RestartSec=5
Type=notify
User=k8s
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
--experimental-encryption-provider-config :启用加密特性;
--authorization-mode=Node,RBAC : 开启 Node 和 RBAC 授权模式,拒绝未授 权的请求;
--enable-admission-plugins :启用 ServiceAccount 和 NodeRestriction ;
--service-account-key-file :签名 ServiceAccount Token 的公钥文件, kube-controller-manager 的 --service-account-private-key-file 指定私钥 文件,两者配对使用;
--tls-*-file :指定 apiserver 使用的证书、私钥和 CA 文件。 --client-cafile 用于验证 client (kue-controller-manager、kube-scheduler、kubelet、kubeproxy 等)请求所带的证书;
--kubelet-client-certificate 、 --kubelet-client-key :如果指定,则使 用 https 访问 kubelet APIs;需要为证书对应的用户(上面 kubernetes*.pem 证书的 用户为 kubernetes) 用户定义 RBAC 规则,否则访问 kubelet API 时提示未授权;
--bind-address : 不能为 127.0.0.1 ,否则外界不能访问它的安全端口 6443;
--insecure-port=0 :关闭监听非安全端口(8080);
--service-cluster-ip-range : 指定 Service Cluster IP 地址段;
--service-node-port-range : 指定 NodePort 的端口范围;
--runtime-config=api/all=true : 启用所有版本的 APIs,如 autoscaling/v2alpha1;
--enable-bootstrap-token-auth :启用 kubelet bootstrap 的 token 认证;
--apiserver-count=3 :指定集群运行模式,多台 kube-apiserver 会通过 leader 选举产生一个工作节点,其它节点处于阻塞状态; User=k8s :使用 k8s 账户运行
分发 systemd uint 文件到 master 节点:
source /opt/k8s/bin/environment.sh
scp kube-apiserver.service root@${MASTER_IP}:/etc/systemd/system/
ssh root@${MASTER_IP} "mkdir -p /var/log/kubernetes && chown -R k8s /var/log/kubernetes"
必须先创建日志目录;
授予 kubernetes 证书访问 kubelet API 的权限
在执行 kubectl exec、run、logs 等命令时,apiserver 会转发到 kubelet。这里定义 RBAC 规则,授权 apiserver 调用 kubelet API。
kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
启动 kube-apiserver 服务
ssh root@${MASTER_IP} "systemctl daemon-reload && systemctl enable kube-apiserver && systemctl restart kube-apiserver"
检查 kube-apiserver 运行状态
ssh root@${MASTER_IP} "systemctl status kube-apiserver |grep 'Active: '"
确保状态为 active (running) ,否则到 master 节点查看日志,确认原因:
$ journalctl -u kube-apiserver
打印 kube-apiserver 写入 etcd 的数据
source /opt/k8s/bin/environment.sh
ETCDCTL_API=3 etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--cacert=/etc/kubernetes/cert/ca.pem \
--cert=/etc/etcd/cert/etcd.pem \
--key=/etc/etcd/cert/etcd-key.pem \
get /registry/ --prefix --keys-only
检查集群信息
kubectl cluster-info
- 上一篇: CKA备考实验 | 安装后的设置
- 下一篇: 使用kubeadm搭建一单节点k8s测试集群
猜你喜欢
- 2024-12-31 二进制部署k8s集群
- 2024-12-31 Kubernetes系列之集群部署
- 2024-12-31 容器化部署SpringBoot微服务
- 2024-12-31 【云原生】k8s 一键部署(ansible)
- 2024-12-31 【云原生】k8s 离线部署讲解和实战操作
- 2024-12-31 探索eBPF:Linux内核的黑科技
- 2024-12-31 Kubernetes 常见故障排查和处理
- 2024-12-31 使用RKE的方式快速部署K8S集群
- 2024-12-31 在 Anolis 8.8 | Rocky 9.3 | AlmaLinux 9.3 上部署 k8s v1.28.3 集群
- 2024-12-31 k8s集群报错:check that the calico/node container is running and has
你 发表评论:
欢迎- 368℃用AI Agent治理微服务的复杂性问题|QCon
- 365℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 358℃初次使用IntelliJ IDEA新建Maven项目
- 351℃Maven技术方案最全手册(mavena)
- 348℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 347℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 345℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 343℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)