一、引言

在当今的云计算时代,Kubernetes 已经成为了容器编排和管理领域的事实标准。它能够帮助我们高效地部署、扩展和管理容器化应用程序,大大提高了应用的开发和运维效率。而在 CentOS 8 系统上通过二进制方式部署 K8s 集群,虽然相对复杂一些,但可以让我们更深入地了解 K8s 的各个组件和工作原理。接下来就让我们一步步详细介绍如何在 CentOS 8 系统上进行 K8s 集群的二进制部署。

二、环境准备

1. 服务器规划

我们假设有三台服务器用于搭建 K8s 集群,一台作为主节点(Master),另外两台作为工作节点(Worker)。具体信息如下: | 节点角色 | 主机名 | IP 地址 | | ---- | ---- | ---- | | Master | k8s-master | 192.168.1.100 | | Worker1 | k8s-worker1 | 192.168.1.101 | | Worker2 | k8s-worker2 | 192.168.1.102 |

2. 系统配置

在每台服务器上进行如下操作:

关闭防火墙和 SELinux

# 停止并禁用防火墙
systemctl stop firewalld
systemctl disable firewalld

# 临时关闭 SELinux
setenforce 0
# 永久关闭 SELinux,修改 /etc/selinux/config 文件
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

配置主机名和 hosts 文件

在每台服务器上设置主机名:

# 在 Master 节点上
hostnamectl set-hostname k8s-master
# 在 Worker1 节点上
hostnamectl set-hostname k8s-worker1
# 在 Worker2 节点上
hostnamectl set-hostname k8s-worker2

然后在每台服务器的 /etc/hosts 文件中添加以下内容:

192.168.1.100 k8s-master
192.168.1.101 k8s-worker1
192.168.1.102 k8s-worker2

时间同步

为了避免节点之间时间不一致导致的各种问题,需要进行时间同步。在每台服务器上安装并启动 NTP 服务:

# 安装 NTP 服务
dnf install -y ntpd
# 启动 NTP 服务并设置为开机自启
systemctl start ntpd
systemctl enable ntpd

三、安装 Docker

Kubernetes 依赖于容器运行时,这里我们选择 Docker。在每台服务器上执行以下命令安装 Docker:

# 添加 Docker 官方源
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
# 安装 Docker CE
dnf install -y docker-ce docker-ce-cli containerd.io
# 启动 Docker 并设置为开机自启
systemctl start docker
systemctl enable docker

配置 Docker 的 Cgroup Driver 为 systemd,编辑 /etc/docker/daemon.json 文件,添加以下内容:

{
    "exec-opts": ["native.cgroupdriver=systemd"]
}

然后重启 Docker 服务:

systemctl restart docker

四、下载和部署 K8s 组件

1. 下载 K8s 二进制文件

在 Master 节点上下载 K8s 的二进制文件,你可以从官方 GitHub 仓库下载:

wget https://dl.k8s.io/v1.23.0/kubernetes-server-linux-amd64.tar.gz
# 解压文件
tar -zxvf kubernetes-server-linux-amd64.tar.gz

2. 部署 Master 组件

kube-apiserver

