Kubeadm 简介

kubeadm 是一个提供了 kubeadm init 和 kubeadm join 的工具,作为创建 Kubernetes 集群的 “快捷途径” 的最佳实践

kubeadm 通过执行必要的操作来启动和运行最小可用集群。按照设计,它只关注启动引导,而非配置机器。同样的,安装各种 “锦上添花” 的扩展,例如 Kubernetes Dashboard,监控方案,以及特定云平台的扩展,都不在讨论范围内

k8s 官方社区推出 Kubeadm 工具的原因,就是为了让 kubernetes 集群的部署变得快速简单

安装要求

一台或多台机器,操作系统(CentOS 7、Ubuntu 16.04+、Red Hat Enterprise Linux (RHEL) 7 等)

每台机器 2 GB 或更多的 RAM

2 核 CPU 或更多

集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)

节点之中不可以有重复的主机名、MAC 地址或 product_uuid

禁用 swap 分区

准备环境

节点规划

k8s-master 10.10.110.190
k8s-ndoe1 10.10.110.191
k8s-node2 10.10.110.192

架构图

配置节点

# 关闭防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service

# 关闭seliinux
sed -i 's#^SELINUX=enforcing#SELINUX=disabled#' /etc/selinux/config

# 关闭swap分区
swapoff -a
sed -i 's!^/dev/mapper/centos-swap!#&!' /etc/fstab

# 设置主机名
hostnamectl set-hostname [hostname]

# 配置hosts解析
cat >> /etc/hosts << EOF
10.10.110.190 k8s-master
10.10.110.191 k8s-node1
10.10.110.192 k8s-node2
EOF

# 避免 iptables 被绕过而导致流量无法正确路由
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
vm.swappiness = 0
EOF

sysctl --system    # 确保在此步骤之前已加载了 br_netfilter 模块,这可以通过运行 lsmod | grep br_netfilter 来查看,需要加载请执行 modprobe br_netfilter

# 时间同步
yum install ntpdate -y
ntpdate cn.pool.ntp.org

安装 docker kubeadm kubelet kubectl

在所有节点安装 docker kubeadm kubelet,kubernetes 默认的 CRI 是 docker,因此先安装 docker 。kubeadm 是用来初始化集群的指令,kubelet 负责在集群中的每个节点上用来启动 pod 和容器,kubectl 是用来与集群通信的命令行工具。安装时需要确保kubeadm、kubelet、kubectl 和 kubeadm 安装的版本相匹配,否则存在发生版本偏差的风险

安装 docker

# 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2

# 添加 Docker 阿里云镜像源
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo

# 安装 Docker CE
yum install -y docker-ce

# 启动 Docker 服务并设置开机启动
systemctl start docker
systemctl enable docker

