2.1 安装前准备
1. 系统要求
硬件要求: - CPU:至少2核 - 内存:至少2GB - 磁盘:至少20GB可用空间 - 网络:集群内节点需要网络连通
软件要求: - 操作系统:Ubuntu 18.04+、CentOS 7+、RHEL 7+ - 容器运行时:Docker、containerd、CRI-O - 网络:禁用swap分区
2. 环境准备脚本
prepare-system.sh
#!/bin/bash
# 设置主机名和hosts文件
echo "设置主机名和hosts文件..."
hostnamectl set-hostname k8s-master
cat >> /etc/hosts << EOF
192.168.1.100 k8s-master
192.168.1.101 k8s-worker1
192.168.1.102 k8s-worker2
EOF
# 关闭防火墙
echo "关闭防火墙..."
systemctl stop firewalld
systemctl disable firewalld
# 关闭SELinux
echo "关闭SELinux..."
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# 关闭swap
echo "关闭swap..."
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 配置内核参数
echo "配置内核参数..."
cat > /etc/modules-load.d/k8s.conf << EOF
br_netfilter
EOF
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
modprobe br_netfilter
sysctl --system
# 配置时间同步
echo "配置时间同步..."
yum install -y chrony
systemctl enable chronyd
systemctl start chronyd
echo "系统准备完成!"
3. 容器运行时安装
Docker安装
install-docker.sh
#!/bin/bash
# 卸载旧版本
yum remove -y docker docker-client docker-client-latest docker-common \
docker-latest docker-latest-logrotate docker-logrotate docker-engine
# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加Docker仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装Docker CE
yum install -y docker-ce docker-ce-cli containerd.io
# 配置Docker
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
]
}
EOF
# 启动Docker
systemctl daemon-reload
systemctl enable docker
systemctl start docker
# 验证安装
docker --version
docker info
echo "Docker安装完成!"
containerd安装
install-containerd.sh
#!/bin/bash
# 安装containerd
yum install -y containerd.io
# 生成默认配置
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 配置systemd cgroup驱动
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# 配置镜像加速
sed -i '/\[plugins."io.containerd.grpc.v1.cri".registry.mirrors\]/a\ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\n endpoint = ["https://docker.mirrors.ustc.edu.cn"]' /etc/containerd/config.toml
# 启动containerd
systemctl daemon-reload
systemctl enable containerd
systemctl start containerd
# 验证安装
ctr version
echo "containerd安装完成!"
2.2 使用kubeadm安装集群
1. 安装kubeadm、kubelet、kubectl
install-k8s-tools.sh
#!/bin/bash
# 添加Kubernetes仓库
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 安装kubeadm、kubelet、kubectl
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
# 启用kubelet
systemctl enable kubelet
# 验证安装
kubeadm version
kubectl version --client
kubelet --version
echo "Kubernetes工具安装完成!"
2. 初始化Master节点
init-master.sh
#!/bin/bash
# 预拉取镜像
echo "预拉取镜像..."
kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers
# 初始化集群
echo "初始化Master节点..."
kubeadm init \
--apiserver-advertise-address=192.168.1.100 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all
# 配置kubectl
echo "配置kubectl..."
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 验证集群状态
echo "验证集群状态..."
kubectl get nodes
kubectl get pods -n kube-system
echo "Master节点初始化完成!"
echo "请保存以下join命令,用于添加Worker节点:"
kubeadm token create --print-join-command
3. kubeadm配置文件
kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.1.100
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: k8s-master
taints: null
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: 1.28.0
clusterName: kubernetes
controlPlaneEndpoint: "k8s-master:6443"
imageRepository: registry.aliyuncs.com/google_containers
networking:
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16
dnsDomain: cluster.local
apiServer:
bindPort: 6443
certSANs:
- "k8s-master"
- "192.168.1.100"
- "127.0.0.1"
- "localhost"
extraArgs:
authorization-mode: Node,RBAC
enable-admission-plugins: NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota
controllerManager:
extraArgs:
bind-address: 0.0.0.0
scheduler:
extraArgs:
bind-address: 0.0.0.0
etcd:
local:
dataDir: /var/lib/etcd
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
ipvs:
strictARP: true
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
anonymous:
enabled: false
webhook:
enabled: true
authorization:
mode: Webhook
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
cpuManagerPolicy: none
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
failSwapOn: false
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
kind: KubeletConfiguration
maxOpenFiles: 1000000
maxPods: 110
resolvConf: /etc/resolv.conf
runtimeRequestTimeout: 2m
serializeImagePulls: false
staticPodPath: /etc/kubernetes/manifests
syncFrequency: 1m
volumeStatsAggPeriod: 1m
4. 添加Worker节点
join-worker.sh
#!/bin/bash
# 从Master节点获取join命令
# kubeadm token create --print-join-command
# 加入集群(替换为实际的join命令)
kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
echo "Worker节点加入完成!"
2.3 网络插件安装
1. Flannel网络插件
install-flannel.sh
#!/bin/bash
# 下载Flannel配置文件
wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 修改网络配置(如果需要)
sed -i 's|10.244.0.0/16|10.244.0.0/16|g' kube-flannel.yml
# 应用Flannel
kubectl apply -f kube-flannel.yml
# 验证安装
echo "等待Flannel Pod启动..."
sleep 30
kubectl get pods -n kube-flannel
kubectl get nodes
echo "Flannel网络插件安装完成!"
kube-flannel.yml
apiVersion: v1
kind: Namespace
metadata:
labels:
k8s-app: flannel
pod-security.kubernetes.io/enforce: privileged
name: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: flannel
name: flannel
namespace: kube-flannel
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: flannel
name: flannel
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
- apiGroups:
- networking.k8s.io
resources:
- clustercidrs
verbs:
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: flannel
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-flannel
---
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: flannel
tier: node
name: kube-flannel-cfg
namespace: kube-flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
k8s-app: flannel
tier: node
name: kube-flannel-ds
namespace: kube-flannel
spec:
selector:
matchLabels:
k8s-app: flannel
template:
metadata:
labels:
k8s-app: flannel
tier: node
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
containers:
- args:
- --ip-masq
- --kube-subnet-mgr
command:
- /opt/bin/flanneld
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: EVENT_QUEUE_DEPTH
value: "5000"
image: docker.io/flannel/flannel:v0.22.0
name: kube-flannel
resources:
requests:
cpu: 100m
memory: 50Mi
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
privileged: false
volumeMounts:
- mountPath: /run/flannel
name: run
- mountPath: /etc/kube-flannel/
name: flannel-cfg
- mountPath: /run/xtables.lock
name: xtables-lock
hostNetwork: true
initContainers:
- args:
- -f
- /flannel
- /opt/cni/bin/flannel
command:
- cp
image: docker.io/flannel/flannel-cni-plugin:v1.1.2
name: install-cni-plugin
volumeMounts:
- mountPath: /opt/cni/bin
name: cni-plugin
- args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
command:
- cp
image: docker.io/flannel/flannel:v0.22.0
name: install-cni
volumeMounts:
- mountPath: /etc/cni/net.d
name: cni
- mountPath: /etc/kube-flannel/
name: flannel-cfg
priorityClassName: system-node-critical
restartPolicy: Always
serviceAccountName: flannel
tolerations:
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /run/flannel
name: run
- hostPath:
path: /opt/cni/bin
name: cni-plugin
- hostPath:
path: /etc/cni/net.d
name: cni
- configMap:
name: kube-flannel-cfg
name: flannel-cfg
- hostPath:
path: /run/xtables.lock
type: FileOrCreate
name: xtables-lock
2. Calico网络插件
install-calico.sh
#!/bin/bash
# 下载Calico配置文件
wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/tigera-operator.yaml
wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/custom-resources.yaml
# 安装Tigera Operator
kubectl create -f tigera-operator.yaml
# 修改网络配置
sed -i 's|192.168.0.0/16|10.244.0.0/16|g' custom-resources.yaml
# 安装Calico
kubectl create -f custom-resources.yaml
# 验证安装
echo "等待Calico Pod启动..."
watch kubectl get pods -n calico-system
echo "Calico网络插件安装完成!"
custom-resources.yaml
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
ipPools:
- blockSize: 26
cidr: 10.244.0.0/16
encapsulation: VXLANCrossSubnet
natOutgoing: Enabled
nodeSelector: all()
---
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
name: default
spec: {}
2.4 使用二进制文件安装
1. 下载二进制文件
download-binaries.sh
#!/bin/bash
K8S_VERSION="v1.28.0"
ETCD_VERSION="v3.5.9"
# 创建目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
mkdir -p /opt/etcd/{bin,cfg,ssl}
# 下载Kubernetes二进制文件
echo "下载Kubernetes二进制文件..."
wget https://dl.k8s.io/${K8S_VERSION}/kubernetes-server-linux-amd64.tar.gz
tar -xzf kubernetes-server-linux-amd64.tar.gz
cp kubernetes/server/bin/{kube-apiserver,kube-controller-manager,kube-scheduler,kubelet,kube-proxy,kubectl} /opt/kubernetes/bin/
# 下载etcd二进制文件
echo "下载etcd二进制文件..."
wget https://github.com/etcd-io/etcd/releases/download/${ETCD_VERSION}/etcd-${ETCD_VERSION}-linux-amd64.tar.gz
tar -xzf etcd-${ETCD_VERSION}-linux-amd64.tar.gz
cp etcd-${ETCD_VERSION}-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
# 设置权限
chmod +x /opt/kubernetes/bin/*
chmod +x /opt/etcd/bin/*
# 添加到PATH
echo 'export PATH=/opt/kubernetes/bin:/opt/etcd/bin:$PATH' >> /etc/profile
source /etc/profile
echo "二进制文件下载完成!"
2. 生成证书
generate-certs.sh
#!/bin/bash
# 安装cfssl
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl-certinfo_1.6.4_linux_amd64
chmod +x cfssl*
mv cfssl_1.6.4_linux_amd64 /usr/local/bin/cfssl
mv cfssljson_1.6.4_linux_amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_1.6.4_linux_amd64 /usr/local/bin/cfssl-certinfo
# 创建证书目录
mkdir -p /opt/kubernetes/ssl
cd /opt/kubernetes/ssl
# 生成CA证书
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
cat > ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
# 生成kube-apiserver证书
cat > server-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"10.0.0.1",
"127.0.0.1",
"192.168.1.100",
"192.168.1.101",
"192.168.1.102",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
echo "证书生成完成!"
3. 配置etcd集群
etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
User=etcd
ExecStart=/opt/etcd/bin/etcd \
--data-dir=/var/lib/etcd \
--name=etcd-01 \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/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.pem \
--peer-client-cert-auth \
--client-cert-auth \
--listen-peer-urls=https://192.168.1.100:2380 \
--initial-advertise-peer-urls=https://192.168.1.100:2380 \
--listen-client-urls=https://192.168.1.100:2379,http://127.0.0.1:2379 \
--advertise-client-urls=https://192.168.1.100:2379 \
--initial-cluster-token=etcd-cluster-0 \
--initial-cluster=etcd-01=https://192.168.1.100:2380,etcd-02=https://192.168.1.101:2380,etcd-03=https://192.168.1.102:2380 \
--initial-cluster-state=new \
--auto-tls \
--peer-auto-tls
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
4. 配置kube-apiserver
kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/opt/kubernetes/bin/kube-apiserver \
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--advertise-address=192.168.1.100 \
--bind-address=192.168.1.100 \
--insecure-port=0 \
--authorization-mode=Node,RBAC \
--runtime-config=api/all \
--enable-bootstrap-token-auth \
--service-cluster-ip-range=10.0.0.0/24 \
--service-node-port-range=30000-32767 \
--tls-cert-file=/opt/kubernetes/ssl/server.pem \
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-issuer=https://kubernetes.default.svc.cluster.local \
--etcd-cafile=/opt/kubernetes/ssl/ca.pem \
--etcd-certfile=/opt/kubernetes/ssl/server.pem \
--etcd-keyfile=/opt/kubernetes/ssl/server-key.pem \
--etcd-servers=https://192.168.1.100:2379,https://192.168.1.101:2379,https://192.168.1.102:2379 \
--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=/opt/kubernetes/logs/k8s-audit.log \
--event-ttl=1h \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/opt/kubernetes/logs \
--v=2
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
2.5 高可用集群配置
1. 负载均衡器配置
haproxy.cfg
global
log stdout local0
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
mode http
log global
option httplog
option dontlognull
option log-health-checks
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 20s
timeout connect 5s
timeout client 20s
timeout server 20s
timeout http-keep-alive 10s
timeout check 10s
# Kubernetes API Server
frontend k8s-api
bind *:6443
mode tcp
option tcplog
default_backend k8s-api
backend k8s-api
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server k8s-api-1 192.168.1.100:6443 check
server k8s-api-2 192.168.1.101:6443 check
server k8s-api-3 192.168.1.102:6443 check
# Statistics
frontend stats
bind *:8404
stats enable
stats uri /stats
stats refresh 30s
stats admin if TRUE
2. Keepalived配置
keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
admin@example.com
}
notification_email_from keepalived@example.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
script "/bin/bash -c 'if [[ $(netstat -nlp | grep :6443) ]]; then exit 0; else exit 1; fi'"
interval 2
weight -2
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.200/24
}
track_script {
chk_haproxy
}
}
3. 高可用集群初始化
init-ha-cluster.sh
#!/bin/bash
# 高可用集群初始化配置
cat > kubeadm-ha-config.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.1.100
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: 1.28.0
controlPlaneEndpoint: "192.168.1.200:6443"
imageRepository: registry.aliyuncs.com/google_containers
networking:
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16
apiServer:
certSANs:
- "192.168.1.200"
- "192.168.1.100"
- "192.168.1.101"
- "192.168.1.102"
etcd:
local:
serverCertSANs:
- "192.168.1.100"
- "192.168.1.101"
- "192.168.1.102"
peerCertSANs:
- "192.168.1.100"
- "192.168.1.101"
- "192.168.1.102"
EOF
# 初始化第一个Master节点
kubeadm init --config=kubeadm-ha-config.yaml --upload-certs
# 配置kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
echo "第一个Master节点初始化完成!"
echo "请保存以下命令用于添加其他Master节点和Worker节点:"
kubeadm token create --print-join-command
echo "添加Master节点需要额外的--control-plane --certificate-key参数"
2.6 集群验证和测试
1. 集群状态检查
check-cluster.sh
#!/bin/bash
echo "=== 检查集群状态 ==="
# 检查节点状态
echo "1. 节点状态:"
kubectl get nodes -o wide
# 检查系统Pod状态
echo "\n2. 系统Pod状态:"
kubectl get pods -n kube-system
# 检查组件状态
echo "\n3. 组件状态:"
kubectl get componentstatuses
# 检查集群信息
echo "\n4. 集群信息:"
kubectl cluster-info
# 检查API版本
echo "\n5. API版本:"
kubectl api-versions
# 检查存储类
echo "\n6. 存储类:"
kubectl get storageclass
# 检查网络策略
echo "\n7. 网络策略:"
kubectl get networkpolicies --all-namespaces
echo "\n=== 集群检查完成 ==="
2. 部署测试应用
test-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-test
labels:
app: nginx-test
spec:
replicas: 3
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: nginx-test-service
spec:
selector:
app: nginx-test
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
type: NodePort
3. 网络连通性测试
network-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: network-test
spec:
containers:
- name: network-test
image: busybox:1.35
command: ['sh', '-c', 'sleep 3600']
restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
name: network-test-2
spec:
containers:
- name: network-test-2
image: busybox:1.35
command: ['sh', '-c', 'sleep 3600']
restartPolicy: Never
test-network.sh
#!/bin/bash
echo "=== 网络连通性测试 ==="
# 部署测试Pod
kubectl apply -f network-test.yaml
# 等待Pod启动
echo "等待测试Pod启动..."
sleep 30
# 获取Pod IP
POD1_IP=$(kubectl get pod network-test -o jsonpath='{.status.podIP}')
POD2_IP=$(kubectl get pod network-test-2 -o jsonpath='{.status.podIP}')
echo "Pod1 IP: $POD1_IP"
echo "Pod2 IP: $POD2_IP"
# 测试Pod间通信
echo "\n测试Pod间通信:"
kubectl exec network-test -- ping -c 3 $POD2_IP
# 测试DNS解析
echo "\n测试DNS解析:"
kubectl exec network-test -- nslookup kubernetes.default.svc.cluster.local
# 测试外网连通性
echo "\n测试外网连通性:"
kubectl exec network-test -- ping -c 3 8.8.8.8
# 清理测试资源
kubectl delete -f network-test.yaml
echo "\n=== 网络测试完成 ==="
总结
本章详细介绍了Kubernetes集群的安装和配置方法,包括:
安装方式
- kubeadm安装 - 官方推荐的集群部署工具
- 二进制安装 - 手动部署,更灵活的配置选项
- 高可用集群 - 生产环境的多Master节点部署
核心组件
- 容器运行时 - Docker、containerd等容器引擎
- 网络插件 - Flannel、Calico等CNI插件
- 负载均衡 - HAProxy、Keepalived等高可用组件
最佳实践
- 系统准备 - 关闭swap、配置内核参数、时间同步
- 证书管理 - 使用cfssl生成和管理证书
- 配置优化 - 合理配置资源限制和网络参数
- 监控验证 - 部署测试应用验证集群功能
注意事项
- 版本兼容 - 确保各组件版本兼容性
- 网络规划 - 合理规划Pod和Service网段
- 安全配置 - 启用RBAC、配置网络策略
- 备份恢复 - 定期备份etcd数据
下一章我们将学习Pod的详细概念和管理方法,包括Pod的生命周期、资源管理、调度策略等内容。