基于二进制部署Kubernetes集群
环境准备
三台CentOS 7.9虚拟机,配置为2核4GB,需具备外网访问能力。
| IP地址 | 角色 |
|---|---|
| 192.168.0.148 | k8s-master01 |
| 192.168.0.246 | k8s-node01 |
| 192.168.0.104 | k8s-node02 |
主机名与网络配置
hostnamectl set-hostname k8s-master01
hostnamectl set-hostname k8s-node01
hostnamectl set-hostname k8s-node02
# 编辑 hosts 文件
echo "192.168.0.148 k8s-master01" >> /etc/hosts
echo "192.168.0.246 k8s-node01" >> /etc/hosts
echo "192.168.0.104 k8s-node02" >> /etc/hosts
关闭安全组件
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
swapoff -a
# 编辑 /etc/fstab,注释 swap 行
时间同步
ntpdate time.windows.com
文件下载
Master 节点
mkdir -p /root/kubernetes/resources
cd /root/kubernetes/resources
wget https://dl.k8s.io/v1.18.20/kubernetes-server-linux-amd64.tar.gz
wget https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
wget https://docs.projectcalico.org/v3.19/manifests/calico.yaml
Node 节点
mkdir -p /root/kubernetes/resources
cd /root/kubernetes/resources
wget https://dl.k8s.io/v1.18.20/kubernetes-node-linux-amd64.tar.gz
wget https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz
wget https://github.com/containernetworking/plugins/releases/download/v0.8.6/cni-plugins-linux-amd64-v0.8.6.tgz
部署 etcd 集群
使用 cfssl 工具生成 CA 证书及 etcd 安全通信密钥对。
安装 cfssl
cd /root/kubernetes/resources
cp cfssl_linux-amd64 /usr/bin/cfssl
cp cfssljson_linux-amd64 /usr/bin/cfssljson
cp cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
chmod +x /usr/bin/cfssl /usr/bin/cfssljson /usr/bin/cfssl-certinfo
mkdir -p /etc/etcd/ssl
生成 CA 证书
cd /root/kubernetes/resources/cert/etcd
vim ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"etcd": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
vim ca-csr.json
{
"CN": "etcd ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
生成 etcd 服务证书
vim server-csr.json
{
"CN": "etcd",
"hosts": [
"192.168.0.148",
"192.168.0.246",
"192.168.0.104"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd server-csr.json | cfssljson -bare server
分发证书
cp ca.pem server-key.pem server.pem /etc/etcd/ssl
scp ca.pem server-key.pem server.pem k8s-node01:/etc/etcd/ssl
scp ca.pem server-key.pem server.pem k8s-node02:/etc/etcd/ssl
安装 etcd 二进制
cd /root/kubernetes/resources
tar -zxvf etcd-v3.4.9-linux-amd64.tar.gz
cp etcd-v3.4.9-linux-amd64/etcd etcd-v3.4.9-linux-amd64/etcdctl /usr/bin
配置 etcd 服务
在各节点分别创建配置文件:
# /etc/etcd/etcd.conf
[Member]
ETCD_NAME="etcd01"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.0.148:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.0.148:2379"
[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.0.148:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.0.148:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.0.148:2380,etcd02=https://192.168.0.246:2380,etcd03=https://192.168.0.104:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
启动 etcd 服务
mkdir -p /var/lib/etcd
vim /usr/lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/etc/etcd/etcd.conf
ExecStart=/usr/bin/etcd \
--cert-file=/etc/etcd/ssl/server.pem \
--key-file=/etc/etcd/ssl/server-key.pem \
--peer-cert-file=/etc/etcd/ssl/server.pem \
--peer-key-file=/etc/etcd/ssl/server-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start etcd
systemctl enable etcd
验证集群状态
etcdctl endpoint health \
--cacert=/etc/etcd/ssl/ca.pem \
--cert=/etc/etcd/ssl/server.pem \
--key=/etc/etcd/ssl/server-key.pem \
--endpoints="https://192.168.0.148:2379,https://192.168.0.246:2379,https://192.168.0.104:2379"
部署 Master 组件
安装 kubectl
cd /root/kubernetes/resources
tar -zxvf kubernetes-server-linux-amd64.tar.gz
cp kubernetes/server/bin/kubectl /usr/bin
生成 Kubernetes 证书
mkdir -p /root/kubernetes/resources/cert/kubernetes /etc/kubernetes/{ssl,bin}
cp kubernetes/server/bin/kube-apiserver kube-controller-manager kube-scheduler /etc/kubernetes/bin
cd /root/kubernetes/resources/cert/kubernetes
CA 配置
vim ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
CA 证书生成
vim ca-csr.json
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "kubernetes",
"OU": "System"
}
]
}
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
API Server 证书
vim kube-apiserver-csr.json
{
"CN": "kubernetes",
"hosts": [
"10.0.0.1",
"127.0.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local",
"172.29.7.148",
"172.29.7.149",
"172.29.7.150"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "kubernetes",
"OU": "System"
}
]
}
生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-apiserver-csr.json | cfssljson -bare kube-apiserver
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
分发 kube-proxy 证书
mkdir -p /etc/kubernetes/ssl
cp ca.pem ca-key.pem kube-apiserver.pem kube-apiserver-key.pem kube-proxy.pem kube-proxy-key.pem /etc/kubernetes/ssl
scp -r /etc/kubernetes/ssl k8s-node01:/etc/kubernetes
scp -r /etc/kubernetes/ssl k8s-node02:/etc/kubernetes
创建 Bootstrap Token
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
# 输出示例:d5c5d767b64db39db132b433e9c45fbc
vim token.csv
d5c5d767b64db39db132b433e9c45fbc,kubelet-bootstrap,10001,"system:node-bootstrapper"
配置 kube-apiserver
vim /etc/kubernetes/apiserver
KUBE_API_ARGS="--logtostderr=false \
--v=2 \
--log-dir=/var/log/kubernetes \
--etcd-servers=https://192.168.0.148:2379,https://192.168.0.246:2379,https://192.168.0.104:2379 \
--bind-address=192.168.0.148 \
--secure-port=6443 \
--advertise-address=192.168.0.148 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth=true \
--token-auth-file=/etc/kubernetes/token.csv \
--service-node-port-range=30000-32767 \
--kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem \
--kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/etc/etcd/ssl/ca.pem \
--etcd-certfile=/etc/etcd/ssl/server.pem \
--etcd-keyfile=/etc/etcd/ssl/server-key.pem \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/logs/kubernetes/k8s-audit.log"
启动 apiserver 服务
vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
After=etcd.service
[Service]
EnvironmentFile=/etc/kubernetes/apiserver
ExecStart=/etc/kubernetes/bin/kube-apiserver $KUBE_API_ARGS
Restart=on-failure
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver
部署 controller-manager 与 scheduler
配置方式类似,略去详细步骤。核心参数包括:
- controller-manager: 启用 leader-elect,指定 cluster-signing 证书路径
- scheduler: 启用 leader-elect,绑定本地地址
授权 bootstrap 用户
kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap
检查 Master 状态
kubectl get cs
部署 Node 节点
安装 Docker
yum remove docker docker-client docker-common -y
yum install yum-utils -y
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io -y
systemctl enable docker && systemctl start docker
配置镜像加速器
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
安装 kubelet
cd /root/kubernetes/resources
tar -zxvf kubernetes-node-linux-amd64.tar.gz
mkdir -p /etc/kubernetes/{ssl,bin}
cp kubernetes/node/bin/kubelet kubernetes/node/bin/kube-proxy /etc/kubernetes/bin
配置 kubelet
vim /etc/kubernetes/kubelet
KUBELET_ARGS="--logtostderr=false \
--v=2 \
--log-dir=/var/log/kubernetes \
--enable-server=true \
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
--hostname-override=k8s-node01 \
--network-plugin=cni \
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \
--config=/etc/kubernetes/kubelet-config.yml \
--cert-dir=/etc/kubernetes/ssl"
生成 bootstrap.kubeconfig
vim /etc/kubernetes/bootstrap.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority: /etc/kubernetes/ssl/ca.pem
server: https://192.168.0.148:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubelet-bootstrap
name: default
current-context: default
kind: Config
users:
- name: kubelet-bootstrap
user:
token: d5c5d767b64db39db132b433e9c45fbc
配置 kubelet-config.yml
vim /etc/kubernetes/kubelet-config.yml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/ssl/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
启动 kubelet
systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet
审批 CSR 请求
kubectl get csr
kubectl certificate approve node-csr-xxxxx
安装 kube-proxy
vim /etc/kubernetes/kube-proxy
KUBE_PROXY_ARGS="--logtostderr=false \
--v=2 \
--log-dir=/var/log/kubernetes \
--config=/etc/kubernetes/kube-proxy-config.yml"
配置 kube-proxy-config.yml
vim /etc/kubernetes/kube-proxy-config.yml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
address: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
hostnameOverride: k8s-node01
clusterCIDR: 10.0.0.0/24
mode: ipvs
ipvs:
scheduler: "rr"
iptables:
masqueradeAll: true
启动 kube-proxy
systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy
部署 CNI 插件
mkdir -p /opt/cni/bin /etc/cni/net.d
tar -zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin
部署 Calico 网络
kubectl apply -f calico.yaml
测试集群
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
curl 192.168.0.246:32063