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集群的安装和配置方法,包括:

安装方式

  1. kubeadm安装 - 官方推荐的集群部署工具
  2. 二进制安装 - 手动部署,更灵活的配置选项
  3. 高可用集群 - 生产环境的多Master节点部署

核心组件

  1. 容器运行时 - Docker、containerd等容器引擎
  2. 网络插件 - Flannel、Calico等CNI插件
  3. 负载均衡 - HAProxy、Keepalived等高可用组件

最佳实践

  1. 系统准备 - 关闭swap、配置内核参数、时间同步
  2. 证书管理 - 使用cfssl生成和管理证书
  3. 配置优化 - 合理配置资源限制和网络参数
  4. 监控验证 - 部署测试应用验证集群功能

注意事项

  1. 版本兼容 - 确保各组件版本兼容性
  2. 网络规划 - 合理规划Pod和Service网段
  3. 安全配置 - 启用RBAC、配置网络策略
  4. 备份恢复 - 定期备份etcd数据

下一章我们将学习Pod的详细概念和管理方法,包括Pod的生命周期、资源管理、调度策略等内容。