# 配置阿里云镜像服务加速地址
tee /etc/docker/daemon.json << EOF
{
    "registry-mirrors": ["https://265wemgl.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker.service

安装 kubeadm kubelet kubectl

# 添加 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

# 指定版本安装
yum install -y kubelet-1.19.0 kubeadm-1.19.0 kubectl-1.19.0
systemctl enable kubelet

初始化 kubernetes master 节点

在 master 节点执行

kubeadm init \
  --apiserver-advertise-address=10.10.110.190 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.19.0 \
  --service-cidr=10.10.0.0/12 \
  --pod-network-cidr=10.244.0.0/16 \
  --ignore-preflight-errors=all
  • –apiserver-advertise-address 服务器所公布的其正在监听的 IP 地址

  • –image-repository 默认拉取镜像地址为 k8s.gcr.io ,这里指定阿里云镜像仓库地址

  • –kubernetes-version 指定 k8s 安装版本

  • –service-cidr 集群内部虚拟网络,Pod 统一访问入口

  • –pod-network-cidr 指明 pod 网络可以使用的 IP 地址段

拷贝 kubectl 连接 k8s 所使用的认证文件到当前用户的默认路径

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

设置 k8s 命令自动补全

yum install -y epel-release bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

kubernetes 集群添加节点

在 10.10.110.191/192 节点上执行,所有 node 节点都需要执行,执行 kubeadm init 输出的 kubeadm join 命令

kubeadm join 10.10.110.190:6443 --token j3rqzp.ku4k3ift3i6z1hnb \
    --discovery-token-ca-cert-hash sha256:c9460068e3b3bd4d3b111dd1581f50eaada11c2e7a47c958b3a7d158c6ae2170

这时候我们在 master 执行 kubectl get nodes ,发现 node 的状态其实是 NotReady 的

安装 Pod 网络插件

我们必须部署一个基于容器网络接口 (CNI) 的 Pod 网络插件,这样 Pods 之间才可以相互通信。在安装网络之前,群集 DNS (CoreDNS)不会启动,这也是为什么 node 的状态其实是 NotReady 的原因。k8s 常用的网络插件包括 calico、flannel、Canal 和 Weave,这里我们使用 calico 来为 kubernetes 集群提供网络策略支持

部署 calico 网络插件

# 下载 calico 官方配置文件(国内网络可能会下载失败)
wget https://docs.projectcalico.org/manifests/calico.yaml

# 修改 calico 配置文件
- name: CALICO_IPV4POOL_CIDR
  value: "10.244.0.0/16"    # 这个默认网段是192.168.0.0/16,修改成前面 kubeadm init 指定的 --pod-network-cidr 一样

# 应用配置文件
kubectl apply -f calico.yaml

# 查看 pods 运行状态
kubectl get pods -n kube-system

测试 kubernetes 集群

我们在搭建好 kubernetes 集群后,创建一个 pod 验证集群是否正常运行

kubectl create deployment nginx-deploy --image=nginx
kubectl expose deployment nginx-deploy --port=8080 --type=NodePort --target-port=80
kubectl get pod,svc -o wide

NodePort 类型的 service 会从 30000-32767 范围随机分配一个端口
--port 指的是 service CLUSTER-IP 的端口
--target-port 指的是 pod 的端口

[root@k8s-master ~]# kubectl get pod,svc -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
pod/nginx-deploy-8588f9dfb-h28ck   1/1     Running   0          10m   10.244.169.135   k8s-node2   <none>           <none>

NAME                   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE     SELECTOR
service/kubernetes     ClusterIP   10.0.0.1      <none>        443/TCP          6d17h   <none>
service/nginx-deploy   NodePort    10.4.54.140   <none>        8080:31234/TCP   14s     app=nginx-deploy
[root@k8s-master ~]# kubectl get ep
NAME           ENDPOINTS            AGE
kubernetes     10.10.110.190:6443   6d17h
nginx-deploy   10.244.169.135:80    18s

nodeIP:31234 >> 10.4.54.140:8080 >> 10.244.169.135:80

我们使用 NodePort 的方式将 service 暴露出去,如果 service 不指定类型那默认是 ClusterIP,只能集群内部访问

部署 Dashboard

kubernetes dashboard 是一个用于 kubernetes 集群的通用、基于 web 的用户界面。它允许用户管理在集群中运行的应用程序并对其进行故障排除,以及管理集群本身

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml

# dashboard 默认的 service 是 ClusterIP 类型,我们需要修改为 NodePort 类型,才能让外部访问到我们的 dashboard
---
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30023
  selector:
    k8s-app: kubernetes-dashboard
  type: NodePort
---

kubectl apply -f recommended.yaml

dashboard 访问地址: https://nodeIP:30023

# 我们首先在 kubernetes-dashboard 命名空间中创建名为 admin-user 的 service account
kubectl create serviceaccount admin-user -n kubernetes-dashboard
kubectl get serviceaccounts -n kubernetes-dashboard

# 给 admin-user 用户授权
kubectl create clusterrolebinding admin-user --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:admin-user

# 获取 kubernetes-dashboard 命名空间下 admin-user 用户的 token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

使用输出的 token 就可以登录到 dashboard 管理页面