# 创建目录
mkdir -p /etc/kubernetes/manifests /etc/kubernetes/pki /var/lib/kubernetes
# 复制二进制文件
cp kubernetes/server/bin/kube-apiserver /usr/local/bin/
# 创建 kube-apiserver 配置文件
cat <<EOF > /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
  name: kube-apiserver
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-apiserver
    image: k8s.gcr.io/kube-apiserver:v1.23.0
    command:
    - kube-apiserver
    - --advertise-address=192.168.1.100
    - --allow-privileged=true
    - --apiserver-count=1
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/var/lib/kubernetes/ca.crt
    - --enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota
    - --etcd-cafile=/var/lib/kubernetes/ca.crt
    - --etcd-certfile=/var/lib/kubernetes/kubernetes.pem
    - --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem
    - --etcd-servers=https://192.168.1.100:2379
    - --kubelet-certificate-authority=/var/lib/kubernetes/ca.crt
    - --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem
    - --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem
    - --kubelet-https=true
    - --runtime-config=api/all=true
    - --service-account-key-file=/var/lib/kubernetes/service-account.pem
    - --service-account-signing-key-file=/var/lib/kubernetes/service-account-key.pem
    - --service-account-issuer=https://kubernetes.default.svc.cluster.local
    - --service-cluster-ip-range=10.96.0.0/12
    - --service-node-port-range=30000-32767
    - --tls-cert-file=/var/lib/kubernetes/kubernetes.pem
    - --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem
    volumeMounts:
    - name: var-lib-kubernetes
      mountPath: /var/lib/kubernetes
  volumes:
  - name: var-lib-kubernetes
    hostPath:
      path: /var/lib/kubernetes
      type: DirectoryOrCreate
EOF

kube-controller-manager

# 复制二进制文件
cp kubernetes/server/bin/kube-controller-manager /usr/local/bin/
# 创建 kube-controller-manager 配置文件
cat <<EOF > /etc/kubernetes/manifests/kube-controller-manager.yaml
apiVersion: v1
kind: Pod
metadata:
  name: kube-controller-manager
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-controller-manager
    image: k8s.gcr.io/kube-controller-manager:v1.23.0
    command:
    - kube-controller-manager
    - --allocate-node-cidrs=true
    - --cluster-cidr=10.244.0.0/16
    - --cluster-name=kubernetes
    - --cluster-signing-cert-file=/var/lib/kubernetes/ca.crt
    - --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem
    - --controllers=*,bootstrapsigner,tokencleaner
    - --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig
    - --leader-elect=true
    - --root-ca-file=/var/lib/kubernetes/ca.crt
    - --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem
    - --service-cluster-ip-range=10.96.0.0/12
    - --use-service-account-credentials=true
    volumeMounts:
    - name: var-lib-kubernetes
      mountPath: /var/lib/kubernetes
  volumes:
  - name: var-lib-kubernetes
    hostPath:
      path: /var/lib/kubernetes
      type: DirectoryOrCreate
EOF

kube-scheduler

# 复制二进制文件
cp kubernetes/server/bin/kube-scheduler /usr/local/bin/
# 创建 kube-scheduler 配置文件
cat <<EOF > /etc/kubernetes/manifests/kube-scheduler.yaml
apiVersion: v1
kind: Pod
metadata:
  name: kube-scheduler
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-scheduler
    image: k8s.gcr.io/kube-scheduler:v1.23.0
    command:
    - kube-scheduler
    - --kubeconfig=/var/lib/kubernetes/kube-scheduler.kubeconfig
    - --leader-elect=true
    volumeMounts:
    - name: var-lib-kubernetes
      mountPath: /var/lib/kubernetes
  volumes:
  - name: var-lib-kubernetes
    hostPath:
      path: /var/lib/kubernetes
      type: DirectoryOrCreate
EOF

3. 部署 Worker 组件

在 Worker 节点上执行以下操作:

kubelet

# 复制二进制文件
cp kubernetes/server/bin/kubelet /usr/local/bin/
# 创建 kubelet 配置文件
cat <<EOF > /etc/kubernetes/kubelet-config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: true
  x509:
    clientCAFile: "/var/lib/kubernetes/ca.crt"
authorization:
  mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
  - "10.96.0.10"
resolvConf: "/etc/resolv.conf"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/kubelet.crt"
tlsPrivateKeyFile: "/var/lib/kubelet/kubelet.key"
EOF
# 创建 kubelet.service 文件
cat <<EOF > /etc/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service

