基于二进制部署Kubernetes集群完整教程
服务器资源规划
| 角色 | IP地址 | 关键组件 |
|---|---|---|
| k8s-master1 | 192.168.31.63 | kube-apiserver, kube-controller-manager, kube-scheduler, etcd |
| k8s-master2 | 192.168.31.64 | kube-apiserver, kube-controller-manager, kube-scheduler |
| k8s-node1 | 192.168.31.65 | kubelet, kube-proxy, docker, etcd |
| k8s-node2 | 192.168.31.66 | kubelet, kube-proxy, docker, etcd |
| LB主节点 | 192.168.31.61 (VIP: 192.168.31.60) | Nginx L4 |
| LB备节点 | 192.168.31.62 | Nginx L4 |
一、基础环境准备
所有节点执行以下操作。
1. 停用防火墙
systemctl stop firewalld
systemctl disable firewalld
2. 关闭SELinux
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
3. 关闭Swap
swapoff -a
# 并编辑 /etc/fstab 注释掉swap行
4. 时间同步
ntpdate time.windows.com
5. 配置主机名解析
cat >> /etc/hosts <<EOF
192.168.31.63 k8s-master1
192.168.31.64 k8s-master2
192.168.31.65 k8s-node1
192.168.31.66 k8s-node2
EOF
6. 修改主机名(各节点分别执行)
hostnamectl set-hostname k8s-master1 # 示例
二、搭建Etcd集群
选择一个节点执行证书生成,然后部署到三个etcd节点上。
2.1 生成Etcd证书
安装cfssl后,编辑请求文件(server-csr.json),hosts列表包含所有etcd节点IP:
{
"CN": "etcd",
"hosts": [
"192.168.31.63",
"192.168.31.64",
"192.168.31.65"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{"C": "CN", "L": "BeiJing", "ST": "BeiJing"}
]
}
./generate_etcd_cert.sh
ls *pem # 应有 ca-key.pem, ca.pem, server-key.pem, server.pem
2.2 部署三个Etcd节点
解压etcd包,将证书放到ssl目录,然后分别拷贝到三个节点:
scp -r etcd root@192.168.31.63:/opt
scp etcd.service root@192.168.31.63:/usr/lib/systemd/system
# 其他节点类似
登录每个节点修改 /opt/etcd/cfg/etcd.conf,调整节点名称和IP:
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.31.63:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.31.63:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.31.63:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.31.63:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.31.63:2380,etcd-2=https://192.168.31.64:2380,etcd-3=https://192.168.31.65:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
启动并启用etcd:
systemctl start etcd
systemctl enable etcd
2.3 验证集群健康
/opt/etcd/bin/etcdctl \
--ca-file=/opt/etcd/ssl/ca.pem \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--endpoints="https://192.168.31.63:2379,https://192.168.31.64:2379,https://192.168.31.65:2379" \
cluster-health
输出应显示三个成员健康。
三、部署Master节点
3.1 生成API Server证书
编辑server-csr.json,hosts包含所有节点IP以及VIP、Service IP等:
{
"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",
"192.168.31.60",
"192.168.31.61",
"192.168.31.62",
"192.168.31.63",
"192.168.31.64",
"192.168.31.65",
"192.168.31.66"
],
"key": {"algo": "rsa", "size": 2048},
"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing","O": "k8s","OU": "System"}]
}
./generate_k8s_cert.sh
ls *pem # 应有 ca.pem, server.pem, kube-proxy.pem 等
3.2 启动kube-apiserver、controller-manager、scheduler
在master1上操作:
tar zxvf k8s-master.tar.gz
cd kubernetes
cp TLS/k8s/ssl/*.pem ssl/
cp -rf kubernetes /opt
cp kube-apiserver.service kube-controller-manager.service kube-scheduler.service /usr/lib/systemd/system
编辑 /opt/kubernetes/cfg/kube-apiserver.conf,配置etcd地址、绑定IP(本机IP)等:
KUBE_APISERVER_OPTS="--logtostderr=false --v=2 --log-dir=/opt/kubernetes/logs \
--etcd-servers=https://192.168.31.63:2379,https://192.168.31.64:2379,https://192.168.31.65:2379 \
--bind-address=192.168.31.63 --secure-port=6443 --advertise-address=192.168.31.63 ..."
启动服务:
systemctl start kube-apiserver kube-controller-manager kube-scheduler
systemctl enable kube-apiserver kube-controller-manager kube-scheduler
3.3 配置TLS Bootstrap
创建token文件(/opt/kubernetes/cfg/token.csv):
c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-bootstrapper"
为kubelet-bootstrap用户授权:
kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap
token可随机生成:head -c 16 /dev/urandom | od -An -t x | tr -d ' ',需与后续node配置保持一致。
四、部署Worker节点
4.1 安装Docker
tar zxvf k8s-node.tar.gz
tar zxvf docker-18.09.6.tgz
mv docker/* /usr/bin
mkdir /etc/docker
mv daemon.json /etc/docker
mv docker.service /usr/lib/systemd/system
systemctl start docker && systemctl enable docker
4.2 部署kubelet和kube-proxy
将证书从master复制到node1:
cd TLS/k8s
scp ca.pem kube-proxy*.pem root@192.168.31.65:/opt/kubernetes/ssl/
解压k8s-node包并复制服务文件:
tar zxvf k8s-node.tar.gz
mv kubernetes /opt
cp kubelet.service kube-proxy.service /usr/lib/systemd/system
编辑三个config文件中的API Server地址(指向master1或后续的VIP):
# 这些文件在 /opt/kubernetes/cfg/ 下
sed -i 's#192.168.31.63#192.168.31.60#g' bootstrap.kubeconfig kubelet.kubeconfig kube-proxy.kubeconfig
修改kubelet.conf和kube-proxy-config.yml中的主机名:
--hostname-override=k8s-node1
hostnameOverride: k8s-node1
启动:
systemctl start kubelet kube-proxy
systemctl enable kubelet kube-proxy
4.3 批准Node证书申请
kubectl get csr
kubectl certificate approve <csr-name>
kubectl get nodes
4.4 部署CNI网络(Flannel)
安装CNI插件:
mkdir -p /opt/cni/bin /etc/cni/net.d
tar zxvf cni-plugins-linux-amd64-v0.8.2.tgz -C /opt/cni/bin
确认kubelet配置包含 --network-plugin=cni。
应用Flannel网络:
kubectl apply -f kube-flannel.yaml
kubectl get pods -n kube-system
4.5 授权API Server访问kubelet
修改kubelet-config.yml启用webhook认证:
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /opt/kubernetes/ssl/ca.pem
应用RBAC规则:kubectl apply -f apiserver-to-kubelet-rbac.yaml
五、部署Dashboard和CoreDNS
5.1 Dashboard
下载yaml并修改Service为NodePort:
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta4/aio/deploy/recommended.yaml
# 编辑文件,将 service spec.type 改为 NodePort,并设置 nodePort: 30001
kubectl apply -f recommended.yaml
创建管理员用户:
cat > dashboard-adminuser.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
kubectl apply -f dashboard-adminuser.yaml
获取token:
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
通过 https://任意NodeIP:30001 访问,使用token登录。
5.2 CoreDNS
kubectl apply -f coredns.yaml
kubectl get pods -n kube-system
六、高可用配置
6.1 部署第二个Master节点
将master1的配置复制到master2:
scp -r /opt/kubernetes root@192.168.31.64:/opt
scp -r /opt/etcd/ssl root@192.168.31.64:/opt/etcd
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@192.168.31.64:/usr/lib/systemd/system
在master2上修改 /opt/kubernetes/cfg/kube-apiserver.conf 中的 bind-address 和 advertise-address 为本地IP(192.168.31.64),然后启动服务。
6.2 部署Nginx负载均衡
在所有Master节点(或专门的LB节点)上安装Nginx,配置四层代理:
rpm -vih http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.0-1.el7.ngx.x86_64.rpm
cat >/etc/nginx/nginx.conf <<EOF
stream {
log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
access_log /var/log/nginx/k8s-access.log main;
upstream k8s-apiserver {
server 192.168.31.63:6443;
server 192.168.31.64:6443;
}
server {
listen 6443;
proxy_pass k8s-apiserver;
}
}
EOF
systemctl start nginx && systemctl enable nginx
6.3 Keepalived实现高可用
主节点和备节点分别安装keepalived:
yum install -y keepalived
主节点配置(/etc/keepalived/keepalived.conf):
global_defs {
notification_email { acassen@firewall.loc }
router_id NGINX_MASTER
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication { auth_type PASS; auth_pass 1111; }
virtual_ipaddress { 192.168.31.60/24 }
track_script { check_nginx }
}
创建健康检查脚本 /etc/keepalived/check_nginx.sh:
#!/bin/bash
count=$(ps -ef |grep nginx |egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then exit 1; else exit 0; fi
备节点配置类似,state改为BACKUP,priority改为90,router_id改为NGINX_BACKUP。
启动:
systemctl start keepalived && systemctl enable keepalived
验证VIP已绑定到主节点:ip a 应显示192.168.31.60。
6.4 修改Node连接到VIP
将所有Node上的kubelet、kube-proxy配置指向VIP:
cd /opt/kubernetes/cfg
sed -i 's#192.168.31.63#192.168.31.60#g' *.kubeconfig bootstrap.kubeconfig
重启kubelet和kube-proxy:
systemctl restart kubelet kube-proxy
验证:
curl -k --header "Authorization: Bearer c47ffb939f5ca36231d9e3121a252940" https://192.168.31.60:6443/version