[Service]
ExecStart=/usr/local/bin/kubelet \\
  --config=/etc/kubernetes/kubelet-config.yaml \\
  --kubeconfig=/var/lib/kubelet/kubeconfig \\
  --bootstrap-kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig \\
  --container-runtime=docker \\
  --container-runtime-endpoint=unix:///var/run/docker.sock \\
  --image-pull-progress-deadline=2m \\
  --kubeconfig=/var/lib/kubelet/kubeconfig \\
  --network-plugin=cni \\
  --register-node=true \\
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

kube-proxy

# 复制二进制文件
cp kubernetes/server/bin/kube-proxy /usr/local/bin/
# 创建 kube-proxy 配置文件
cat <<EOF > /var/lib/kube-proxy/kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
  kubeconfig: "/var/lib/kube-proxy/kubeconfig"
mode: "iptables"
clusterCIDR: "10.244.0.0/16"
EOF
# 创建 kube-proxy.service 文件
cat <<EOF > /etc/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-proxy \\
  --config=/var/lib/kube-proxy/kube-proxy-config.yaml
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

五、配置网络组件

这里我们选择 Calico 作为网络组件。在 Master 节点上执行以下命令:

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

六、验证集群部署

1. 检查 Master 组件状态

在 Master 节点上执行以下命令:

kubectl get pods -n kube-system

如果所有组件的状态都是 Running,则表示 Master 组件部署成功。

2. 检查 Node 状态

kubectl get nodes

如果所有节点的状态都是 Ready,则表示整个 K8s 集群部署成功。

七、应用场景

Kubernetes 在很多场景下都有广泛的应用,比如:

1. 微服务架构

在微服务架构中,Kubernetes 可以帮助我们管理大量的微服务实例,实现服务的自动部署、伸缩和发现。例如,一个电商系统可能由多个微服务组成,如用户服务、商品服务、订单服务等,Kubernetes 可以确保这些微服务的高效运行和良好协作。

2. CI/CD 流水线

在持续集成和持续部署(CI/CD)过程中,Kubernetes 可以作为部署目标,实现应用的快速部署和更新。通过与 Jenkins 等 CI/CD 工具集成,可以实现自动化的构建、测试和部署流程。

八、技术优缺点

优点

1. 高度自动化

Kubernetes 提供了自动部署、伸缩和故障恢复等功能,大大减少了人工干预和运维成本。例如,当应用的负载增加时,Kubernetes 可以自动创建更多的 Pod 实例来处理请求。

2. 开源和生态丰富

Kubernetes 是开源项目,拥有庞大的社区和丰富的生态系统。可以方便地集成各种第三方工具和服务,如监控、日志、安全等。

缺点

1. 复杂性高

Kubernetes 的配置和管理相对复杂,需要有一定的技术基础和经验。对于初学者来说,学习曲线较陡。

2. 资源消耗大

Kubernetes 本身会消耗一定的系统资源,尤其是在大规模集群中。需要合理规划资源,避免资源浪费。

九、注意事项

1. 版本兼容性

在部署 K8s 集群时,要确保各个组件的版本兼容,避免因版本不兼容导致的问题。

2. 安全配置

Kubernetes 涉及到大量的安全配置,如认证、授权、网络策略等。要仔细配置,确保集群的安全性。

3. 网络问题

网络是 K8s 集群正常运行的关键。要确保节点之间的网络连通性,以及网络组件的正确配置。

十、文章总结

通过以上步骤,我们详细介绍了在 CentOS 8 系统上通过二进制方式部署 K8s 集群的过程。从环境准备到各个组件的安装和配置,再到网络组件的部署和集群的验证,每一步都至关重要。Kubernetes 作为容器编排和管理的强大工具,在微服务架构和 CI/CD 等场景中有着广泛的应用。虽然它具有高效、自动化等优点,但也存在复杂性高和资源消耗大等缺点。在实际应用中,要注意版本兼容性、安全配置和网络问题等。希望本文能帮助你成功搭建 K8s 集群,更好地利用 Kubernetes 的强大功能。